Пример #1
0
    def __new__(cls, name, dimension, scale_factor=S.One, abbrev=None, **assumptions):

        if not isinstance(name, Symbol):
            name = Symbol(name)

        if not isinstance(dimension, dimensions.Dimension):
            if dimension == 1:
                dimension = Dimension(1)
            else:
                raise ValueError("expected dimension or 1")
        scale_factor = sympify(scale_factor)

        dimex = Quantity.get_dimensional_expr(scale_factor)
        if dimex != 1:
            if dimension != Dimension(dimex):
                raise ValueError("quantity value and dimension mismatch")

        # replace all prefixes by their ratio to canonical units:
        scale_factor = scale_factor.replace(lambda x: isinstance(x, Prefix), lambda x: x.scale_factor)
        # replace all quantities by their ratio to canonical units:
        scale_factor = scale_factor.replace(lambda x: isinstance(x, Quantity), lambda x: x.scale_factor)

        if abbrev is None:
            abbrev = name
        elif isinstance(abbrev, string_types):
            abbrev = Symbol(abbrev)

        obj = AtomicExpr.__new__(cls, name, dimension, scale_factor, abbrev)
        obj._name = name
        obj._dimension = dimension
        obj._scale_factor = scale_factor
        obj._abbrev = abbrev
        return obj
