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_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>')
Esempio n. 3
0
 def _parse_expression(self, s, var=None):
     """
     Attempts to read an expression from the given string ``s`` and parse it
     using the context of variable ``var`` to resolve any references.
     """
     s = str(s)
     # Pre-process some basic html entities
     entities = {
         '&eq;': '==',
         '&ne;': '!=',
         '&neq;': '!=',  # Not a html entity!
         '&lt;': '<',
         '&gt;': '>',
         '&le;': '<=',
         '&ge;': '>=',
     }
     s = s.replace('&amp;', '&')
     for k, v in entities.items():
         s = s.replace(k, v)
     # Attempt to handle single a?b:c construct
     if '?' in s:
         c, v = s.split('?', 1)
         if ':' in v:
             v = v.split(':', 1)
         else:
             v = (v, '0')
         return myokit.If(myokit.parse_expression(c, var),
                          myokit.parse_expression(v[0], var),
                          myokit.parse_expression(v[1], var))
     return myokit.parse_expression(s, var)
    def test_logic_operators(self):
        # Tests parsing logic operators

        # Not
        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>'
        e = myokit.Not(cond1)
        x = '<apply><not/>' + c1 + '</apply>'
        self.assertEqual(self.p(x), e)

        # And
        e = myokit.And(cond1, cond2)
        x = '<apply><and/>' + c1 + c2 + '</apply>'
        self.assertEqual(self.p(x), e)

        # Or
        e = myokit.Or(cond1, cond2)
        x = '<apply><or/>' + c1 + c2 + '</apply>'
        self.assertEqual(self.p(x), e)

        # Xor
        e = myokit.And(
            myokit.Or(cond1, cond2),
            myokit.Not(myokit.And(cond1, cond2))
        )
        x = '<apply><xor/>' + c1 + c2 + '</apply>'
        self.assertEqual(self.p(x), e)
Esempio n. 5
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)
Esempio n. 6
0
    def test_logical(self):
        # Tests printing logical operators and functions

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

        # Not
        cond1 = myokit.parse_expression('5 > 3')
        cond2 = myokit.parse_expression('2 < 1')
        c1 = ('<apply><gt/>'
              '<cn cellml:units="dimensionless">5.0</cn>'
              '<cn cellml:units="dimensionless">3.0</cn>'
              '</apply>')
        c2 = ('<apply><lt/>'
              '<cn cellml:units="dimensionless">2.0</cn>'
              '<cn cellml:units="dimensionless">1.0</cn>'
              '</apply>')
        x = myokit.Not(cond1)
        self.assertWrite(x, '<apply><not/>' + c1 + '</apply>')
        # And
        x = myokit.And(cond1, cond2)
        self.assertWrite(x, '<apply><and/>' + c1 + c2 + '</apply>')
        # Or
        x = myokit.Or(cond1, cond2)
        self.assertWrite(x, '<apply><or/>' + c1 + c2 + '</apply>')
        # 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>')
def evaluate(expression):
    """
    Evaluates an expression in mmt syntax.
    """
    import myokit
    try:
        e = myokit.parse_expression(expression)
        e = e.eval() if e.is_literal() else e
        print(expression + ' = ' + str(e))
    except myokit.ParseError as ex:
        print(myokit.format_parse_error(ex, iter([expression])))
    def test_logic_operators(self):
        # Tests writing logic operators

        cond1 = myokit.parse_expression('5 > 3')
        cond2 = myokit.parse_expression('2 < 1')
        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>'

        # Not
        x = myokit.Not(cond1)
        self.assertWrite(
            x, '<mrow><mo>(</mo><mo>not</mo>' + c1 + '<mo>)</mo></mrow>')

        # And
        x = myokit.And(cond1, cond2)
        self.assertWrite(x, '<mrow>' + c1 + '<mo>and</mo>' + c2 + '</mrow>')

        # Or
        x = myokit.Or(cond1, cond2)
        self.assertWrite(x, '<mrow>' + c1 + '<mo>or</mo>' + c2 + '</mrow>')
    def test_logic_operators(self):
        # Tests writing logic operators

        # Not
        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>'
        e = myokit.Not(cond1)
        x = '<apply><not/>' + c1 + '</apply>'
        self.assertWrite(e, x)

        # And
        e = myokit.And(cond1, cond2)
        x = '<apply><and/>' + c1 + c2 + '</apply>'
        self.assertWrite(e, x)

        # Or
        e = myokit.Or(cond1, cond2)
        x = '<apply><or/>' + c1 + c2 + '</apply>'
        self.assertWrite(e, x)
Esempio n. 10
0
    def test_python_writer(self):
        # Test Python expression writer obtaining method.

        import myokit
        w = myokit.python_writer()
        import myokit.formats
        import myokit.formats.python
        self.assertIsInstance(w, myokit.formats.python.PythonExpressionWriter)

        # Test custom name method for this writer
        e = myokit.parse_expression('5 + 3 * x')
        self.assertEqual(w.ex(e), '5.0 + 3.0 * x')

        # Test with unvalidated model (no unames set)
        m = myokit.Model()
        c = m.add_component('c')
        x = c.add_variable('x')
        x.set_rhs('5 + x')
        self.assertEqual(w.ex(x.rhs()), '5.0 + c_x')
Esempio n. 11
0
    def opiecewise(self):
        """
        Test of OrderedPiecewise class
        """
        x = myokit.Name('x')
        p = myokit.OrderedPiecewise(
            x,
            myokit.parse_expression('1 * 10'), myokit.Number(1),
            myokit.parse_expression('2 * 10'), myokit.Number(2),
            myokit.parse_expression('3 * 10'), myokit.Number(3),
            myokit.parse_expression('4 * 10')
        )

        def test(p, x):
            self.assertEqual(p.eval(subst={x: 0}), 10)
            self.assertEqual(p.eval(subst={x: 0.99}), 10)
            self.assertEqual(p.eval(subst={x: 1}), 20)
            self.assertEqual(p.eval(subst={x: 1.99}), 20)
            self.assertEqual(p.eval(subst={x: 2}), 30)
            self.assertEqual(p.eval(subst={x: 2.99}), 30)
            self.assertEqual(p.eval(subst={x: 3}), 40)
            self.assertEqual(p.eval(subst={x: 4}), 40)
        test(p, x)

        # Conversion to piecewise
        w = myokit.Piecewise(
            myokit.Less(x, myokit.Number(1)), myokit.parse_expression('1* 10'),
            myokit.Less(x, myokit.Number(2)), myokit.parse_expression('2 *10'),
            myokit.Less(
                x, myokit.Number(3)), myokit.parse_expression('3 * 10'),
            myokit.parse_expression('4 * 10'))
        test(w, x)
        q = p.piecewise()
        self.assertEqual(q, w)
        test(p, x)

        # Test conversion to binary tree
        r = p.if_tree()
        test(r, x)
