Beispiel #1
0
 def assign_str(self, lhs, rhs):
     rhs = Expression.expand_integer_powers(rhs)
     nmodl_str = ccode(rhs, user_functions=Expression._cfunc_map,
                       assign_to=lhs)
     nmodl_str = Expression.strip_L_from_rationals(nmodl_str)
     nmodl_str = nmodl_str.replace(';', '')
     return nmodl_str
Beispiel #2
0
 def test_escape_of_carets(self):
     self.assertEquals(Expression("a^2").rhs_cstr, 'a*a')
     self.assertEquals(Expression("(a - 2)^2").rhs_cstr, '(a - 2)*(a - 2)')
     self.assertEquals(
         Expression("(a - (a - 2)^2.5)^2.5").rhs_cstr,
         'pow(a - pow(a - 2, 2.5), 2.5)')
     self.assertEquals(Expression("a^(a - 2)").rhs_cstr, 'pow(a, a - 2)')
Beispiel #3
0
 def test_equality_combined(self):
     expr = Expression('(a == b) && (c == d) || (e == f)')
     self.assertEqual(
         expr.rhs,
         sympy.Or(
             sympy.And(sympy.Eq(self.a, self.b), sympy.Eq(self.c, self.d)),
             sympy.Eq(self.e, self.f)))
Beispiel #4
0
 def test_nested_relational(self):
     expr = Expression('((a == b) || (c == d)) && ((e == f) || (g < f))')
     self.assertEqual(
         expr.rhs,
         sympy.And(
             sympy.Or(sympy.Eq(self.a, self.b), sympy.Eq(self.c, self.d)),
             sympy.Or(sympy.Eq(self.e, self.f), sympy.Lt(self.g, self.f))))
Beispiel #5
0
 def scale_time_derivative(self, element):
     """
     Scales the time derivative, ensuring that the overall expression is in
     the same units as the state variable divided by the time units
     """
     if isinstance(element, basestring):
         element = self.component_class[element]
     expr, dims = self._flatten(sympify(element.rhs))
     state_var_dims = self.component_class.state_variable(
         element.variable).dimension
     assert dims == state_var_dims / un.time
     exp = self.dimension_to_units_compound(dims)[0]
     target_exp, compound = self.dimension_to_units_compound(state_var_dims)
     # Divide the state variable units by the time units to get the target
     # compound
     try:
         time_unit, power = compound.pop(
             next(i for i, (u, _) in enumerate(compound)
                  if u.dimension == un.time))
         compound.append((time_unit, power - 1))
     except StopIteration:
         compound.append((self.time_units, -1))
     target_exp -= self.time_units.power
     scale = exp - target_exp
     # Scale expression to match target expression
     expr = 10 ** scale * expr
     units_str = self._units_for_code_gen(compound)
     return Expression(expr), units_str
Beispiel #6
0
 def scale_alias(self, element):
     if isinstance(element, basestring):
         element = self.component_class.element(element)
     scaled, dims = self._flatten(sympify(element.rhs))
     units_str = self._units_for_code_gen(
         self.dimension_to_units_compound(dims)[1])
     return Expression(scaled), units_str
Beispiel #7
0
 def test_nested_relational(self):
     expr = Expression(
         sympy.And(
             sympy.Or(sympy.Eq(self.a, self.b), sympy.Eq(self.c, self.d)),
             sympy.Or(sympy.Eq(self.e, self.f), sympy.Lt(self.g, self.f))))
     self.assertEqual(expr.rhs_cstr,
                      '(a == b || c == d) && (e == f || g < f)')
Beispiel #8
0
 def test_equality_nested_func(self):
     expr = Expression('((a == b) || (c == pow(d, 2))) && (e == f)')
     self.assertEqual(
         expr.rhs,
         sympy.And(
             sympy.Or(sympy.Eq(self.a, self.b), sympy.Eq(self.c,
                                                         self.d**2)),
             sympy.Eq(self.e, self.f)))
