I am done

This commit is contained in:
2024-10-30 22:14:35 +01:00
parent 720dc28c09
commit 40e2a747cf
36901 changed files with 5011519 additions and 0 deletions

View File

@ -0,0 +1,150 @@
from sympy.physics.units.systems.si import dimsys_SI
from sympy.core.numbers import pi
from sympy.core.singleton import S
from sympy.core.symbol import Symbol
from sympy.functions.elementary.complexes import Abs
from sympy.functions.elementary.exponential import log
from sympy.functions.elementary.miscellaneous import sqrt
from sympy.functions.elementary.trigonometric import (acos, atan2, cos)
from sympy.physics.units.dimensions import Dimension
from sympy.physics.units.definitions.dimension_definitions import (
length, time, mass, force, pressure, angle
)
from sympy.physics.units import foot
from sympy.testing.pytest import raises
def test_Dimension_definition():
assert dimsys_SI.get_dimensional_dependencies(length) == {length: 1}
assert length.name == Symbol("length")
assert length.symbol == Symbol("L")
halflength = sqrt(length)
assert dimsys_SI.get_dimensional_dependencies(halflength) == {length: S.Half}
def test_Dimension_error_definition():
# tuple with more or less than two entries
raises(TypeError, lambda: Dimension(("length", 1, 2)))
raises(TypeError, lambda: Dimension(["length"]))
# non-number power
raises(TypeError, lambda: Dimension({"length": "a"}))
# non-number with named argument
raises(TypeError, lambda: Dimension({"length": (1, 2)}))
# symbol should by Symbol or str
raises(AssertionError, lambda: Dimension("length", symbol=1))
def test_str():
assert str(Dimension("length")) == "Dimension(length)"
assert str(Dimension("length", "L")) == "Dimension(length, L)"
def test_Dimension_properties():
assert dimsys_SI.is_dimensionless(length) is False
assert dimsys_SI.is_dimensionless(length/length) is True
assert dimsys_SI.is_dimensionless(Dimension("undefined")) is False
assert length.has_integer_powers(dimsys_SI) is True
assert (length**(-1)).has_integer_powers(dimsys_SI) is True
assert (length**1.5).has_integer_powers(dimsys_SI) is False
def test_Dimension_add_sub():
assert length + length == length
assert length - length == length
assert -length == length
raises(TypeError, lambda: length + foot)
raises(TypeError, lambda: foot + length)
raises(TypeError, lambda: length - foot)
raises(TypeError, lambda: foot - length)
# issue 14547 - only raise error for dimensional args; allow
# others to pass
x = Symbol('x')
e = length + x
assert e == x + length and e.is_Add and set(e.args) == {length, x}
e = length + 1
assert e == 1 + length == 1 - length and e.is_Add and set(e.args) == {length, 1}
assert dimsys_SI.get_dimensional_dependencies(mass * length / time**2 + force) == \
{length: 1, mass: 1, time: -2}
assert dimsys_SI.get_dimensional_dependencies(mass * length / time**2 + force -
pressure * length**2) == \
{length: 1, mass: 1, time: -2}
raises(TypeError, lambda: dimsys_SI.get_dimensional_dependencies(mass * length / time**2 + pressure))
def test_Dimension_mul_div_exp():
assert 2*length == length*2 == length/2 == length
assert 2/length == 1/length
x = Symbol('x')
m = x*length
assert m == length*x and m.is_Mul and set(m.args) == {x, length}
d = x/length
assert d == x*length**-1 and d.is_Mul and set(d.args) == {x, 1/length}
d = length/x
assert d == length*x**-1 and d.is_Mul and set(d.args) == {1/x, length}
velo = length / time
assert (length * length) == length ** 2
assert dimsys_SI.get_dimensional_dependencies(length * length) == {length: 2}
assert dimsys_SI.get_dimensional_dependencies(length ** 2) == {length: 2}
assert dimsys_SI.get_dimensional_dependencies(length * time) == {length: 1, time: 1}
assert dimsys_SI.get_dimensional_dependencies(velo) == {length: 1, time: -1}
assert dimsys_SI.get_dimensional_dependencies(velo ** 2) == {length: 2, time: -2}
assert dimsys_SI.get_dimensional_dependencies(length / length) == {}
assert dimsys_SI.get_dimensional_dependencies(velo / length * time) == {}
assert dimsys_SI.get_dimensional_dependencies(length ** -1) == {length: -1}
assert dimsys_SI.get_dimensional_dependencies(velo ** -1.5) == {length: -1.5, time: 1.5}
length_a = length**"a"
assert dimsys_SI.get_dimensional_dependencies(length_a) == {length: Symbol("a")}
assert dimsys_SI.get_dimensional_dependencies(length**pi) == {length: pi}
assert dimsys_SI.get_dimensional_dependencies(length**(length/length)) == {length: Dimension(1)}
raises(TypeError, lambda: dimsys_SI.get_dimensional_dependencies(length**length))
assert length != 1
assert length / length != 1
length_0 = length ** 0
assert dimsys_SI.get_dimensional_dependencies(length_0) == {}
# issue 18738
a = Symbol('a')
b = Symbol('b')
c = sqrt(a**2 + b**2)
c_dim = c.subs({a: length, b: length})
assert dimsys_SI.equivalent_dims(c_dim, length)
def test_Dimension_functions():
raises(TypeError, lambda: dimsys_SI.get_dimensional_dependencies(cos(length)))
raises(TypeError, lambda: dimsys_SI.get_dimensional_dependencies(acos(angle)))
raises(TypeError, lambda: dimsys_SI.get_dimensional_dependencies(atan2(length, time)))
raises(TypeError, lambda: dimsys_SI.get_dimensional_dependencies(log(length)))
raises(TypeError, lambda: dimsys_SI.get_dimensional_dependencies(log(100, length)))
raises(TypeError, lambda: dimsys_SI.get_dimensional_dependencies(log(length, 10)))
assert dimsys_SI.get_dimensional_dependencies(pi) == {}
assert dimsys_SI.get_dimensional_dependencies(cos(1)) == {}
assert dimsys_SI.get_dimensional_dependencies(cos(angle)) == {}
assert dimsys_SI.get_dimensional_dependencies(atan2(length, length)) == {}
assert dimsys_SI.get_dimensional_dependencies(log(length / length, length / length)) == {}
assert dimsys_SI.get_dimensional_dependencies(Abs(length)) == {length: 1}
assert dimsys_SI.get_dimensional_dependencies(Abs(length / length)) == {}
assert dimsys_SI.get_dimensional_dependencies(sqrt(-1)) == {}

