def prefix_unit(unit, prefixes): """ Return a list of all units formed by unit and the given prefixes. You can use the predefined PREFIXES or BIN_PREFIXES, but you can also pass as argument a subdict of them if you don't want all prefixed units. >>> from sympy.physics.units.prefixes import (PREFIXES, ... prefix_unit) >>> from sympy.physics.units.systems import MKS >>> from sympy.physics.units import m >>> pref = {"m": PREFIXES["m"], "c": PREFIXES["c"], "d": PREFIXES["d"]} >>> prefix_unit(m, pref) #doctest: +SKIP [cm, dm, mm] """ from sympy.physics.units.quantities import Quantity prefixed_units = [] for prefix_abbr, prefix in prefixes.items(): quantity = Quantity( "%s%s" % (prefix.name, unit.name), abbrev=("%s%s" % (prefix.abbrev, unit.abbrev)) ) quantity.set_dimension(unit.dimension) quantity.set_scale_factor(unit.scale_factor*prefix) prefixed_units.append(quantity) return prefixed_units
def test_extend(): ms = UnitSystem((m, s), (c,)) Js = Quantity("Js") Js.set_dimension(action) Js.set_scale_factor(1) mks = ms.extend((kg,), (Js,)) res = UnitSystem((m, s, kg), (c, Js)) assert set(mks._base_units) == set(res._base_units) assert set(mks._units) == set(res._units)
def test_convert_to(): q = Quantity("q1", length, 5000) assert q.convert_to(m) == 5000*m assert speed_of_light.convert_to(m / s) == 299792458 * m / s # TODO: eventually support this kind of conversion: # assert (2*speed_of_light).convert_to(m / s) == 2 * 299792458 * m / s assert day.convert_to(s) == 86400*s # Wrong dimension to convert: assert q.convert_to(s) == q assert speed_of_light.convert_to(m) == speed_of_light
def test_print_unit_base(): A = Quantity("A") A.set_dimension(current) A.set_scale_factor(S.One) Js = Quantity("Js") Js.set_dimension(action) Js.set_scale_factor(S.One) mksa = UnitSystem((m, kg, s, A), (Js,)) with warns_deprecated_sympy(): assert mksa.print_unit_base(Js) == m**2*kg*s**-1
def test_factor_and_dimension(): assert (3000, Dimension(1)) == Quantity._collect_factor_and_dimension(3000) assert (1001, length) == Quantity._collect_factor_and_dimension(meter + km) assert (2, length/time) == Quantity._collect_factor_and_dimension( meter/second + 36*km/(10*hour)) x, y = symbols('x y') assert (x + y/100, length) == Quantity._collect_factor_and_dimension( x*m + y*centimeter) cH = Quantity('cH', amount_of_substance/volume) pH = -log(cH) assert (1, volume/amount_of_substance) == Quantity._collect_factor_and_dimension( exp(pH)) v_w1 = Quantity('v_w1', length/time, S(3)/2*meter/second) v_w2 = Quantity('v_w2', length/time, 2*meter/second) expr = Abs(v_w1/2 - v_w2) assert (S(5)/4, length/time) == \ Quantity._collect_factor_and_dimension(expr) expr = S(5)/2*second/meter*v_w1 - 3000 assert (-(2996 + S(1)/4), Dimension(1)) == \ Quantity._collect_factor_and_dimension(expr) expr = v_w1**(v_w2/v_w1) assert ((S(3)/2)**(S(4)/3), (length/time)**(S(4)/3)) == \ Quantity._collect_factor_and_dimension(expr)
def test_print_unit_base(): with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=SymPyDeprecationWarning) A = Quantity("A") A.set_dimension(current) A.set_scale_factor(S.One) Js = Quantity("Js") Js.set_dimension(action) Js.set_scale_factor(S.One) mksa = UnitSystem((m, kg, s, A), (Js,)) assert mksa.print_unit_base(Js) == m**2*kg*s**-1/1000
def __add__(self, other): from sympy.physics.units.quantities import Quantity other = sympify(other) if isinstance(other, Basic): if other.has(Quantity): other = Dimension(Quantity.get_dimensional_expr(other)) if isinstance(other, Dimension) and self == other: return self return super(Dimension, self).__add__(other) return self
def test_definition(): # want to test if the system can have several units of the same dimension dm = Quantity("dm") dm.set_dimension(length) dm.set_scale_factor(Rational(1, 10)) base = (m, s) base_dim = (m.dimension, s.dimension) ms = UnitSystem(base, (c, dm), "MS", "MS system") assert set(ms._base_units) == set(base) assert set(ms._units) == set((m, s, c, dm)) #assert ms._units == DimensionSystem._sort_dims(base + (velocity,)) assert ms.name == "MS" assert ms.descr == "MS system" assert ms._system.base_dims == base_dim assert ms._system.derived_dims == (velocity,)
def _get_conversion_matrix_for_expr(expr, target_units): from sympy import Matrix expr_dim = Dimension(Quantity.get_dimensional_expr(expr)) dim_dependencies = expr_dim.get_dimensional_dependencies(mark_dimensionless=True) target_dims = [Dimension(Quantity.get_dimensional_expr(x)) for x in target_units] canon_dim_units = {i for x in target_dims for i in x.get_dimensional_dependencies(mark_dimensionless=True)} canon_expr_units = {i for i in dim_dependencies} if not canon_expr_units.issubset(canon_dim_units): return None canon_dim_units = sorted(canon_dim_units) camat = Matrix([[i.get_dimensional_dependencies(mark_dimensionless=True).get(j, 0) for i in target_dims] for j in canon_dim_units]) exprmat = Matrix([dim_dependencies.get(k, 0) for k in canon_dim_units]) res_exponents = camat.solve_least_squares(exprmat, method=None) return res_exponents
def __mul__(self, other): from sympy.physics.units.quantities import Quantity if isinstance(other, Basic): if other.has(Quantity): other = Dimension(Quantity.get_dimensional_expr(other)) if isinstance(other, Dimension): return Dimension(self.name*other.name) if not other.free_symbols: # other.is_number cannot be used return self return super(Dimension, self).__mul__(other) return self
def test_quantity_postprocessing(): q1 = Quantity('q1', length*pressure**2*temperature/time) q2 = Quantity('q2', energy*pressure*temperature/(length**2*time)) assert q1 + q2 q = q1 + q2 Dq = Dimension(Quantity.get_dimensional_expr(q)) assert dimsys_default.get_dimensional_dependencies(Dq) == { 'length': -1, 'mass': 2, 'temperature': 1, 'time': -5, }
def test_quantity_abs(): v_w1 = Quantity('v_w1', length/time, meter/second) v_w2 = Quantity('v_w2', length/time, meter/second) v_w3 = Quantity('v_w3', length/time, meter/second) expr = v_w3 - Abs(v_w1 - v_w2) Dq = Dimension(Quantity.get_dimensional_expr(expr)) assert dimsys_default.get_dimensional_dependencies(Dq) == { 'length': 1, 'time': -1, } assert meter == sqrt(meter**2)
def prefix_unit(unit, prefixes): """ Return a list of all units formed by unit and the given prefixes. You can use the predefined PREFIXES or BIN_PREFIXES, but you can also pass as argument a subdict of them if you don't want all prefixed units. >>> from sympy.physics.units.prefixes import (PREFIXES, ... prefix_unit) >>> from sympy.physics.units.systems import MKS >>> from sympy.physics.units import m >>> pref = {"m": PREFIXES["m"], "c": PREFIXES["c"], "d": PREFIXES["d"]} >>> prefix_unit(m, pref) #doctest: +SKIP [cm, dm, mm] """ from sympy.physics.units.quantities import Quantity prefixed_units = [] for prefix_abbr, prefix in prefixes.items(): quantity = Quantity("%s%s" % (prefix.name, unit.name), abbrev=("%s%s" % (prefix.abbrev, unit.abbrev))) quantity.set_dimension(unit.dimension) quantity.set_scale_factor(unit.scale_factor * prefix) prefixed_units.append(quantity) return prefixed_units
def test_deprecated_quantity_methods(): step = Quantity("step") with warns_deprecated_sympy(): step.set_dimension(length) step.set_scale_factor(2*meter) assert convert_to(step, centimeter) == 200*centimeter assert convert_to(1000*step/second, kilometer/second) == 2*kilometer/second
def test_factor_and_dimension(): assert (3000, Dimension(1)) == SI._collect_factor_and_dimension(3000) assert (1001, length) == SI._collect_factor_and_dimension(meter + km) assert (2, length / time) == SI._collect_factor_and_dimension(meter / second + 36 * km / (10 * hour)) x, y = symbols('x y') assert (x + y / 100, length) == SI._collect_factor_and_dimension(x * m + y * centimeter) cH = Quantity('cH') SI.set_quantity_dimension(cH, amount_of_substance / volume) pH = -log(cH) assert (1, volume / amount_of_substance) == SI._collect_factor_and_dimension(exp(pH)) v_w1 = Quantity('v_w1') v_w2 = Quantity('v_w2') v_w1.set_global_relative_scale_factor(Rational(3, 2), meter / second) v_w2.set_global_relative_scale_factor(2, meter / second) expr = Abs(v_w1 / 2 - v_w2) assert (Rational(5, 4), length/time) == \ SI._collect_factor_and_dimension(expr) expr = Rational(5, 2) * second / meter * v_w1 - 3000 assert (-(2996 + Rational(1, 4)), Dimension(1)) == \ SI._collect_factor_and_dimension(expr) expr = v_w1**(v_w2 / v_w1) assert ((Rational(3, 2))**Rational(4, 3), (length/time)**Rational(4, 3)) == \ SI._collect_factor_and_dimension(expr) with warns_deprecated_sympy(): assert (3000, Dimension(1)) == Quantity._collect_factor_and_dimension(3000)
def test_factor_and_dimension_with_Abs(): with warns_deprecated_sympy(): v_w1 = Quantity('v_w1', length/time, S(3)/2*meter/second) v_w1.set_dimension(length/time) v_w1.set_scale_factor(S(3)/2*meter/second) expr = v_w1 - Abs(v_w1) assert (0, length/time) == Quantity._collect_factor_and_dimension(expr)
def dim_simplify(expr): """ NOTE: this function could be deprecated in the future. Simplify expression by recursively evaluating the dimension arguments. This function proceeds to a very rough dimensional analysis. It tries to simplify expression with dimensions, and it deletes all what multiplies a dimension without being a dimension. This is necessary to avoid strange behavior when Add(L, L) be transformed into Mul(2, L). """ _, expr = Quantity._collect_factor_and_dimension(expr) return expr
def test_convert_to(): q = Quantity("q1") q.set_dimension(length) q.set_scale_factor(S(5000)) assert q.convert_to(m) == 5000*m assert speed_of_light.convert_to(m / s) == 299792458 * m / s # TODO: eventually support this kind of conversion: # assert (2*speed_of_light).convert_to(m / s) == 2 * 299792458 * m / s assert day.convert_to(s) == 86400*s # Wrong dimension to convert: assert q.convert_to(s) == q assert speed_of_light.convert_to(m) == speed_of_light
def test_definition(): # want to test if the system can have several units of the same dimension dm = Quantity("dm") base = (m, s) # base_dim = (m.dimension, s.dimension) ms = UnitSystem(base, (c, dm), "MS", "MS system") ms.set_quantity_dimension(dm, length) ms.set_quantity_scale_factor(dm, Rational(1, 10)) assert set(ms._base_units) == set(base) assert set(ms._units) == {m, s, c, dm} # assert ms._units == DimensionSystem._sort_dims(base + (velocity,)) assert ms.name == "MS" assert ms.descr == "MS system"
def test_mul_div(): u = Quantity("u", length, 10) assert 1 / u == u**(-1) assert u / 1 == u v1 = u / Quantity("t", time, 2) v2 = Quantity("v", length / time, 5) # Pow only supports structural equality: assert v1 != v2 assert v1 == v2.convert_to(v1) # TODO: decide whether to allow such expression in the future # (requires somehow manipulating the core). #assert u / Quantity(length, 2) == 5 assert u * 1 == u ut1 = u * Quantity("t", time, 2) ut2 = Quantity("ut", length*time, 20) # Mul only supports structural equality: assert ut1 != ut2 assert ut1 == ut2.convert_to(ut1) # Mul only supports structural equality: assert u * Quantity("lp1", length**-1, 2) != 20 assert u**0 == 1 assert u**1 == u # TODO: Pow only support structural equality: assert u ** 2 != Quantity("u2", length ** 2, 100) assert u ** -1 != Quantity("u3", length ** -1, 0.1) assert u ** 2 == Quantity("u2", length ** 2, 100).convert_to(u) assert u ** -1 == Quantity("u3", length ** -1, S.One/10).convert_to(u)
def _convert_to(expr, quantity): if isinstance(expr, Add): return Add(*[_convert_to(i, quantity) for i in expr.args]) elif isinstance(expr, Mul): new_args = [_convert_to(i, quantity) for i in expr.args] edim = Dimension(Quantity.get_dimensional_expr(expr)) if edim == quantity.dimension: scale_factor_old = get_total_scale_factor(expr) return expr / get_units( expr) * scale_factor_old / quantity.scale_factor * quantity return Mul(*new_args) elif isinstance(expr, Pow): base = _convert_to(expr.base, quantity) edim = Dimension(Quantity.get_dimensional_expr(base))**expr.exp if edim == quantity.dimension: scale_factor_old = get_total_scale_factor(expr) return expr / get_units( expr) * scale_factor_old / quantity.scale_factor * quantity return base**expr.exp elif isinstance(expr, Quantity): edim = Dimension(Quantity.get_dimensional_expr(expr)) edep1 = edim.get_dimensional_dependencies() edep2 = quantity.dimension.get_dimensional_dependencies() if edim == quantity.dimension: return expr.scale_factor / quantity.scale_factor * quantity if set(edep1.keys()) == set(edep2.keys()): fracs = [ Rational(v1, v2) for v1, v2 in zip(edep1.values(), edep2.values()) ] powers = list(set(fracs)) if len(powers) == 1: return expr.scale_factor / quantity.scale_factor**powers[ 0] * quantity**powers[0] else: return expr return expr
def test_extend(): ms = UnitSystem((m, s), (c, )) Js = Quantity("Js") Js.set_dimension(action) Js.set_scale_factor(1) mks = ms.extend((kg, ), (Js, )) res = UnitSystem((m, s, kg), (c, Js)) assert set(mks._base_units) == set(res._base_units) assert set(mks._units) == set(res._units)
def test_definition(): # want to test if the system can have several units of the same dimension dm = Quantity("dm", length, Rational(1, 10)) base = (m, s) base_dim = (m.dimension, s.dimension) ms = UnitSystem(base, (c, dm), "MS", "MS system") assert set(ms._base_units) == set(base) assert set(ms._units) == set((m, s, c, dm)) #assert ms._units == DimensionSystem._sort_dims(base + (velocity,)) assert ms.name == "MS" assert ms.descr == "MS system" assert ms._system._base_dims == DimensionSystem.sort_dims(base_dim) assert set(ms._system._dims) == set(base_dim + (velocity,))
def test_add_sub(): u = Quantity("u", length, 10) v = Quantity("v", length, 5) w = Quantity("w", time, 2) assert isinstance(u + v, Add) assert (u + v.convert_to(u)) == (1 + S.Half)*u # TODO: eventually add this: # assert (u + v).convert_to(u) == (1 + S.Half)*u assert isinstance(u - v, Add) assert (u - v.convert_to(u)) == S.Half*u
def test_dimensional_expr_of_derivative(): l = Quantity('l', length, 36 * km) t = Quantity('t', time, hour) t1 = Quantity('t1', time, second) x = Symbol('x') y = Symbol('y') f = Function('f') dfdx = f(x, y).diff(x, y) dl_dt = dfdx.subs({f(x, y): l, x: t, y: t1}) assert Quantity.get_dimensional_expr(dl_dt) ==\ Quantity.get_dimensional_expr(l / t / t1) ==\ Symbol("length")/Symbol("time")**2 assert Quantity._collect_factor_and_dimension(dl_dt) ==\ Quantity._collect_factor_and_dimension(l / t / t1) ==\ (10, length/time**2)
def dim_simplify(expr): """ NOTE: this function could be deprecated in the future. Simplify expression by recursively evaluating the dimension arguments. This function proceeds to a very rough dimensional analysis. It tries to simplify expression with dimensions, and it deletes all what multiplies a dimension without being a dimension. This is necessary to avoid strange behavior when Add(L, L) be transformed into Mul(2, L). """ SymPyDeprecationWarning( deprecated_since_version="1.2", feature="dimensional simplification function", issue=13336, useinstead="don't use", ).warn() _, expr = Quantity._collect_factor_and_dimension(expr) return expr
def check_dimensions(expr): """Return expr if there are not unitless values added to dimensional quantities, else raise a ValueError.""" from sympy.solvers.solveset import _term_factors # 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 adds = expr.atoms(Add) DIM_OF = dimsys_default.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(Quantity.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 _get_conversion_matrix_for_expr(expr, target_units): from sympy import Matrix expr_dim = Dimension(Quantity.get_dimensional_expr(expr)) dim_dependencies = expr_dim.get_dimensional_dependencies(mark_dimensionless=True) target_dims = [Dimension(_get_dimension_of_expr(x)) for x in target_units] canon_dim_units = {i for x in target_dims for i in x.get_dimensional_dependencies(mark_dimensionless=True)} canon_expr_units = {i for i in dim_dependencies} if not canon_expr_units.issubset(canon_dim_units): return None canon_dim_units = sorted(canon_dim_units) camat = Matrix([[i.get_dimensional_dependencies(mark_dimensionless=True).get(j, 0) for i in target_dims] for j in canon_dim_units]) exprmat = Matrix([dim_dependencies.get(k, 0) for k in canon_dim_units]) res_exponents = camat.solve_least_squares(exprmat, method=None) return res_exponents
def test_convert_to(): q = Quantity("q1") q.set_global_relative_scale_factor(S(5000), meter) assert q.convert_to(m) == 5000 * m assert speed_of_light.convert_to(m / s) == 299792458 * m / s # TODO: eventually support this kind of conversion: # assert (2*speed_of_light).convert_to(m / s) == 2 * 299792458 * m / s assert day.convert_to(s) == 86400 * s # Wrong dimension to convert: assert q.convert_to(s) == q assert speed_of_light.convert_to(m) == speed_of_light expr = joule * second conv = convert_to(expr, joule) assert conv == joule * second
def test_Quantity_definition(): q = Quantity("s10", time, 10, abbrev="sabbr") assert q.scale_factor == 10 assert q.dimension == time assert q.abbrev == Symbol("sabbr") u = Quantity("u", length, 10, abbrev="dam") assert u.dimension == length assert u.scale_factor == 10 assert u.abbrev == Symbol("dam") km = Quantity("km", length, kilo) assert km.scale_factor == 1000 assert km.func(*km.args) == km assert km.func(*km.args).args == km.args v = Quantity("u", length, 5*kilo) assert v.dimension == length assert v.scale_factor == 5 * 1000 raises(ValueError, lambda: Quantity('invalid', 'dimension', 1)) raises(ValueError, lambda: Quantity('mismatch', length, kg))
dimsys_default, Dimension, acceleration, action, amount_of_substance, capacitance, charge, conductance, current, energy, force, frequency, information, impedance, inductance, length, luminous_intensity, magnetic_density, magnetic_flux, mass, power, pressure, temperature, time, velocity, voltage) from sympy.physics.units.prefixes import (centi, deci, kilo, micro, milli, nano, pico, kibi, mebi, gibi, tebi, pebi, exbi) One = S.One #### UNITS #### # Dimensionless: percent = percents = Quantity("percent") percent.set_dimension(One) percent.set_scale_factor(Rational(1, 100)) permille = Quantity("permille") permille.set_dimension(One) permille.set_scale_factor(Rational(1, 1000)) # Angular units (dimensionless) rad = radian = radians = Quantity("radian") radian.set_dimension(One) radian.set_scale_factor(One) deg = degree = degrees = Quantity("degree", abbrev="deg") degree.set_dimension(One)
def test_factor_and_dimension_with_Abs(): v_w1 = Quantity('v_w1', length/time, S(3)/2*meter/second) expr = v_w1 - Abs(v_w1) assert (0, lenth/time) == Quantity._collect_factor_and_dimension(expr)
def test_print_unit_base(): A = Quantity("A", current, 1) Js = Quantity("Js", action, 1) mksa = UnitSystem((m, kg, s, A), (Js,)) assert mksa.print_unit_base(Js) == m**2*kg*s**-1/1000
def test_print_unit_base(): A = Quantity("A") A.set_dimension(current) A.set_scale_factor(S.One) Js = Quantity("Js") Js.set_dimension(action) Js.set_scale_factor(S.One) mksa = UnitSystem((m, kg, s, A), (Js, )) with warns_deprecated_sympy(): assert mksa.print_unit_base(Js) == m**2 * kg * s**-1
from sympy.physics.units.dimensions import dimsys_default, Dimension from sympy.physics.units.prefixes import ( centi, deci, kilo, micro, milli, nano, pico, kibi, mebi, gibi, tebi, pebi, exbi) One = S.One #### UNITS #### # Dimensionless: percent = percents = Quantity("percent") percent.set_dimension(One) percent.set_scale_factor(Rational(1, 100)) permille = Quantity("permille") permille.set_dimension(One) permille.set_scale_factor(Rational(1, 1000)) # Angular units (dimensionless) rad = radian = radians = Quantity("radian") radian.set_dimension(One) radian.set_scale_factor(One) deg = degree = degrees = Quantity("degree", abbrev="deg") degree.set_dimension(One) degree.set_scale_factor(pi/180) sr = steradian = steradians = Quantity("steradian", abbrev="sr")
def test_quantity_abs(): v_w1 = Quantity('v_w1') v_w2 = Quantity('v_w2') v_w3 = Quantity('v_w3') v_w1.set_dimension(length/time) v_w2.set_dimension(length/time) v_w3.set_dimension(length/time) v_w1.set_scale_factor(meter/second) v_w2.set_scale_factor(meter/second) v_w3.set_scale_factor(meter/second) expr = v_w3 - Abs(v_w1 - v_w2) Dq = Dimension(Quantity.get_dimensional_expr(expr)) assert dimsys_default.get_dimensional_dependencies(Dq) == { 'length': 1, 'time': -1, } assert meter == sqrt(meter**2)
def test_abbrev(): u = Quantity("u") u.set_dimension(length) u.set_scale_factor(S.One) assert u.name == Symbol("u") assert u.abbrev == Symbol("u") u = Quantity("u", abbrev="om") u.set_dimension(length) u.set_scale_factor(S(2)) assert u.name == Symbol("u") assert u.abbrev == Symbol("om") assert u.scale_factor == 2 assert isinstance(u.scale_factor, Number) u = Quantity("u", abbrev="ikm") u.set_dimension(length) u.set_scale_factor(3*kilo) assert u.abbrev == Symbol("ikm") assert u.scale_factor == 3000
def test_print(): u = Quantity("unitname", length, 10, "dam") assert repr(u) == "unitname" assert str(u) == "unitname"
def test_get_dimensional_expr_with_function(): v_w1 = Quantity('v_w1') v_w2 = Quantity('v_w2') v_w1.set_dimension(length/time) v_w2.set_dimension(length/time) v_w1.set_scale_factor(meter/second) v_w2.set_scale_factor(meter/second) assert Quantity.get_dimensional_expr(sin(v_w1)) == \ sin(Quantity.get_dimensional_expr(v_w1)) assert Quantity.get_dimensional_expr(sin(v_w1/v_w2)) == 1
def test_print(): u = Quantity("unitname", abbrev="dam") assert repr(u) == "unitname" assert str(u) == "unitname"
def test_factor_and_dimension(): assert (3000, Dimension(1)) == Quantity._collect_factor_and_dimension(3000) assert (1001, length) == Quantity._collect_factor_and_dimension(meter + km) assert (2, length/time) == Quantity._collect_factor_and_dimension( meter/second + 36*km/(10*hour)) x, y = symbols('x y') assert (x + y/100, length) == Quantity._collect_factor_and_dimension( x*m + y*centimeter) cH = Quantity('cH') cH.set_dimension(amount_of_substance/volume) pH = -log(cH) assert (1, volume/amount_of_substance) == Quantity._collect_factor_and_dimension( exp(pH)) v_w1 = Quantity('v_w1') v_w2 = Quantity('v_w2') v_w1.set_dimension(length/time) v_w2.set_dimension(length/time) v_w1.set_scale_factor(S(3)/2*meter/second) v_w2.set_scale_factor(2*meter/second) expr = Abs(v_w1/2 - v_w2) assert (S(5)/4, length/time) == \ Quantity._collect_factor_and_dimension(expr) expr = S(5)/2*second/meter*v_w1 - 3000 assert (-(2996 + S(1)/4), Dimension(1)) == \ Quantity._collect_factor_and_dimension(expr) expr = v_w1**(v_w2/v_w1) assert ((S(3)/2)**(S(4)/3), (length/time)**(S(4)/3)) == \ Quantity._collect_factor_and_dimension(expr)
def test_mul_div(): u = Quantity("u") v = Quantity("v") t = Quantity("t") ut = Quantity("ut") v2 = Quantity("v") u.set_dimension(length) v.set_dimension(length) t.set_dimension(time) ut.set_dimension(length*time) v2.set_dimension(length/time) u.set_scale_factor(S(10)) v.set_scale_factor(S(5)) t.set_scale_factor(S(2)) ut.set_scale_factor(S(20)) v2.set_scale_factor(S(5)) assert 1 / u == u**(-1) assert u / 1 == u v1 = u / t v2 = v # Pow only supports structural equality: assert v1 != v2 assert v1 == v2.convert_to(v1) # TODO: decide whether to allow such expression in the future # (requires somehow manipulating the core). # assert u / Quantity('l2', dimension=length, scale_factor=2) == 5 assert u * 1 == u ut1 = u * t ut2 = ut # Mul only supports structural equality: assert ut1 != ut2 assert ut1 == ut2.convert_to(ut1) # Mul only supports structural equality: lp1 = Quantity("lp1") lp1.set_dimension(length**-1) lp1.set_scale_factor(S(2)) assert u * lp1 != 20 assert u**0 == 1 assert u**1 == u # TODO: Pow only support structural equality: u2 = Quantity("u2") u3 = Quantity("u3") u2.set_dimension(length**2) u3.set_dimension(length**-1) u2.set_scale_factor(S(100)) u3.set_scale_factor(S(1)/10) assert u ** 2 != u2 assert u ** -1 != u3 assert u ** 2 == u2.convert_to(u) assert u ** -1 == u3.convert_to(u)
def test_get_dimensional_expr_with_function_1(): v_w1 = Quantity('v_w1', length / time, meter / second) v_w2 = Quantity('v_w2', length / time, meter / second) assert Quantity.get_dimensional_expr(sin(v_w1/v_w2)) == 1
def test_check_unit_consistency(): u = Quantity("u") v = Quantity("v") w = Quantity("w") u.set_dimension(length) v.set_dimension(length) w.set_dimension(time) u.set_scale_factor(S(10)) v.set_scale_factor(S(5)) w.set_scale_factor(S(2)) def check_unit_consistency(expr): Quantity._collect_factor_and_dimension(expr) raises(ValueError, lambda: check_unit_consistency(u + w)) raises(ValueError, lambda: check_unit_consistency(u - w)) raises(ValueError, lambda: check_unit_consistency(u + 1)) raises(ValueError, lambda: check_unit_consistency(u - 1)) raises(ValueError, lambda: check_unit_consistency(1 - exp(u / w)))
def test_get_dimensional_expr_with_function(): v_w1 = Quantity('v_w1', length / time, meter / second) assert Quantity.get_dimensional_expr(sin(v_w1)) == \ sin(Quantity.get_dimensional_expr(v_w1))
def test_Quantity_definition(): q = Quantity("s10", abbrev="sabbr") q.set_dimension(time) q.set_scale_factor(10) u = Quantity("u", abbrev="dam") u.set_dimension(length) u.set_scale_factor(10) km = Quantity("km") km.set_dimension(length) km.set_scale_factor(kilo) v = Quantity("u") v.set_dimension(length) v.set_scale_factor(5*kilo) assert q.scale_factor == 10 assert q.dimension == time assert q.abbrev == Symbol("sabbr") assert u.dimension == length assert u.scale_factor == 10 assert u.abbrev == Symbol("dam") assert km.scale_factor == 1000 assert km.func(*km.args) == km assert km.func(*km.args).args == km.args assert v.dimension == length assert v.scale_factor == 5000 with warns_deprecated_sympy(): Quantity('invalid', 'dimension', 1) with warns_deprecated_sympy(): Quantity('mismatch', dimension=length, scale_factor=kg)
def check_unit_consistency(expr): Quantity._collect_factor_and_dimension(expr)
def test_add_sub(): u = Quantity("u") v = Quantity("v") w = Quantity("w") u.set_dimension(length) v.set_dimension(length) w.set_dimension(time) u.set_scale_factor(S(10)) v.set_scale_factor(S(5)) w.set_scale_factor(S(2)) assert isinstance(u + v, Add) assert (u + v.convert_to(u)) == (1 + S.Half)*u # TODO: eventually add this: # assert (u + v).convert_to(u) == (1 + S.Half)*u assert isinstance(u - v, Add) assert (u - v.convert_to(u)) == S.Half*u