def test_csymbol(self):
        # Test csymbol parsing
        # A csymbol MathML's way to define extensions, e.g. functions or
        # operators or symbols not defined in MathML. In Myokit we only
        # support their use as a type of <ci>.

        self.assertEqual(
            self.p('<csymbol definitionURL="hello" />'),
            myokit.Name('hello')
        )

        # Missing definition url
        self.assertRaisesRegex(
            mathml.MathMLError, 'must contain a definitionURL attribute',
            self.p, '<csymbol>Hiya</csymbol>')

        # Unknown variable
        d = {'a': myokit.Name('a')}
        p = mathml.MathMLParser(
            lambda x, y: d[x],
            lambda x, y: myokit.Number(x),
        )
        x = etree.fromstring('<csymbol definitionURL="a" />')
        self.assertEqual(p.parse(x), myokit.Name('a'))
        x = etree.fromstring('<csymbol definitionURL="b" />')
        self.assertRaisesRegex(
            mathml.MathMLError, 'Unable to create Name from csymbol',
            p.parse, x)
def _add_dose_compartment(model, drug_amount, time_unit):
    """
    Adds a dose compartment to the model with a linear absorption rate to
    the connected compartment.
    """
    # Add a dose compartment to the model
    dose_comp = model.add_component_allow_renaming('dose')

    # Create a state variable for the drug amount in the dose compartment
    dose_drug_amount = dose_comp.add_variable('drug_amount')
    dose_drug_amount.set_rhs(0)
    dose_drug_amount.set_unit(drug_amount.unit())
    dose_drug_amount.promote()

    # Create an absorption rate variable
    absorption_rate = dose_comp.add_variable('absorption_rate')
    absorption_rate.set_rhs(1)
    absorption_rate.set_unit(1 / time_unit)

    # Add outflow expression to dose compartment
    dose_drug_amount.set_rhs(
        myokit.Multiply(myokit.PrefixMinus(myokit.Name(absorption_rate)),
                        myokit.Name(dose_drug_amount)))

    # Add inflow expression to connected compartment
    rhs = drug_amount.rhs()
    drug_amount.set_rhs(
        myokit.Plus(
            rhs,
            myokit.Multiply(myokit.Name(absorption_rate),
                            myokit.Name(dose_drug_amount))))

    return dose_drug_amount
示例#3
0
 def equal(self):
     """
     Test of __eq__ operators
     """
     a1 = myokit.Number(4)
     a2 = myokit.Number(5)
     self.assertEqual(a1, a1)
     self.assertEqual(a1, myokit.Number(4))
     self.assertEqual(a1, myokit.Number(4.0))
     self.assertNotEqual(a1, a2)
     b1 = myokit.Name('test')
     b2 = myokit.Name('tost')
     self.assertEqual(b1, b1)
     self.assertNotEqual(b1, b2)
     c1 = myokit.PrefixPlus(a1)
     c2 = myokit.PrefixPlus(a1)
     self.assertEqual(c1, c1)
     self.assertEqual(c1, c2)
     c2 = myokit.PrefixPlus(a2)
     self.assertNotEqual(c1, c2)
     d1 = myokit.Plus(a1, a2)
     d2 = myokit.Plus(a1, a2)
     self.assertEqual(d1, d1)
     self.assertEqual(d1, d2)
     d2 = myokit.Plus(a2, a1)
     self.assertNotEqual(d2, d1)
     e1 = myokit.Sqrt(a1)
     e2 = myokit.Sqrt(a1)
     self.assertEqual(e1, e1)
     self.assertEqual(e1, e2)
     e2 = myokit.Sqrt(a2)
     self.assertNotEqual(e1, e2)
示例#4
0
    def test_promote_demote(self):
        # Test variable promotion and demotion.

        m = myokit.Model()
        c = m.add_component('c')
        v = c.add_variable('v')
        v.set_rhs(3)

        self.assertTrue(v.is_literal())
        self.assertTrue(v.is_constant())
        self.assertFalse(v.is_intermediary())
        self.assertFalse(v.is_state())
        self.assertEqual(v.lhs(), myokit.Name(v))
        self.assertRaises(Exception, v.demote)
        self.assertRaises(Exception, v.indice)
        self.assertRaises(Exception, v.state_value)

        v.promote(3)
        self.assertFalse(v.is_literal())
        self.assertFalse(v.is_constant())
        self.assertFalse(v.is_intermediary())
        self.assertTrue(v.is_state())
        self.assertEqual(v.lhs(), myokit.Derivative(myokit.Name(v)))
        self.assertEqual(v.indice(), 0)
        self.assertEqual(v.state_value(), 3)

        v.demote()
        self.assertTrue(v.is_literal())
        self.assertTrue(v.is_constant())
        self.assertFalse(v.is_intermediary())
        self.assertFalse(v.is_state())
        self.assertEqual(v.lhs(), myokit.Name(v))
        self.assertRaises(Exception, v.demote)
        self.assertRaises(Exception, v.indice)
        self.assertRaises(Exception, v.state_value)

        # Test errors
        v.promote(3)
        self.assertRaisesRegex(Exception, 'already', v.promote, 4)
        v.demote()
        v.set_binding('time')
        self.assertRaisesRegex(Exception, 'cannot be bound', v.promote, 4)
        w = v.add_variable('w')
        self.assertRaisesRegex(
            Exception, 'only be added to Components', w.promote, 4)

        # Test we can't demote a variable with references to its derivative
        m = myokit.Model()
        c = m.add_component('c')
        x = c.add_variable('x')
        x.set_rhs(3)
        x.promote()
        y = c.add_variable('y')
        y.set_rhs('1 + dot(x)')
        self.assertRaisesRegex(
            Exception, 'references to its derivative', x.demote)
        y.set_rhs('1 + x')
        x.demote()