Esempio n. 12
0
    def test_logical(self):

        # Single and double precision and native maths
        ws = myokit.formats.opencl.OpenCLExpressionWriter()
        wd = myokit.formats.opencl.OpenCLExpressionWriter(
            myokit.DOUBLE_PRECISION)
        wn = myokit.formats.opencl.OpenCLExpressionWriter(native_math=False)

        a = myokit.Name(myokit.Model().add_component('c').add_variable('a'))
        b = myokit.Number('12', 'pF')
        cond1 = myokit.parse_expression('5 > 3')
        cond2 = myokit.parse_expression('2 < 1')
        condx = myokit.Number(1.2)

        # Not
        x = myokit.Not(cond1)
        self.assertEqual(ws.ex(x), '!((5.0f > 3.0f))')
        self.assertEqual(wd.ex(x), '!((5.0 > 3.0))')
        self.assertEqual(wn.ex(x), '!((5.0f > 3.0f))')
        x = myokit.Not(condx)
        self.assertEqual(ws.ex(x), '!((1.2f != 0.0f))')
        self.assertEqual(wd.ex(x), '!((1.2 != 0.0))')
        self.assertEqual(wn.ex(x), '!((1.2f != 0.0f))')

        # And
        x = myokit.And(cond1, cond2)
        self.assertEqual(ws.ex(x), '((5.0f > 3.0f) && (2.0f < 1.0f))')
        self.assertEqual(wd.ex(x), '((5.0 > 3.0) && (2.0 < 1.0))')
        self.assertEqual(wn.ex(x), '((5.0f > 3.0f) && (2.0f < 1.0f))')
        x = myokit.And(condx, cond2)
        self.assertEqual(ws.ex(x), '((1.2f != 0.0f) && (2.0f < 1.0f))')
        self.assertEqual(wd.ex(x), '((1.2 != 0.0) && (2.0 < 1.0))')
        self.assertEqual(wn.ex(x), '((1.2f != 0.0f) && (2.0f < 1.0f))')
        x = myokit.And(cond1, condx)
        self.assertEqual(ws.ex(x), '((5.0f > 3.0f) && (1.2f != 0.0f))')
        self.assertEqual(wd.ex(x), '((5.0 > 3.0) && (1.2 != 0.0))')
        self.assertEqual(wn.ex(x), '((5.0f > 3.0f) && (1.2f != 0.0f))')

        # Or
        x = myokit.Or(cond1, cond2)
        self.assertEqual(ws.ex(x), '((5.0f > 3.0f) || (2.0f < 1.0f))')
        self.assertEqual(wd.ex(x), '((5.0 > 3.0) || (2.0 < 1.0))')
        self.assertEqual(wn.ex(x), '((5.0f > 3.0f) || (2.0f < 1.0f))')
        x = myokit.Or(condx, cond2)
        self.assertEqual(ws.ex(x), '((1.2f != 0.0f) || (2.0f < 1.0f))')
        self.assertEqual(wd.ex(x), '((1.2 != 0.0) || (2.0 < 1.0))')
        self.assertEqual(wn.ex(x), '((1.2f != 0.0f) || (2.0f < 1.0f))')
        x = myokit.Or(cond1, condx)
        self.assertEqual(ws.ex(x), '((5.0f > 3.0f) || (1.2f != 0.0f))')
        self.assertEqual(wd.ex(x), '((5.0 > 3.0) || (1.2 != 0.0))')
        self.assertEqual(wn.ex(x), '((5.0f > 3.0f) || (1.2f != 0.0f))')

        # If
        x = myokit.If(cond1, a, b)
        self.assertEqual(ws.ex(x), '((5.0f > 3.0f) ? c.a : 12.0f)')
        self.assertEqual(wd.ex(x), '((5.0 > 3.0) ? c.a : 12.0)')
        self.assertEqual(wn.ex(x), '((5.0f > 3.0f) ? c.a : 12.0f)')
        x = myokit.If(condx, a, b)
        self.assertEqual(ws.ex(x), '((1.2f != 0.0f) ? c.a : 12.0f)')
        self.assertEqual(wd.ex(x), '((1.2 != 0.0) ? c.a : 12.0)')
        self.assertEqual(wn.ex(x), '((1.2f != 0.0f) ? c.a : 12.0f)')

        # Piecewise
        c = myokit.Number(1)
        x = myokit.Piecewise(cond1, a, cond2, b, c)
        self.assertEqual(
            ws.ex(x), '((5.0f > 3.0f) ? c.a : ((2.0f < 1.0f) ? 12.0f : 1.0f))')
        self.assertEqual(wd.ex(x),
                         '((5.0 > 3.0) ? c.a : ((2.0 < 1.0) ? 12.0 : 1.0))')
        self.assertEqual(
            wn.ex(x), '((5.0f > 3.0f) ? c.a : ((2.0f < 1.0f) ? 12.0f : 1.0f))')
        x = myokit.Piecewise(condx, a, condx, b, c)
        self.assertEqual(
            ws.ex(x),
            '((1.2f != 0.0f) ? c.a : ((1.2f != 0.0f) ? 12.0f : 1.0f))')
        self.assertEqual(wd.ex(x),
                         '((1.2 != 0.0) ? c.a : ((1.2 != 0.0) ? 12.0 : 1.0))')
        self.assertEqual(
            wn.ex(x),
            '((1.2f != 0.0f) ? c.a : ((1.2f != 0.0f) ? 12.0f : 1.0f))')
    def test_conditionals(self):
        # Tests if and piecewise parsing

        # If
        a = myokit.Name('c.a')
        b = myokit.Number(1.0)
        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>'
        e = myokit.If(cond1, a, b)
        x = (
            '<piecewise>'
            '<piece><ci>c.a</ci>' + c1 + '</piece>'
            '<otherwise><cn>1.0</cn></otherwise>'
            '</piecewise>'
        )
        self.assertEqual(self.p(x), e.piecewise())

        # Piecewise
        e = myokit.Piecewise(cond1, a, cond2, b, myokit.Number(100))
        x = (
            '<piecewise>'
            '<piece><ci>c.a</ci>' + c1 + '</piece>'
            '<piece><cn>1.0</cn>' + c2 + '</piece>'
            '<otherwise><cn>100.0</cn></otherwise>'
            '</piecewise>'
        )
        self.assertEqual(self.p(x), e)

        # Piecewise with extra otherwise
        x = (
            '<piecewise>'
            '  <piece>'
            '    <cn>1.0</cn><apply><eq/><cn>1.0</cn><cn>1.0</cn></apply>'
            '  </piece>'
            '  <otherwise>'
            '    <cn>2</cn>'
            '  </otherwise>'
            '  <otherwise>'
            '    <cn>3</cn>'
            '  </otherwise>'
            '</piecewise>'
        )
        self.assertRaisesRegex(
            mathml.MathMLError, 'Found more than one <otherwise>', self.p, x)

        # Check otherwise is automatically added if not given
        x = (
            '<piecewise>'
            '  <piece>'
            '    <cn>2</cn><apply><eq/><cn>1.0</cn><cn>1.0</cn></apply>'
            '  </piece>'
            '  <piece>'
            '    <cn>1.0</cn><apply><eq/><cn>1.0</cn><cn>1.0</cn></apply>'
            '  </piece>'
            '</piecewise>'
        )
        e = self.p(x)
        pieces = list(e.pieces())
        self.assertEqual(len(pieces), 3)
        self.assertEqual(pieces[0], myokit.Number(2))
        self.assertEqual(pieces[1], myokit.Number(1))
        self.assertEqual(pieces[2], myokit.Number(0))

        # Too much stuff in a piece
        x = (
            '<piecewise>'
            '  <piece>'
            '    <cn>1</cn><apply><eq/><cn>1</cn><cn>1</cn></apply>'
            '    <cn>2</cn>'
            '  </piece>'
            '  <otherwise>'
            '    <cn>3</cn>'
            '  </otherwise>'
            '</piecewise>'
        )
        self.assertRaisesRegex(
            mathml.MathMLError, '<piece> element must have exactly 2 children',
            self.p, x)

        # Too much stuff in an otherwise
        x = (
            '<piecewise>'
            '  <piece>'
            '    <cn>1</cn><apply><eq/><cn>1</cn><cn>1</cn></apply>'
            '  </piece>'
            '  <otherwise>'
            '    <cn>3</cn><ci>x</ci>'
            '  </otherwise>'
            '</piecewise>'
        )
        self.assertRaisesRegex(
            mathml.MathMLError, '<otherwise> element must have exactly 1',
            self.p, x)

        # Unexpected tag in piecwise
        x = (
            '<piecewise>'
            '  <piece>'
            '    <cn>1.0</cn><apply><eq/><cn>1.0</cn><cn>1.0</cn></apply>'
            '  </piece>'
            '  <otherwise>'
            '    <cn>3</cn>'
            '  </otherwise>'
            '  <apply><eq/><cn>1.0</cn><cn>1.0</cn></apply>'
            '</piecewise>'
        )
        self.assertRaisesRegex(
            mathml.MathMLError, 'Unexpected content in <piecewise>', self.p, x)
    def test_trig_extra(self):
        # Tests parsing of the annoying trig functions.

        # Cosecant
        x = self.p('<apply><csc/><cn>3</cn></apply>')
        y = myokit.parse_expression('1/ sin(3)')
        self.assertEqual(x, y)

        # Secant
        x = self.p('<apply><sec/><cn>3</cn></apply>')
        y = myokit.parse_expression('1/ cos(3)')
        self.assertEqual(x, y)

        # Cotangent
        x = self.p('<apply><cot/><cn>3</cn></apply>')
        y = myokit.parse_expression('1/ tan(3)')
        self.assertEqual(x, y)

        # arc-cosecant
        x = self.p('<apply><arccsc/><cn>3</cn></apply>')
        y = myokit.parse_expression('asin(1/ 3)')
        self.assertEqual(x, y)

        # arc-secant
        x = self.p('<apply><arcsec/><cn>3</cn></apply>')
        y = myokit.parse_expression('acos(1/ 3)')
        self.assertEqual(x, y)

        # arc-cotangent
        x = self.p('<apply><arccot/><cn>3</cn></apply>')
        y = myokit.parse_expression('atan(1/ 3)')
        self.assertEqual(x, y)

        # Hyperbolic sine
        x = self.p('<apply><sinh/><cn>3</cn></apply>')
        y = myokit.parse_expression('0.5 * (exp(3) - exp(-3))')
        self.assertEqual(x, y)

        # Hyperbolic cosine
        x = self.p('<apply><cosh/><cn>3</cn></apply>')
        y = myokit.parse_expression('0.5 * (exp(3) + exp(-3))')
        self.assertEqual(x, y)

        # Hyperbolic tangent
        x = self.p('<apply><tanh/><cn>3</cn></apply>')
        y = myokit.parse_expression('(exp(2*3) - 1)/ (exp(2*3) + 1)')
        self.assertEqual(x, y)

        # Hyperbolic arc sine
        x = self.p('<apply><arcsinh/><cn>3</cn></apply>')
        y = myokit.parse_expression('log(3 + sqrt(1 + 3*3))')
        self.assertEqual(x, y)

        # Hyperbolic arc cosine
        x = self.p('<apply><arccosh/><cn>3</cn></apply>')
        y = myokit.parse_expression('log(3 + sqrt(3 + 1) * sqrt(3 - 1))')
        self.assertEqual(x, y)

        # Hyperbolic arc tangent
        x = self.p('<apply><arctanh/><cn>3</cn></apply>')
        y = myokit.parse_expression('0.5 * (log(1 + 3) - log(1 - 3))')
        self.assertEqual(x, y)

        # Hyperbolic cosecant
        x = self.p('<apply><csch/><cn>3</cn></apply>')
        y = myokit.parse_expression('2/ (exp(3) - exp(-3))')
        self.assertEqual(x, y)

        # Hyperbolic secant
        x = self.p('<apply><sech/><cn>3</cn></apply>')
        y = myokit.parse_expression('2/ (exp(3) + exp(-3))')
        self.assertEqual(x, y)

        # Hyperbolic cotangent
        x = self.p('<apply><coth/><cn>3</cn></apply>')
        y = myokit.parse_expression('(exp(2*3) + 1)/ (exp(2*3) - 1)')
        self.assertEqual(x, y)

        # Hyperbolic arc cosecant
        x = self.p('<apply><arccsch/><cn>3</cn></apply>')
        y = myokit.parse_expression('log(sqrt(1/(3*3) + 1) + 1/3)')
        self.assertEqual(x, y)

        # Hyperbolic arc secant
        x = self.p('<apply><arcsech/><cn>3</cn></apply>')
        y = myokit.parse_expression('log(sqrt(1/(3*3) - 1) + 1/3)')
        self.assertEqual(x, y)

        # Hyperbolic arc cotangent
        x = self.p('<apply><arccoth/><cn>3</cn></apply>')
        y = myokit.parse_expression('0.5 * log((3 + 1)/ (3 - 1))')
        self.assertEqual(x, y)