Beispiel #9
0
 def test_rationals_match(self):
     self.assertEqual(Expression.strip_L_from_rationals('aL/bL'), 'aL/bL')
     self.assertEqual(Expression.strip_L_from_rationals('a0L/bL'), 'a0L/bL')
     self.assertEqual(Expression.strip_L_from_rationals('aL/b0L'), 'aL/b0L')
     self.assertEqual(Expression.strip_L_from_rationals('a0L/b0L'),
                      'a0L/b0L')
     self.assertEqual(Expression.strip_L_from_rationals('aL/b0L'), 'aL/b0L')
     self.assertEqual(Expression.strip_L_from_rationals('1/2'), '1/2')
     self.assertEqual(Expression.strip_L_from_rationals('1L/2L'), '1/2')
     self.assertEqual(Expression.strip_L_from_rationals('1.0L/2.0L'),
                      '1.0/2.0')
Beispiel #10
0
 def test_rationals_match(self):
     self.assertEqual(Expression.strip_L_from_rationals('aL/bL'), 'aL/bL')
     self.assertEqual(Expression.strip_L_from_rationals('a0L/bL'), 'a0L/bL')
     self.assertEqual(Expression.strip_L_from_rationals('aL/b0L'), 'aL/b0L')
     self.assertEqual(Expression.strip_L_from_rationals('a0L/b0L'),
                      'a0L/b0L')
     self.assertEqual(Expression.strip_L_from_rationals('aL/b0L'), 'aL/b0L')
     self.assertEqual(Expression.strip_L_from_rationals('1/2'), '1/2')
     self.assertEqual(Expression.strip_L_from_rationals('1L/2L'), '1/2')
     self.assertEqual(Expression.strip_L_from_rationals('1.0L/2.0L'),
                      '1.0/2.0')
Beispiel #11
0
    def test_rhs_name_transform_inplace(self):
        # Signature: name(self, name_map)
        # Replace atoms on the RHS with values in the name_map

        e = Expression("V*sin(V)/(eta*mg_conc*exp(-V^2*gamma) + 1)")
        e.rhs_name_transform_inplace({'V': 'VNEW'})
        self.assertEquals(
            e.rhs_str, "VNEW*sin(VNEW)/(eta*mg_conc*exp(-VNEW^2*gamma) + 1)")

        # Don't Change builtin function names:
        e.rhs_name_transform_inplace({'sin': 'SIN'})
        self.assertEquals(
            e.rhs_str, "VNEW*sin(VNEW)/(eta*mg_conc*exp(-VNEW^2*gamma) + 1)")
        e.rhs_name_transform_inplace({'exp': 'EXP'})
        self.assertEquals(
            e.rhs_str, "VNEW*sin(VNEW)/(eta*mg_conc*exp(-VNEW^2*gamma) + 1)")

        # Check the attributes:
        self.assertEquals(
            set(e.rhs_atoms),
            set(['VNEW', 'mg_conc', 'eta', 'gamma', 'exp', 'sin']))
        self.assertEquals(set(str(f) for f in e.rhs_funcs), set(['exp',
                                                                 'sin']))
Beispiel #12
0
 def test_scaling_and_assignment(self):
     handler1 = TestUnitHandler1(self.a)
     handler2 = NestUnitHandler(self.a)
     self.assertEqual(
         handler1.scale_alias('A2'), (Expression('ARP2 + P3'), 'ms*nA'),
         "Difference in scaled alias {} vs {}:\n{}".format(
             handler1.scale_alias('A2'), (Expression('ARP2 + P3'), 'ms*nA'),
             handler1.scale_alias('A2')[0].find_mismatch(
                 Expression('ARP2 + P3'))))
     self.assertEqual(handler1.scale_alias('A4'),
                      (Expression('ARP3 + 100/(P2*P6)'), 'S/cm2'))
     self.assertEqual(handler1.scale_alias('A5'),
                      (Expression('P7 * P8'), 'mV'))
     self.assertEqual(handler1.scale_alias('A6'),
                      (Expression('1e-3 * P9/P10'), 'ms'))
     self.assertEqual(
         handler2.scale_time_derivative(self.a.regime('R1').element('SV2')),
         (Expression('C1 * SV2 ** 2 + C2 * SV2 + C3 + SV3 + '
                     'ARP4 / P11'), 'mV/ms'))
     self.assertEqual(
         handler2.scale_time_derivative(self.a.regime('R1').element('SV3')),
         (Expression('P12*(SV2*P13 - SV3)'), 'mV/ms^2'))
     self.assertEqual(handler1.assign_units_to_variable('P2'), '1/uS')
     self.assertEqual(handler1.assign_units_to_variable('P6'), 'um^2')