示例#5
0
def create_dimless_tumour_growth_model():
    r"""
    Returns a tumour growth myokit model.

    .. math::
        \frac{\text{d}v}{\text{d}\tau} = \frac{a_1 v}
        {v + a_0},

    where the tumour volume :math:`v` and time :math:`\tau` are dimensionless
    and measured in characteristic scales :math:`V^c_T` and :math:`t^c`.
    The model parameters :math:`a_0` and :math:`a_1` are also dimensionless.
    """
    # Instantiate model
    model = Model()

    # Add central compartment
    central_comp = model.add_compartment('central')

    # Add tumour growth variables to central compartment
    volume_t = central_comp.add_variable('volume_t')
    a_0 = central_comp.add_variable('a_0')
    a_1 = central_comp.add_variable('a_1')

    # Bind time
    time = central_comp.add_variable('time')
    time.set_binding('time')

    # Set intial values (some default values) and units
    time.set_rhs(0)

    volume_t.set_rhs(0)
    a_0.set_rhs(1)  # Avoid ZeroDivisionError
    a_1.set_rhs(0)

    # Set units
    time.set_unit('dimensionless')

    volume_t.set_unit('dimensionless')
    a_0.set_unit('dimensionless')
    a_1.set_unit('dimensionless')

    # Set rhs of tumor volume
    # dot(volume_t) =
    #  (a_1 * volume_t) /
    #  (volume_t + a_0)
    volume_t.promote()
    volume_t.set_rhs(
        myokit.Divide(myokit.Multiply(myokit.Name(a_1), myokit.Name(volume_t)),
                      myokit.Plus(myokit.Name(volume_t), myokit.Name(a_0))))

    # Validate model
    model.validate()

    # Check units
    model.check_units()

    return model
示例#6
0
 def setUpClass(cls):
     # Create a model with a variable
     cls._model = myokit.Model()
     component = cls._model.add_component('c')
     bvar = component.add_variable('b')
     bvar.set_rhs(1.23)
     avar = component.add_variable('a')
     avar.set_rhs('b')
     cls._a = myokit.Name(avar)
     cls._b = myokit.Name(bvar)
示例#7
0
 def _ex_name(self, e):
     var = str(e)
     # Check if this is a derivative
     # See :meth:`SymPyExpressionWriter._ex_derivative()`.
     if self._model:
         if var[:4] == 'dot(' and var[-1:] == ')':
             var = self._model.get(var[4:-1], myokit.Variable)
             return myokit.Derivative(myokit.Name(var))
         var = self._model.get(var, myokit.Variable)
     return myokit.Name(var)
示例#8
0
    def fit(self, model, var, rng, report=None):
        """
        Attempts to approximate suitable functions in the given model.

        A variable ``var`` must be specified, as well as the range ``rng`` that
        this variable is likely to take. A typical example would be the
        variable ``membrane.V`` and the range ``(-100, 50)``.

        The variable can be specified as a name (string), an object
        representing a variable or an LhsExpression.

        The range can be specified as any sequence type of length 2.

        If the variable ``report`` is set, a small HTML based report will be
        generated and stored in the directory indicated by ``report``.
        """
        # Copy model
        self.original_model = model
        model = model.clone()
        # Get left-hand side expression for variable
        if isinstance(var, myokit.LhsExpression):
            if isinstance(var, myokit.Derivative):
                raise ValueError('Cannot fit with respect to a state.')
            # Get equivalent variable from cloned model
            var = model.get(var.var().qname())
            lhs = myokit.Name(var)
        else:
            if type(var) in [str, unicode]:
                lhs = myokit.Name(model.get(var))
            elif isinstance(var, myokit.Variable):
                # Get equivalent variable from cloned model
                var = model.get(var.var().qname())
                lhs = myokit.Name(var)
            else:
                raise ValueError(
                    'The argument "var" must be either an LhsExpression, a'
                    ' Variable or a string referencing a model variable')
        # Test suitability of variable
        if lhs.is_constant():
            raise ValueError('The given variable can not be constant.')
        # Test suitability of range
        if len(rng) < 2:
            raise ValueError(
                'The argument "rng" must contain the lower and'
                ' upper boundaries of the variable\'s name.')
        if rng[0] == rng[1]:
            raise ValueError(
                'The given range must contain two distinct values.')
        if rng[0] > rng[1]:
            rng = rng.reverse()
        # Reset list of changed variables
        self._changed = []
        # Go!
        return self._fit(model, lhs, rng, report)