Esempio n. 15
0
    def test_format_parse_error(self):
        """
        Test format_parse_error.
        """
        # Test basic formatting, with and without source
        bad = '    5 + / 2'
        try:
            myokit.parse_expression(bad)
        except myokit.ParseError as e:

            # No source
            self.assertEqual(
                myokit.format_parse_error(e), '\n'.join([
                    'Syntax error',
                    '  Unexpected token SLASH "/" expecting expression',
                    'On line 1 character 8',
                ]))

            # List-of-strings source
            self.assertEqual(
                myokit.format_parse_error(e, source=[bad]), '\n'.join([
                    'Syntax error',
                    '  Unexpected token SLASH "/" expecting expression',
                    'On line 1 character 8', '  5 + / 2', '      ^'
                ]))

            # File source
            with TemporaryDirectory() as d:
                path = d.path('mmt')
                with open(path, 'w') as f:
                    f.write(bad + '\n')
                myokit.format_parse_error(e, source=path),
                '\n'.join([
                    'Syntax error',
                    '  Unexpected token SLASH "/" expecting expression',
                    'On line 1 character 8', '  5 + / 2', '      ^'
                ])

            # Line doesn't exist in source
            self.assertEqual(
                myokit.format_parse_error(e, source=[]), '\n'.join([
                    'Syntax error',
                    '  Unexpected token SLASH "/" expecting expression',
                    'On line 1 character 8',
                ]))

            # Char doesn't exist in source
            self.assertEqual(
                myokit.format_parse_error(e, source=['x']), '\n'.join([
                    'Syntax error',
                    '  Unexpected token SLASH "/" expecting expression',
                    'On line 1 character 8',
                ]))

        # Very long lines
        bad = '    1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 100 + 1000 + 11'
        bad += ' + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22'
        bad += ' + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31'

        # Error near start
        error = '\n'.join([
            'Syntax error',
            '  Unexpected token SLASH "/" expecting expression',
            'On line 1 character 12',
            '  1 + 2 + / 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 100 + 1000 + ..',
            '          ^',
        ])
        b = bad[:12] + '/ ' + bad[12:]
        try:
            myokit.parse_expression(b)
        except myokit.ParseError as e:
            self.assertEqual(myokit.format_parse_error(e, source=[b]), error)

        error = '\n'.join([
            'Syntax error',
            '  Unexpected token SLASH "/" expecting expression',
            'On line 1 character 83',
            '  ..+ 12 + 13 + 14 + 15 + / 16 + 17 + 18 + 19 + 20 + 21 + 22..',
            '                          ^',
        ])
        b = bad[:83] + '/ ' + bad[83:]
        try:
            myokit.parse_expression(b)
        except myokit.ParseError as e:
            self.assertEqual(myokit.format_parse_error(e, source=[b]), error)

        error = '\n'.join([
            'Syntax error',
            '  Unexpected token SLASH "/" expecting expression',
            'On line 1 character 133',
            '  ..+ 21 + 22 + 23 + 24 + 25 + / 26 + 27 + 28 + 29 + 30 + 31',
            '                               ^',
        ])
        b = bad[:133] + '/ ' + bad[133:]
        try:
            myokit.parse_expression(b)
        except myokit.ParseError as e:
            self.assertEqual(myokit.format_parse_error(e, source=[b]), error)
