示例#1
0
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
示例#2
0
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)
示例#3
0
 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
示例#4
0
文件: util.py 项目: sixpearls/sympy
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
示例#5
0
 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:
             return self
         return super(Dimension, self).__mul__(other)
     return self
示例#6
0
 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_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)
示例#8
0
def test_dimensional_expr_of_derivative():
    l = Quantity('l')
    t = Quantity('t')
    t1 = Quantity('t1')
    l.set_dimension(length)
    t.set_dimension(time)
    t1.set_dimension(time)
    l.set_scale_factor(36*km)
    t.set_scale_factor(hour)
    t1.set_scale_factor(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 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,
    }
示例#10
0
 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
示例#11
0
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
示例#12
0
文件: util.py 项目: bjodah/sympy
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)
示例#13
0
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)
示例#14
0
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))

    with warns_deprecated_sympy():
        Dq1 = Dimension(Quantity.get_dimensional_expr(expr))
        assert Dq == Dq1

    assert SI.get_dimension_system().get_dimensional_dependencies(Dq) == {
        'length': 1,
        'time': -1,
    }
    assert meter == sqrt(meter**2)
示例#15
0
mebibyte = mebibytes = Quantity("mebibyte")
mebibyte.set_dimension(information)
mebibyte.set_scale_factor(mebi * byte)

gibibyte = gibibytes = Quantity("gibibyte")
gibibyte.set_dimension(information)
gibibyte.set_scale_factor(gibi * byte)

tebibyte = tebibytes = Quantity("tebibyte")
tebibyte.set_dimension(information)
tebibyte.set_scale_factor(tebi * byte)

pebibyte = pebibytes = Quantity("pebibyte")
pebibyte.set_dimension(information)
pebibyte.set_scale_factor(pebi * byte)

exbibyte = exbibytes = Quantity("exbibyte")
exbibyte.set_dimension(information)
exbibyte.set_scale_factor(exbi * byte)

# check that scale factors are the right SI dimensions:
for _scale_factor, _dimension in zip(
        Quantity.SI_quantity_scale_factors.values(),
        Quantity.SI_quantity_dimension_map.values()):
    dimex = Quantity.get_dimensional_expr(_scale_factor)
    if dimex != 1:
        if not dimsys_default.equivalent_dims(_dimension, Dimension(dimex)):
            raise ValueError("quantity value and dimension mismatch")
del _scale_factor, _dimension
示例#16
0
mebibyte = mebibytes = Quantity("mebibyte")
mebibyte.set_dimension(information)
mebibyte.set_scale_factor(mebi*byte)

gibibyte = gibibytes = Quantity("gibibyte")
gibibyte.set_dimension(information)
gibibyte.set_scale_factor(gibi*byte)

tebibyte = tebibytes = Quantity("tebibyte")
tebibyte.set_dimension(information)
tebibyte.set_scale_factor(tebi*byte)

pebibyte = pebibytes = Quantity("pebibyte")
pebibyte.set_dimension(information)
pebibyte.set_scale_factor(pebi*byte)

exbibyte = exbibytes = Quantity("exbibyte")
exbibyte.set_dimension(information)
exbibyte.set_scale_factor(exbi*byte)


# check that scale factors are the right SI dimensions:
for _scale_factor, _dimension in zip(
        Quantity.SI_quantity_scale_factors.values(),
        Quantity.SI_quantity_dimension_map.values()):
    dimex = Quantity.get_dimensional_expr(_scale_factor)
    if dimex != 1:
        if not dimsys_default.equivalent_dims(_dimension, Dimension(dimex)):
            raise ValueError("quantity value and dimension mismatch")
del _scale_factor, _dimension
示例#17
0
def convert_to(expr, quantity):
    """
    Convert `expr` to the same expression with all of its units and quantities
    represented as factors of `quantity`, whenever the dimension is compatible.

    Examples
    ========

    >>> from sympy.physics.units import speed_of_light, meter, gram, \
        second, day, mile, newton, kilogram, inch, centimeter, atomic_mass_constant
    >>> from sympy.physics.units.definitions import kilometer
    >>> 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.66053904e-24*gram
    """
    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 expr.scale_factor
        return 1

    def get_units(expr):
        if isinstance(expr, Mul):
            return reduce(lambda x, y: x * y,
                          [get_units(i) for i in expr.args])
        elif isinstance(expr, Pow):
            return get_units(expr.base)**expr.exp
        elif isinstance(expr, Quantity):
            return expr
        return 1

    if isinstance(quantity, Quantity):
        backup_quantity = None
    else:
        backup_quantity = quantity
        quantity = Quantity("_temp",
                            Dimension(Quantity.get_dimensional_expr(quantity)),
                            get_total_scale_factor(quantity))

    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

    res = _convert_to(expr, quantity)
    if backup_quantity:
        res = res.subs(quantity, backup_quantity)
    return res
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_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))