示例#9
0
    def _test_maths(self, version):
        # Test maths is written (in selected ``version``)

        # Create model
        m1 = cellml.Model('m', version)
        c1 = m1.add_component('c')
        p1 = c1.add_variable('p', 'mole')
        p1.set_initial_value(2)
        q1 = c1.add_variable('q', 'dimensionless')
        r1 = c1.add_variable('r', 'second')
        r1.set_initial_value(0.1)
        t1 = c1.add_variable('t', 'second')
        m1.set_variable_of_integration(t1)

        # Add component without maths
        d1 = m1.add_component('d')
        s1 = d1.add_variable('s', 'volt')
        s1.set_initial_value(1.23)

        # Add two equations
        # Note: Numbers without units become dimensionless in CellML
        eq1 = myokit.Equation(
            myokit.Name(q1),
            myokit.Plus(myokit.Number(3, myokit.units.mole), myokit.Name(p1)))
        er1 = myokit.Equation(myokit.Derivative(myokit.Name(r1)),
                              myokit.Power(myokit.Name(q1), myokit.Number(2)))
        q1.set_equation(eq1)
        r1.set_equation(er1)

        # Write and read
        xml = cellml.write_string(m1)
        m2 = cellml.parse_string(xml)

        # Check results
        p2, q2, r2, s2 = m2['c']['p'], m2['c']['q'], m2['c']['r'], m2['d']['s']
        subst = {
            myokit.Name(p1): myokit.Name(p2),
            myokit.Name(q1): myokit.Name(q2),
            myokit.Name(r1): myokit.Name(r2),
        }
        eq2 = eq1.clone(subst)
        er2 = er1.clone(subst)

        self.assertEqual(q2.equation(), eq2)
        self.assertEqual(r2.equation(), er2)
        self.assertEqual(s2.initial_value(),
                         myokit.Number(1.23, myokit.units.volt))
        self.assertFalse(p2.is_state())
        self.assertFalse(q2.is_state())
        self.assertTrue(r2.is_state())
        self.assertFalse(s2.is_state())
        self.assertIs(m2.variable_of_integration(), m2['c']['t'])
示例#10
0
    def test_user_function(self):
        # Test :class:`UserFunction` creation and methods.

        # Create without arguments
        f = myokit.UserFunction('bert', [], myokit.Number(12))
        args = list(f.arguments())
        self.assertEqual(len(args), 0)
        self.assertEqual(f.convert([]), myokit.Number(12))

        # Create with one argument
        f = myokit.UserFunction('x', [myokit.Name('a')],
                                myokit.parse_expression('1 + a'))
        self.assertEqual(len(list(f.arguments())), 1)
        args = {myokit.Name('a'): myokit.Number(3)}
        self.assertEqual(f.convert(args).eval(), 4)

        # Create with two argument
        f = myokit.UserFunction(
            'x', [myokit.Name('a'), myokit.Name('b')],
            myokit.parse_expression('a + b'))
        self.assertEqual(len(list(f.arguments())), 2)
        args = {
            myokit.Name('a'): myokit.Number(3),
            myokit.Name('b'): myokit.Number(4)
        }
        self.assertEqual(f.convert(args), myokit.parse_expression('3 + 4'))

        # Call with wrong arguments
        del (args[myokit.Name('a')])
        self.assertRaisesRegex(ValueError, 'Wrong number', f.convert, args)
        args[myokit.Name('c')] = myokit.Number(100)
        self.assertRaisesRegex(ValueError, 'Missing input argument', f.convert,
                               args)