Esempio n. 16
0
    def test_all(self):
        w = myokit.formats.ewriter('easyml')

        model = myokit.Model()
        component = model.add_component('c')
        avar = component.add_variable('a')

        # Name
        a = myokit.Name(avar)
        self.assertEqual(w.ex(a), 'c.a')
        # Number with unit
        b = myokit.Number('12', 'pF')
        self.assertEqual(w.ex(b), '12.0')
        # Integer
        c = myokit.Number(1)
        self.assertEqual(w.ex(c), '1.0')
        # Integer

        # Prefix plus
        x = myokit.PrefixPlus(b)
        self.assertEqual(w.ex(x), '12.0')
        # Prefix minus
        x = myokit.PrefixMinus(b)
        self.assertEqual(w.ex(x), '(-12.0)')

        # Plus
        x = myokit.Plus(a, b)
        self.assertEqual(w.ex(x), 'c.a + 12.0')
        # Minus
        x = myokit.Minus(a, b)
        self.assertEqual(w.ex(x), 'c.a - 12.0')
        # Multiply
        x = myokit.Multiply(a, b)
        self.assertEqual(w.ex(x), 'c.a * 12.0')
        # Divide
        x = myokit.Divide(a, b)
        self.assertEqual(w.ex(x), 'c.a / 12.0')

        # Quotient
        x = myokit.Quotient(a, b)
        with WarningCollector() as c:
            self.assertEqual(w.ex(x), 'floor(c.a / 12.0)')
        # Remainder
        x = myokit.Remainder(a, b)
        with WarningCollector() as c:
            self.assertEqual(w.ex(x), 'c.a - 12.0 * (floor(c.a / 12.0))')

        # Power
        x = myokit.Power(a, b)
        self.assertEqual(w.ex(x), 'pow(c.a, 12.0)')
        # Sqrt
        x = myokit.Sqrt(b)
        self.assertEqual(w.ex(x), 'sqrt(12.0)')
        # Exp
        x = myokit.Exp(a)
        self.assertEqual(w.ex(x), 'exp(c.a)')
        # Log(a)
        x = myokit.Log(b)
        self.assertEqual(w.ex(x), 'log(12.0)')
        # Log(a, b)
        x = myokit.Log(a, b)
        self.assertEqual(w.ex(x), '(log(c.a) / log(12.0))')
        # Log10
        x = myokit.Log10(b)
        self.assertEqual(w.ex(x), 'log10(12.0)')

        # Sin
        with WarningCollector() as c:
            x = myokit.Sin(b)
            self.assertEqual(w.ex(x), 'sin(12.0)')
            # Cos
            x = myokit.Cos(b)
            self.assertEqual(w.ex(x), 'cos(12.0)')
            # Tan
            x = myokit.Tan(b)
            self.assertEqual(w.ex(x), 'tan(12.0)')
            # ASin
            x = myokit.ASin(b)
            self.assertEqual(w.ex(x), 'asin(12.0)')
            # ACos
            x = myokit.ACos(b)
            self.assertEqual(w.ex(x), 'acos(12.0)')
            # ATan
            x = myokit.ATan(b)
            self.assertEqual(w.ex(x), 'atan(12.0)')

        with WarningCollector() as c:
            # Floor
            x = myokit.Floor(b)
            self.assertEqual(w.ex(x), 'floor(12.0)')
            # Ceil
            x = myokit.Ceil(b)
            self.assertEqual(w.ex(x), 'ceil(12.0)')
            # Abs
            x = myokit.Abs(b)
            self.assertEqual(w.ex(x), 'fabs(12.0)')

        # Equal
        x = myokit.Equal(a, b)
        self.assertEqual(w.ex(x), '(c.a == 12.0)')
        # NotEqual
        x = myokit.NotEqual(a, b)
        self.assertEqual(w.ex(x), '(c.a != 12.0)')
        # More
        x = myokit.More(a, b)
        self.assertEqual(w.ex(x), '(c.a > 12.0)')
        # Less
        x = myokit.Less(a, b)
        self.assertEqual(w.ex(x), '(c.a < 12.0)')
        # MoreEqual
        x = myokit.MoreEqual(a, b)
        self.assertEqual(w.ex(x), '(c.a >= 12.0)')
        # LessEqual
        x = myokit.LessEqual(a, b)
        self.assertEqual(w.ex(x), '(c.a <= 12.0)')

        # Not
        cond1 = myokit.parse_expression('5 > 3')
        cond2 = myokit.parse_expression('2 < 1')
        x = myokit.Not(cond1)
        self.assertEqual(w.ex(x), '!((5.0 > 3.0))')
        # And
        x = myokit.And(cond1, cond2)
        self.assertEqual(w.ex(x), '((5.0 > 3.0) and (2.0 < 1.0))')
        # Or
        x = myokit.Or(cond1, cond2)
        self.assertEqual(w.ex(x), '((5.0 > 3.0) or (2.0 < 1.0))')

        # If
        x = myokit.If(cond1, a, b)
        self.assertEqual(w.ex(x), '((5.0 > 3.0) ? c.a : 12.0)')
        # Piecewise
        c = myokit.Number(1)
        x = myokit.Piecewise(cond1, a, cond2, b, c)
        self.assertEqual(w.ex(x),
                         '((5.0 > 3.0) ? c.a : ((2.0 < 1.0) ? 12.0 : 1.0))')

        # Test without a Myokit expression
        self.assertRaisesRegex(ValueError, 'Unknown expression type', w.ex, 7)