View File

@ -0,0 +1,95 @@
from sympy.core.symbol import symbols
from sympy.matrices.dense import (Matrix, eye)
from sympy.physics.units.definitions.dimension_definitions import (
action, current, length, mass, time,
velocity)
from sympy.physics.units.dimensions import DimensionSystem
def test_extend():
ms = DimensionSystem((length, time), (velocity,))
mks = ms.extend((mass,), (action,))
res = DimensionSystem((length, time, mass), (velocity, action))
assert mks.base_dims == res.base_dims
assert mks.derived_dims == res.derived_dims
def test_list_dims():
dimsys = DimensionSystem((length, time, mass))
assert dimsys.list_can_dims == (length, mass, time)
def test_dim_can_vector():
dimsys = DimensionSystem(
[length, mass, time],
[velocity, action],
{
velocity: {length: 1, time: -1}
}
)
assert dimsys.dim_can_vector(length) == Matrix([1, 0, 0])
assert dimsys.dim_can_vector(velocity) == Matrix([1, 0, -1])
dimsys = DimensionSystem(
(length, velocity, action),
(mass, time),
{
time: {length: 1, velocity: -1}
}
)
assert dimsys.dim_can_vector(length) == Matrix([0, 1, 0])
assert dimsys.dim_can_vector(velocity) == Matrix([0, 0, 1])
assert dimsys.dim_can_vector(time) == Matrix([0, 1, -1])
dimsys = DimensionSystem(
(length, mass, time),
(velocity, action),
{velocity: {length: 1, time: -1},
action: {mass: 1, length: 2, time: -1}})
assert dimsys.dim_vector(length) == Matrix([1, 0, 0])
assert dimsys.dim_vector(velocity) == Matrix([1, 0, -1])
def test_inv_can_transf_matrix():
dimsys = DimensionSystem((length, mass, time))
assert dimsys.inv_can_transf_matrix == eye(3)
def test_can_transf_matrix():
dimsys = DimensionSystem((length, mass, time))
assert dimsys.can_transf_matrix == eye(3)
dimsys = DimensionSystem((length, velocity, action))
assert dimsys.can_transf_matrix == eye(3)
dimsys = DimensionSystem((length, time), (velocity,), {velocity: {length: 1, time: -1}})
assert dimsys.can_transf_matrix == eye(2)
def test_is_consistent():
assert DimensionSystem((length, time)).is_consistent is True
def test_print_dim_base():
mksa = DimensionSystem(
(length, time, mass, current),
(action,),
{action: {mass: 1, length: 2, time: -1}})
L, M, T = symbols("L M T")
assert mksa.print_dim_base(action) == L**2*M/T
def test_dim():
dimsys = DimensionSystem(
(length, mass, time),
(velocity, action),
{velocity: {length: 1, time: -1},
action: {mass: 1, length: 2, time: -1}}
)
assert dimsys.dim == 3

View File

@ -0,0 +1,86 @@
from sympy.core.mul import Mul
from sympy.core.numbers import Rational
from sympy.core.singleton import S
from sympy.core.symbol import (Symbol, symbols)
from sympy.physics.units import Quantity, length, meter, W
from sympy.physics.units.prefixes import PREFIXES, Prefix, prefix_unit, kilo, \
kibi
from sympy.physics.units.systems import SI
x = Symbol('x')
def test_prefix_operations():
m = PREFIXES['m']
k = PREFIXES['k']
M = PREFIXES['M']
dodeca = Prefix('dodeca', 'dd', 1, base=12)
assert m * k is S.One
assert m * W == W / 1000
assert k * k == M
assert 1 / m == k
assert k / m == M
assert dodeca * dodeca == 144
assert 1 / dodeca == S.One / 12
assert k / dodeca == S(1000) / 12
assert dodeca / dodeca is S.One
m = Quantity("fake_meter")
SI.set_quantity_dimension(m, S.One)
SI.set_quantity_scale_factor(m, S.One)
assert dodeca * m == 12 * m
assert dodeca / m == 12 / m
expr1 = kilo * 3
assert isinstance(expr1, Mul)
assert expr1.args == (3, kilo)
expr2 = kilo * x
assert isinstance(expr2, Mul)
assert expr2.args == (x, kilo)
expr3 = kilo / 3
assert isinstance(expr3, Mul)
assert expr3.args == (Rational(1, 3), kilo)
assert expr3.args == (S.One/3, kilo)
expr4 = kilo / x
assert isinstance(expr4, Mul)
assert expr4.args == (1/x, kilo)
def test_prefix_unit():
m = Quantity("fake_meter", abbrev="m")
m.set_global_relative_scale_factor(1, meter)
pref = {"m": PREFIXES["m"], "c": PREFIXES["c"], "d": PREFIXES["d"]}
q1 = Quantity("millifake_meter", abbrev="mm")
q2 = Quantity("centifake_meter", abbrev="cm")
q3 = Quantity("decifake_meter", abbrev="dm")
SI.set_quantity_dimension(q1, length)
SI.set_quantity_scale_factor(q1, PREFIXES["m"])
SI.set_quantity_scale_factor(q1, PREFIXES["c"])
SI.set_quantity_scale_factor(q1, PREFIXES["d"])
res = [q1, q2, q3]
prefs = prefix_unit(m, pref)
assert set(prefs) == set(res)
assert {v.abbrev for v in prefs} == set(symbols("mm,cm,dm"))
def test_bases():
assert kilo.base == 10
assert kibi.base == 2
def test_repr():
assert eval(repr(kilo)) == kilo
assert eval(repr(kibi)) == kibi