示例#11
0
    def test_remove_component(self):
        # Test the removal of a component.

        # Create model
        m = myokit.Model('LotkaVolterra')
        # Simplest case
        X = m.add_component('X')
        self.assertEqual(m.count_components(), 1)
        m.remove_component(X)
        self.assertEqual(m.count_components(), 0)
        self.assertRaises(KeyError, m.remove_component, X)

        # Test if orphaned
        self.assertIsNone(X.parent())

        # Re-adding
        self.assertEqual(m.count_components(), 0)
        X = m.add_component('X')
        self.assertEqual(m.count_components(), 1)

        # With internal variables and string name
        a = X.add_variable('a')
        a.set_rhs(myokit.Number(4))
        b = X.add_variable('b')
        b.set_rhs(myokit.Name(a))
        m.remove_component('X')
        self.assertEqual(m.count_components(), 0)

        # With dependencies from another component
        X = m.add_component('X')
        a = X.add_variable('a')
        a.set_rhs(myokit.Number(45))
        b = X.add_variable('b')
        b.set_rhs(myokit.Name(b))
        Y = m.add_component('Y')
        c = Y.add_variable('c')
        c.set_rhs(myokit.Name(a))
        d = Y.add_variable('d')
        d.set_rhs(myokit.Name(c))
        self.assertEqual(m.count_components(), 2)
        self.assertRaises(myokit.IntegrityError, m.remove_component, X)
        self.assertEqual(m.count_components(), 2)

        # In the right order...
        m.remove_component(Y)
        self.assertEqual(m.count_components(), 1)
        m.remove_component(X)
        self.assertEqual(m.count_components(), 0)
示例#12
0
 def polynomial(self):
     """
     Test of Polynomial class
     """
     x = myokit.Name('x')
     c = [
         myokit.Number(5),
         myokit.Number(4),
         myokit.Number(3),
         myokit.Number(2)
     ]
     p = myokit.Polynomial(x, *c)
     self.assertEqual(p.eval(subst={x: 0}), 5)
     self.assertEqual(p.eval(subst={x: 1}), 14)
     self.assertEqual(p.eval(subst={x: 2}), 41)
     self.assertEqual(p.eval(subst={x: -1}), 2)
     self.assertEqual(p.eval(subst={x: 0.5}), 8)
     q = p.tree()
     self.assertNotEqual(p, q)
     for i in [-1, 0, 0.5, 1, 2]:
         s = {x: i}
         self.assertEqual(p.eval(subst=s), q.eval(subst=s))
     q = p.tree(horner=False)
     self.assertNotEqual(p, q)
     for i in [-1, 0, 0.5, 1, 2]:
         s = {x: i}
         self.assertEqual(p.eval(subst=s), q.eval(subst=s))
示例#13
0
    def test_read_write(self):
        # Test using the read() and write() methods
        try:
            import sympy as sp
        except ImportError:
            print('Sympy not found, skipping test.')
            return

        # Test writing and reading with a model
        a = self._a
        ca = sp.Symbol('c.a')
        self.assertEqual(mypy.write(a), ca)
        self.assertEqual(mypy.read(ca, self._model), a)

        # Test doing it again, with a different model
        m = myokit.Model()
        a = m.add_component('cc').add_variable('aa')
        a = myokit.Name(a)
        ca = sp.Symbol('cc.aa')
        self.assertEqual(mypy.write(a), ca)
        self.assertEqual(mypy.read(ca, m), a)

        # Test reading without a model
        b = myokit.Number('12')
        cb = sp.Float(12)
        self.assertEqual(mypy.write(b), cb)
        self.assertEqual(mypy.read(cb), b)
    def test_conditionals(self):
        # Tests if and piecewise writing

        a = myokit.Name('a')
        b = myokit.Number(1)
        cond1 = myokit.parse_expression('5 > 3')
        cond2 = myokit.parse_expression('2 < 1')
        c1 = '<apply><gt/><cn>5.0</cn><cn>3.0</cn></apply>'
        c2 = '<apply><lt/><cn>2.0</cn><cn>1.0</cn></apply>'

        # If
        e = myokit.If(cond1, a, b)
        x = (
            '<piecewise>'
            '<piece><ci>a</ci>' + c1 + '</piece>'
            '<otherwise><cn>1.0</cn></otherwise>'
            '</piecewise>'
        )
        self.assertWrite(e, x)

        # Piecewise
        e = myokit.Piecewise(cond1, a, cond2, b, myokit.Number(100))
        x = (
            '<piecewise>'
            '<piece><ci>a</ci>' + c1 + '</piece>'
            '<piece><cn>1.0</cn>' + c2 + '</piece>'
            '<otherwise><cn>100.0</cn></otherwise>'
            '</piecewise>'
        )
        self.assertWrite(e, x)
    def test_inequalities(self):
        # Test parsing (in)equalities

        # Equal
        a = myokit.Name('a')
        b = myokit.Number(1.0)
        e = myokit.Equal(a, b)
        x = '<apply><eq/><ci>a</ci><cn>1.0</cn></apply>'
        self.assertEqual(self.p(x), e)

        # NotEqual
        e = myokit.NotEqual(a, b)
        x = '<apply><neq/><ci>a</ci><cn>1.0</cn></apply>'
        self.assertEqual(self.p(x), e)

        # More
        e = myokit.More(a, b)
        x = '<apply><gt/><ci>a</ci><cn>1.0</cn></apply>'
        self.assertEqual(self.p(x), e)

        # Less
        e = myokit.Less(a, b)
        x = '<apply><lt/><ci>a</ci><cn>1.0</cn></apply>'
        self.assertEqual(self.p(x), e)

        # MoreEqual
        e = myokit.MoreEqual(a, b)
        x = '<apply><geq/><ci>a</ci><cn>1.0</cn></apply>'
        self.assertEqual(self.p(x), e)

        # LessEqual
        e = myokit.LessEqual(a, b)
        x = '<apply><leq/><ci>a</ci><cn>1.0</cn></apply>'
        self.assertEqual(self.p(x), e)
    def test_constants(self):
        # Tests parsing of MathML special constants.

        # Pi
        import math
        x = self.p('<pi/>')
        self.assertAlmostEqual(math.pi, float(x))

        # Test e
        import math
        x = self.p('<exponentiale/>')
        self.assertAlmostEqual(math.e, float(x))

        # Test booleans
        import math
        x = self.p('<true/>')
        self.assertEqual(float(x), 1)
        x = self.p('<false/>')
        self.assertEqual(float(x), 0)

        # Nan and inf
        x = self.p('<notanumber/>')
        self.assertTrue(math.isnan(float(x)))
        x = self.p('<infinity/>')
        self.assertEqual(float(x), float('inf'))

        # Test constants are handled via the number factory
        xml = '<pi/>'
        x = mathml.parse_mathml_etree(
            etree.fromstring(xml),
            lambda x, y: myokit.Name(x),
            lambda x, y: myokit.Number(x, myokit.units.volt),
        )
        self.assertEqual(x.unit(), myokit.units.volt)