Esempio n. 17
0
    def test_conditional(self):

        # Single and double precision and native maths
        ws = myokit.formats.opencl.OpenCLExpressionWriter()
        wd = myokit.formats.opencl.OpenCLExpressionWriter(
            myokit.DOUBLE_PRECISION)
        wn = myokit.formats.opencl.OpenCLExpressionWriter(native_math=False)

        a = myokit.Name(myokit.Model().add_component('c').add_variable('a'))
        b = myokit.Number('12', 'pF')
        cond1 = myokit.parse_expression('5 > 3')
        cond2 = myokit.parse_expression('2 < 1')

        # Equal
        x = myokit.Equal(a, b)
        self.assertEqual(ws.ex(x), '(c.a == 12.0f)')
        self.assertEqual(wd.ex(x), '(c.a == 12.0)')
        self.assertEqual(wn.ex(x), '(c.a == 12.0f)')
        x = myokit.Equal(cond1, cond2)
        self.assertEqual(ws.ex(x), '((5.0f > 3.0f) == (2.0f < 1.0f))')
        self.assertEqual(wd.ex(x), '((5.0 > 3.0) == (2.0 < 1.0))')
        self.assertEqual(wn.ex(x), '((5.0f > 3.0f) == (2.0f < 1.0f))')
        x = myokit.Equal(cond1, b)
        self.assertEqual(ws.ex(x), '((5.0f > 3.0f) == (12.0f != 0.0f))')
        self.assertEqual(wd.ex(x), '((5.0 > 3.0) == (12.0 != 0.0))')
        self.assertEqual(wn.ex(x), '((5.0f > 3.0f) == (12.0f != 0.0f))')
        x = myokit.Equal(a, cond2)
        self.assertEqual(ws.ex(x), '((c.a != 0.0f) == (2.0f < 1.0f))')
        self.assertEqual(wd.ex(x), '((c.a != 0.0) == (2.0 < 1.0))')
        self.assertEqual(wn.ex(x), '((c.a != 0.0f) == (2.0f < 1.0f))')

        # NotEqual
        x = myokit.NotEqual(a, b)
        self.assertEqual(ws.ex(x), '(c.a != 12.0f)')
        self.assertEqual(wd.ex(x), '(c.a != 12.0)')
        self.assertEqual(wn.ex(x), '(c.a != 12.0f)')
        x = myokit.NotEqual(cond1, cond2)
        self.assertEqual(ws.ex(x), '((5.0f > 3.0f) != (2.0f < 1.0f))')
        self.assertEqual(wd.ex(x), '((5.0 > 3.0) != (2.0 < 1.0))')
        self.assertEqual(wn.ex(x), '((5.0f > 3.0f) != (2.0f < 1.0f))')
        x = myokit.NotEqual(cond1, b)
        self.assertEqual(ws.ex(x), '((5.0f > 3.0f) != (12.0f != 0.0f))')
        self.assertEqual(wd.ex(x), '((5.0 > 3.0) != (12.0 != 0.0))')
        self.assertEqual(wn.ex(x), '((5.0f > 3.0f) != (12.0f != 0.0f))')
        x = myokit.NotEqual(a, cond2)
        self.assertEqual(ws.ex(x), '((c.a != 0.0f) != (2.0f < 1.0f))')
        self.assertEqual(wd.ex(x), '((c.a != 0.0) != (2.0 < 1.0))')
        self.assertEqual(wn.ex(x), '((c.a != 0.0f) != (2.0f < 1.0f))')

        # More
        x = myokit.More(a, b)
        self.assertEqual(ws.ex(x), '(c.a > 12.0f)')
        self.assertEqual(wd.ex(x), '(c.a > 12.0)')
        self.assertEqual(wn.ex(x), '(c.a > 12.0f)')
        x = myokit.More(cond1, cond2)
        self.assertEqual(ws.ex(x), '((5.0f > 3.0f) > (2.0f < 1.0f))')
        self.assertEqual(wd.ex(x), '((5.0 > 3.0) > (2.0 < 1.0))')
        self.assertEqual(wn.ex(x), '((5.0f > 3.0f) > (2.0f < 1.0f))')
        x = myokit.More(cond1, b)
        self.assertEqual(ws.ex(x), '((5.0f > 3.0f) > (12.0f != 0.0f))')
        self.assertEqual(wd.ex(x), '((5.0 > 3.0) > (12.0 != 0.0))')
        self.assertEqual(wn.ex(x), '((5.0f > 3.0f) > (12.0f != 0.0f))')
        x = myokit.More(a, cond2)
        self.assertEqual(ws.ex(x), '((c.a != 0.0f) > (2.0f < 1.0f))')
        self.assertEqual(wd.ex(x), '((c.a != 0.0) > (2.0 < 1.0))')
        self.assertEqual(wn.ex(x), '((c.a != 0.0f) > (2.0f < 1.0f))')

        # Less
        x = myokit.Less(a, b)
        self.assertEqual(ws.ex(x), '(c.a < 12.0f)')
        self.assertEqual(wd.ex(x), '(c.a < 12.0)')
        self.assertEqual(wn.ex(x), '(c.a < 12.0f)')
        x = myokit.Less(cond1, cond2)
        self.assertEqual(ws.ex(x), '((5.0f > 3.0f) < (2.0f < 1.0f))')
        self.assertEqual(wd.ex(x), '((5.0 > 3.0) < (2.0 < 1.0))')
        self.assertEqual(wn.ex(x), '((5.0f > 3.0f) < (2.0f < 1.0f))')
        x = myokit.Less(cond1, b)
        self.assertEqual(ws.ex(x), '((5.0f > 3.0f) < (12.0f != 0.0f))')
        self.assertEqual(wd.ex(x), '((5.0 > 3.0) < (12.0 != 0.0))')
        self.assertEqual(wn.ex(x), '((5.0f > 3.0f) < (12.0f != 0.0f))')
        x = myokit.Less(a, cond2)
        self.assertEqual(ws.ex(x), '((c.a != 0.0f) < (2.0f < 1.0f))')
        self.assertEqual(wd.ex(x), '((c.a != 0.0) < (2.0 < 1.0))')
        self.assertEqual(wn.ex(x), '((c.a != 0.0f) < (2.0f < 1.0f))')

        # MoreEqual
        x = myokit.MoreEqual(a, b)
        self.assertEqual(ws.ex(x), '(c.a >= 12.0f)')
        self.assertEqual(wd.ex(x), '(c.a >= 12.0)')
        self.assertEqual(wn.ex(x), '(c.a >= 12.0f)')
        x = myokit.MoreEqual(cond1, cond2)
        self.assertEqual(ws.ex(x), '((5.0f > 3.0f) >= (2.0f < 1.0f))')
        self.assertEqual(wd.ex(x), '((5.0 > 3.0) >= (2.0 < 1.0))')
        self.assertEqual(wn.ex(x), '((5.0f > 3.0f) >= (2.0f < 1.0f))')
        x = myokit.MoreEqual(cond1, b)
        self.assertEqual(ws.ex(x), '((5.0f > 3.0f) >= (12.0f != 0.0f))')
        self.assertEqual(wd.ex(x), '((5.0 > 3.0) >= (12.0 != 0.0))')
        self.assertEqual(wn.ex(x), '((5.0f > 3.0f) >= (12.0f != 0.0f))')
        x = myokit.MoreEqual(a, cond2)
        self.assertEqual(ws.ex(x), '((c.a != 0.0f) >= (2.0f < 1.0f))')
        self.assertEqual(wd.ex(x), '((c.a != 0.0) >= (2.0 < 1.0))')
        self.assertEqual(wn.ex(x), '((c.a != 0.0f) >= (2.0f < 1.0f))')

        # LessEqual
        x = myokit.LessEqual(a, b)
        self.assertEqual(ws.ex(x), '(c.a <= 12.0f)')
        self.assertEqual(wd.ex(x), '(c.a <= 12.0)')
        self.assertEqual(wn.ex(x), '(c.a <= 12.0f)')
        x = myokit.LessEqual(cond1, cond2)
        self.assertEqual(ws.ex(x), '((5.0f > 3.0f) <= (2.0f < 1.0f))')
        self.assertEqual(wd.ex(x), '((5.0 > 3.0) <= (2.0 < 1.0))')
        self.assertEqual(wn.ex(x), '((5.0f > 3.0f) <= (2.0f < 1.0f))')
        x = myokit.LessEqual(cond1, b)
        self.assertEqual(ws.ex(x), '((5.0f > 3.0f) <= (12.0f != 0.0f))')
        self.assertEqual(wd.ex(x), '((5.0 > 3.0) <= (12.0 != 0.0))')
        self.assertEqual(wn.ex(x), '((5.0f > 3.0f) <= (12.0f != 0.0f))')
        x = myokit.LessEqual(a, cond2)
        self.assertEqual(ws.ex(x), '((c.a != 0.0f) <= (2.0f < 1.0f))')
        self.assertEqual(wd.ex(x), '((c.a != 0.0) <= (2.0 < 1.0))')
        self.assertEqual(wn.ex(x), '((c.a != 0.0f) <= (2.0f < 1.0f))')