Пример #2
0
    def _get_conversion_matrix_for_expr(expr, target_units, unit_system):
        """depend on sympy 1.5-1.6!!!"""
        from sympy import Matrix

        dimension_system = unit_system.get_dimension_system()

        expr_dim = Dimension(unit_system.get_dimensional_expr(expr))
        dim_dependencies = dimension_system.get_dimensional_dependencies(expr_dim, mark_dimensionless=True)
        target_dims = [Dimension(unit_system.get_dimensional_expr(x)) for x in target_units]
        canon_dim_units = [i for x in target_dims for i in
                           dimension_system.get_dimensional_dependencies(x, mark_dimensionless=True)]
        canon_expr_units = {i for i in dim_dependencies}

        if not canon_expr_units.issubset(set(canon_dim_units)):
            raise TypeError("There is an invalid character in '%s'" % expr,
                            "the expr must be sympy.physics.unit or number")

        seen = set([])
        canon_dim_units = [i for i in canon_dim_units if not (i in seen or seen.add(i))]

        camat = Matrix(
            [[dimension_system.get_dimensional_dependencies(i, 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, canon_dim_units
Пример #3
0
 def _collect_factor_and_dimension(expr):
     """Return tuple with factor expression and dimension expression."""
     if isinstance(expr, Quantity):
         return expr.scale_factor, expr.dimension
     elif isinstance(expr, Mul):
         factor = 1
         dimension = Dimension(1)
         for arg in expr.args:
             arg_factor, arg_dim = Quantity._collect_factor_and_dimension(
                 arg)
             factor *= arg_factor
             dimension *= arg_dim
         return factor, dimension
     elif isinstance(expr, Pow):
         factor, dim = Quantity._collect_factor_and_dimension(expr.base)
         return factor**expr.exp, dim**expr.exp
     elif isinstance(expr, Add):
         factor, dim = Quantity._collect_factor_and_dimension(expr.args[0])
         for addend in expr.args[1:]:
             addend_factor, addend_dim = \
                 Quantity._collect_factor_and_dimension(addend)
             assert dim == addend_dim
             factor += addend_factor
         return factor, dim
     elif isinstance(expr, Function):
         fds = [
             Quantity._collect_factor_and_dimension(arg)
             for arg in expr.args
         ]
         return expr.func(*(f[0] for f in fds)), expr.func(*(d[1]
                                                             for d in fds))
     else:
         return expr, Dimension(1)
Пример #4
0
def derive_base_dimension(dim):
    """Derive base dimension of dimension."""
    return functools.reduce(
        operator.mul,
        (Dimension(d)**p
         for d, p in dimsys_SI.get_dimensional_dependencies(dim).items()),
        Dimension(1))
Пример #5
0
def match_dimensionless_units(lhs_units, rhs_units):
    '''if lhs_units is dimensionless and rhs_units is not dimensionless, assign rhs_units to lhs_units (and vice versa)'''
    if lhs_units == Dimension(1):  # f = ...
        if rhs_units != lhs_units:  # f = rho[kg/m^3]
            lhs_units = rhs_units  # f[kg/m^3] = rho[kg/m^3]
    elif rhs_units == Dimension(1):  # ... = x
        if rhs_units != lhs_units:  # f[kg/m^3] = x
            rhs_units = lhs_units  # f[kg/m^3] = x[kg/m^3]
    return lhs_units, rhs_units
Пример #6
0
    def __div__(self, other):

        if isinstance(other, Dim):
            if self.name == other.name:
                return Dim(Dimension(1))
            else:
                return Dim(Dimension(self.name / other.name))
        elif isinstance(other, (numbers.Real, sympy.Rational, sympy.Float)):
            return self
        else:
            raise TypeError
Пример #7
0
    def __new__(cls,
                name,
                dimension,
                scale_factor=S.One,
                abbrev=None,
                dim_sys=dimsys_default,
                **assumptions):

        if not isinstance(name, Symbol):
            name = Symbol(name)

        if not isinstance(dim_sys, DimensionSystem):
            raise TypeError("%s is not a DimensionSystem" % dim_sys)

        if not isinstance(dimension, dimensions.Dimension):
            if dimension == 1:
                dimension = Dimension(1)
            else:
                raise ValueError("expected dimension or 1")
        else:
            for dim_sym in dimension.name.atoms(Dimension):
                if dim_sym not in [
                        i.name for i in dim_sys._dimensional_dependencies
                ]:
                    raise ValueError("Dimension %s is not registered in the "
                                     "dimensional dependency tree." % dim_sym)

        scale_factor = sympify(scale_factor)

        dimex = Quantity.get_dimensional_expr(scale_factor)
        if dimex != 1:
            if not dim_sys.equivalent_dims(dimension, Dimension(dimex)):
                raise ValueError("quantity value and dimension mismatch")

        # replace all prefixes by their ratio to canonical units:
        scale_factor = scale_factor.replace(lambda x: isinstance(x, Prefix),
                                            lambda x: x.scale_factor)
        # replace all quantities by their ratio to canonical units:
        scale_factor = scale_factor.replace(lambda x: isinstance(x, Quantity),
                                            lambda x: x.scale_factor)

        if abbrev is None:
            abbrev = name
        elif isinstance(abbrev, string_types):
            abbrev = Symbol(abbrev)

        obj = AtomicExpr.__new__(cls, name, dimension, scale_factor, abbrev)
        obj._name = name
        obj._dimension = dimension
        obj._scale_factor = scale_factor
        obj._dim_sys = dim_sys
        obj._abbrev = abbrev
        return obj
Пример #8
0
 def _collect_factor_and_dimension(expr):
     """Return tuple with factor expression and dimension expression."""
     if isinstance(expr, Quantity):
         return expr.scale_factor, expr.dimension
     elif isinstance(expr, Mul):
         factor = 1
         dimension = Dimension(1)
         for arg in expr.args:
             arg_factor, arg_dim = Quantity._collect_factor_and_dimension(
                 arg)
             factor *= arg_factor
             dimension *= arg_dim
         return factor, dimension
     elif isinstance(expr, Pow):
         factor, dim = Quantity._collect_factor_and_dimension(expr.base)
         exp_factor, exp_dim = Quantity._collect_factor_and_dimension(
             expr.exp)
         if exp_dim.is_dimensionless:
             exp_dim = 1
         return factor**exp_factor, dim**(exp_factor * exp_dim)
     elif isinstance(expr, Add):
         factor, dim = Quantity._collect_factor_and_dimension(expr.args[0])
         for addend in expr.args[1:]:
             addend_factor, addend_dim = \
                 Quantity._collect_factor_and_dimension(addend)
             if dim != addend_dim:
                 raise TypeError('Dimension of "{0}" is {1}, '
                                 'but it should be {2}'.format(
                                     addend, addend_dim.name, dim.name))
             factor += addend_factor
         return factor, dim
     elif isinstance(expr, Derivative):
         factor, dim = Quantity._collect_factor_and_dimension(expr.args[0])
         for independent in expr.args[1:]:
             ifactor, idim = Quantity._collect_factor_and_dimension(
                 independent)
             factor /= ifactor
             dim /= idim
         return factor, dim
     elif isinstance(expr, Function):
         fds = [
             Quantity._collect_factor_and_dimension(arg)
             for arg in expr.args
         ]
         return (expr.func(*(f[0] for f in fds)),
                 expr.func(*(d[1] for d in fds)))
     elif isinstance(expr, Dimension):
         return 1, expr
     else:
         return expr, Dimension(1)
Пример #9
0
    def check_unit(expr):
        """Construct postprocessor for the addition.

        Checks for dimension mismatches of the addends, thus preventing
        expressions like `meter + second` to be created.
        """
        deset = {
            tuple(
                sorted(
                    dimsys_default.get_dimensional_dependencies(
                        Dimension(
                            Variable.get_dimensional_expr(i)
                            if not i.is_number else 1
                        )
                    ).items()
                )
            )
            for i in expr.args
        }
        # If `deset` has more than one element, then some dimensions do not
        # match in the sum:
        if len(deset) > 1:
            raise ValueError(
                "summation of quantities of incompatible dimensions"
            )
        return expr
Пример #10
0
def get_unit(unit_str, unit_subs=unit_subs):
    """get the unit quantity corresponding to this string

    unit_subs should contain a dictonary {symbol: quantity} of custom units not available in sympy"""

    unit_str = clean_unit(unit_str)
    units = get_unit_quantities()

    if unit_subs is not None:
        units.update(unit_subs)

    if len(unit_str) == 0:
        return Dimension(1)

    unit_expr = parse_expr(unit_str.replace('^', '**'), locals=_clash)
    try:
        unit = unit_expr.subs(units)
    except:
        raise NameError('something wrong with unit str [{}], type {}, {}'.format(
            unit_str, type(unit_str), unit_expr))
    try:
        assert len(unit.free_symbols) == 0
    except:
        raise NameError("Unsupported unit: {} {} {}".format(
            unit_str, type(unit_str), unit.free_symbols))
    return unit
Пример #11
0
    def __new__(cls, name, parents, dct):
        """Build and register new variable."""
        if '__registry__' not in dct:
            unit = dct.pop('unit', S.One)
            if unit == 1:
                unit = S.One
            definition = dct.pop('expr', None)

            dct.setdefault('name', name)
            dct.setdefault('assumptions', {'real': True})
            dct.setdefault('latex_name', dct['name'])
            dct.setdefault('unit', unit)

            instance = super(VariableMeta,
                             cls).__new__(cls, name, parents, dct)

            # Variable with definition expression.
            if definition is not None:
                definition = build_instance_expression(instance, definition)
                derived_unit = derive_unit(definition, name=name)

                if unit == S.One:
                    unit = derived_unit  # only if unit is None
                instance.expr, instance.unit = definition, unit

                dim_derived = dimsys_SI.get_dimensional_dependencies(
                    Variable.get_dimensional_expr(derived_unit))
                dim_unit = dimsys_SI.get_dimensional_dependencies(
                    Variable.get_dimensional_expr(unit))
                if dim_derived != dim_unit:
                    raise ValueError(
                        'Invalid expression units {0} should be {1}'.format(
                            instance.unit, unit))

            expr = BaseVariable(instance,
                                dct['name'],
                                abbrev=dct['latex_name'],
                                dimension=Dimension(
                                    SI.get_dimensional_expr(unit)),
                                scale_factor=unit or S.One,
                                **dct['assumptions'])
            instance[expr] = instance

            # Store definition as variable expression.
            if definition is not None:
                instance.__expressions__[expr] = definition

            # Store default variable only if it is defined.
            if 'default' in dct:
                instance.__defaults__[expr] = dct['default']

            # Store unit for each variable:
            instance.__units__[expr] = unit

            return expr

        return super(VariableMeta, cls).__new__(cls, name, parents, dct)
Пример #12
0
 def _eval_power(self, other):
     other = sympify(other)
     if isinstance(other, (numbers.Real, sympy.Rational, sympy.Float)):
         return Dim(Dimension(self.name**other))
     elif isinstance(other, Dim):
         if other.name == 1:
             return self
     else:
         raise TypeError
Пример #13
0
def derive_unit(expr, name=None):
    """Derive SI-unit from an expression, omitting scale factors."""
    from essm.variables import Variable
    from essm.variables.utils import extract_variables
    from sympy.physics.units import Dimension
    from sympy.physics.units.dimensions import dimsys_SI

    variables = extract_variables(expr)
    for var1 in variables:
        q1 = Quantity('q_' + str(var1))
        q1.set_dimension(
            Dimension(Quantity.get_dimensional_expr(var1.definition.unit)))
        q1.set_scale_factor(var1.definition.unit)
        expr = expr.xreplace({var1: q1})
    dim = Dimension(Quantity.get_dimensional_expr(expr))
    return functools.reduce(
        operator.mul,
        (SI_DIMENSIONS[d]**p
         for d, p in dimsys_SI.get_dimensional_dependencies(dim).items()), 1)
Пример #14
0
def generate(pset0, dim_list):
    """generate_index core method"""

    same = False
    # same = True
    comp = pset0.terminals_comp
    prop = pset0.terminals_prop

    expr = []
    if dim_list[3] != Dim(Dimension(1)):
        prop_count = [pset0.mapping['powre'], pset0.mapping['pow1'],
                      pset0.mapping['pow2'], pset0.mapping['pow3']]
    else:
        prop_count = [pset0.mapping['exp'], pset0.mapping['log'],
                      pset0.mapping['sqrt'], pset0.mapping['powre'], pset0.mapping['pow1'],
                      pset0.mapping['pow2'], pset0.mapping['pow3']]

    comp_count = [pset0.mapping['exp'], pset0.mapping['log'],
                  pset0.mapping['sqrt'], pset0.mapping['powre'], pset0.mapping['pow1'],
                  pset0.mapping['pow2'], pset0.mapping['pow3']]
    out1_count = [pset0.mapping['pow1'], ]
    link_count = [pset0.mapping['Add'], pset0.mapping['Div'], ]
    out2_count = [pset0.mapping['exp'], pset0.mapping['log'],
                  pset0.mapping['sqrt'], pset0.mapping['pow1'],
                  ]

    for i in prop_count:
        for j in comp_count:
            for l in out1_count:
                expr.append([prop[0], i, comp[0], j, pset0.mapping['Mul'], l])

    expr_list0 = []

    for k in range(len(comp)):
        exprco = copy.deepcopy(expr)
        for expri in exprco:
            expri[0] = prop[k]
            expri[2] = comp[k]
        expr_list0.append(exprco)
    if same is True:
        expr_list = list(zip(*expr_list0))
    else:
        expr_list = list(product(*expr_list0))

    expr_list2 = []
    for m in out2_count:
        for t in link_count:
            exprr = [t] * (len(comp) - 1)
            exprr.append(m)
            for exp1 in expr_list:
                ex = list(chain(*exp1))
                expp = ex + exprr
                expp.reverse()
                expr_list2.append(expp)
    return expr_list2
Пример #15
0
def validate_units(expr, units):
    result = expr.subs(units, simultaneous=True)
    if len(result.free_symbols) != 0:
        return Dimension(1)
    else:
        for s, unit in list(units.items()):
            try:
                result = result.replace(wildcard(s), unit)
            except:
                pass
        return result
Пример #16
0
def test_prefix_unit():
    length = Dimension("length")
    m = Quantity("meter", length, 1, abbrev="m")

    pref = {"m": PREFIXES["m"], "c": PREFIXES["c"], "d": PREFIXES["d"]}

    res = [Quantity("millimeter", length, PREFIXES["m"], abbrev="mm"),
           Quantity("centimeter", length, PREFIXES["c"], abbrev="cm"),
           Quantity("decimeter", length, PREFIXES["d"], abbrev="dm")]

    prefs = prefix_unit(m, pref)
    assert set(prefs) == set(res)
    assert set(map(lambda x: x.abbrev, prefs)) == set(symbols("mm,cm,dm"))
Пример #17
0
def derive_baseunit(expr, name=None):
    """Derive SI base unit from an expression, omitting scale factors."""
    from essm.variables import Variable
    from essm.variables.utils import extract_variables
    from sympy.physics.units import Dimension
    from sympy.physics.units.systems.si import dimsys_SI

    Variable.check_unit(expr)  # check for dimensional consistency
    variables = extract_variables(expr)
    for var1 in variables:
        q1 = Quantity('q_' + str(var1))
        SI.set_quantity_dimension(
            q1,
            Dimension(
                SI.get_dimensional_expr(derive_baseunit(
                    var1.definition.unit))))
        SI.set_quantity_scale_factor(q1, var1.definition.unit)
        expr = expr.xreplace({var1: q1})
    dim = Dimension(Variable.get_dimensional_expr(expr))
    return functools.reduce(
        operator.mul,
        (SI_BASE_DIMENSIONS[Symbol(d)]**p
         for d, p in dimsys_SI.get_dimensional_dependencies(dim).items()), 1)
Пример #18
0
def get_kamodo_unit_system():
    """Same as SI but supports anglular frequency"""

    radian = sympy.physics.units.radian
    degree = sympy.physics.units.degree
    si_unit_system = UnitSystem.get_unit_system('SI')
    si_dimension_system = si_unit_system.get_dimension_system()

    angle = Dimension('angle', 'A')

    kamodo_dims = si_dimension_system.extend(
        new_base_dims=(angle, ),
        new_derived_dims=[Dimension('angular_velocity')],
        new_dim_deps={
            Symbol('angular_velocity'): {
                Symbol('angle'): 1,
                Symbol('time'): -1
            }
        })

    kamodo_units = si_unit_system.extend((radian, ), (radian, degree),
                                         dimension_system=kamodo_dims)

    return kamodo_units
Пример #19
0
def _Quantity_constructor_postprocessor_Add(expr):
    # Construction postprocessor for the addition,
    # checks for dimension mismatches of the addends, thus preventing
    # expressions like `meter + second` to be created.

    deset = {
        tuple(Dimension(Quantity.get_dimensional_expr(i)).get_dimensional_dependencies().items())
        for i in expr.args
        if i.free_symbols == set()  # do not raise if there are symbols
                    # (free symbols could contain the units corrections)
        and not i.is_number
    }
    # If `deset` has more than one element, then some dimensions do not
    # match in the sum:
    if len(deset) > 1:
        raise ValueError("summation of quantities of incompatible dimensions")
    return expr
Пример #20
0
    def set_dimension(self, dimension, unit_system="SI"):
        from sympy.physics.units.dimensions import dimsys_default, DimensionSystem

        if unit_system != "SI":
            # TODO: add support for more units and dimension systems:
            raise NotImplementedError("Currently only SI is supported")

        dim_sys = dimsys_default

        if not isinstance(dimension, dimensions.Dimension):
            if dimension == 1:
                dimension = Dimension(1)
            else:
                raise ValueError("expected dimension or 1")
        else:
            for dim_sym in dimension.name.atoms(Dimension):
                if dim_sym not in [i.name for i in dim_sys._dimensional_dependencies]:
                    raise ValueError("Dimension %s is not registered in the "
                                     "dimensional dependency tree." % dim_sym)
        Quantity.SI_quantity_dimension_map[self] = dimension
Пример #21
0
def get_unit(unit_str, unit_subs=unit_subs):
    unit_str = clean_unit(unit_str)
    units = get_unit_quantities()

    if unit_subs is not None:
        units.update(unit_subs)

    if len(unit_str) == 0:
        return Dimension(1)
    try:
        unit = parse_expr(unit_str.replace('^', '**')).subs(units)
    except:
        raise NameError('something wrong with unit str [{}], type {}'.format(
            unit_str, type(unit_str)))
    try:
        assert len(unit.free_symbols) == 0
    except:
        raise ValueError("Unsupported unit: {} {}".format(
            unit_str, type(unit_str)))
    return unit
Пример #22
0
    def __setitem__(self, sym_name, input_expr):
        """Assigns a function or expression to a new symbol, performing unit conversion where necessary

		"""
        if self.verbose:
            print('')
        try:
            symbol, args, units, lhs_expr = self.parse_key(sym_name)
        except KeyError as error:
            if self.verbose:
                print(error)
            found_sym_name = str(error).split('found')[0].strip("'").strip(' ')
            if self.verbose:
                print('replacing {}'.format(found_sym_name))
            self.remove_symbol(found_sym_name)
            symbol, args, units, lhs_expr = self.parse_key(sym_name)

        if hasattr(input_expr, '__call__'):
            self.register_function(input_expr, symbol, lhs_expr, units)
        else:
            rhs_expr = self.parse_value(input_expr, self.symbol_registry)
            units_map = self.get_units_map()
            lhs_units = get_unit(units)
            rhs_units = validate_units(
                rhs_expr, units_map)  # check that rhs units are consistent

            try:
                lhs_units, rhs_units = match_dimensionless_units(
                    lhs_units, rhs_units)
                check_unit_compatibility(rhs_units, lhs_units)
            except:
                print(type(rhs_units))
                print(get_unit(units), validate_units(rhs_expr, units_map))
                raise

            rhs_expr_with_units = get_expr_with_units(rhs_expr, units_map)

            if self.verbose:
                print('rhs_expr with units:', rhs_expr_with_units)

            # convert back to expression without units for lambdify
            if units != '':
                try:
                    if self.verbose:
                        print('converting to {}'.format(lhs_units))
                        for k, v in list(units_map.items()):
                            print('\t', k, v, type(k))
                    rhs_expr = get_expr_without_units(rhs_expr_with_units,
                                                      lhs_units, units_map)
                    if self.verbose:
                        print('rhs_expr without units:', rhs_expr)
                except:
                    print('error with units? [{}]'.format(units))
                    raise
            else:
                if lhs_units != Dimension(
                        1):  # lhs_units were obtained from rhs_units
                    units = str(lhs_units)

            rhs_args = rhs_expr.free_symbols

            if self.verbose:
                print('lhs_expr:', lhs_expr, 'units:', lhs_units)
                print('rhs_expr:', rhs_expr, 'units:', rhs_units)
            try:
                symbol = self.check_or_replace_symbol(symbol, rhs_args,
                                                      rhs_expr)
                self.validate_function(symbol, rhs_expr)

            except:
                if self.verbose:
                    print('\n Error in __setitem__', input_expr)
                    print(symbol, lhs_expr, rhs_args)
                    print('symbol registry:', self.symbol_registry)
                    print('signatures:', self.signatures)
                raise

            composition = self.get_composition(lhs_expr, rhs_expr)
            func = self.vectorize_function(symbol, rhs_expr, composition)
            self.register_signature(symbol, units, lhs_expr, rhs_expr)
            super(Kamodo, self).__setitem__(symbol, func)
            super(Kamodo, self).__setitem__(type(symbol), self[symbol])
            self.register_symbol(symbol)
            self[symbol].meta = dict(units=units)
Пример #23
0
from sympy.physics.units import Dimension


angle = Dimension(name="angle")  # type: Dimension

# base dimensions (MKS)
length = Dimension(name="length", symbol="L")
mass = Dimension(name="mass", symbol="M")
time = Dimension(name="time", symbol="T")

# base dimensions (MKSA not in MKS)
current = Dimension(name='current', symbol='I')  # type: Dimension

# other base dimensions:
temperature = Dimension("temperature", "T")  # type: Dimension
amount_of_substance = Dimension("amount_of_substance")  # type: Dimension
luminous_intensity = Dimension("luminous_intensity")  # type: Dimension

# derived dimensions (MKS)
velocity = Dimension(name="velocity")
acceleration = Dimension(name="acceleration")
momentum = Dimension(name="momentum")
force = Dimension(name="force", symbol="F")
energy = Dimension(name="energy", symbol="E")
power = Dimension(name="power")
pressure = Dimension(name="pressure")
frequency = Dimension(name="frequency", symbol="f")
action = Dimension(name="action", symbol="A")
area = Dimension("area")
volume = Dimension("volume")
Пример #24
0
SI.set_quantity_scale_factor(curie, 37000000000*becquerel)

SI.set_quantity_dimension(rutherford, 1 / time)
SI.set_quantity_scale_factor(rutherford, 1000000*becquerel)


# check that scale factors are the right SI dimensions:
for _scale_factor, _dimension in zip(
    SI._quantity_scale_factors.values(),
    SI._quantity_dimension_map.values()
):
    dimex = SI.get_dimensional_expr(_scale_factor)
    if dimex != 1:
        # XXX: equivalent_dims is an instance method taking two arguments in
        # addition to self so this can not work:
        if not DimensionSystem.equivalent_dims(_dimension, Dimension(dimex)):  # type: ignore
            raise ValueError("quantity value and dimension mismatch")
del _scale_factor, _dimension

__all__ = [
    'mmHg', 'atmosphere', 'inductance', 'newton', 'meter',
    'vacuum_permittivity', 'pascal', 'magnetic_constant', 'voltage',
    'angular_mil', 'luminous_intensity', 'all_units',
    'julian_year', 'weber', 'exbibyte', 'liter',
    'molar_gas_constant', 'faraday_constant', 'avogadro_constant',
    'lightyear', 'planck_density', 'gee', 'mol', 'bit', 'gray',
    'planck_momentum', 'bar', 'magnetic_density', 'prefix_unit', 'PREFIXES',
    'planck_time', 'dimex', 'gram', 'candela', 'force', 'planck_intensity',
    'energy', 'becquerel', 'planck_acceleration', 'speed_of_light',
    'conductance', 'frequency', 'coulomb_constant', 'degree', 'lux', 'planck',
    'current', 'planck_current', 'tebibyte', 'planck_power', 'MKSA', 'power',
Пример #25
0
def base_dimensions(d):
    dependencies = dimsys_SI.get_dimensional_dependencies(d)
    return Mul.fromiter(
        Pow(Dimension(base), exp_) for base, exp_ in dependencies.items())
Пример #26
0
SI.set_quantity_dimension(curie, 1 / time)
SI.set_quantity_scale_factor(curie, 37000000000 * becquerel)

SI.set_quantity_dimension(rutherford, 1 / time)
SI.set_quantity_scale_factor(rutherford, 1000000 * becquerel)

# check that scale factors are the right SI dimensions:
for _scale_factor, _dimension in zip(SI._quantity_scale_factors.values(),
                                     SI._quantity_dimension_map.values()):
    dimex = SI.get_dimensional_expr(_scale_factor)
    if dimex != 1:
        # XXX: equivalent_dims is an instance method taking two arguments in
        # addition to self so this can not work:
        if not DimensionSystem.equivalent_dims(
                _dimension, Dimension(dimex)):  # type: ignore
            raise ValueError("quantity value and dimension mismatch")
del _scale_factor, _dimension

__all__ = [
    'mmHg',
    'atmosphere',
    'inductance',
    'newton',
    'meter',
    'vacuum_permittivity',
    'pascal',
    'magnetic_constant',
    'voltage',
    'angular_mil',
    'luminous_intensity',
Пример #27
0
SI.set_quantity_scale_factor(planck_current, planck_charge / planck_time)

SI.set_quantity_dimension(planck_voltage, voltage)
SI.set_quantity_scale_factor(planck_voltage, planck_energy / planck_charge)

SI.set_quantity_dimension(planck_impedance, impedance)
SI.set_quantity_scale_factor(planck_impedance, planck_voltage / planck_current)

SI.set_quantity_dimension(planck_acceleration, acceleration)
SI.set_quantity_scale_factor(planck_acceleration, speed_of_light / planck_time)

# Older units for radioactivity

SI.set_quantity_dimension(curie, 1 / time)
SI.set_quantity_scale_factor(curie, 37000000000*becquerel)

SI.set_quantity_dimension(rutherford, 1 / time)
SI.set_quantity_scale_factor(rutherford, 1000000*becquerel)


# check that scale factors are the right SI dimensions:
for _scale_factor, _dimension in zip(
    SI._quantity_scale_factors.values(),
    SI._quantity_dimension_map.values()
):
    dimex = SI.get_dimensional_expr(_scale_factor)
    if dimex != 1:
        if not DimensionSystem.equivalent_dims(_dimension, Dimension(dimex)):
            raise ValueError("quantity value and dimension mismatch")
del _scale_factor, _dimension
Пример #28
0
def summarise_results(logdir):

    dirlist = os.listdir(logdir)
    try:
        dirlist.remove('results.csv')
    except ValueError:
        pass

    dim_dict = {'exp': exp,
                'log': log}

    m = Dimension('length')
    s = Dimension('time')

    input_dims = {"grad_u_T1": 1 / s,
                  "grad_u_T2": 1 / s,
                  "grad_u_T3": 1 / s,
                  "grad_u_T4": 1 / s,
                  "k": (m ** 2) / (s ** 2),
                  "inv1": m / m,
                  "inv2": m / m,
                  "T1": m / m,
                  "T2": m / m,
                  "T3": m / m,
                  "T4": m / m}

    df_results = pd.DataFrame()

    for run in dirlist:

        if '.csv' in run:
            continue

        run_dir = os.path.join(logdir, run)
        print(f'Working on: {run}')
        with open(os.path.join(run_dir, 'config.json'), encoding='utf-8') as f:
            config_run = json.load(f)

        output = config_run['task']['dataset']['output'][:4]
        case = ''.join([letter for letter in config_run['task']['dataset']['name'] if not letter.isnumeric()])
        sw = config_run['task']['dataset']['skip_wall']
        ntok = config_run['prior']['length']['max_']

        run_name = f'{output}_{case}_sw{sw}_{ntok}tokens'

        results = load_iterations(os.path.join(logdir, run))

        df_joined = pd.DataFrame()

        for key in results:
            df_joined = pd.concat([df_joined, results[key]], axis=0, ignore_index=True)

        inputs = config_run['task']['dataset']['input']
        for ii in range(len(inputs)):
            dim_dict[f'x{ii+1}'] = input_dims[inputs[ii]]


        df_joined = df_joined[~df_joined['batch_r_max_expression'].isna()]

        df_joined['r_sum'] = df_joined.apply(lambda x: x['r_max_PH'] + x['r_max_CD'] + x['r_max_CBFS'], axis=1)

        if output == 'kDef':
            df_joined['dimensions'] = df_joined.apply(
                lambda x: check_expression_dim(x['batch_r_max_expression'], dim_dict), axis=1)

            target_dim = (0, 2, -3, 0, 0, 0, 0)
        if output == 'bDel':
            target_dim = (0, 0, 0, 0, 0, 0, 0)
            df_joined['dimensions'] = [(0, 0, 0, 0, 0, 0, 0) for _ in df_joined.index]

        df_joined = df_joined.drop_duplicates(subset=['batch_r_max_expression'])
        df_joined['converted_expression'] = df_joined.apply(lambda x: convert_expression(x['batch_r_max_expression'], inputs), axis=1)

        df_joined['name'] = run_name
        df_joined['output'] = output
        df_joined['training_case'] = case
        df_joined['skip_wall'] = sw

        if 'tokens' in df_joined.columns:
            df_joined['ntokens'] = df_joined.apply(lambda x: count_tokens(x['tokens'], ntok), axis=1)
        else:
            df_joined['ntokens'] = ntok

        df_right_dim = df_joined[df_joined['dimensions'] == target_dim]
        df_right_dim = df_right_dim.drop_duplicates(subset=['batch_r_max_expression'])
        df_right_dim['correct_dim'] = True

        # add best on all cases
        df_best = df_right_dim.sort_values('r_sum', ascending=False).head(70)
        df_best['rank'] = np.arange(len(df_best))
        df_best['ranked_by'] = 'r_sum'
        df_results = pd.concat([df_results, df_best], axis=0, ignore_index=True)

        # add best on all cases
        df_best = df_right_dim.sort_values(f'r_max_{case}', ascending=False).head(70)
        df_best['rank'] = np.arange(len(df_best))
        df_best['ranked_by'] = f'r_max_{case}'
        df_results = pd.concat([df_results, df_best], axis=0, ignore_index=True)


        save_arr = df_joined['r_max_PH'].values
        np.savetxt(os.path.join(logdir, f'LR{config_run["controller"]["learning_rate"]}_ent{config_run["controller"]["entropy_weight"]}_rewards.csv'), save_arr, delimiter=',')

        plt.figure()
        plt.hist(df_joined['r_max_PH'], bins=20)
        plt.title(f'{df_joined["r_max_PH"].max()}')
        plt.savefig(f'../logs_completed/aa_plots/aatmp_len{config_run["prior"]["length"]["max_"]}_LR{config_run["controller"]["learning_rate"]}_ent{config_run["controller"]["entropy_weight"]}.png')


        # df_wrong_dim = df_joined[df_joined['dimensions'] != target_dim]
        # df_wrong_dim = df_wrong_dim.drop_duplicates(subset=['batch_r_max_expression'])
        # df_wrong_dim['correct_dim'] = False
        #
        # # add best on all cases
        # df_best = df_wrong_dim.sort_values('r_sum', ascending=False).head(70)
        # df_best['rank'] = np.arange(len(df_best))
        # df_best['ranked_by'] = 'r_sum'
        # df_results = pd.concat([df_results, df_best], axis=0, ignore_index=True)
        #
        # # add best on all cases
        # df_best = df_wrong_dim.sort_values(f'r_max_{case}', ascending=False).head(70)
        # df_best['rank'] = np.arange(len(df_best))
        # df_best['ranked_by'] = f'r_max_{case}'
        # df_results = pd.concat([df_results, df_best], axis=0, ignore_index=True)


    save_cols = ['name','rank', 'ranked_by', 'r_max_PH', 'r_max_CD', 'r_max_CBFS', 'r_sum', 'batch_r_max_expression',
                 'dimensions', 'training_case', 'skip_wall', 'ntokens', 'correct_dim', 'converted_expression']
    df_save = df_results[save_cols]
    df_save = df_save.drop_duplicates(subset=['batch_r_max_expression'])

    df_save.to_csv(os.path.join(logdir, 'results.csv'),index=False)
Пример #29
0
def plot_ntokens_r_max(logdir):

    dirlist = os.listdir(logdir)

    tokens = []
    r_max_PH = []
    r_max_CD = []
    r_max_CBFS = []

    dim_dict = {'exp': exp,
                'log': log}

    m = Dimension('length')
    s = Dimension('time')

    input_dims = {"grad_u_T1": 1 / s,
                  "grad_u_T2": 1 / s,
                  "grad_u_T3": 1 / s,
                  "grad_u_T4": 1 / s,
                  "k": (m ** 2) / (s ** 2),
                  "inv1": m / m,
                  "inv2": m / m,
                  "T1": m / m,
                  "T2": m / m,
                  "T3": m / m,
                  "T4": m / m}

    for run in dirlist:

        if '.csv' in run:
            continue

        run_dir = os.path.join(logdir, run)
        print(f'Working on: {run}')
        with open(os.path.join(run_dir, 'config.json'), encoding='utf-8') as f:
            config_run = json.load(f)

        output = config_run['task']['dataset']['output'][:4]
        case = ''.join([letter for letter in config_run['task']['dataset']['name'] if not letter.isnumeric()])
        sw = config_run['task']['dataset']['skip_wall']
        ntok = config_run['prior']['length']['max_']

        run_name = f'{output}_{case}_sw{sw}_{ntok}tokens'

        results = load_iterations(os.path.join(logdir, run))

        df_joined = pd.DataFrame()

        for key in results:
            df_joined = pd.concat([df_joined, results[key]], axis=0, ignore_index=True)

        df_joined['r_sum'] = df_joined.apply(lambda x: x['r_max_PH'] + x['r_max_CD'] + x['r_max_CBFS'], axis=1)

        inputs = config_run['task']['dataset']['input']
        for ii in range(len(inputs)):
            dim_dict[f'x{ii + 1}'] = input_dims[inputs[ii]]

        df_joined['dimensions'] = df_joined.apply(lambda x: check_expression_dim(x['batch_r_max_expression'], dim_dict), axis=1)

        if output == 'kDef':
            target_dim = (0, 2, -3, 0, 0, 0, 0)
        if output == 'bDel':
            target_dim = (0, 0, 0, 0, 0, 0, 0)

        df_joined = df_joined[df_joined['dimensions'] == target_dim]

        df_joined['name'] = run_name
        df_joined['output'] = output
        df_joined['training_case'] = case
        df_joined['skip_wall'] = sw

        if 'tokens' in df_joined.columns:
            df_joined['ntokens'] = df_joined.apply(lambda x: count_tokens(x['tokens'], ntok), axis=1)
        else:
            df_joined['ntokens'] = ntok

        tokens.append(df_joined['ntokens'].values)
        r_max_PH.append(df_joined['r_max_PH'].values)
        r_max_CD.append(df_joined['r_max_CD'].values)
        r_max_CBFS.append(df_joined['r_max_CBFS'].values)

    tokens = np.concatenate(tokens, axis=0)
    r_max_PH = np.concatenate(r_max_PH, axis=0)
    r_max_CD = np.concatenate(r_max_CD, axis=0)
    r_max_CBFS = np.concatenate(r_max_CBFS, axis=0)

    sorted_tokens = []
    sorted_r_max_PH = []
    sorted_r_max_CD = []
    sorted_r_max_CBFS = []

    for token in np.unique(tokens):
        sorted_tokens.append(token)
        best_model_PH = np.argmax(r_max_PH[tokens == token])
        sorted_r_max_PH.append(r_max_PH[tokens == token][best_model_PH])
        sorted_r_max_CD.append(r_max_CD[tokens == token][best_model_PH])
        sorted_r_max_CBFS.append(r_max_CBFS[tokens == token][best_model_PH])

    markersize = 25
    lw = 2
    width = 7
    figsize = (width, 3*width/4)
    cm = 1 / 2.54  # centimeters in inches

    plt.figure(figsize=tuple([val*cm for val in list(figsize)]))
    plt.xlabel(r"$n_{tokens}$")
    plt.ylabel(r"$r_{max}$")
    plt.xticks(np.arange(0,25,2))
    plt.yticks(np.arange(0,1,0.05))
    ax = plt.gca()
    ax.set_axisbelow(True)
    plt.grid('both', linestyle=':')
    plt.plot(sorted_tokens, sorted_r_max_CD, label='$CD_{12600}$', c='C1', linestyle='--', linewidth=lw, marker='^')
    plt.plot(sorted_tokens, sorted_r_max_CBFS, label='$CBFS_{13700}$', c='C2', linestyle=':', linewidth=lw, marker='v')
    plt.plot(sorted_tokens, sorted_r_max_PH, label='$PH_{10595}$', c='C0', linestyle=(0, (3, 1, 1, 1)), linewidth=lw, marker='d')

    order = [2, 0, 1]
    handles, labels = ax.get_legend_handles_labels()
    plt.legend(handles=[handles[idx] for idx in order], labels=[labels[idx] for idx in order], ncol=3, loc='center', bbox_to_anchor=(0.5, 1.15), prop={'size': 8}) # ,ncol=4, loc='center', bbox_to_anchor=(0.5, 1.1), prop={'size': 9}

    plt.savefig(f'../logs_completed/aa_plots/ntokens_r_max{logdir.split("/")[-1]}.eps', format='eps', bbox_inches='tight')
Пример #30
0
 def collect_factor_and_basedimension(expr):
     """Return tuple with factor expression and dimension expression."""
     if isinstance(expr, BaseVariable):
         expr = expr.definition.unit
     if isinstance(expr, Quantity):
         return expr.scale_factor, derive_base_dimension(expr.dimension)
     elif isinstance(expr, Mul):
         factor = 1
         dimension = Dimension(1)
         for arg in expr.args:
             arg_factor, arg_dim = \
                 Variable.collect_factor_and_basedimension(arg)
             factor *= arg_factor
             dimension *= arg_dim
         return factor, dimension
     elif isinstance(expr, Pow):
         factor, dim = Variable.collect_factor_and_basedimension(expr.base)
         exp_factor, exp_dim = \
             Variable.collect_factor_and_basedimension(expr.exp)
         if exp_dim.is_dimensionless:
             exp_dim = 1
         return factor**exp_factor, derive_base_dimension(
             dim**(exp_factor * exp_dim)).simplify()
     elif isinstance(expr, log):
         return expr, Dimension(1)
     elif isinstance(expr, Add):
         factor, dim = \
             Variable.collect_factor_and_basedimension(expr.args[0])
         for addend in expr.args[1:]:
             addend_factor, addend_dim = \
                 Variable.collect_factor_and_basedimension(addend)
             if dim != addend_dim:
                 raise ValueError(
                     'Dimension of "{0}" is {1}, '
                     'but it should be the same as {2}, i.e. {3}'.format(
                         addend, addend_dim, expr.args[0], dim))
             factor += addend_factor
         return factor, dim
     elif isinstance(expr, Derivative):
         factor, dim = \
             Variable.collect_factor_and_basedimension(expr.args[0])
         for independent, count in expr.variable_count:
             ifactor, idim = \
                 Variable.collect_factor_and_basedimension(independent)
             factor /= ifactor**count
             dim /= idim**count
         return factor, dim
     elif isinstance(expr, Integral):
         try:
             Variable.collect_factor_and_basedimension(sum(expr.args[1]))
         except ValueError:
             raise ValueError(
                 "Wrong dimensions of integration limits ({expr}).".format(
                     expr=expr))
         factor, dim = \
             Variable.collect_factor_and_basedimension(expr.args[0] *
                                                       expr.args[1][0])
         return factor, dim
     elif isinstance(expr, Piecewise):
         factor, dim = Variable.collect_factor_and_basedimension(
             sum([x[0] for x in expr.args]))
         return factor, dim
     elif isinstance(expr, Function):
         fds = {
             Variable.collect_factor_and_basedimension(arg)[1]
             for arg in expr.args
         }
         if fds != {Dimension(1)}:
             raise ValueError(
                 'Arguments in function are not dimensionless, '
                 'but have dimensions of {0}'.format(fds))
         return expr, Dimension(1)
     elif isinstance(expr, Dimension):
         return 1, expr
     else:
         return expr, Dimension(1)