Beispiel #13
0
    def test_rhs_name_transform_inplace(self):
        # Signature: name(self, name_map)
                # Replace atoms on the RHS with values in the name_map

        e = Expression("V*sin(V)/(eta*mg_conc*exp(-V^2*gamma) + 1)")
        e.rhs_name_transform_inplace({'V': 'VNEW'})
        self.assertEquals(
            e.rhs_str, "VNEW*sin(VNEW)/(eta*mg_conc*exp(-VNEW^2*gamma) + 1)")

        # Don't Change builtin function names:
        e.rhs_name_transform_inplace({'sin': 'SIN'})
        self.assertEquals(
            e.rhs_str, "VNEW*sin(VNEW)/(eta*mg_conc*exp(-VNEW^2*gamma) + 1)")
        e.rhs_name_transform_inplace({'exp': 'EXP'})
        self.assertEquals(
            e.rhs_str, "VNEW*sin(VNEW)/(eta*mg_conc*exp(-VNEW^2*gamma) + 1)")

        # Check the attributes:
        self.assertEquals(set(e.rhs_atoms), set(
            ['VNEW', 'mg_conc', 'eta', 'gamma', 'exp', 'sin']))
        self.assertEquals(set(str(f) for f in e.rhs_funcs),
                          set(['exp', 'sin']))
Beispiel #14
0
 def test_logical_and(self):
     "Tests conversion of rationals back from the c-code version 1.0L/2.0L"
     expr = Expression('1/2')
     self.assertEqual(str(expr.rhs), '1/2')
Beispiel #15
0
 def test_c89(self):
     "Tests conversion of rationals back from the c-code version 1.0L/2.0L"
     expr = Expression('1/2')
     self.assertEqual(expr.rhs_cstr, '1.0/2.0')
Beispiel #16
0
 def test_negation(self):
     expr = Expression(sympy.Not(self.a))
     self.assertEqual(expr.rhs_cstr, '!a')
Beispiel #17
0
 def test_random(self):
     expr = Expression('random.exponential(a)')
     self.assertEqual(expr.rhs_cstr, 'random_exponential_(a)')
Beispiel #18
0
    parameters=['P1', 'P2'])

dynD = Dynamics(
    name='dynD',
    state_variables=[StateVariable('SV1', dimension=un.voltage)],
    regimes=[
        Regime('dSV1/dt = -SV1 / P1 + ADP1 + ARP1 * P3',
               transitions=[
                   On('SV1 > P2', do=[OutputEvent('ESP1')]),
                   On('ERP1',
                      do=[StateAssignment('SV1', 'P2 * random.binomial(1,2)')])
               ],
               name='R1'),
    ],
    constants=[Constant('C1', -67.0 * un.Mohm)],
    aliases=[Alias('A1', Expression('SV1 / C1'))],
    ports=[
        AnalogSendPort('A1', dimension=un.current),
        AnalogReducePort('ADP1', dimension=(un.voltage / un.time)),
        AnalogReceivePort('ARP1', dimension=un.current),
        EventSendPort('ESP1'),
        EventReceivePort('ERP1')
    ],
    parameters=[
        Parameter('P1', dimension=un.time),
        Parameter('P2', dimension=un.voltage),
        Parameter('P3', dimension=(un.voltage / (un.time * un.current)))
    ])