示例#17
0
    def test_name_and_numbers(self):
        # Test name and number writing

        self.assertWrite(myokit.Name('a'), '<ci>a</ci>')

        # Number without unit
        self.assertWrite(myokit.Number(0), '<cn>0.0</cn>')
        self.assertWrite(myokit.Number(1), '<cn>1.0</cn>')

        # Number with unit
        # Unit isn't exported by default!
        self.assertWrite(myokit.Number('-12', 'pF'), '<cn>-12.0</cn>')

        # Number with e notation (note that Python will turn e.g. 1e3 into
        # 1000, so must pick tests carefully)
        self.assertWrite(myokit.Number(1e3), '<cn>1000.0</cn>')
        self.assertWrite(myokit.Number(1e-3), '<cn>0.001</cn>')
        self.assertWrite(
            myokit.Number(1e-6),
            '<cn type="e-notation">1<sep/>-6</cn>')
        self.assertWrite(
            myokit.Number(2.3e24),
            '<cn type="e-notation">2.3<sep/>24</cn>')
        # myokit.float.str(1.23456789) = 1.23456788999999989e+00
        self.assertWrite(
            myokit.Number(1.23456789), '<cn>1.23456788999999989</cn>')
    def test_conditionals(self):
        # Tests if and piecewise writing

        a = myokit.Name('a')
        b = myokit.Number(1)
        c = myokit.Number(1)
        cond1 = myokit.parse_expression('5 > 3')
        cond2 = myokit.parse_expression('2 < 1')

        ca = '<mi>a</mi>'
        cb = '<mn>1.0</mn>'
        cc = '<mn>1.0</mn>'
        c1 = '<mrow><mn>5.0</mn><mo>&gt;</mo><mn>3.0</mn></mrow>'
        c2 = '<mrow><mn>2.0</mn><mo>&lt;</mo><mn>1.0</mn></mrow>'

        # If
        x = myokit.If(cond1, a, b)
        self.assertWrite(
            x, '<piecewise>'
            '<piece>' + ca + c1 + '</piece>'
            '<otherwise>' + cb + '</otherwise>'
            '</piecewise>')
        # Piecewise
        x = myokit.Piecewise(cond1, a, cond2, b, c)
        self.assertWrite(
            x, '<piecewise>'
            '<piece>' + ca + c1 + '</piece>'
            '<piece>' + cb + c2 + '</piece>'
            '<otherwise>' + cc + '</otherwise>'
            '</piecewise>')