Esempio n. 18
0
    def test_all(self):
        w = myokit.formats.python.PythonExpressionWriter()

        model = myokit.Model()
        component = model.add_component('c')
        avar = component.add_variable('a')

        # Name
        a = myokit.Name(avar)
        self.assertEqual(w.ex(a), 'c.a')
        # Number with unit
        b = myokit.Number('12', 'pF')
        self.assertEqual(w.ex(b), '12.0')

        # Prefix plus
        x = myokit.PrefixPlus(b)
        self.assertEqual(w.ex(x), '12.0')
        # Prefix minus
        x = myokit.PrefixMinus(b)
        self.assertEqual(w.ex(x), '(-12.0)')

        # Plus
        x = myokit.Plus(a, b)
        self.assertEqual(w.ex(x), 'c.a + 12.0')
        # Minus
        x = myokit.Minus(a, b)
        self.assertEqual(w.ex(x), 'c.a - 12.0')
        # Multiply
        x = myokit.Multiply(a, b)
        self.assertEqual(w.ex(x), 'c.a * 12.0')
        # Divide
        x = myokit.Divide(a, b)
        self.assertEqual(w.ex(x), 'c.a / 12.0')

        # Quotient
        x = myokit.Quotient(a, b)
        self.assertEqual(w.ex(x), 'c.a // 12.0')
        # Remainder
        x = myokit.Remainder(a, b)
        self.assertEqual(w.ex(x), 'c.a % 12.0')

        # Power
        x = myokit.Power(a, b)
        self.assertEqual(w.ex(x), 'c.a ** 12.0')
        # Sqrt
        x = myokit.Sqrt(b)
        self.assertEqual(w.ex(x), 'math.sqrt(12.0)')
        # Exp
        x = myokit.Exp(a)
        self.assertEqual(w.ex(x), 'math.exp(c.a)')
        # Log(a)
        x = myokit.Log(b)
        self.assertEqual(w.ex(x), 'math.log(12.0)')
        # Log(a, b)
        x = myokit.Log(a, b)
        self.assertEqual(w.ex(x), 'math.log(c.a, 12.0)')
        # Log10
        x = myokit.Log10(b)
        self.assertEqual(w.ex(x), 'math.log10(12.0)')

        # Sin
        x = myokit.Sin(b)
        self.assertEqual(w.ex(x), 'math.sin(12.0)')
        # Cos
        x = myokit.Cos(b)
        self.assertEqual(w.ex(x), 'math.cos(12.0)')
        # Tan
        x = myokit.Tan(b)
        self.assertEqual(w.ex(x), 'math.tan(12.0)')
        # ASin
        x = myokit.ASin(b)
        self.assertEqual(w.ex(x), 'math.asin(12.0)')
        # ACos
        x = myokit.ACos(b)
        self.assertEqual(w.ex(x), 'math.acos(12.0)')
        # ATan
        x = myokit.ATan(b)
        self.assertEqual(w.ex(x), 'math.atan(12.0)')

        # Floor
        x = myokit.Floor(b)
        self.assertEqual(w.ex(x), 'math.floor(12.0)')
        # Ceil
        x = myokit.Ceil(b)
        self.assertEqual(w.ex(x), 'math.ceil(12.0)')
        # Abs
        x = myokit.Abs(b)
        self.assertEqual(w.ex(x), 'abs(12.0)')

        # Equal
        x = myokit.Equal(a, b)
        self.assertEqual(w.ex(x), '(c.a == 12.0)')
        # NotEqual
        x = myokit.NotEqual(a, b)
        self.assertEqual(w.ex(x), '(c.a != 12.0)')
        # More
        x = myokit.More(a, b)
        self.assertEqual(w.ex(x), '(c.a > 12.0)')
        # Less
        x = myokit.Less(a, b)
        self.assertEqual(w.ex(x), '(c.a < 12.0)')
        # MoreEqual
        x = myokit.MoreEqual(a, b)
        self.assertEqual(w.ex(x), '(c.a >= 12.0)')
        # LessEqual
        x = myokit.LessEqual(a, b)
        self.assertEqual(w.ex(x), '(c.a <= 12.0)')

        # Not
        cond1 = myokit.parse_expression('5 > 3')
        cond2 = myokit.parse_expression('2 < 1')
        x = myokit.Not(cond1)
        self.assertEqual(w.ex(x), 'not ((5.0 > 3.0))')
        # And
        x = myokit.And(cond1, cond2)
        self.assertEqual(w.ex(x), '((5.0 > 3.0) and (2.0 < 1.0))')
        # Or
        x = myokit.Or(cond1, cond2)
        self.assertEqual(w.ex(x), '((5.0 > 3.0) or (2.0 < 1.0))')

        # If
        x = myokit.If(cond1, a, b)
        self.assertEqual(w.ex(x), '(c.a if (5.0 > 3.0) else 12.0)')
        # Piecewise
        c = myokit.Number(1)
        x = myokit.Piecewise(cond1, a, cond2, b, c)
        self.assertEqual(
            w.ex(x),
            '(c.a if (5.0 > 3.0) else (12.0 if (2.0 < 1.0) else 1.0))')

        # Test fetching using ewriter method
        w = myokit.formats.ewriter('python')
        self.assertIsInstance(w, myokit.formats.python.PythonExpressionWriter)

        # Test lhs method
        w.set_lhs_function(lambda x: 'sheep')
        self.assertEqual(w.ex(a), 'sheep')

        # Test without a Myokit expression
        self.assertRaisesRegex(ValueError, 'Unknown expression type', w.ex, 7)
Esempio n. 19
0
    def test_all(self):
        w = myokit.formats.matlab.MatlabExpressionWriter()

        model = myokit.Model()
        component = model.add_component('c')
        avar = component.add_variable('a')

        # Name
        a = myokit.Name(avar)
        self.assertEqual(w.ex(a), 'c.a')
        # Number with unit
        b = myokit.Number('12', 'pF')
        self.assertEqual(w.ex(b), '12.0')

        # Prefix plus
        x = myokit.PrefixPlus(b)
        self.assertEqual(w.ex(x), '12.0')
        # Prefix minus
        x = myokit.PrefixMinus(b)
        self.assertEqual(w.ex(x), '(-12.0)')

        # Plus
        x = myokit.Plus(a, b)
        self.assertEqual(w.ex(x), 'c.a + 12.0')
        # Minus
        x = myokit.Minus(a, b)
        self.assertEqual(w.ex(x), 'c.a - 12.0')
        # Multiply
        x = myokit.Multiply(a, b)
        self.assertEqual(w.ex(x), 'c.a * 12.0')
        # Divide
        x = myokit.Divide(a, b)
        self.assertEqual(w.ex(x), 'c.a / 12.0')

        # Quotient

        x = myokit.Quotient(a, b)
        self.assertEqual(w.ex(x), 'floor(c.a / 12.0)')
        # Remainder
        x = myokit.Remainder(a, b)
        self.assertEqual(w.ex(x), 'mod(c.a, 12.0)')

        # Power
        x = myokit.Power(a, b)
        self.assertEqual(w.ex(x), 'c.a ^ 12.0')
        # Sqrt
        x = myokit.Sqrt(b)
        self.assertEqual(w.ex(x), 'sqrt(12.0)')
        # Exp
        x = myokit.Exp(a)
        self.assertEqual(w.ex(x), 'exp(c.a)')
        # Log(a)
        x = myokit.Log(b)
        self.assertEqual(w.ex(x), 'log(12.0)')
        # Log(a, b)
        x = myokit.Log(a, b)
        self.assertEqual(w.ex(x), '(log(c.a) / log(12.0))')
        # Log10
        x = myokit.Log10(b)
        self.assertEqual(w.ex(x), 'log10(12.0)')

        # Sin
        x = myokit.Sin(b)
        self.assertEqual(w.ex(x), 'sin(12.0)')
        # Cos
        x = myokit.Cos(b)
        self.assertEqual(w.ex(x), 'cos(12.0)')
        # Tan
        x = myokit.Tan(b)
        self.assertEqual(w.ex(x), 'tan(12.0)')
        # ASin
        x = myokit.ASin(b)
        self.assertEqual(w.ex(x), 'asin(12.0)')
        # ACos
        x = myokit.ACos(b)
        self.assertEqual(w.ex(x), 'acos(12.0)')
        # ATan
        x = myokit.ATan(b)
        self.assertEqual(w.ex(x), 'atan(12.0)')

        # Floor
        x = myokit.Floor(b)
        self.assertEqual(w.ex(x), 'floor(12.0)')
        # Ceil
        x = myokit.Ceil(b)
        self.assertEqual(w.ex(x), 'ceil(12.0)')
        # Abs
        x = myokit.Abs(b)
        self.assertEqual(w.ex(x), 'abs(12.0)')

        # Equal
        x = myokit.Equal(a, b)
        self.assertEqual(w.ex(x), '(c.a == 12.0)')
        # NotEqual
        x = myokit.NotEqual(a, b)
        self.assertEqual(w.ex(x), '(c.a != 12.0)')
        # More
        x = myokit.More(a, b)
        self.assertEqual(w.ex(x), '(c.a > 12.0)')
        # Less
        x = myokit.Less(a, b)
        self.assertEqual(w.ex(x), '(c.a < 12.0)')
        # MoreEqual
        x = myokit.MoreEqual(a, b)
        self.assertEqual(w.ex(x), '(c.a >= 12.0)')
        # LessEqual
        x = myokit.LessEqual(a, b)
        self.assertEqual(w.ex(x), '(c.a <= 12.0)')

        # Not
        cond1 = myokit.parse_expression('5 > 3')
        cond2 = myokit.parse_expression('2 < 1')
        x = myokit.Not(cond1)
        self.assertEqual(w.ex(x), '!((5.0 > 3.0))')
        # And
        x = myokit.And(cond1, cond2)
        self.assertEqual(w.ex(x), '((5.0 > 3.0) && (2.0 < 1.0))')
        # Or
        x = myokit.Or(cond1, cond2)
        self.assertEqual(w.ex(x), '((5.0 > 3.0) || (2.0 < 1.0))')

        # If (custom function)
        x = myokit.If(cond1, a, b)
        self.assertEqual(w.ex(x), 'ifthenelse((5.0 > 3.0), c.a, 12.0)')
        # Piecewise
        c = myokit.Number(1)
        x = myokit.Piecewise(cond1, a, cond2, b, c)
        self.assertEqual(
            w.ex(x),
            'ifthenelse((5.0 > 3.0), c.a, ifthenelse((2.0 < 1.0), 12.0, 1.0))')

        # Test fetching using ewriter method
        w = myokit.formats.ewriter('matlab')
        self.assertIsInstance(w, myokit.formats.matlab.MatlabExpressionWriter)

        # Test without a Myokit expression
        self.assertRaisesRegex(ValueError, 'Unknown expression type', w.ex, 7)