dynE = Dynamics(name='dynE',
                state_variables=[StateVariable('SV1', dimension=un.voltage)],
Beispiel #19
0
 def test_pow(self):
     expr = Expression(self.a**self.b)
     self.assertEqual(expr.rhs_cstr, 'pow(a, b)')
Beispiel #20
0
 def test_equality(self):
     expr = Expression(sympy.Eq(self.a, self.b))
     self.assertEqual(expr.rhs_cstr, 'a == b')
Beispiel #21
0
 def test_equality_combined(self):
     expr = Expression(
         sympy.Or(
             sympy.And(sympy.Eq(self.a, self.b), sympy.Eq(self.c, self.d)),
             sympy.Eq(self.e, self.f)))
     self.assertEqual(expr.rhs_cstr, 'a == b && c == d || e == f')
Beispiel #22
0
 def test_logical_and(self):
     expr = Expression(sympy.And(self.a, self.b))
     self.assertEqual(expr.rhs_cstr, 'a && b')
Beispiel #23
0
 def test_logical_or(self):
     expr = Expression(sympy.Or(self.a, self.b))
     self.assertEqual(expr.rhs_cstr, 'a || b')
Beispiel #24
0
 def test_triple_negation(self):
     expr = Expression('!!!a')
     self.assertEqual(expr.rhs, sympy.Not(self.a))
Beispiel #25
0
 def test_double_negation(self):
     expr = Expression('!!a')
     self.assertEqual(expr.rhs, self.a)
Beispiel #26
0
    def test_Valid(self):
        # rhs, expt_vars, expt_funcs, result, values
        valid_rhses = [
            (('a'), ('a'), (), 5, {'a': 5}),
            (('b'), ('b'), (), 7, {'b': 7}),
            (('a+b'), ('a', 'b'), (), 13, {'a': 12, 'b': 1}),
            (('1./(alpha+2*beta)'), ('alpha', 'beta'), (), 0.2,
             {'alpha': 1, 'beta': 2}),
        ]

        for rhs, exp_var, exp_func, exp_res, params in valid_rhses:
            e = Expression(rhs)
            self.assertEquals(set(e.rhs_symbol_names), set(exp_var))
            self.assertEquals(set(str(f) for f in e.rhs_funcs), set(exp_func))
            self.assertAlmostEqual(e.rhs_as_python_func(**params), exp_res,
                                   places=4)

        import numpy
        expr_vars = [
            ["-A/tau_r", ("A", "tau_r"), ()],
            ["V*V", ("V",), ()],
            ["a*(b*V - U)", ("U", "V", "b", "a"), ()],
            [" 0.04*V*V + 5.0*V + 1. + 140.0 - U + Isyn",
             ("V", "U", "Isyn"), ()],
            ["c", ("c"), ()],
            ["1", (), ()],
            ["atan2(sin(x),cos(y))", ("x", "y"),
             ("atan2", "sin", "cos")],
            ["1.*V", ("V"), ()],
            ["1.0", (), ()],
            [".1", (), ()],
            ["1/(1 + mg_conc*eta*exp(-1*gamma*V))", (
                "mg_conc", "eta", "gamma", "V"), ('exp',)],
            ["1 / ( 1 + mg_conc * eta *  exp( -1 * gamma*V))",
             ("mg_conc", "eta", "gamma", "V"), ('exp',)],
            ["1 / ( 1 + mg_conc * sin(0.5 * V) *  exp ( -1 * gamma*V))",
             ("mg_conc", "gamma", "V"), ('exp', "sin")],
            [".1 / ( 1.0 + mg_conc * sin(V) *  exp ( -1.0 * gamma*V))",
             ("mg_conc", "gamma", "V"), ('exp', "sin")],
            ["sin(w)", ("w"), ("sin",)]]

        namespace = {
            "A": 10.0,
            "tau_r": 11.0,
            "V": -70.0,
            "a": 1.2,
            "b": 3.0,
            "U": -80.0,
            "Isyn": 2.0,
            "c": 10.0,
            "mg_conc": 1.0,
            "eta": 2.0,
            "gamma": -20.0,
            "x": 1.0,
            "y": 1.0,
            "w": numpy.arange(10)
        }

        return_values = [-0.909090909091, 4900.0, -156.0, 69.0, 10.0, 1,
                         1.0, -70.0, 1.0, 0.1, 1.0, 1.0, 1.0, 0.1,
                         numpy.sin(namespace['w'])]

        for i, (expr, expt_vars, expt_funcs) in enumerate(expr_vars):
            c = Expression(expr)
            self.assertEqual(set(c.rhs_symbol_names), set(expt_vars))
            self.assertEqual(set(str(f) for f in c.rhs_funcs), set(expt_funcs))

            python_func = c.rhs_as_python_func
            param_dict = dict([(v, namespace[v]) for v in expt_vars])

            v = return_values[i] - python_func(**param_dict)
            self.assertAlmostEqual(numpy.dot(v, v), 0)
Beispiel #27
0
 def scale_expr(self, expr):
     scaled, dims = self._flatten(sympify(expr))
     units_str = self._units_for_code_gen(
         self.dimension_to_units_compound(dims)[1])
     return Expression(scaled), units_str
Beispiel #28
0
    def test_Valid(self):
        # rhs, expt_vars, expt_funcs, result, values
        valid_rhses = [
            (('a'), ('a'), (), 5, {
                'a': 5
            }),
            (('b'), ('b'), (), 7, {
                'b': 7
            }),
            (('a+b'), ('a', 'b'), (), 13, {
                'a': 12,
                'b': 1
            }),
            (('1./(alpha+2*beta)'), ('alpha', 'beta'), (), 0.2, {
                'alpha': 1,
                'beta': 2
            }),
        ]

        for rhs, exp_var, exp_func, exp_res, params in valid_rhses:
            e = Expression(rhs)
            self.assertEquals(set(e.rhs_symbol_names), set(exp_var))
            self.assertEquals(set(str(f) for f in e.rhs_funcs), set(exp_func))
            self.assertAlmostEqual(e.rhs_as_python_func(**params),
                                   exp_res,
                                   places=4)

        import numpy
        expr_vars = [
            ["-A/tau_r", ("A", "tau_r"), ()], ["V*V", ("V", ), ()],
            ["a*(b*V - U)", ("U", "V", "b", "a"), ()],
            [
                " 0.04*V*V + 5.0*V + 1. + 140.0 - U + Isyn",
                ("V", "U", "Isyn"), ()
            ], ["c", ("c"), ()], ["1", (), ()],
            ["atan2(sin(x),cos(y))", ("x", "y"), ("atan2", "sin", "cos")],
            ["1.*V", ("V"), ()], ["1.0", (), ()], [".1", (), ()],
            [
                "1/(1 + mg_conc*eta*exp(-1*gamma*V))",
                ("mg_conc", "eta", "gamma", "V"), ('exp', )
            ],
            [
                "1 / ( 1 + mg_conc * eta *  exp( -1 * gamma*V))",
                ("mg_conc", "eta", "gamma", "V"), ('exp', )
            ],
            [
                "1 / ( 1 + mg_conc * sin(0.5 * V) *  exp ( -1 * gamma*V))",
                ("mg_conc", "gamma", "V"), ('exp', "sin")
            ],
            [
                ".1 / ( 1.0 + mg_conc * sin(V) *  exp ( -1.0 * gamma*V))",
                ("mg_conc", "gamma", "V"), ('exp', "sin")
            ], ["sin(w)", ("w"), ("sin", )]
        ]

        namespace = {
            "A": 10.0,
            "tau_r": 11.0,
            "V": -70.0,
            "a": 1.2,
            "b": 3.0,
            "U": -80.0,
            "Isyn": 2.0,
            "c": 10.0,
            "mg_conc": 1.0,
            "eta": 2.0,
            "gamma": -20.0,
            "x": 1.0,
            "y": 1.0,
            "w": numpy.arange(10)
        }

        return_values = [
            -0.909090909091, 4900.0, -156.0, 69.0, 10.0, 1, 1.0, -70.0, 1.0,
            0.1, 1.0, 1.0, 1.0, 0.1,
            numpy.sin(namespace['w'])
        ]

        for i, (expr, expt_vars, expt_funcs) in enumerate(expr_vars):
            c = Expression(expr)
            self.assertEqual(set(c.rhs_symbol_names), set(expt_vars))
            self.assertEqual(set(str(f) for f in c.rhs_funcs), set(expt_funcs))

            python_func = c.rhs_as_python_func
            param_dict = dict([(v, namespace[v]) for v in expt_vars])

            v = return_values[i] - python_func(**param_dict)
            self.assertAlmostEqual(numpy.dot(v, v), 0)