示例#19
0
    def test_functions(self):
        # Test printing functions

        a = myokit.Name(self.avar)
        b = myokit.Number('12', 'pF')
        ca = '<ci>a</ci>'
        cb = ('<cn cellml:units="picofarad">12.0</cn>')

        # Power
        x = myokit.Power(a, b)
        self.assertWrite(x, '<apply><power/>' + ca + cb + '</apply>')
        # Sqrt
        x = myokit.Sqrt(b)
        self.assertWrite(x, '<apply><root/>' + cb + '</apply>')
        # Exp
        x = myokit.Exp(a)
        self.assertWrite(x, '<apply><exp/>' + ca + '</apply>')

        # Floor
        x = myokit.Floor(b)
        self.assertWrite(x, '<apply><floor/>' + cb + '</apply>')
        # Ceil
        x = myokit.Ceil(b)
        self.assertWrite(x, '<apply><ceiling/>' + cb + '</apply>')
        # Abs
        x = myokit.Abs(b)
        self.assertWrite(x, '<apply><abs/>' + cb + '</apply>')
    def test_inequalities(self):
        # Test writing (in)equalities

        a = myokit.Name(self.avar)
        b = myokit.Number('12', 'pF')
        ca = '<mi>c.a</mi>'
        cb = '<mn>12.0</mn>'

        # Equal
        x = myokit.Equal(a, b)
        self.assertWrite(x, '<mrow>' + ca + '<mo>==</mo>' + cb + '</mrow>')

        # NotEqual
        x = myokit.NotEqual(a, b)
        self.assertWrite(x, '<mrow>' + ca + '<mo>!=</mo>' + cb + '</mrow>')

        # More
        x = myokit.More(a, b)
        self.assertWrite(x, '<mrow>' + ca + '<mo>&gt;</mo>' + cb + '</mrow>')

        # Less
        x = myokit.Less(a, b)
        self.assertWrite(x, '<mrow>' + ca + '<mo>&lt;</mo>' + cb + '</mrow>')

        # MoreEqual
        # Named version &ge; is not output, shows decimal code instead
        x = myokit.MoreEqual(a, b)
        self.assertWrite(x,
                         '<mrow>' + ca + '<mo>&#8805;</mo>' + cb + '</mrow>')

        # LessEqual
        # Named version &le; is not output, shows decimal code instead
        x = myokit.LessEqual(a, b)
        self.assertWrite(x,
                         '<mrow>' + ca + '<mo>&#8804;</mo>' + cb + '</mrow>')
示例#21
0
    def test_inequalities(self):
        # Tests printing inequalities

        a = myokit.Name(self.avar)
        b = myokit.Number('12', 'pF')
        ca = '<ci>a</ci>'
        cb = ('<cn cellml:units="picofarad">12.0</cn>')

        # Equal
        x = myokit.Equal(a, b)
        self.assertWrite(x, '<apply><eq/>' + ca + cb + '</apply>')
        # NotEqual
        x = myokit.NotEqual(a, b)
        self.assertWrite(x, '<apply><neq/>' + ca + cb + '</apply>')
        # More
        x = myokit.More(a, b)
        self.assertWrite(x, '<apply><gt/>' + ca + cb + '</apply>')
        # Less
        x = myokit.Less(a, b)
        self.assertWrite(x, '<apply><lt/>' + ca + cb + '</apply>')
        # MoreEqual
        x = myokit.MoreEqual(a, b)
        self.assertWrite(x, '<apply><geq/>' + ca + cb + '</apply>')
        # LessEqual
        x = myokit.LessEqual(a, b)
        self.assertWrite(x, '<apply><leq/>' + ca + cb + '</apply>')
示例#22
0
    def test_arithmetic(self):
        # Test basic arithmetic

        a = myokit.Name(self.avar)
        b = myokit.Number('12', 'pF')
        ca = '<ci>a</ci>'
        cb = ('<cn cellml:units="picofarad">12.0</cn>')

        # Prefix plus
        x = myokit.PrefixPlus(b)
        self.assertWrite(x, '<apply><plus/>' + cb + '</apply>')
        # Prefix minus
        x = myokit.PrefixMinus(b)
        self.assertWrite(x, '<apply><minus/>' + cb + '</apply>')

        # Plus
        x = myokit.Plus(a, b)
        self.assertWrite(x, '<apply><plus/>' + ca + cb + '</apply>')
        # Minus
        x = myokit.Minus(a, b)
        self.assertWrite(x, '<apply><minus/>' + ca + cb + '</apply>')
        # Multiply
        x = myokit.Multiply(a, b)
        self.assertWrite(x, '<apply><times/>' + ca + cb + '</apply>')
        # Divide
        x = myokit.Divide(a, b)
        self.assertWrite(x, '<apply><divide/>' + ca + cb + '</apply>')