View File

@ -0,0 +1,575 @@
import warnings
from sympy.core.add import Add
from sympy.core.function import (Function, diff)
from sympy.core.numbers import (Number, Rational)
from sympy.core.singleton import S
from sympy.core.symbol import (Symbol, symbols)
from sympy.functions.elementary.complexes import Abs
from sympy.functions.elementary.exponential import (exp, log)
from sympy.functions.elementary.miscellaneous import sqrt
from sympy.functions.elementary.trigonometric import sin
from sympy.integrals.integrals import integrate
from sympy.physics.units import (amount_of_substance, area, convert_to, find_unit,
volume, kilometer, joule, molar_gas_constant,
vacuum_permittivity, elementary_charge, volt,
ohm)
from sympy.physics.units.definitions import (amu, au, centimeter, coulomb,
day, foot, grams, hour, inch, kg, km, m, meter, millimeter,
minute, quart, s, second, speed_of_light, bit,
byte, kibibyte, mebibyte, gibibyte, tebibyte, pebibyte, exbibyte,
kilogram, gravitational_constant, electron_rest_mass)
from sympy.physics.units.definitions.dimension_definitions import (
Dimension, charge, length, time, temperature, pressure,
energy, mass
)
from sympy.physics.units.prefixes import PREFIXES, kilo
from sympy.physics.units.quantities import PhysicalConstant, Quantity
from sympy.physics.units.systems import SI
from sympy.testing.pytest import raises
k = PREFIXES["k"]
def test_str_repr():
assert str(kg) == "kilogram"
def test_eq():
# simple test
assert 10*m == 10*m
assert 10*m != 10*s
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
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", abbrev="sabbr")
q.set_global_relative_scale_factor(10, second)
u = Quantity("u", abbrev="dam")
u.set_global_relative_scale_factor(10, meter)
km = Quantity("km")
km.set_global_relative_scale_factor(kilo, meter)
v = Quantity("u")
v.set_global_relative_scale_factor(5*kilo, meter)
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
def test_abbrev():
u = Quantity("u")
u.set_global_relative_scale_factor(S.One, meter)
assert u.name == Symbol("u")
assert u.abbrev == Symbol("u")
u = Quantity("u", abbrev="om")
u.set_global_relative_scale_factor(S(2), meter)
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_global_relative_scale_factor(3*kilo, meter)
assert u.abbrev == Symbol("ikm")
assert u.scale_factor == 3000
def test_print():
u = Quantity("unitname", abbrev="dam")
assert repr(u) == "unitname"
assert str(u) == "unitname"
def test_Quantity_eq():
u = Quantity("u", abbrev="dam")
v = Quantity("v1")
assert u != v
v = Quantity("v2", abbrev="ds")
assert u != v
v = Quantity("v3", abbrev="dm")
assert u != v
def test_add_sub():
u = Quantity("u")
v = Quantity("v")
w = Quantity("w")
u.set_global_relative_scale_factor(S(10), meter)
v.set_global_relative_scale_factor(S(5), meter)
w.set_global_relative_scale_factor(S(2), second)
assert isinstance(u + v, Add)
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_quantity_abs():
v_w1 = Quantity('v_w1')
v_w2 = Quantity('v_w2')
v_w3 = Quantity('v_w3')
v_w1.set_global_relative_scale_factor(1, meter/second)
v_w2.set_global_relative_scale_factor(1, meter/second)
v_w3.set_global_relative_scale_factor(1, meter/second)
expr = v_w3 - Abs(v_w1 - v_w2)
assert SI.get_dimensional_expr(v_w1) == (length/time).name
Dq = Dimension(SI.get_dimensional_expr(expr))
assert SI.get_dimension_system().get_dimensional_dependencies(Dq) == {
length: 1,
time: -1,
}
assert meter == sqrt(meter**2)
def test_check_unit_consistency():
u = Quantity("u")
v = Quantity("v")
w = Quantity("w")
u.set_global_relative_scale_factor(S(10), meter)
v.set_global_relative_scale_factor(S(5), meter)
w.set_global_relative_scale_factor(S(2), second)
def check_unit_consistency(expr):
SI._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_mul_div():
u = Quantity("u")
v = Quantity("v")
t = Quantity("t")
ut = Quantity("ut")
v2 = Quantity("v")
u.set_global_relative_scale_factor(S(10), meter)
v.set_global_relative_scale_factor(S(5), meter)
t.set_global_relative_scale_factor(S(2), second)
ut.set_global_relative_scale_factor(S(20), meter*second)
v2.set_global_relative_scale_factor(S(5), meter/second)
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_global_relative_scale_factor(S(2), 1/meter)
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_global_relative_scale_factor(S(100), meter**2)
u3.set_global_relative_scale_factor(Rational(1, 10), 1/meter)
assert u ** 2 != u2
assert u ** -1 != u3
assert u ** 2 == u2.convert_to(u)
assert u ** -1 == u3.convert_to(u)
def test_units():
assert convert_to((5*m/s * day) / km, 1) == 432
assert convert_to(foot / meter, meter) == Rational(3048, 10000)
# amu is a pure mass so mass/mass gives a number, not an amount (mol)
# TODO: need better simplification routine:
assert str(convert_to(grams/amu, grams).n(2)) == '6.0e+23'
# Light from the sun needs about 8.3 minutes to reach earth
t = (1*au / speed_of_light) / minute
# TODO: need a better way to simplify expressions containing units:
t = convert_to(convert_to(t, meter / minute), meter)
assert t.simplify() == Rational(49865956897, 5995849160)
# TODO: fix this, it should give `m` without `Abs`
assert sqrt(m**2) == m
assert (sqrt(m))**2 == m
t = Symbol('t')
assert integrate(t*m/s, (t, 1*s, 5*s)) == 12*m*s
assert (t * m/s).integrate((t, 1*s, 5*s)) == 12*m*s
def test_issue_quart():
assert convert_to(4 * quart / inch ** 3, meter) == 231
assert convert_to(4 * quart / inch ** 3, millimeter) == 231
def test_electron_rest_mass():
assert convert_to(electron_rest_mass, kilogram) == 9.1093837015e-31*kilogram
assert convert_to(electron_rest_mass, grams) == 9.1093837015e-28*grams
def test_issue_5565():
assert (m < s).is_Relational
def test_find_unit():
assert find_unit('coulomb') == ['coulomb', 'coulombs', 'coulomb_constant']
assert find_unit(coulomb) == ['C', 'coulomb', 'coulombs', 'planck_charge', 'elementary_charge']
assert find_unit(charge) == ['C', 'coulomb', 'coulombs', 'planck_charge', 'elementary_charge']
assert find_unit(inch) == [
'm', 'au', 'cm', 'dm', 'ft', 'km', 'ly', 'mi', 'mm', 'nm', 'pm', 'um', 'yd',
'nmi', 'feet', 'foot', 'inch', 'mile', 'yard', 'meter', 'miles', 'yards',
'inches', 'meters', 'micron', 'microns', 'angstrom', 'angstroms', 'decimeter',
'kilometer', 'lightyear', 'nanometer', 'picometer', 'centimeter', 'decimeters',
'kilometers', 'lightyears', 'micrometer', 'millimeter', 'nanometers', 'picometers',
'centimeters', 'micrometers', 'millimeters', 'nautical_mile', 'planck_length',
'nautical_miles', 'astronomical_unit', 'astronomical_units']
assert find_unit(inch**-1) == ['D', 'dioptre', 'optical_power']
assert find_unit(length**-1) == ['D', 'dioptre', 'optical_power']
assert find_unit(inch ** 2) == ['ha', 'hectare', 'planck_area']
assert find_unit(inch ** 3) == [
'L', 'l', 'cL', 'cl', 'dL', 'dl', 'mL', 'ml', 'liter', 'quart', 'liters', 'quarts',
'deciliter', 'centiliter', 'deciliters', 'milliliter',
'centiliters', 'milliliters', 'planck_volume']
assert find_unit('voltage') == ['V', 'v', 'volt', 'volts', 'planck_voltage']
assert find_unit(grams) == ['g', 't', 'Da', 'kg', 'me', 'mg', 'ug', 'amu', 'mmu', 'amus',
'gram', 'mmus', 'grams', 'pound', 'tonne', 'dalton', 'pounds',
'kilogram', 'kilograms', 'microgram', 'milligram', 'metric_ton',
'micrograms', 'milligrams', 'planck_mass', 'milli_mass_unit', 'atomic_mass_unit',
'electron_rest_mass', 'atomic_mass_constant']
def test_Quantity_derivative():
x = symbols("x")
assert diff(x*meter, x) == meter
assert diff(x**3*meter**2, x) == 3*x**2*meter**2
assert diff(meter, meter) == 1
assert diff(meter**2, meter) == 2*meter
def test_quantity_postprocessing():
q1 = Quantity('q1')
q2 = Quantity('q2')
SI.set_quantity_dimension(q1, length*pressure**2*temperature/time)
SI.set_quantity_dimension(q2, energy*pressure*temperature/(length**2*time))
assert q1 + q2
q = q1 + q2
Dq = Dimension(SI.get_dimensional_expr(q))
assert SI.get_dimension_system().get_dimensional_dependencies(Dq) == {
length: -1,
mass: 2,
temperature: 1,
time: -5,
}
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)
def test_dimensional_expr_of_derivative():
l = Quantity('l')
t = Quantity('t')
t1 = Quantity('t1')
l.set_global_relative_scale_factor(36, km)
t.set_global_relative_scale_factor(1, hour)
t1.set_global_relative_scale_factor(1, 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 SI.get_dimensional_expr(dl_dt) ==\
SI.get_dimensional_expr(l / t / t1) ==\
Symbol("length")/Symbol("time")**2
assert SI._collect_factor_and_dimension(dl_dt) ==\
SI._collect_factor_and_dimension(l / t / t1) ==\
(10, length/time**2)
def test_get_dimensional_expr_with_function():
v_w1 = Quantity('v_w1')
v_w2 = Quantity('v_w2')
v_w1.set_global_relative_scale_factor(1, meter/second)
v_w2.set_global_relative_scale_factor(1, meter/second)
assert SI.get_dimensional_expr(sin(v_w1)) == \
sin(SI.get_dimensional_expr(v_w1))
assert SI.get_dimensional_expr(sin(v_w1/v_w2)) == 1
def test_binary_information():
assert convert_to(kibibyte, byte) == 1024*byte
assert convert_to(mebibyte, byte) == 1024**2*byte
assert convert_to(gibibyte, byte) == 1024**3*byte
assert convert_to(tebibyte, byte) == 1024**4*byte
assert convert_to(pebibyte, byte) == 1024**5*byte
assert convert_to(exbibyte, byte) == 1024**6*byte
assert kibibyte.convert_to(bit) == 8*1024*bit
assert byte.convert_to(bit) == 8*bit
a = 10*kibibyte*hour
assert convert_to(a, byte) == 10240*byte*hour
assert convert_to(a, minute) == 600*kibibyte*minute
assert convert_to(a, [byte, minute]) == 614400*byte*minute
def test_conversion_with_2_nonstandard_dimensions():
good_grade = Quantity("good_grade")
kilo_good_grade = Quantity("kilo_good_grade")
centi_good_grade = Quantity("centi_good_grade")
kilo_good_grade.set_global_relative_scale_factor(1000, good_grade)
centi_good_grade.set_global_relative_scale_factor(S.One/10**5, kilo_good_grade)
charity_points = Quantity("charity_points")
milli_charity_points = Quantity("milli_charity_points")
missions = Quantity("missions")
milli_charity_points.set_global_relative_scale_factor(S.One/1000, charity_points)
missions.set_global_relative_scale_factor(251, charity_points)
assert convert_to(
kilo_good_grade*milli_charity_points*millimeter,
[centi_good_grade, missions, centimeter]
) == S.One * 10**5 / (251*1000) / 10 * centi_good_grade*missions*centimeter
def test_eval_subs():
energy, mass, force = symbols('energy mass force')
expr1 = energy/mass
units = {energy: kilogram*meter**2/second**2, mass: kilogram}
assert expr1.subs(units) == meter**2/second**2
expr2 = force/mass
units = {force:gravitational_constant*kilogram**2/meter**2, mass:kilogram}
assert expr2.subs(units) == gravitational_constant*kilogram/meter**2
def test_issue_14932():
assert (log(inch) - log(2)).simplify() == log(inch/2)
assert (log(inch) - log(foot)).simplify() == -log(12)
p = symbols('p', positive=True)
assert (log(inch) - log(p)).simplify() == log(inch/p)
def test_issue_14547():
# the root issue is that an argument with dimensions should
# not raise an error when the `arg - 1` calculation is
# performed in the assumptions system
from sympy.physics.units import foot, inch
from sympy.core.relational import Eq
assert log(foot).is_zero is None
assert log(foot).is_positive is None
assert log(foot).is_nonnegative is None
assert log(foot).is_negative is None
assert log(foot).is_algebraic is None
assert log(foot).is_rational is None
# doesn't raise error
assert Eq(log(foot), log(inch)) is not None # might be False or unevaluated
x = Symbol('x')
e = foot + x
assert e.is_Add and set(e.args) == {foot, x}
e = foot + 1
assert e.is_Add and set(e.args) == {foot, 1}
def test_issue_22164():
warnings.simplefilter("error")
dm = Quantity("dm")
SI.set_quantity_dimension(dm, length)
SI.set_quantity_scale_factor(dm, 1)
bad_exp = Quantity("bad_exp")
SI.set_quantity_dimension(bad_exp, length)
SI.set_quantity_scale_factor(bad_exp, 1)
expr = dm ** bad_exp
# deprecation warning is not expected here
SI._collect_factor_and_dimension(expr)
def test_issue_22819():
from sympy.physics.units import tonne, gram, Da
from sympy.physics.units.systems.si import dimsys_SI
assert tonne.convert_to(gram) == 1000000*gram
assert dimsys_SI.get_dimensional_dependencies(area) == {length: 2}
assert Da.scale_factor == 1.66053906660000e-24
def test_issue_20288():
from sympy.core.numbers import E
from sympy.physics.units import energy
u = Quantity('u')
v = Quantity('v')
SI.set_quantity_dimension(u, energy)
SI.set_quantity_dimension(v, energy)
u.set_global_relative_scale_factor(1, joule)
v.set_global_relative_scale_factor(1, joule)
expr = 1 + exp(u**2/v**2)
assert SI._collect_factor_and_dimension(expr) == (1 + E, Dimension(1))
def test_issue_24062():
from sympy.core.numbers import E
from sympy.physics.units import impedance, capacitance, time, ohm, farad, second
R = Quantity('R')
C = Quantity('C')
T = Quantity('T')
SI.set_quantity_dimension(R, impedance)
SI.set_quantity_dimension(C, capacitance)
SI.set_quantity_dimension(T, time)
R.set_global_relative_scale_factor(1, ohm)
C.set_global_relative_scale_factor(1, farad)
T.set_global_relative_scale_factor(1, second)
expr = T / (R * C)
dim = SI._collect_factor_and_dimension(expr)[1]
assert SI.get_dimension_system().is_dimensionless(dim)
exp_expr = 1 + exp(expr)
assert SI._collect_factor_and_dimension(exp_expr) == (1 + E, Dimension(1))
def test_issue_24211():
from sympy.physics.units import time, velocity, acceleration, second, meter
V1 = Quantity('V1')
SI.set_quantity_dimension(V1, velocity)
SI.set_quantity_scale_factor(V1, 1 * meter / second)
A1 = Quantity('A1')
SI.set_quantity_dimension(A1, acceleration)
SI.set_quantity_scale_factor(A1, 1 * meter / second**2)
T1 = Quantity('T1')
SI.set_quantity_dimension(T1, time)
SI.set_quantity_scale_factor(T1, 1 * second)
expr = A1*T1 + V1
# should not throw ValueError here
SI._collect_factor_and_dimension(expr)
def test_prefixed_property():
assert not meter.is_prefixed
assert not joule.is_prefixed
assert not day.is_prefixed
assert not second.is_prefixed
assert not volt.is_prefixed
assert not ohm.is_prefixed
assert centimeter.is_prefixed
assert kilometer.is_prefixed
assert kilogram.is_prefixed
assert pebibyte.is_prefixed
def test_physics_constant():
from sympy.physics.units import definitions
for name in dir(definitions):
quantity = getattr(definitions, name)
if not isinstance(quantity, Quantity):
continue
if name.endswith('_constant'):
assert isinstance(quantity, PhysicalConstant), f"{quantity} must be PhysicalConstant, but is {type(quantity)}"
assert quantity.is_physical_constant, f"{name} is not marked as physics constant when it should be"
for const in [gravitational_constant, molar_gas_constant, vacuum_permittivity, speed_of_light, elementary_charge]:
assert isinstance(const, PhysicalConstant), f"{const} must be PhysicalConstant, but is {type(const)}"
assert const.is_physical_constant, f"{const} is not marked as physics constant when it should be"
assert not meter.is_physical_constant
assert not joule.is_physical_constant

View File

@ -0,0 +1,55 @@
from sympy.concrete.tests.test_sums_products import NS
from sympy.core.singleton import S
from sympy.functions.elementary.miscellaneous import sqrt
from sympy.physics.units import convert_to, coulomb_constant, elementary_charge, gravitational_constant, planck
from sympy.physics.units.definitions.unit_definitions import angstrom, statcoulomb, coulomb, second, gram, centimeter, erg, \
newton, joule, dyne, speed_of_light, meter, farad, henry, statvolt, volt, ohm
from sympy.physics.units.systems import SI
from sympy.physics.units.systems.cgs import cgs_gauss
def test_conversion_to_from_si():
assert convert_to(statcoulomb, coulomb, cgs_gauss) == coulomb/2997924580
assert convert_to(coulomb, statcoulomb, cgs_gauss) == 2997924580*statcoulomb
assert convert_to(statcoulomb, sqrt(gram*centimeter**3)/second, cgs_gauss) == centimeter**(S(3)/2)*sqrt(gram)/second
assert convert_to(coulomb, sqrt(gram*centimeter**3)/second, cgs_gauss) == 2997924580*centimeter**(S(3)/2)*sqrt(gram)/second
# SI units have an additional base unit, no conversion in case of electromagnetism:
assert convert_to(coulomb, statcoulomb, SI) == coulomb
assert convert_to(statcoulomb, coulomb, SI) == statcoulomb
# SI without electromagnetism:
assert convert_to(erg, joule, SI) == joule/10**7
assert convert_to(erg, joule, cgs_gauss) == joule/10**7
assert convert_to(joule, erg, SI) == 10**7*erg
assert convert_to(joule, erg, cgs_gauss) == 10**7*erg
assert convert_to(dyne, newton, SI) == newton/10**5
assert convert_to(dyne, newton, cgs_gauss) == newton/10**5
assert convert_to(newton, dyne, SI) == 10**5*dyne
assert convert_to(newton, dyne, cgs_gauss) == 10**5*dyne
def test_cgs_gauss_convert_constants():
assert convert_to(speed_of_light, centimeter/second, cgs_gauss) == 29979245800*centimeter/second
assert convert_to(coulomb_constant, 1, cgs_gauss) == 1
assert convert_to(coulomb_constant, newton*meter**2/coulomb**2, cgs_gauss) == 22468879468420441*meter**2*newton/(2500000*coulomb**2)
assert convert_to(coulomb_constant, newton*meter**2/coulomb**2, SI) == 22468879468420441*meter**2*newton/(2500000*coulomb**2)
assert convert_to(coulomb_constant, dyne*centimeter**2/statcoulomb**2, cgs_gauss) == centimeter**2*dyne/statcoulomb**2
assert convert_to(coulomb_constant, 1, SI) == coulomb_constant
assert NS(convert_to(coulomb_constant, newton*meter**2/coulomb**2, SI)) == '8987551787.36818*meter**2*newton/coulomb**2'
assert convert_to(elementary_charge, statcoulomb, cgs_gauss)
assert convert_to(angstrom, centimeter, cgs_gauss) == 1*centimeter/10**8
assert convert_to(gravitational_constant, dyne*centimeter**2/gram**2, cgs_gauss)
assert NS(convert_to(planck, erg*second, cgs_gauss)) == '6.62607015e-27*erg*second'
spc = 25000*second/(22468879468420441*centimeter)
assert convert_to(ohm, second/centimeter, cgs_gauss) == spc
assert convert_to(henry, second**2/centimeter, cgs_gauss) == spc*second
assert convert_to(volt, statvolt, cgs_gauss) == 10**6*statvolt/299792458
assert convert_to(farad, centimeter, cgs_gauss) == 299792458**2*centimeter/10**5

View File

@ -0,0 +1,86 @@
from sympy.physics.units import DimensionSystem, joule, second, ampere
from sympy.core.numbers import Rational
from sympy.core.singleton import S
from sympy.physics.units.definitions import c, kg, m, s
from sympy.physics.units.definitions.dimension_definitions import length, time
from sympy.physics.units.quantities import Quantity
from sympy.physics.units.unitsystem import UnitSystem
from sympy.physics.units.util import convert_to
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_str_repr():
assert str(UnitSystem((m, s), name="MS")) == "MS"
assert str(UnitSystem((m, s))) == "UnitSystem((meter, second))"
assert repr(UnitSystem((m, s))) == "<UnitSystem: (%s, %s)>" % (m, s)
def test_convert_to():
A = Quantity("A")
A.set_global_relative_scale_factor(S.One, ampere)
Js = Quantity("Js")
Js.set_global_relative_scale_factor(S.One, joule*second)
mksa = UnitSystem((m, kg, s, A), (Js,))
assert convert_to(Js, mksa._base_units) == m**2*kg*s**-1/1000
def test_extend():
ms = UnitSystem((m, s), (c,))
Js = Quantity("Js")
Js.set_global_relative_scale_factor(1, joule*second)
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_dim():
dimsys = UnitSystem((m, kg, s), (c,))
assert dimsys.dim == 3
def test_is_consistent():
dimension_system = DimensionSystem([length, time])
us = UnitSystem([m, s], dimension_system=dimension_system)
assert us.is_consistent == True
def test_get_units_non_prefixed():
from sympy.physics.units import volt, ohm
unit_system = UnitSystem.get_unit_system("SI")
units = unit_system.get_units_non_prefixed()
for prefix in ["giga", "tera", "peta", "exa", "zetta", "yotta", "kilo", "hecto", "deca", "deci", "centi", "milli", "micro", "nano", "pico", "femto", "atto", "zepto", "yocto"]:
for unit in units:
assert isinstance(unit, Quantity), f"{unit} must be a Quantity, not {type(unit)}"
assert not unit.is_prefixed, f"{unit} is marked as prefixed"
assert not unit.is_physical_constant, f"{unit} is marked as physics constant"
assert not unit.name.name.startswith(prefix), f"Unit {unit.name} has prefix {prefix}"
assert volt in units
assert ohm in units
def test_derived_units_must_exist_in_unit_system():
for unit_system in UnitSystem._unit_systems.values():
for preferred_unit in unit_system.derived_units.values():
units = preferred_unit.atoms(Quantity)
for unit in units:
assert unit in unit_system._units, f"Unit {unit} is not in unit system {unit_system}"

View File

@ -0,0 +1,178 @@
from sympy.core.containers import Tuple
from sympy.core.numbers import pi
from sympy.core.power import Pow
from sympy.core.symbol import symbols
from sympy.core.sympify import sympify
from sympy.printing.str import sstr
from sympy.physics.units import (
G, centimeter, coulomb, day, degree, gram, hbar, hour, inch, joule, kelvin,
kilogram, kilometer, length, meter, mile, minute, newton, planck,
planck_length, planck_mass, planck_temperature, planck_time, radians,
second, speed_of_light, steradian, time, km)
from sympy.physics.units.util import convert_to, check_dimensions
from sympy.testing.pytest import raises
from sympy.functions.elementary.miscellaneous import sqrt
def NS(e, n=15, **options):
return sstr(sympify(e).evalf(n, **options), full_prec=True)
L = length
T = time
def test_dim_simplify_add():
# assert Add(L, L) == L
assert L + L == L
def test_dim_simplify_mul():
# assert Mul(L, T) == L*T
assert L*T == L*T
def test_dim_simplify_pow():
assert Pow(L, 2) == L**2
def test_dim_simplify_rec():
# assert Mul(Add(L, L), T) == L*T
assert (L + L) * T == L*T
def test_convert_to_quantities():
assert convert_to(3, meter) == 3
assert convert_to(mile, kilometer) == 25146*kilometer/15625
assert convert_to(meter/second, speed_of_light) == speed_of_light/299792458
assert convert_to(299792458*meter/second, speed_of_light) == speed_of_light
assert convert_to(2*299792458*meter/second, speed_of_light) == 2*speed_of_light
assert convert_to(speed_of_light, meter/second) == 299792458*meter/second
assert convert_to(2*speed_of_light, meter/second) == 599584916*meter/second
assert convert_to(day, second) == 86400*second
assert convert_to(2*hour, minute) == 120*minute
assert convert_to(mile, meter) == 201168*meter/125
assert convert_to(mile/hour, kilometer/hour) == 25146*kilometer/(15625*hour)
assert convert_to(3*newton, meter/second) == 3*newton
assert convert_to(3*newton, kilogram*meter/second**2) == 3*meter*kilogram/second**2
assert convert_to(kilometer + mile, meter) == 326168*meter/125
assert convert_to(2*kilometer + 3*mile, meter) == 853504*meter/125
assert convert_to(inch**2, meter**2) == 16129*meter**2/25000000
assert convert_to(3*inch**2, meter) == 48387*meter**2/25000000
assert convert_to(2*kilometer/hour + 3*mile/hour, meter/second) == 53344*meter/(28125*second)
assert convert_to(2*kilometer/hour + 3*mile/hour, centimeter/second) == 213376*centimeter/(1125*second)
assert convert_to(kilometer * (mile + kilometer), meter) == 2609344 * meter ** 2
assert convert_to(steradian, coulomb) == steradian
assert convert_to(radians, degree) == 180*degree/pi
assert convert_to(radians, [meter, degree]) == 180*degree/pi
assert convert_to(pi*radians, degree) == 180*degree
assert convert_to(pi, degree) == 180*degree
# https://github.com/sympy/sympy/issues/26263
assert convert_to(sqrt(meter**2 + meter**2.0), meter) == sqrt(meter**2 + meter**2.0)
assert convert_to((meter**2 + meter**2.0)**2, meter) == (meter**2 + meter**2.0)**2
def test_convert_to_tuples_of_quantities():
from sympy.core.symbol import symbols
alpha, beta = symbols('alpha beta')
assert convert_to(speed_of_light, [meter, second]) == 299792458 * meter / second
assert convert_to(speed_of_light, (meter, second)) == 299792458 * meter / second
assert convert_to(speed_of_light, Tuple(meter, second)) == 299792458 * meter / second
assert convert_to(joule, [meter, kilogram, second]) == kilogram*meter**2/second**2
assert convert_to(joule, [centimeter, gram, second]) == 10000000*centimeter**2*gram/second**2
assert convert_to(299792458*meter/second, [speed_of_light]) == speed_of_light
assert convert_to(speed_of_light / 2, [meter, second, kilogram]) == meter/second*299792458 / 2
# This doesn't make physically sense, but let's keep it as a conversion test:
assert convert_to(2 * speed_of_light, [meter, second, kilogram]) == 2 * 299792458 * meter / second
assert convert_to(G, [G, speed_of_light, planck]) == 1.0*G
assert NS(convert_to(meter, [G, speed_of_light, hbar]), n=7) == '6.187142e+34*gravitational_constant**0.5000000*hbar**0.5000000/speed_of_light**1.500000'
assert NS(convert_to(planck_mass, kilogram), n=7) == '2.176434e-8*kilogram'
assert NS(convert_to(planck_length, meter), n=7) == '1.616255e-35*meter'
assert NS(convert_to(planck_time, second), n=6) == '5.39125e-44*second'
assert NS(convert_to(planck_temperature, kelvin), n=7) == '1.416784e+32*kelvin'
assert NS(convert_to(convert_to(meter, [G, speed_of_light, planck]), meter), n=10) == '1.000000000*meter'
# similar to https://github.com/sympy/sympy/issues/26263
assert convert_to(sqrt(meter**2 + second**2.0), [meter, second]) == sqrt(meter**2 + second**2.0)
assert convert_to((meter**2 + second**2.0)**2, [meter, second]) == (meter**2 + second**2.0)**2
# similar to https://github.com/sympy/sympy/issues/21463
assert convert_to(1/(beta*meter + meter), 1/meter) == 1/(beta*meter + meter)
assert convert_to(1/(beta*meter + alpha*meter), 1/kilometer) == (1/(kilometer*beta/1000 + alpha*kilometer/1000))
def test_eval_simplify():
from sympy.physics.units import cm, mm, km, m, K, kilo
from sympy.core.symbol import symbols
x, y = symbols('x y')
assert (cm/mm).simplify() == 10
assert (km/m).simplify() == 1000
assert (km/cm).simplify() == 100000
assert (10*x*K*km**2/m/cm).simplify() == 1000000000*x*kelvin
assert (cm/km/m).simplify() == 1/(10000000*centimeter)
assert (3*kilo*meter).simplify() == 3000*meter
assert (4*kilo*meter/(2*kilometer)).simplify() == 2
assert (4*kilometer**2/(kilo*meter)**2).simplify() == 4
def test_quantity_simplify():
from sympy.physics.units.util import quantity_simplify
from sympy.physics.units import kilo, foot
from sympy.core.symbol import symbols
x, y = symbols('x y')
assert quantity_simplify(x*(8*kilo*newton*meter + y)) == x*(8000*meter*newton + y)
assert quantity_simplify(foot*inch*(foot + inch)) == foot**2*(foot + foot/12)/12
assert quantity_simplify(foot*inch*(foot*foot + inch*(foot + inch))) == foot**2*(foot**2 + foot/12*(foot + foot/12))/12
assert quantity_simplify(2**(foot/inch*kilo/1000)*inch) == 4096*foot/12
assert quantity_simplify(foot**2*inch + inch**2*foot) == 13*foot**3/144
def test_quantity_simplify_across_dimensions():
from sympy.physics.units.util import quantity_simplify
from sympy.physics.units import ampere, ohm, volt, joule, pascal, farad, second, watt, siemens, henry, tesla, weber, hour, newton
assert quantity_simplify(ampere*ohm, across_dimensions=True, unit_system="SI") == volt
assert quantity_simplify(6*ampere*ohm, across_dimensions=True, unit_system="SI") == 6*volt
assert quantity_simplify(volt/ampere, across_dimensions=True, unit_system="SI") == ohm
assert quantity_simplify(volt/ohm, across_dimensions=True, unit_system="SI") == ampere
assert quantity_simplify(joule/meter**3, across_dimensions=True, unit_system="SI") == pascal
assert quantity_simplify(farad*ohm, across_dimensions=True, unit_system="SI") == second
assert quantity_simplify(joule/second, across_dimensions=True, unit_system="SI") == watt
assert quantity_simplify(meter**3/second, across_dimensions=True, unit_system="SI") == meter**3/second
assert quantity_simplify(joule/second, across_dimensions=True, unit_system="SI") == watt
assert quantity_simplify(joule/coulomb, across_dimensions=True, unit_system="SI") == volt
assert quantity_simplify(volt/ampere, across_dimensions=True, unit_system="SI") == ohm
assert quantity_simplify(ampere/volt, across_dimensions=True, unit_system="SI") == siemens
assert quantity_simplify(coulomb/volt, across_dimensions=True, unit_system="SI") == farad
assert quantity_simplify(volt*second/ampere, across_dimensions=True, unit_system="SI") == henry
assert quantity_simplify(volt*second/meter**2, across_dimensions=True, unit_system="SI") == tesla
assert quantity_simplify(joule/ampere, across_dimensions=True, unit_system="SI") == weber
assert quantity_simplify(5*kilometer/hour, across_dimensions=True, unit_system="SI") == 25*meter/(18*second)
assert quantity_simplify(5*kilogram*meter/second**2, across_dimensions=True, unit_system="SI") == 5*newton
def test_check_dimensions():
x = symbols('x')
assert check_dimensions(inch + x) == inch + x
assert check_dimensions(length + x) == length + x
# after subs we get 2*length; check will clear the constant
assert check_dimensions((length + x).subs(x, length)) == length
assert check_dimensions(newton*meter + joule) == joule + meter*newton
raises(ValueError, lambda: check_dimensions(inch + 1))
raises(ValueError, lambda: check_dimensions(length + 1))
raises(ValueError, lambda: check_dimensions(length + time))
raises(ValueError, lambda: check_dimensions(meter + second))
raises(ValueError, lambda: check_dimensions(2 * meter + second))
raises(ValueError, lambda: check_dimensions(2 * meter + 3 * second))
raises(ValueError, lambda: check_dimensions(1 / second + 1 / meter))
raises(ValueError, lambda: check_dimensions(2 * meter*(mile + centimeter) + km))