Esempio n. 20
0
    def test_all(self):
        w = myokit.formats.latex.LatexExpressionWriter()

        model = myokit.Model()
        component = model.add_component('c')
        avar = component.add_variable('a')

        # Model needs to be validated --> sets unames
        avar.set_rhs(12)
        avar.set_binding('time')
        model.validate()

        # Name
        a = myokit.Name(avar)
        self.assertEqual(w.ex(a), '\\text{a}')
        # Number with unit
        b = myokit.Number('12', 'pF')
        self.assertEqual(w.ex(b), '12.0')

        # Prefix plus
        x = myokit.PrefixPlus(b)
        self.assertEqual(w.ex(x), '12.0')
        # Prefix minus
        x = myokit.PrefixMinus(b)
        self.assertEqual(w.ex(x), '\\left(-12.0\\right)')
        # Prefix minus with bracket
        x = myokit.PrefixMinus(myokit.Plus(a, b))
        self.assertEqual(w.ex(x),
                         '\\left(-\\left(\\text{a}+12.0\\right)\\right)')

        # Plus
        x = myokit.Plus(a, b)
        self.assertEqual(w.ex(x), '\\text{a}+12.0')
        # Minus
        x = myokit.Minus(a, b)
        self.assertEqual(w.ex(x), '\\text{a}-12.0')
        # Multiply
        x = myokit.Multiply(a, b)
        self.assertEqual(w.ex(x), '\\text{a}*12.0')
        # Divide
        x = myokit.Divide(a, b)
        self.assertEqual(w.ex(x), '\\frac{\\text{a}}{12.0}')

        # Quotient
        # Not supported in latex!
        x = myokit.Quotient(a, b)
        self.assertEqual(
            w.ex(x), '\\left\\lfloor\\frac{\\text{a}}{12.0}\\right\\rfloor')
        # Remainder
        x = myokit.Remainder(a, b)
        self.assertEqual(w.ex(x), '\\bmod\\left(\\text{a},12.0\\right)')

        # Power
        x = myokit.Power(a, b)
        self.assertEqual(w.ex(x), '\\text{a}^{12.0}')
        # Power with brackets
        x = myokit.Power(myokit.Plus(a, b), b)
        self.assertEqual(w.ex(x), '\\left(\\text{a}+12.0\\right)^{12.0}')
        # Sqrt
        x = myokit.Sqrt(b)
        self.assertEqual(w.ex(x), '\\sqrt{12.0}')
        # Exp
        x = myokit.Exp(a)
        self.assertEqual(w.ex(x), '\\exp\\left(\\text{a}\\right)')
        # Log(a)
        x = myokit.Log(b)
        self.assertEqual(w.ex(x), '\\log\\left(12.0\\right)')
        # Log(a, b)
        x = myokit.Log(a, b)
        self.assertEqual(w.ex(x), '\\log_{12.0}\\left(\\text{a}\\right)')
        # Log10
        x = myokit.Log10(b)
        self.assertEqual(w.ex(x), '\\log_{10.0}\\left(12.0\\right)')

        # Sin
        x = myokit.Sin(b)
        self.assertEqual(w.ex(x), '\\sin\\left(12.0\\right)')
        # Cos
        x = myokit.Cos(b)
        self.assertEqual(w.ex(x), '\\cos\\left(12.0\\right)')
        # Tan
        x = myokit.Tan(b)
        self.assertEqual(w.ex(x), '\\tan\\left(12.0\\right)')
        # ASin
        x = myokit.ASin(b)
        self.assertEqual(w.ex(x), '\\arcsin\\left(12.0\\right)')
        # ACos
        x = myokit.ACos(b)
        self.assertEqual(w.ex(x), '\\arccos\\left(12.0\\right)')
        # ATan
        x = myokit.ATan(b)
        self.assertEqual(w.ex(x), '\\arctan\\left(12.0\\right)')

        # Floor
        x = myokit.Floor(b)
        self.assertEqual(w.ex(x), '\\left\\lfloor{12.0}\\right\\rfloor')
        # Ceil
        x = myokit.Ceil(b)
        self.assertEqual(w.ex(x), '\\left\\lceil{12.0}\\right\\rceil')
        # Abs
        x = myokit.Abs(b)
        self.assertEqual(w.ex(x), '\\lvert{12.0}\\rvert')

        # Equal
        x = myokit.Equal(a, b)
        self.assertEqual(w.ex(x), '\\left(\\text{a}=12.0\\right)')
        # NotEqual
        x = myokit.NotEqual(a, b)
        self.assertEqual(w.ex(x), '\\left(\\text{a}\\neq12.0\\right)')
        # More
        x = myokit.More(a, b)
        self.assertEqual(w.ex(x), '\\left(\\text{a}>12.0\\right)')
        # Less
        x = myokit.Less(a, b)
        self.assertEqual(w.ex(x), '\\left(\\text{a}<12.0\\right)')
        # MoreEqual
        x = myokit.MoreEqual(a, b)
        self.assertEqual(w.ex(x), '\\left(\\text{a}\\geq12.0\\right)')
        # LessEqual
        x = myokit.LessEqual(a, b)
        self.assertEqual(w.ex(x), '\\left(\\text{a}\\leq12.0\\right)')

        # Not
        cond1 = myokit.parse_expression('5 > 3')
        cond2 = myokit.parse_expression('2 < 1')
        x = myokit.Not(cond1)
        self.assertEqual(w.ex(x), '\\not\\left(\\left(5.0>3.0\\right)\\right)')
        # And
        x = myokit.And(cond1, cond2)
        self.assertEqual(
            w.ex(x), '\\left(\\left(5.0>3.0\\right)\\and'
            '\\left(2.0<1.0\\right)\\right)')
        # Or
        x = myokit.Or(cond1, cond2)
        self.assertEqual(
            w.ex(x), '\\left(\\left(5.0>3.0\\right)\\or'
            '\\left(2.0<1.0\\right)\\right)')
        # If
        x = myokit.If(cond1, a, b)
        self.assertEqual(
            w.ex(x), 'if\\left(\\left(5.0>3.0\\right),\\text{a},12.0\\right)')
        # Piecewise
        c = myokit.Number(1)
        x = myokit.Piecewise(cond1, a, cond2, b, c)
        self.assertEqual(
            w.ex(x), 'piecewise\\left(\\left(5.0>3.0\\right),\\text{a},'
            '\\left(2.0<1.0\\right),12.0,1.0\\right)')

        # Test fetching using ewriter method
        w = myokit.formats.ewriter('latex')
        self.assertIsInstance(w, myokit.formats.latex.LatexExpressionWriter)

        # Test without a Myokit expression
        self.assertRaisesRegex(ValueError, 'Unknown expression type', w.ex, 7)
