Ejemplo n.º 1
0
    def __new__(cls, name, dependency, unit_system, standard=True):

        self = Unit.__new__(cls, name)
        self.standard = standard
        if isinstance(dependency, str):
            self.dependency = parse_expr(dependency, local_dict=unit_system)
            for u in self.dependency.free_symbols:
                if not isinstance(u, Unit):
                    raise ValueError("%s is not a unit." % u.name)
        else:
            self.dependency = dependency

        #calculate factor
        self.factor = self.dependency
        for var in self.dependency.free_symbols:
            exponent = self.factor.as_coeff_exponent(var)[1]
            self.factor *= var.factor**exponent
            self.factor /= var**exponent
        assert self.factor.is_number

        #calculate dimension
        dim = self.dependency
        for var in self.dependency.free_symbols:
            dim = subs_symbols(dim, {var.name: var.dim})
        self.dim = dim_simplify(dim)

        #calculate complexity
        self.complexity = 0
        for exponent in self.dim.values():
            self.complexity += abs(exponent)

        return self
Ejemplo n.º 2
0
def parse_unit(unit, unit_system=None):
    """
	parses a unit string or unit expression and returns (factor,dimension,unit)
	where factor is the correction factor to get to the base unit system,
	dimension is the physical dimension as a Dimension object
	and unit is the unit as an Expression containing Unit objects

	Returns:
	tuple of factor, dimension and unit
	"""

    if unit_system is None:
        unit_system = DEF_UNIT_SYSTEM

    if isinstance(unit, str):
        if unit == "":
            unit = S.One
        else:
            unit = parse_expr(unit, local_dict=unit_system)
    for u in unit.free_symbols:
        if not isinstance(u, Unit):
            raise ValueError("%s is not a unit." % u.name)

    #calculate dimension
    dim = unit
    factor = unit
    for var in unit.free_symbols:
        exp = unit.as_coeff_exponent(var)[1]
        if exp == 0:
            raise ValueError("%s is not a valid unit string." % unitStr)
        dim = subs_symbols(dim, {var.name: var.dim})
        factor = factor.subs(var, var.factor)

    return (factor, dim_simplify(dim), unit)
Ejemplo n.º 3
0
def get_dimension(expr):
    """ finds out physical dimension of a term containing quantities

    Args:
    - expr: Expr object possibly containing Quantity objects

    Returns: Dimension object
    """

    dim = expr
    for var in expr.free_symbols:
        if var.dim is None:
            raise RuntimeError ("quantity '%s' doesn't have a dimension, yet." % var.name)
        dim = subs_symbols(dim,{var.name:var.dim})
    return dim_simplify(dim)
Ejemplo n.º 4
0
def dim_solve_global(expr, resolved={}):
    expr = subs_symbols(expr, resolved)
    return dim_simplify(expr)
Ejemplo n.º 5
0
def convert_to_unit(input_dimension,
                    output_unit=None,
                    only_base=False,
                    unit_system=None):
    """
	function that converts dimension to unit

	Args:
	 - input_dimension: physical dimension as Dimension object
	 - output_unit: if specified, this function will only calculate the corresponding factor
	 - only_base: if True, will just use base units
	 - unit_system: dictionary of unit system to use

	Returns tuple of factor and unit.
	"""
    if unit_system is None:
        unit_system = DEF_UNIT_SYSTEM

    if output_unit == None:
        output_unit = S.One
        if input_dimension.is_dimensionless:
            return (S.One, S.One)
        assert isinstance(input_dimension, Dimension)
        factor = 1

        sortedComplexities = sorted(set(
            map(lambda x: unit_system[x].complexity, unit_system)),
                                    reverse=True)
        #iterates all complexities
        for complexity in sortedComplexities:
            reciprocal = S.One
            #checks first putting in normally, then putting in reciprocally
            while True:
                #iterates all units of this complexity
                for unit in unit_system.values():
                    if (not only_base) or isinstance(unit, BaseUnit):
                        if unit.standard and unit.complexity == complexity:
                            #tries to put in as often as possible
                            while True:
                                if fits_in(unit, input_dimension, reciprocal):
                                    input_dimension = dim_simplify(
                                        input_dimension /
                                        (unit.dim**reciprocal))
                                    output_unit *= unit**reciprocal
                                    factor *= unit.factor**reciprocal
                                    if input_dimension.is_dimensionless:
                                        return (factor, output_unit)
                                else:
                                    break

                if reciprocal == S.One:
                    reciprocal = S.NegativeOne
                else:
                    break
        assert input_dimension.is_dimensionless
    else:
        factor, dim, unit = parse_unit(output_unit, unit_system)
        if not input_dimension == dim:
            raise RuntimeError("unit %s does not fit dimension %s." %
                               (output_unit, input_dimension))

    return (factor, output_unit)