def set_scale_factor(self, scale_factor, unit_system="SI"): SymPyDeprecationWarning( deprecated_since_version="1.5", issue=17765, feature="Moving method to UnitSystem class", useinstead= "unit_system.set_quantity_scale_factor or {}.set_global_relative_scale_factor" .format(self), ).warn() from sympy.physics.units import UnitSystem unit_system = UnitSystem.get_unit_system(unit_system) unit_system.set_quantity_scale_factor(self, scale_factor)
def _collect_factor_and_dimension(expr, unit_system="SI"): """Return tuple with scale factor expression and dimension expression.""" SymPyDeprecationWarning( deprecated_since_version="1.5", issue=17765, feature="This method has been moved to the UnitSystem class.", useinstead="unit_system._collect_factor_and_dimension", ).warn() from sympy.physics.units import UnitSystem unit_system = UnitSystem.get_unit_system(unit_system) return unit_system._collect_factor_and_dimension(expr)
def set_dimension(self, dimension, unit_system="SI"): sympy_deprecation_warning( f""" Quantity.set_dimension() is deprecated. Use either unit_system.set_quantity_dimension() or {self}.set_global_dimension() instead. """, deprecated_since_version="1.5", active_deprecations_target="deprecated-quantity-methods", ) from sympy.physics.units import UnitSystem unit_system = UnitSystem.get_unit_system(unit_system) unit_system.set_quantity_dimension(self, dimension)
def get_dimensional_expr(expr, unit_system="SI"): SymPyDeprecationWarning( deprecated_since_version="1.5", issue=17765, feature= "get_dimensional_expr() is now associated with UnitSystem objects. " "The dimensional relations depend on the unit system used.", useinstead="unit_system.get_dimensional_expr", ).warn() from sympy.physics.units import UnitSystem unit_system = UnitSystem.get_unit_system(unit_system) return unit_system.get_dimensional_expr(expr)
def get_dimensional_expr(expr, unit_system="SI"): sympy_deprecation_warning( """ Quantity.get_dimensional_expr() is deprecated. It is now associated with UnitSystem objects. The dimensional relations depend on the unit system used. Use unit_system.get_dimensional_expr() instead. """, deprecated_since_version="1.5", active_deprecations_target="deprecated-quantity-methods", ) from sympy.physics.units import UnitSystem unit_system = UnitSystem.get_unit_system(unit_system) return unit_system.get_dimensional_expr(expr)
def _collect_factor_and_dimension(expr, unit_system="SI"): """Return tuple with scale factor expression and dimension expression.""" sympy_deprecation_warning( """ Quantity._collect_factor_and_dimension() is deprecated. This method has been moved to the UnitSystem class. Use unit_system._collect_factor_and_dimension(expr) instead. """, deprecated_since_version="1.5", active_deprecations_target="deprecated-quantity-methods", ) from sympy.physics.units import UnitSystem unit_system = UnitSystem.get_unit_system(unit_system) return unit_system._collect_factor_and_dimension(expr)
def convert_to(cls, expr, target_units=None, unit_system="SI"): """depend on sympy 1.5-1.6!!!""" from sympy.physics.units import UnitSystem unit_system = UnitSystem.get_unit_system(unit_system) if not target_units: target_units = unit_system._base_units if not isinstance(target_units, (Iterable, Tuple)): target_units = [target_units] if isinstance(expr, Add): raise TypeError("can not be add") expr = sympify(expr) if not isinstance(expr, Quantity) and expr.has(Quantity): expr = expr.replace( lambda x: isinstance(x, Quantity), lambda x: x.convert_to(target_units, unit_system)) def get_total_scale_factor(expr0): if isinstance(expr0, Mul): return reduce(lambda x, y: x * y, [get_total_scale_factor(i) for i in expr0.args]) elif isinstance(expr0, Pow): return get_total_scale_factor(expr0.base)**expr0.exp elif isinstance(expr0, Quantity): return unit_system.get_quantity_scale_factor(expr0) return expr0 depmat, canon_dim_units = cls._get_conversion_matrix_for_expr( expr, target_units, unit_system) if depmat is None: raise TypeError("There is an invalid character in '%s'" % expr, "the expr must be sympy.physics.unit or number") expr_scale_factor = get_total_scale_factor(expr) dim_dict = {} for u, p in zip(target_units, depmat): expr_scale_factor /= get_total_scale_factor(u)**p dim_dict["%s" % u] = p d = cls(np.array(list(dim_dict.values()))) d.dim = canon_dim_units d.unit = target_units return expr_scale_factor, d
def inverse_convert(cls, dim, scale=1, target_units=None, unit_system="SI"): """ depend on sympy 1.5-1.6!!! Quick method. Translate ui to other unit. Parameters ---------- dim: Dim dim scale: float scale generated before. target_units: None or list of sympy.physics.unit if None, the target_units is 7 SI units unit_system: str default is unit_system="SI" Returns ------- scale: float expr: Expr """ from sympy.physics.units import UnitSystem unit_system = UnitSystem.get_unit_system(unit_system) if not target_units: target_units = unit_system._base_units if not isinstance(target_units, (Iterable, Tuple)): target_units = [target_units] def get_total_scale_factor(expr): if isinstance(expr, Mul): return reduce(lambda x, y: x * y, [get_total_scale_factor(i) for i in expr.args]) elif isinstance(expr, Pow): return get_total_scale_factor(expr.base) ** expr.exp elif isinstance(expr, Quantity): return unit_system.get_quantity_scale_factor(expr) return expr sc = scale * Mul.fromiter(1 / get_total_scale_factor(u) ** p for u, p in zip(target_units, dim)) sc = sc * Mul.fromiter(1 / get_total_scale_factor(u) ** p for u, p in zip(unit_system._base_units, dim)) tar = Mul.fromiter((1 / get_total_scale_factor(u) * u) ** p for u, p in zip(target_units, dim)) bas = Mul.fromiter((get_total_scale_factor(u)) ** p for u, p in zip(unit_system._base_units, dim)) return sc, scale * tar * bas
def check_dimensions(expr, unit_system="SI"): """Return expr if there are not unitless values added to dimensional quantities, else raise a ValueError.""" # the case of adding a number to a dimensional quantity # is ignored for the sake of SymPy core routines, so this # function will raise an error now if such an addend is # found. # Also, when doing substitutions, multiplicative constants # might be introduced, so remove those now from sympy.physics.units import UnitSystem unit_system = UnitSystem.get_unit_system(unit_system) adds = expr.atoms(Add) DIM_OF = unit_system.get_dimension_system().get_dimensional_dependencies for a in adds: deset = set() for ai in a.args: if ai.is_number: deset.add(()) continue dims = [] skip = False for i in Mul.make_args(ai): if i.has(Quantity): i = Dimension(unit_system.get_dimensional_expr(i)) if i.has(Dimension): dims.extend(DIM_OF(i).items()) elif i.free_symbols: skip = True break if not skip: deset.add(tuple(sorted(dims))) if len(deset) > 1: raise ValueError( "addends have incompatible dimensions") # clear multiplicative constants on Dimensions which may be # left after substitution reps = {} for m in expr.atoms(Mul): if any(isinstance(i, Dimension) for i in m.args): reps[m] = m.func(*[ i for i in m.args if not i.is_number]) return expr.xreplace(reps)
def __init__(self, unit_system="SI"): self.unit_system = UnitSystem.get_unit_system(unit_system) self.dim_sys = self.unit_system.get_dimension_system() self._mapping = {} for i in u.__dict__: unit = getattr(u, i) if not isinstance(unit, u.Quantity): continue key = self._makekey(unit) # Use earlier defined units if key not in self._mapping: self._mapping[key] = unit # Remove entry for no units. self._mapping.pop(self._makekey(1)) # Add entry for S * ohm, etc. key = (None, ) * len(key) self._mapping[key] = S.One
def get_kamodo_unit_system(): """Same as SI but supports anglular frequency""" radian = sympy.physics.units.radian degree = sympy.physics.units.degree si_unit_system = UnitSystem.get_unit_system('SI') si_dimension_system = si_unit_system.get_dimension_system() angle = Dimension('angle', 'A') kamodo_dims = si_dimension_system.extend( new_base_dims=(angle, ), new_derived_dims=[Dimension('angular_velocity')], new_dim_deps={ Symbol('angular_velocity'): { Symbol('angle'): 1, Symbol('time'): -1 } }) kamodo_units = si_unit_system.extend((radian, ), (radian, degree), dimension_system=kamodo_dims) return kamodo_units
units = [m, g, s, J, N, W, Pa, Hz] all_units = [] # Prefixes of units like g, J, N etc get added using `prefix_unit` # in the for loop, but the actual units have to be added manually. all_units.extend([g, J, N, W, Pa, Hz]) for u in units: all_units.extend(prefix_unit(u, PREFIXES)) all_units.extend([G, c]) # unit system MKS = UnitSystem( base_units=(m, kg, s), units=all_units, name="MKS", dimension_system=dimsys_length_weight_time, ) __all__ = [ "force", "division", "DimensionSystem", "energy", "Pa", "MKS", "dimsys_length_weight_time", "Hz", "power", "s", "UnitSystem",
units = [meter, gram, second, joule, newton, watt, pascal, hertz] all_units = [] # Prefixes of units like gram, joule, newton etc get added using `prefix_unit` # in the for loop, but the actual units have to be added manually. all_units.extend([gram, joule, newton, watt, pascal, hertz]) for u in units: all_units.extend(prefix_unit(u, PREFIXES)) all_units.extend([gravitational_constant, speed_of_light]) # unit system MKS = UnitSystem(base_units=(meter, kilogram, second), units=all_units, name="MKS", dimension_system=dimsys_length_weight_time, derived_units={ power: watt, time: second, pressure: pascal, length: meter, frequency: hertz, mass: kilogram, force: newton, energy: joule, velocity: meter/second, acceleration: meter/(second**2), }) __all__ = [ 'MKS', 'units', 'all_units', 'dims', ]
for u in units: all_units.extend(prefix_unit(u, PREFIXES)) all_units.extend([G, c]) dimsys_MKS = DimensionSystem( [ # Dimensional dependencies for MKS base dimensions length, mass, time, ], dimensional_dependencies=dict( # Dimensional dependencies for derived dimensions velocity=dict(length=1, time=-1), acceleration=dict(length=1, time=-2), momentum=dict(mass=1, length=1, time=-1), force=dict(mass=1, length=1, time=-2), energy=dict(mass=1, length=2, time=-2), power=dict(length=2, mass=1, time=-3), pressure=dict(mass=1, length=-1, time=-2), frequency=dict(time=-1), action=dict(length=2, mass=1, time=-1), volume=dict(length=3), )) # unit system MKS = UnitSystem(base_units=(m, kg, s), units=all_units, name="MKS", dimension_system=dimsys_MKS)
from __future__ import division from sympy.physics.units import DimensionSystem, UnitSystem from sympy.physics.units.definitions import G, Hz, J, N, Pa, W, c, g, kg, m, s from sympy.physics.units.dimensions import (acceleration, action, energy, force, frequency, length, mass, momentum, power, pressure, time, velocity, dimsys_MKS) from sympy.physics.units.prefixes import PREFIXES, prefix_unit dims = (velocity, acceleration, momentum, force, energy, power, pressure, frequency, action) # dimension system _mks_dim = dimsys_MKS units = [m, g, s, J, N, W, Pa, Hz] all_units = [] # Prefixes of units like g, J, N etc get added using `prefix_unit` # in the for loop, but the actual units have to be added manually. all_units.extend([g, J, N, W, Pa, Hz]) for u in units: all_units.extend(prefix_unit(u, PREFIXES)) all_units.extend([G, c]) # unit system MKS = UnitSystem(base=(m, kg, s), units=all_units, name="MKS")
def dimension(self): from sympy.physics.units import UnitSystem unit_system = UnitSystem.get_default_unit_system() return unit_system.get_quantity_dimension(self)
def convert_to(expr, target_units, unit_system="SI"): """ Convert ``expr`` to the same expression with all of its units and quantities represented as factors of ``target_units``, whenever the dimension is compatible. ``target_units`` may be a single unit/quantity, or a collection of units/quantities. Examples ======== >>> from sympy.physics.units import speed_of_light, meter, gram, second, day >>> from sympy.physics.units import mile, newton, kilogram, atomic_mass_constant >>> from sympy.physics.units import kilometer, centimeter >>> from sympy.physics.units import gravitational_constant, hbar >>> from sympy.physics.units import convert_to >>> convert_to(mile, kilometer) 25146*kilometer/15625 >>> convert_to(mile, kilometer).n() 1.609344*kilometer >>> convert_to(speed_of_light, meter/second) 299792458*meter/second >>> convert_to(day, second) 86400*second >>> 3*newton 3*newton >>> convert_to(3*newton, kilogram*meter/second**2) 3*kilogram*meter/second**2 >>> convert_to(atomic_mass_constant, gram) 1.660539060e-24*gram Conversion to multiple units: >>> convert_to(speed_of_light, [meter, second]) 299792458*meter/second >>> convert_to(3*newton, [centimeter, gram, second]) 300000*centimeter*gram/second**2 Conversion to Planck units: >>> from sympy.physics.units import gravitational_constant, hbar >>> convert_to(atomic_mass_constant, [gravitational_constant, speed_of_light, hbar]).n() 7.62963085040767e-20*gravitational_constant**(-0.5)*hbar**0.5*speed_of_light**0.5 """ from sympy.physics.units import UnitSystem unit_system = UnitSystem.get_unit_system(unit_system) if not isinstance(target_units, (Iterable, Tuple)): target_units = [target_units] if isinstance(expr, Add): return Add.fromiter( convert_to(i, target_units, unit_system) for i in expr.args) expr = sympify(expr) if not isinstance(expr, Quantity) and expr.has(Quantity): expr = expr.replace(lambda x: isinstance(x, Quantity), lambda x: x.convert_to(target_units, unit_system)) def get_total_scale_factor(expr): if isinstance(expr, Mul): return reduce(lambda x, y: x * y, [get_total_scale_factor(i) for i in expr.args]) elif isinstance(expr, Pow): return get_total_scale_factor(expr.base)**expr.exp elif isinstance(expr, Quantity): return unit_system.get_quantity_scale_factor(expr) return expr depmat = _get_conversion_matrix_for_expr(expr, target_units, unit_system) if depmat is None: return expr expr_scale_factor = get_total_scale_factor(expr) return expr_scale_factor * Mul.fromiter( (1 / get_total_scale_factor(u) * u)**p for u, p in zip(target_units, depmat))
def convert_unit_to(expr, target_units, unit_system=kamodo_unit_system, raise_errors=True): """ Same as sympy.convert_to but accepts equations and allows functions of units to pass Convert ``expr`` to the same expression with all of its units and quantities represented as factors of ``target_units``, whenever the dimension is compatible. ``target_units`` may be a single unit/quantity, or a collection of units/quantities. Examples ======== >>> from sympy.physics.units import speed_of_light, meter, gram, second, day >>> from sympy.physics.units import mile, newton, kilogram, atomic_mass_constant >>> from sympy.physics.units import kilometer, centimeter >>> from sympy.physics.units import gravitational_constant, hbar >>> from sympy.physics.units import convert_to >>> convert_to(mile, kilometer) 25146*kilometer/15625 >>> convert_to(mile, kilometer).n() 1.609344*kilometer >>> convert_to(speed_of_light, meter/second) 299792458*meter/second >>> convert_to(day, second) 86400*second >>> 3*newton 3*newton >>> convert_to(3*newton, kilogram*meter/second**2) 3*kilogram*meter/second**2 >>> convert_to(atomic_mass_constant, gram) 1.660539060e-24*gram Conversion to multiple units: >>> convert_to(speed_of_light, [meter, second]) 299792458*meter/second >>> convert_to(3*newton, [centimeter, gram, second]) 300000*centimeter*gram/second**2 Conversion to Planck units: >>> from sympy.physics.units import gravitational_constant, hbar >>> convert_to(atomic_mass_constant, [gravitational_constant, speed_of_light, hbar]).n() 7.62963085040767e-20*gravitational_constant**(-0.5)*hbar**0.5*speed_of_light**0.5 """ from sympy.physics.units import UnitSystem unit_system = UnitSystem.get_unit_system(unit_system) if not isinstance(target_units, (Iterable, Tuple)): target_units = [target_units] if hasattr(expr, 'rhs'): return Eq(convert_unit_to(expr.lhs, target_units, unit_system), convert_unit_to(expr.rhs, target_units, unit_system)) # if type(type(expr)) is UndefinedFunction: if is_function(expr): # print('undefined input expr:{}'.format(expr)) return nsimplify(expr, rational=True) if isinstance(expr, Add): return Add.fromiter( convert_unit_to(i, target_units, unit_system) for i in expr.args) expr = sympify(expr) if not isinstance(expr, Quantity) and expr.has(Quantity): try: expr = expr.replace( lambda x: isinstance(x, Quantity), lambda x: x.convert_to(target_units, unit_system)) except OSError: raise OSError('problem converting {} to {}\n{}'.format( expr, target_units, unit_system)) def get_total_scale_factor(expr): if isinstance(expr, Mul): return reduce(lambda x, y: x * y, [get_total_scale_factor(i) for i in expr.args]) elif isinstance(expr, Pow): return get_total_scale_factor(expr.base)**expr.exp elif isinstance(expr, Quantity): return unit_system.get_quantity_scale_factor(expr) return expr if expr == target_units: return expr depmat = _get_conversion_matrix_for_expr(expr, target_units, unit_system) if depmat is None: if raise_errors: raise NameError('cannot convert {} to {} {}'.format( expr, target_units, unit_system)) return nsimplify(expr, rational=True) expr_scale_factor = get_total_scale_factor(expr) result = expr_scale_factor * Mul.fromiter( (1 / get_total_scale_factor(u) * u)**p for u, p in zip(target_units, depmat)) return nsimplify(result, rational=True)
[], new_dim_deps=dict( # Dimensional dependencies for derived dimensions impedance=dict(time=1, length=-1), conductance=dict(time=-1, length=1), capacitance=dict(length=1), inductance=dict(time=2, length=-1), charge=dict(mass=S.Half, length=S(3) / 2, time=-1), current=dict(mass=One / 2, length=3 * One / 2, time=-2), voltage=dict(length=-One / 2, mass=One / 2, time=-1), magnetic_density=dict(length=-One / 2, mass=One / 2, time=-1), magnetic_flux=dict(length=3 * One / 2, mass=One / 2, time=-1), )) cgs_gauss = UnitSystem(base_units=[centimeter, gram, second], units=[], name="cgs_gauss", dimension_system=dimsys_cgs) cgs_gauss.set_quantity_scale_factor(coulombs_constant, 1) cgs_gauss.set_quantity_dimension(statcoulomb, charge) cgs_gauss.set_quantity_scale_factor( statcoulomb, centimeter**(S(3) / 2) * gram**(S(1) / 2) / second) cgs_gauss.set_quantity_dimension(coulomb, charge) cgs_gauss.set_quantity_dimension(statampere, current) cgs_gauss.set_quantity_scale_factor(statampere, statcoulomb / second) cgs_gauss.set_quantity_dimension(statvolt, voltage)