Esempio n. 21
0
    def test_all(self):
        # Single and double precision
        ws = myokit.formats.cuda.CudaExpressionWriter()
        wd = myokit.formats.cuda.CudaExpressionWriter(myokit.DOUBLE_PRECISION)

        model = myokit.Model()
        component = model.add_component('c')
        avar = component.add_variable('a')

        # Name
        a = myokit.Name(avar)
        self.assertEqual(ws.ex(a), 'c.a')
        self.assertEqual(wd.ex(a), 'c.a')
        # Number with unit
        b = myokit.Number('12', 'pF')
        self.assertEqual(ws.ex(b), '12.0f')
        self.assertEqual(wd.ex(b), '12.0')

        # Prefix plus
        x = myokit.PrefixPlus(b)
        self.assertEqual(ws.ex(x), '12.0f')
        self.assertEqual(wd.ex(x), '12.0')
        # Prefix minus
        x = myokit.PrefixMinus(b)
        self.assertEqual(ws.ex(x), '(-12.0f)')
        self.assertEqual(wd.ex(x), '(-12.0)')

        # Plus
        x = myokit.Plus(a, b)
        self.assertEqual(ws.ex(x), 'c.a + 12.0f')
        self.assertEqual(wd.ex(x), 'c.a + 12.0')
        # Minus
        x = myokit.Minus(a, b)
        self.assertEqual(ws.ex(x), 'c.a - 12.0f')
        self.assertEqual(wd.ex(x), 'c.a - 12.0')
        # Multiply
        x = myokit.Multiply(a, b)
        self.assertEqual(ws.ex(x), 'c.a * 12.0f')
        self.assertEqual(wd.ex(x), 'c.a * 12.0')
        # Divide
        x = myokit.Divide(a, b)
        self.assertEqual(ws.ex(x), 'c.a / 12.0f')
        self.assertEqual(wd.ex(x), 'c.a / 12.0')

        # Quotient
        x = myokit.Quotient(a, b)
        self.assertEqual(ws.ex(x), 'floorf(c.a / 12.0f)')
        self.assertEqual(wd.ex(x), 'floor(c.a / 12.0)')
        # Remainder
        x = myokit.Remainder(a, b)
        self.assertEqual(ws.ex(x), 'c.a - 12.0f * (floorf(c.a / 12.0f))')
        self.assertEqual(wd.ex(x), 'c.a - 12.0 * (floor(c.a / 12.0))')

        # Power
        x = myokit.Power(a, b)
        self.assertEqual(ws.ex(x), 'powf(c.a, 12.0f)')
        self.assertEqual(wd.ex(x), 'pow(c.a, 12.0)')
        # Square
        x = myokit.Power(a, myokit.Number(2))
        self.assertEqual(ws.ex(x), '(c.a * c.a)')
        self.assertEqual(wd.ex(x), '(c.a * c.a)')
        # Square with brackets
        x = myokit.Power(myokit.Plus(a, b), myokit.Number(2))
        self.assertEqual(ws.ex(x), '((c.a + 12.0f) * (c.a + 12.0f))')
        self.assertEqual(wd.ex(x), '((c.a + 12.0) * (c.a + 12.0))')
        # Sqrt
        x = myokit.Sqrt(b)
        self.assertEqual(ws.ex(x), 'sqrtf(12.0f)')
        self.assertEqual(wd.ex(x), 'sqrt(12.0)')
        # Exp
        x = myokit.Exp(a)
        self.assertEqual(ws.ex(x), 'expf(c.a)')
        self.assertEqual(wd.ex(x), 'exp(c.a)')
        # Log(a)
        x = myokit.Log(b)
        self.assertEqual(ws.ex(x), 'logf(12.0f)')
        self.assertEqual(wd.ex(x), 'log(12.0)')
        # Log(a, b)
        x = myokit.Log(a, b)
        self.assertEqual(ws.ex(x), '(logf(c.a) / logf(12.0f))')
        self.assertEqual(wd.ex(x), '(log(c.a) / log(12.0))')
        # Log10
        x = myokit.Log10(b)
        self.assertEqual(ws.ex(x), 'log10f(12.0f)')
        self.assertEqual(wd.ex(x), 'log10(12.0)')

        # Sin
        x = myokit.Sin(b)
        self.assertEqual(ws.ex(x), 'sinf(12.0f)')
        self.assertEqual(wd.ex(x), 'sin(12.0)')
        # Cos
        x = myokit.Cos(b)
        self.assertEqual(ws.ex(x), 'cosf(12.0f)')
        self.assertEqual(wd.ex(x), 'cos(12.0)')
        # Tan
        x = myokit.Tan(b)
        self.assertEqual(ws.ex(x), 'tanf(12.0f)')
        self.assertEqual(wd.ex(x), 'tan(12.0)')
        # ASin
        x = myokit.ASin(b)
        self.assertEqual(ws.ex(x), 'asinf(12.0f)')
        self.assertEqual(wd.ex(x), 'asin(12.0)')
        # ACos
        x = myokit.ACos(b)
        self.assertEqual(ws.ex(x), 'acosf(12.0f)')
        self.assertEqual(wd.ex(x), 'acos(12.0)')
        # ATan
        x = myokit.ATan(b)
        self.assertEqual(ws.ex(x), 'atanf(12.0f)')
        self.assertEqual(wd.ex(x), 'atan(12.0)')

        # Floor
        x = myokit.Floor(b)
        self.assertEqual(ws.ex(x), 'floorf(12.0f)')
        self.assertEqual(wd.ex(x), 'floor(12.0)')
        # Ceil
        x = myokit.Ceil(b)
        self.assertEqual(ws.ex(x), 'ceilf(12.0f)')
        self.assertEqual(wd.ex(x), 'ceil(12.0)')
        # Abs
        x = myokit.Abs(b)
        self.assertEqual(ws.ex(x), 'fabsf(12.0f)')
        self.assertEqual(wd.ex(x), 'fabs(12.0)')

        # Equal
        x = myokit.Equal(a, b)
        self.assertEqual(ws.ex(x), '(c.a == 12.0f)')
        self.assertEqual(wd.ex(x), '(c.a == 12.0)')
        # NotEqual
        x = myokit.NotEqual(a, b)
        self.assertEqual(ws.ex(x), '(c.a != 12.0f)')
        self.assertEqual(wd.ex(x), '(c.a != 12.0)')
        # More
        x = myokit.More(a, b)
        self.assertEqual(ws.ex(x), '(c.a > 12.0f)')
        self.assertEqual(wd.ex(x), '(c.a > 12.0)')
        # Less
        x = myokit.Less(a, b)
        self.assertEqual(ws.ex(x), '(c.a < 12.0f)')
        self.assertEqual(wd.ex(x), '(c.a < 12.0)')
        # MoreEqual
        x = myokit.MoreEqual(a, b)
        self.assertEqual(ws.ex(x), '(c.a >= 12.0f)')
        self.assertEqual(wd.ex(x), '(c.a >= 12.0)')
        # LessEqual
        x = myokit.LessEqual(a, b)
        self.assertEqual(ws.ex(x), '(c.a <= 12.0f)')
        self.assertEqual(wd.ex(x), '(c.a <= 12.0)')

        # Not
        cond1 = myokit.parse_expression('5 > 3')
        cond2 = myokit.parse_expression('2 < 1')
        x = myokit.Not(cond1)
        self.assertEqual(ws.ex(x), '!((5.0f > 3.0f))')
        self.assertEqual(wd.ex(x), '!((5.0 > 3.0))')
        # And
        x = myokit.And(cond1, cond2)
        self.assertEqual(ws.ex(x), '((5.0f > 3.0f) && (2.0f < 1.0f))')
        self.assertEqual(wd.ex(x), '((5.0 > 3.0) && (2.0 < 1.0))')
        # Or
        x = myokit.Or(cond1, cond2)
        self.assertEqual(ws.ex(x), '((5.0f > 3.0f) || (2.0f < 1.0f))')
        self.assertEqual(wd.ex(x), '((5.0 > 3.0) || (2.0 < 1.0))')

        # If
        x = myokit.If(cond1, a, b)
        self.assertEqual(ws.ex(x), '((5.0f > 3.0f) ? c.a : 12.0f)')
        self.assertEqual(wd.ex(x), '((5.0 > 3.0) ? c.a : 12.0)')
        # Piecewise
        c = myokit.Number(1)
        x = myokit.Piecewise(cond1, a, cond2, b, c)
        self.assertEqual(
            ws.ex(x), '((5.0f > 3.0f) ? c.a : ((2.0f < 1.0f) ? 12.0f : 1.0f))')
        self.assertEqual(wd.ex(x),
                         '((5.0 > 3.0) ? c.a : ((2.0 < 1.0) ? 12.0 : 1.0))')

        # Test fetching using ewriter method
        w = myokit.formats.ewriter('cuda')
        self.assertIsInstance(w, myokit.formats.cuda.CudaExpressionWriter)

        # Test without a Myokit expression
        self.assertRaisesRegex(ValueError, 'Unknown expression type', w.ex, 7)