示例#23
0
    def test_units(self):
        # Test writing of units

        u1 = myokit.parse_unit('kg*m^2/mole^3 (0.123)')

        m1 = cellml.Model('mmm')
        m1.add_units('flibbit', u1)
        m1.add_units('special_volt', myokit.units.Volt)
        d = m1.add_component('ddd')
        q = d.add_variable('q', 'flibbit')
        q.set_equation(myokit.Equation(myokit.Name(q), myokit.Number(2, u1)))

        xml = cellml.write_string(m1)
        m2 = cellml.parse_string(xml)

        q = m2['ddd']['q']
        self.assertEqual(q.units().name(), 'flibbit')
        self.assertEqual(q.units().myokit_unit(), u1)
        self.assertEqual(
            m2.find_units('special_volt').myokit_unit(), myokit.units.volt)

        # Dimensionless units with a multiplier
        u1 = myokit.parse_unit('1 (0.123)')
        m1 = cellml.Model('mmm')
        m1.add_units('flibbit', u1)
        xml = cellml.write_string(m1)
        m2 = cellml.parse_string(xml)
        u2 = m2.find_units('flibbit')
        u2 = u2.myokit_unit()
        self.assertEqual(u1, u2)
    def test_functions(self):
        # Tests writing basic functions

        a = myokit.Name(self.avar)
        b = myokit.Number('12', 'pF')
        ca = '<mi>c.a</mi>'
        cb = '<mn>12.0</mn>'

        # Power
        x = myokit.Power(a, b)
        self.assertWrite(x, '<msup>' + ca + cb + '</msup>')

        # Sqrt
        x = myokit.Sqrt(b)
        self.assertWrite(
            x, '<mrow><mi>root</mi><mfenced>' + cb + '</mfenced></mrow>')

        # Exp
        x = myokit.Exp(a)
        self.assertWrite(x, '<msup><mi>e</mi>' + ca + '</msup>')

        # Log(a)
        x = myokit.Log(b)
        self.assertWrite(
            x, '<mrow><mi>ln</mi><mfenced>' + cb + '</mfenced></mrow>')

        # Log(a, b)
        x = myokit.Log(a, b)
        self.assertWrite(
            x, '<mrow><msub><mi>log</mi>' + cb + '</msub>'
            '<mfenced>' + ca + '</mfenced></mrow>')

        # Log10
        x = myokit.Log10(b)
        self.assertWrite(
            x, '<mrow><mi>log</mi><mfenced>' + cb + '</mfenced></mrow>')

        # Floor
        x = myokit.Floor(b)
        self.assertWrite(
            x, '<mrow><mi>floor</mi><mfenced>' + cb + '</mfenced></mrow>')

        # Ceil
        x = myokit.Ceil(b)
        self.assertWrite(
            x, '<mrow><mi>ceiling</mi><mfenced>' + cb + '</mfenced></mrow>')

        # Abs
        x = myokit.Abs(b)
        self.assertWrite(
            x, '<mrow><mi>abs</mi><mfenced>' + cb + '</mfenced></mrow>')

        # Quotient
        x = myokit.Quotient(a, b)
        self.assertWrite(x, '<mrow>' + ca + '<mo>//</mo>' + cb + '</mrow>')

        # Remainder
        x = myokit.Remainder(a, b)
        self.assertWrite(x, '<mrow>' + ca + '<mo>%</mo>' + cb + '</mrow>')
    def test_functions(self):
        # Tests writing basic functions

        # Power
        a = myokit.Name('a')
        b = myokit.Number(1)
        e = myokit.Power(a, b)
        x = '<apply><power/><ci>a</ci><cn>1.0</cn></apply>'
        self.assertWrite(e, x)

        # Sqrt
        e = myokit.Sqrt(b)
        x = '<apply><root/><cn>1.0</cn></apply>'
        self.assertWrite(e, x)

        # Exp
        e = myokit.Exp(a)
        x = '<apply><exp/><ci>a</ci></apply>'
        self.assertWrite(e, x)

        # Log(a)
        e = myokit.Log(b)
        x = '<apply><ln/><cn>1.0</cn></apply>'
        self.assertWrite(e, x)

        # Log(a, b)
        e = myokit.Log(a, b)
        x = '<apply><log/><logbase><cn>1.0</cn></logbase><ci>a</ci></apply>'
        self.assertWrite(e, x)

        # Log10
        e = myokit.Log10(b)
        x = '<apply><log/><cn>1.0</cn></apply>'
        self.assertWrite(e, x)

        # Floor
        e = myokit.Floor(b)
        x = '<apply><floor/><cn>1.0</cn></apply>'
        self.assertWrite(e, x)

        # Ceil
        e = myokit.Ceil(b)
        x = '<apply><ceiling/><cn>1.0</cn></apply>'
        self.assertWrite(e, x)

        # Abs
        e = myokit.Abs(b)
        x = '<apply><abs/><cn>1.0</cn></apply>'
        self.assertWrite(e, x)

        # Quotient
        e = myokit.Quotient(a, b)
        x = '<apply><quotient/><ci>a</ci><cn>1.0</cn></apply>'
        self.assertWrite(e, x)

        # Remainder
        e = myokit.Remainder(a, b)
        x = '<apply><rem/><ci>a</ci><cn>1.0</cn></apply>'
        self.assertWrite(e, x)
    def create_myokit_model(self):
        if self.pk_model is None:
            pk_model = myokit.Model()
        else:
            pk_model = self.create_myokit_dosed_pk_model()
        if self.pd_model is None:
            pd_model = myokit.Model()
        else:
            pd_model = self.pd_model.create_myokit_model()
        have_both_models = (self.pk_model is not None
                            and self.pd_model is not None)
        have_no_models = (self.pk_model is None and self.pd_model is None)

        # use pk model as the base and import the pd model
        pkpd_model = pk_model

        # default model is one with just time
        if have_no_models:
            pkpd_model = myokit.parse_model('''
            [[model]]
            [myokit]
            time = 0 [s] bind time
                in [s]
        ''')

        # remove time binding if
        if have_both_models:
            time_var = pd_model.get('myokit.time')
            time_var.set_binding(None)

        pd_components = list(pd_model.components())
        pd_names = [c.name().replace('myokit', 'PD') for c in pd_components]

        if pd_components:
            pkpd_model.import_component(
                pd_components,
                new_name=pd_names,
            )

        # remove imported time var
        if have_both_models:
            imported_pd_component = pkpd_model.get('PD')
            imported_time = imported_pd_component.get('time')
            imported_pd_component.remove_variable(imported_time)

        # do mappings
        for mapping in self.mappings.all():
            pd_var = pkpd_model.get(
                mapping.pd_variable.qname.replace('myokit', 'PD'))
            pk_var = pkpd_model.get(mapping.pk_variable.qname)

            unit_conversion_multiplier = myokit.Unit.conversion_factor(
                pk_var.unit(), pd_var.unit())
            pd_var.set_rhs(
                myokit.Multiply(myokit.Number(unit_conversion_multiplier),
                                myokit.Name(pk_var)))

        pkpd_model.validate()
        return pkpd_model
    def p(self, xml):
        """ Parses a MathML string and returns a myokit.Expression. """

        return mathml.parse_mathml_etree(
            etree.fromstring(xml),
            lambda x, y: myokit.Name(x),
            lambda x, y: myokit.Number(x),
        )
示例#28
0
        def variable_factory(name, element):
            try:
                var = component.variable(name)
            except KeyError:
                raise CellMLParsingError(
                    'Variable references in equation must name a variable from'
                    ' the local component (4.4.2.1).', element)

            return myokit.Name(var)
示例#29
0
文件: approx.py 项目: teosbpl/myokit
 def test_piecewise_polynomial(self):
     """
     Test piecewise polynomial
     """
     # Set up test space
     x = np.linspace(-10, 10, 10000)
     # Test number one
     knots = [1, 2]
     coeff = [
         [0.123, 0.456, 2.789, -0.123, -0.456],
         [5.4123, -0.1456, 7.789, -0.123, -0.456],
         [-40.6123, 0.2456, -0.86453, 0.23, -0.753],
     ]
     f = approx.PiecewisePolynomial(coeff, knots)
     g = f.myokit_form(myokit.Name('x')).pyfunc()
     if myotest.DEBUG:
         import matplotlib.pyplot as pl
         pl.figure()
         p0 = approx.Polynomial(coeff[0])
         p1 = approx.Polynomial(coeff[1])
         p2 = approx.Polynomial(coeff[2])
         pl.plot(x, p0(x), label='p0')
         pl.plot(x, p1(x), label='p1')
         pl.plot(x, p2(x), label='p2')
         pl.plot(x, f(x), label='f')
         pl.plot(x, g(x), label='g')
         pl.legend(loc='lower left')
         pl.show()
     self.assertTrue(np.all(np.abs(f(x) - g(x)) < 1e-15))
     # Test number two
     knots = [-5.0, 1.0, 3.123]
     coeff = [
         [0.123, 0.456, 2.789, -0.123, -0.456, 0.0035],
         [5.4123, -0.1456, 7.789, -0.123, -0.456, 0.023],
         [-40.6123, 0.2456, -0.86453, 0.23, -0.753, 0.4262],
         [-20.4123, -2.0156, 1.79, -0.00642, -0.2632, -1.098],
     ]
     f = approx.PiecewisePolynomial(coeff, knots)
     g = f.myokit_form(myokit.Name('x')).pyfunc()
     self.assertTrue(np.all(np.abs(f(x) - g(x)) < 1e-15))
     # Test cloning
     h = approx.PiecewisePolynomial(f)
     self.assertTrue(np.all(np.abs(f(x) - h(x)) < 1e-15))
示例#30
0
def parse_mathml_string(s):
    """
    Parses a MathML string that should contain a single expression.
    """
    import xml.etree.ElementTree as etree
    p = MathMLParser(
        lambda x, y: myokit.Name(x),
        lambda x, y: myokit.Number(x),
    )
    return p.parse(etree.fromstring(s))