myokit 1.36.1__py3-none-any.whl → 1.37.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- myokit/__init__.py +6 -19
- myokit/_datablock.py +45 -55
- myokit/_datalog.py +2 -2
- myokit/_err.py +26 -3
- myokit/_expressions.py +241 -127
- myokit/_model_api.py +19 -13
- myokit/_myokit_version.py +1 -1
- myokit/_sim/jacobian.py +3 -3
- myokit/_sim/openclsim.py +5 -5
- myokit/_sim/rhs.py +1 -1
- myokit/formats/__init__.py +4 -9
- myokit/formats/ansic/_ewriter.py +4 -20
- myokit/formats/heka/_patchmaster.py +16 -10
- myokit/formats/opencl/_ewriter.py +3 -42
- myokit/formats/opencl/template/minilog.py +1 -1
- myokit/formats/sympy/_ereader.py +2 -1
- myokit/formats/wcp/_wcp.py +3 -3
- myokit/gui/datalog_viewer.py +12 -7
- myokit/lib/markov.py +2 -2
- myokit/lib/plots.py +4 -4
- myokit/tests/data/formats/wcp-file-empty.wcp +0 -0
- myokit/tests/test_datablock.py +10 -10
- myokit/tests/test_datalog.py +4 -1
- myokit/tests/test_expressions.py +532 -251
- myokit/tests/test_formats_ansic.py +6 -18
- myokit/tests/test_formats_cpp.py +0 -5
- myokit/tests/test_formats_cuda.py +7 -15
- myokit/tests/test_formats_easyml.py +4 -9
- myokit/tests/test_formats_latex.py +10 -11
- myokit/tests/test_formats_matlab.py +0 -8
- myokit/tests/test_formats_opencl.py +0 -29
- myokit/tests/test_formats_python.py +2 -19
- myokit/tests/test_formats_stan.py +0 -13
- myokit/tests/test_formats_sympy.py +3 -3
- myokit/tests/test_formats_wcp.py +15 -0
- myokit/tests/test_model.py +20 -20
- myokit/tests/test_parsing.py +19 -0
- {myokit-1.36.1.dist-info → myokit-1.37.0.dist-info}/METADATA +1 -1
- {myokit-1.36.1.dist-info → myokit-1.37.0.dist-info}/RECORD +43 -42
- {myokit-1.36.1.dist-info → myokit-1.37.0.dist-info}/LICENSE.txt +0 -0
- {myokit-1.36.1.dist-info → myokit-1.37.0.dist-info}/WHEEL +0 -0
- {myokit-1.36.1.dist-info → myokit-1.37.0.dist-info}/entry_points.txt +0 -0
- {myokit-1.36.1.dist-info → myokit-1.37.0.dist-info}/top_level.txt +0 -0
myokit/tests/test_expressions.py
CHANGED
|
@@ -415,8 +415,8 @@ class ExpressionTest(unittest.TestCase):
|
|
|
415
415
|
|
|
416
416
|
pe = myokit.parse_expression
|
|
417
417
|
self.assertFalse(pe('1 + 2 + 3').is_conditional())
|
|
418
|
-
self.assertTrue(pe('if(1, 0, 2)').is_conditional())
|
|
419
|
-
self.assertTrue(pe('1 + if(1, 0, 2)').is_conditional())
|
|
418
|
+
self.assertTrue(pe('if(1 == 2, 0, 2)').is_conditional())
|
|
419
|
+
self.assertTrue(pe('1 + if(1 == 1, 0, 2)').is_conditional())
|
|
420
420
|
|
|
421
421
|
def test_pickling_error(self):
|
|
422
422
|
# Tests pickling of expressions raises an exception
|
|
@@ -508,12 +508,6 @@ class ExpressionTest(unittest.TestCase):
|
|
|
508
508
|
p._operands = (myokit.Number(2), p)
|
|
509
509
|
self.assertRaisesRegex(myokit.IntegrityError, 'yclical', p.validate)
|
|
510
510
|
|
|
511
|
-
# Wrong type operands
|
|
512
|
-
# Again, need to hack this in so creation doesn't fault!
|
|
513
|
-
p._operands = (myokit.Number(1), 2)
|
|
514
|
-
self.assertRaisesRegex(
|
|
515
|
-
myokit.IntegrityError, 'must be other Expression', p.validate)
|
|
516
|
-
|
|
517
511
|
def test_walk(self):
|
|
518
512
|
# Test :meth:`Expression.walk().
|
|
519
513
|
|
|
@@ -1103,8 +1097,11 @@ class DerivativeTest(unittest.TestCase):
|
|
|
1103
1097
|
|
|
1104
1098
|
# Derivative of something other than a name: never allowed
|
|
1105
1099
|
self.assertRaisesRegex(
|
|
1106
|
-
myokit.
|
|
1107
|
-
myokit.Number(1))
|
|
1100
|
+
myokit.TypeError, 'requires a myokit.Name',
|
|
1101
|
+
myokit.Derivative, myokit.Number(1))
|
|
1102
|
+
self.assertRaisesRegex( # Not even another LhsExpression
|
|
1103
|
+
myokit.TypeError, 'requires a myokit.Name',
|
|
1104
|
+
myokit.Derivative, myokit.Derivative(myokit.Name(x)))
|
|
1108
1105
|
|
|
1109
1106
|
def test_bracket(self):
|
|
1110
1107
|
# Test Derivative.bracket()
|
|
@@ -1323,22 +1320,22 @@ class PartialDerivativeTest(unittest.TestCase):
|
|
|
1323
1320
|
|
|
1324
1321
|
# Others are not allowed
|
|
1325
1322
|
self.assertRaisesRegex(
|
|
1326
|
-
myokit.
|
|
1323
|
+
myokit.TypeError, 'first argument to a partial',
|
|
1327
1324
|
myokit.PartialDerivative, i, n)
|
|
1328
1325
|
self.assertRaisesRegex(
|
|
1329
|
-
myokit.
|
|
1326
|
+
myokit.TypeError, 'first argument to a partial',
|
|
1330
1327
|
myokit.PartialDerivative, myokit.Number(3), n)
|
|
1331
1328
|
self.assertRaisesRegex(
|
|
1332
|
-
myokit.
|
|
1329
|
+
myokit.TypeError, 'first argument to a partial',
|
|
1333
1330
|
myokit.PartialDerivative, myokit.PrefixPlus(n), n)
|
|
1334
1331
|
self.assertRaisesRegex(
|
|
1335
|
-
myokit.
|
|
1332
|
+
myokit.TypeError, 'second argument to a partial',
|
|
1336
1333
|
myokit.PartialDerivative, n, d)
|
|
1337
1334
|
self.assertRaisesRegex(
|
|
1338
|
-
myokit.
|
|
1335
|
+
myokit.TypeError, 'second argument to a partial',
|
|
1339
1336
|
myokit.PartialDerivative, n, myokit.Number(3))
|
|
1340
1337
|
self.assertRaisesRegex(
|
|
1341
|
-
myokit.
|
|
1338
|
+
myokit.TypeError, 'second argument to a partial',
|
|
1342
1339
|
myokit.PartialDerivative, n, myokit.PrefixPlus(n))
|
|
1343
1340
|
|
|
1344
1341
|
def test_bracket(self):
|
|
@@ -1441,13 +1438,16 @@ class InitialValueTest(unittest.TestCase):
|
|
|
1441
1438
|
|
|
1442
1439
|
# Value must be a name
|
|
1443
1440
|
self.assertRaisesRegex(
|
|
1444
|
-
myokit.
|
|
1441
|
+
myokit.TypeError, 'argument to an initial value must be a variab',
|
|
1445
1442
|
myokit.InitialValue, d)
|
|
1446
1443
|
self.assertRaisesRegex(
|
|
1447
|
-
myokit.
|
|
1444
|
+
myokit.TypeError, 'argument to an initial value must be a variab',
|
|
1445
|
+
myokit.InitialValue, i)
|
|
1446
|
+
self.assertRaisesRegex(
|
|
1447
|
+
myokit.TypeError, 'argument to an initial value must be a variab',
|
|
1448
1448
|
myokit.InitialValue, myokit.Number(3),)
|
|
1449
1449
|
self.assertRaisesRegex(
|
|
1450
|
-
myokit.
|
|
1450
|
+
myokit.TypeError, 'argument to an initial value must be a variab',
|
|
1451
1451
|
myokit.InitialValue, myokit.PrefixPlus(n))
|
|
1452
1452
|
|
|
1453
1453
|
def test_bracket(self):
|
|
@@ -1545,6 +1545,16 @@ class InitialValueTest(unittest.TestCase):
|
|
|
1545
1545
|
class PrefixPlusTest(unittest.TestCase):
|
|
1546
1546
|
"""Tests myokit.PrefixPlus."""
|
|
1547
1547
|
|
|
1548
|
+
def test_bracket(self):
|
|
1549
|
+
# Test PrefixPlus.bracket().
|
|
1550
|
+
i = myokit.Number(1)
|
|
1551
|
+
x = myokit.PrefixPlus(i)
|
|
1552
|
+
self.assertFalse(x.bracket(i))
|
|
1553
|
+
i = myokit.Plus(myokit.Number(1), myokit.Number(2))
|
|
1554
|
+
x = myokit.PrefixPlus(i)
|
|
1555
|
+
self.assertTrue(x.bracket(i))
|
|
1556
|
+
self.assertRaises(ValueError, x.bracket, myokit.Number(1))
|
|
1557
|
+
|
|
1548
1558
|
def test_clone(self):
|
|
1549
1559
|
# Test PrefixPlus.clone().
|
|
1550
1560
|
x = myokit.PrefixPlus(myokit.Number(3))
|
|
@@ -1567,15 +1577,13 @@ class PrefixPlusTest(unittest.TestCase):
|
|
|
1567
1577
|
self.assertNotEqual(x, y)
|
|
1568
1578
|
self.assertEqual(y, myokit.PrefixPlus(j))
|
|
1569
1579
|
|
|
1570
|
-
def
|
|
1571
|
-
#
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
self.
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
self.assertTrue(x.bracket(i))
|
|
1578
|
-
self.assertRaises(ValueError, x.bracket, myokit.Number(1))
|
|
1580
|
+
def test_creation(self):
|
|
1581
|
+
# Operand must be a numerical expression
|
|
1582
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
1583
|
+
myokit.PrefixPlus, 3)
|
|
1584
|
+
self.assertRaisesRegex(
|
|
1585
|
+
myokit.TypeError, 'expected a numerical', myokit.PrefixPlus,
|
|
1586
|
+
myokit.Equal(myokit.Number(1), myokit.Number(2)))
|
|
1579
1587
|
|
|
1580
1588
|
def test_diff(self):
|
|
1581
1589
|
# Tests PrefixPlus.diff()
|
|
@@ -1648,6 +1656,17 @@ class PrefixPlusTest(unittest.TestCase):
|
|
|
1648
1656
|
class PrefixMinusTest(unittest.TestCase):
|
|
1649
1657
|
"""Tests myokit.PrefixMinus."""
|
|
1650
1658
|
|
|
1659
|
+
def test_bracket(self):
|
|
1660
|
+
# Test PrefixMinus.bracket().
|
|
1661
|
+
|
|
1662
|
+
i = myokit.Number(1)
|
|
1663
|
+
x = myokit.PrefixMinus(i)
|
|
1664
|
+
self.assertFalse(x.bracket(i))
|
|
1665
|
+
i = myokit.Plus(myokit.Number(1), myokit.Number(2))
|
|
1666
|
+
x = myokit.PrefixMinus(i)
|
|
1667
|
+
self.assertTrue(x.bracket(i))
|
|
1668
|
+
self.assertRaises(ValueError, x.bracket, myokit.Number(1))
|
|
1669
|
+
|
|
1651
1670
|
def test_clone(self):
|
|
1652
1671
|
# Test PrefixMinus.clone().
|
|
1653
1672
|
x = myokit.PrefixMinus(myokit.Number(3))
|
|
@@ -1670,16 +1689,13 @@ class PrefixMinusTest(unittest.TestCase):
|
|
|
1670
1689
|
self.assertNotEqual(x, y)
|
|
1671
1690
|
self.assertEqual(y, myokit.PrefixMinus(j))
|
|
1672
1691
|
|
|
1673
|
-
def
|
|
1674
|
-
#
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
x = myokit.PrefixMinus(i)
|
|
1681
|
-
self.assertTrue(x.bracket(i))
|
|
1682
|
-
self.assertRaises(ValueError, x.bracket, myokit.Number(1))
|
|
1692
|
+
def test_creation(self):
|
|
1693
|
+
# Operand must be an expression
|
|
1694
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
1695
|
+
myokit.PrefixMinus, 'test')
|
|
1696
|
+
self.assertRaisesRegex(
|
|
1697
|
+
myokit.TypeError, 'expected a numerical', myokit.PrefixMinus,
|
|
1698
|
+
myokit.Equal(myokit.Number(1), myokit.Number(2)))
|
|
1683
1699
|
|
|
1684
1700
|
def test_diff(self):
|
|
1685
1701
|
# Tests PrefixMinus.diff()
|
|
@@ -1752,6 +1768,15 @@ class PrefixMinusTest(unittest.TestCase):
|
|
|
1752
1768
|
class PlusTest(unittest.TestCase):
|
|
1753
1769
|
"""Tests myokit.Plus."""
|
|
1754
1770
|
|
|
1771
|
+
def test_bracket(self):
|
|
1772
|
+
# Test Plus.bracket().
|
|
1773
|
+
i = myokit.Number(1)
|
|
1774
|
+
j = myokit.parse_expression('1 + 2')
|
|
1775
|
+
x = myokit.Plus(i, j)
|
|
1776
|
+
self.assertFalse(x.bracket(i))
|
|
1777
|
+
self.assertTrue(x.bracket(j))
|
|
1778
|
+
self.assertRaises(ValueError, x.bracket, myokit.Number(3))
|
|
1779
|
+
|
|
1755
1780
|
def test_clone(self):
|
|
1756
1781
|
# Test Plus.clone().
|
|
1757
1782
|
i = myokit.Number(3)
|
|
@@ -1777,14 +1802,17 @@ class PlusTest(unittest.TestCase):
|
|
|
1777
1802
|
self.assertNotEqual(x, y)
|
|
1778
1803
|
self.assertEqual(y, myokit.Plus(i, i))
|
|
1779
1804
|
|
|
1780
|
-
def
|
|
1781
|
-
#
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
self.
|
|
1786
|
-
|
|
1787
|
-
|
|
1805
|
+
def test_creation(self):
|
|
1806
|
+
# Operands must be numerical expressions
|
|
1807
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
1808
|
+
myokit.Plus, 'toast', 4)
|
|
1809
|
+
a = myokit.Equal(myokit.Number(1), myokit.Number(2))
|
|
1810
|
+
self.assertRaisesRegex(
|
|
1811
|
+
myokit.TypeError, 'first operand: expected a numerical',
|
|
1812
|
+
myokit.Plus, a, myokit.Number(1))
|
|
1813
|
+
self.assertRaisesRegex(
|
|
1814
|
+
myokit.TypeError, 'second operand: expected a numerical',
|
|
1815
|
+
myokit.Plus, myokit.Number(1), a)
|
|
1788
1816
|
|
|
1789
1817
|
def test_diff(self):
|
|
1790
1818
|
# Tests Plus.diff()
|
|
@@ -1903,9 +1931,20 @@ class PlusTest(unittest.TestCase):
|
|
|
1903
1931
|
class MinusTest(unittest.TestCase):
|
|
1904
1932
|
"""Tests myokit.Minus."""
|
|
1905
1933
|
|
|
1934
|
+
def test_creation(self):
|
|
1935
|
+
# Operands must be numerical expressions
|
|
1936
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
1937
|
+
myokit.Minus, 7, None)
|
|
1938
|
+
a = myokit.NotEqual(myokit.Number(3), myokit.Number(2))
|
|
1939
|
+
self.assertRaisesRegex(
|
|
1940
|
+
myokit.TypeError, 'first operand: expected a numerical',
|
|
1941
|
+
myokit.Minus, a, myokit.Number(3))
|
|
1942
|
+
self.assertRaisesRegex(
|
|
1943
|
+
myokit.TypeError, 'second operand: expected a numerical',
|
|
1944
|
+
myokit.Minus, myokit.Number(3), a)
|
|
1945
|
+
|
|
1906
1946
|
def test_diff(self):
|
|
1907
1947
|
# Tests Minus.diff()
|
|
1908
|
-
|
|
1909
1948
|
m = pd_model.clone()
|
|
1910
1949
|
V = m.get('membrane.V')
|
|
1911
1950
|
g = m.get('ina.g')
|
|
@@ -2002,9 +2041,20 @@ class MinusTest(unittest.TestCase):
|
|
|
2002
2041
|
class MultiplyTest(unittest.TestCase):
|
|
2003
2042
|
"""Tests myokit.Multiply."""
|
|
2004
2043
|
|
|
2044
|
+
def test_creation(self):
|
|
2045
|
+
# Operands must be expressions
|
|
2046
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
2047
|
+
myokit.Multiply, 15, 3)
|
|
2048
|
+
a = myokit.Equal(myokit.Number(1), myokit.Number(2))
|
|
2049
|
+
self.assertRaisesRegex(
|
|
2050
|
+
myokit.TypeError, 'first operand: expected a numerical',
|
|
2051
|
+
myokit.Multiply, a, myokit.Number(1))
|
|
2052
|
+
self.assertRaisesRegex(
|
|
2053
|
+
myokit.TypeError, 'second operand: expected a numerical',
|
|
2054
|
+
myokit.Multiply, myokit.Number(1), a)
|
|
2055
|
+
|
|
2005
2056
|
def test_diff(self):
|
|
2006
2057
|
# Tests Multiply.diff()
|
|
2007
|
-
|
|
2008
2058
|
m = pd_model.clone()
|
|
2009
2059
|
V = m.get('membrane.V')
|
|
2010
2060
|
g = m.get('ina.g')
|
|
@@ -2091,9 +2141,20 @@ class MultiplyTest(unittest.TestCase):
|
|
|
2091
2141
|
class DivideTest(unittest.TestCase):
|
|
2092
2142
|
"""Tests myokit.Divide."""
|
|
2093
2143
|
|
|
2144
|
+
def test_creation(self):
|
|
2145
|
+
# Operands must be expressions
|
|
2146
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
2147
|
+
myokit.Divide, 15, 3)
|
|
2148
|
+
a = myokit.Equal(myokit.Number(1), myokit.Number(2))
|
|
2149
|
+
self.assertRaisesRegex(
|
|
2150
|
+
myokit.TypeError, 'first operand: expected a numerical',
|
|
2151
|
+
myokit.Divide, a, myokit.Number(1))
|
|
2152
|
+
self.assertRaisesRegex(
|
|
2153
|
+
myokit.TypeError, 'second operand: expected a numerical',
|
|
2154
|
+
myokit.Divide, myokit.Number(1), a)
|
|
2155
|
+
|
|
2094
2156
|
def test_diff(self):
|
|
2095
2157
|
# Tests Divide.diff()
|
|
2096
|
-
|
|
2097
2158
|
m = pd_model.clone()
|
|
2098
2159
|
V = m.get('membrane.V')
|
|
2099
2160
|
g = m.get('ina.g')
|
|
@@ -2180,6 +2241,18 @@ class DivideTest(unittest.TestCase):
|
|
|
2180
2241
|
class QuotientTest(unittest.TestCase):
|
|
2181
2242
|
"""Tests myokit.Quotient."""
|
|
2182
2243
|
|
|
2244
|
+
def test_creation(self):
|
|
2245
|
+
# Operands must be expressions
|
|
2246
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
2247
|
+
myokit.Quotient, 15, 3)
|
|
2248
|
+
a = myokit.Equal(myokit.Number(1), myokit.Number(2))
|
|
2249
|
+
self.assertRaisesRegex(
|
|
2250
|
+
myokit.TypeError, 'first operand: expected a numerical',
|
|
2251
|
+
myokit.Quotient, a, myokit.Number(1))
|
|
2252
|
+
self.assertRaisesRegex(
|
|
2253
|
+
myokit.TypeError, 'second operand: expected a numerical',
|
|
2254
|
+
myokit.Quotient, myokit.Number(1), a)
|
|
2255
|
+
|
|
2183
2256
|
def test_diff(self):
|
|
2184
2257
|
# Tests Quotient.diff()
|
|
2185
2258
|
|
|
@@ -2256,6 +2329,18 @@ class QuotientTest(unittest.TestCase):
|
|
|
2256
2329
|
class RemainderTest(unittest.TestCase):
|
|
2257
2330
|
"""Tests myokit.Remainder."""
|
|
2258
2331
|
|
|
2332
|
+
def test_creation(self):
|
|
2333
|
+
# Operands must be expressions
|
|
2334
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
2335
|
+
myokit.Remainder, myokit.Number(3), 3)
|
|
2336
|
+
a = myokit.MoreEqual(myokit.Number(1.1), myokit.Number(2.1))
|
|
2337
|
+
self.assertRaisesRegex(
|
|
2338
|
+
myokit.TypeError, 'first operand: expected a numerical',
|
|
2339
|
+
myokit.Remainder, a, myokit.Number(1.3))
|
|
2340
|
+
self.assertRaisesRegex(
|
|
2341
|
+
myokit.TypeError, 'second operand: expected a numerical',
|
|
2342
|
+
myokit.Remainder, myokit.Number(-1.2), a)
|
|
2343
|
+
|
|
2259
2344
|
def test_diff(self):
|
|
2260
2345
|
# Tests Remainder.diff()
|
|
2261
2346
|
|
|
@@ -2380,6 +2465,18 @@ class PowerTest(unittest.TestCase):
|
|
|
2380
2465
|
self.assertNotEqual(x, y)
|
|
2381
2466
|
self.assertEqual(y, myokit.Power(i, i))
|
|
2382
2467
|
|
|
2468
|
+
def test_creation(self):
|
|
2469
|
+
# Operands must be expressions
|
|
2470
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
2471
|
+
myokit.Power, myokit.Number(3), 3)
|
|
2472
|
+
a = myokit.Less(myokit.Number(1), myokit.Number(2))
|
|
2473
|
+
self.assertRaisesRegex(
|
|
2474
|
+
myokit.TypeError, 'first operand: expected a numerical',
|
|
2475
|
+
myokit.Power, a, myokit.Number(2))
|
|
2476
|
+
self.assertRaisesRegex(
|
|
2477
|
+
myokit.TypeError, 'second operand: expected a numerical',
|
|
2478
|
+
myokit.Power, myokit.Number(3.2), a)
|
|
2479
|
+
|
|
2383
2480
|
def test_diff(self):
|
|
2384
2481
|
# Tests Power.diff()
|
|
2385
2482
|
|
|
@@ -2506,13 +2603,6 @@ class SqrtTest(unittest.TestCase):
|
|
|
2506
2603
|
self.assertFalse(x.bracket(j))
|
|
2507
2604
|
self.assertRaises(ValueError, x.bracket, myokit.Number(3))
|
|
2508
2605
|
|
|
2509
|
-
def test_creation(self):
|
|
2510
|
-
# Test Sqrt creation.
|
|
2511
|
-
myokit.Sqrt(myokit.Number(1))
|
|
2512
|
-
self.assertRaisesRegex(
|
|
2513
|
-
myokit.IntegrityError, 'wrong number', myokit.Sqrt,
|
|
2514
|
-
myokit.Number(1), myokit.Number(2))
|
|
2515
|
-
|
|
2516
2606
|
def test_clone(self):
|
|
2517
2607
|
# Test Sqrt.clone().
|
|
2518
2608
|
i = myokit.Number(3)
|
|
@@ -2534,6 +2624,21 @@ class SqrtTest(unittest.TestCase):
|
|
|
2534
2624
|
self.assertNotEqual(x, y)
|
|
2535
2625
|
self.assertEqual(y, z)
|
|
2536
2626
|
|
|
2627
|
+
def test_creation(self):
|
|
2628
|
+
myokit.Sqrt(myokit.Number(1))
|
|
2629
|
+
|
|
2630
|
+
# Wrong number of operands
|
|
2631
|
+
self.assertRaisesRegex(
|
|
2632
|
+
myokit.IntegrityError, 'wrong number', myokit.Sqrt,
|
|
2633
|
+
myokit.Number(1), myokit.Number(2))
|
|
2634
|
+
|
|
2635
|
+
# Operand must be a numerical expression
|
|
2636
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
2637
|
+
myokit.Sqrt, False)
|
|
2638
|
+
self.assertRaisesRegex(
|
|
2639
|
+
myokit.TypeError, r'sqrt\(\) expects a numerical operand',
|
|
2640
|
+
myokit.Sqrt, myokit.Equal(myokit.Number(1), myokit.Number(2)))
|
|
2641
|
+
|
|
2537
2642
|
def test_diff(self):
|
|
2538
2643
|
# Tests Sqrt.diff()
|
|
2539
2644
|
|
|
@@ -2635,10 +2740,19 @@ class ExpTest(unittest.TestCase):
|
|
|
2635
2740
|
def test_creation(self):
|
|
2636
2741
|
# Test Exp creation.
|
|
2637
2742
|
myokit.Exp(myokit.Number(1))
|
|
2743
|
+
|
|
2744
|
+
# Wrong number of operands
|
|
2638
2745
|
self.assertRaisesRegex(
|
|
2639
2746
|
myokit.IntegrityError, 'wrong number', myokit.Exp,
|
|
2640
2747
|
myokit.Number(1), myokit.Number(2))
|
|
2641
2748
|
|
|
2749
|
+
# Operand must be a numerical expression
|
|
2750
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
2751
|
+
myokit.Exp, 1.2)
|
|
2752
|
+
self.assertRaisesRegex(
|
|
2753
|
+
myokit.TypeError, r'Function exp\(\) expects a numerical operand',
|
|
2754
|
+
myokit.Exp, myokit.Equal(myokit.Number(1), myokit.Number(2)))
|
|
2755
|
+
|
|
2642
2756
|
def test_diff(self):
|
|
2643
2757
|
# Tests Exp.diff()
|
|
2644
2758
|
|
|
@@ -2785,10 +2899,28 @@ class LogTest(unittest.TestCase):
|
|
|
2785
2899
|
# Test Log creation.
|
|
2786
2900
|
myokit.Log(myokit.Number(1))
|
|
2787
2901
|
myokit.Log(myokit.Number(1), myokit.Number(2))
|
|
2902
|
+
|
|
2903
|
+
# Wrong number of operatnds
|
|
2788
2904
|
self.assertRaisesRegex(
|
|
2789
2905
|
myokit.IntegrityError, 'wrong number', myokit.Log,
|
|
2790
2906
|
myokit.Number(1), myokit.Number(2), myokit.Number(3))
|
|
2791
2907
|
|
|
2908
|
+
# Operands must be numerical expressions
|
|
2909
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
2910
|
+
myokit.Log, 1.2)
|
|
2911
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
2912
|
+
myokit.Log, myokit.Number(3), 1.2)
|
|
2913
|
+
a = myokit.Equal(myokit.Number(1), myokit.Number(2))
|
|
2914
|
+
self.assertRaisesRegex(
|
|
2915
|
+
myokit.TypeError, r'first operand: function log\(\) expects numer',
|
|
2916
|
+
myokit.Log, a)
|
|
2917
|
+
self.assertRaisesRegex(
|
|
2918
|
+
myokit.TypeError, r'first operand: function log\(\) expects numer',
|
|
2919
|
+
myokit.Log, a, myokit.Number(1))
|
|
2920
|
+
self.assertRaisesRegex(
|
|
2921
|
+
myokit.TypeError, r'second operand: function log\(\) expects nume',
|
|
2922
|
+
myokit.Log, myokit.Number(1), a)
|
|
2923
|
+
|
|
2792
2924
|
def test_diff(self):
|
|
2793
2925
|
# Tests Log.diff()
|
|
2794
2926
|
|
|
@@ -2918,6 +3050,14 @@ class LogTest(unittest.TestCase):
|
|
|
2918
3050
|
class Log10Test(unittest.TestCase):
|
|
2919
3051
|
"""Tests myokit.Log10."""
|
|
2920
3052
|
|
|
3053
|
+
def test_creation(self):
|
|
3054
|
+
# Operand must be a numerical expression
|
|
3055
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
3056
|
+
myokit.Log10, 1.2)
|
|
3057
|
+
self.assertRaisesRegex(
|
|
3058
|
+
myokit.TypeError, r'log10\(\) expects a numerical operand',
|
|
3059
|
+
myokit.Log10, myokit.Equal(myokit.Number(1), myokit.Number(2)))
|
|
3060
|
+
|
|
2921
3061
|
def test_diff(self):
|
|
2922
3062
|
# Tests Log10.diff()
|
|
2923
3063
|
|
|
@@ -2948,6 +3088,14 @@ class Log10Test(unittest.TestCase):
|
|
|
2948
3088
|
class SinTest(unittest.TestCase):
|
|
2949
3089
|
"""Tests myokit.Sin."""
|
|
2950
3090
|
|
|
3091
|
+
def test_creation(self):
|
|
3092
|
+
# Operand must be a numerical expression
|
|
3093
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
3094
|
+
myokit.Sin, 2.1)
|
|
3095
|
+
self.assertRaisesRegex(
|
|
3096
|
+
myokit.TypeError, r'sin\(\) expects a numerical operand',
|
|
3097
|
+
myokit.Sin, myokit.Equal(myokit.Number(1), myokit.Number(2)))
|
|
3098
|
+
|
|
2951
3099
|
def test_diff(self):
|
|
2952
3100
|
# Tests Sin.diff()
|
|
2953
3101
|
|
|
@@ -2977,6 +3125,14 @@ class SinTest(unittest.TestCase):
|
|
|
2977
3125
|
class CosTest(unittest.TestCase):
|
|
2978
3126
|
"""Tests myokit.Cos."""
|
|
2979
3127
|
|
|
3128
|
+
def test_creation(self):
|
|
3129
|
+
# Operand must be a numerical expression
|
|
3130
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
3131
|
+
myokit.Cos, myokit.Cos)
|
|
3132
|
+
self.assertRaisesRegex(
|
|
3133
|
+
myokit.TypeError, r'cos\(\) expects a numerical operand',
|
|
3134
|
+
myokit.Cos, myokit.Equal(myokit.Number(1), myokit.Number(2)))
|
|
3135
|
+
|
|
2980
3136
|
def test_diff(self):
|
|
2981
3137
|
# Tests Cos.diff()
|
|
2982
3138
|
|
|
@@ -3005,6 +3161,14 @@ class CosTest(unittest.TestCase):
|
|
|
3005
3161
|
class TanTest(unittest.TestCase):
|
|
3006
3162
|
""" Tests myokit.Tan. """
|
|
3007
3163
|
|
|
3164
|
+
def test_creation(self):
|
|
3165
|
+
# Operand must be a numerical expression
|
|
3166
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
3167
|
+
myokit.Tan, myokit.Model())
|
|
3168
|
+
self.assertRaisesRegex(
|
|
3169
|
+
myokit.TypeError, r'tan\(\) expects a numerical operand',
|
|
3170
|
+
myokit.Tan, myokit.Equal(myokit.Number(1), myokit.Number(2)))
|
|
3171
|
+
|
|
3008
3172
|
def test_diff(self):
|
|
3009
3173
|
# Tests Tan.diff()
|
|
3010
3174
|
|
|
@@ -3033,6 +3197,14 @@ class TanTest(unittest.TestCase):
|
|
|
3033
3197
|
class ASinTest(unittest.TestCase):
|
|
3034
3198
|
""" Tests myokit.ASin. """
|
|
3035
3199
|
|
|
3200
|
+
def test_creation(self):
|
|
3201
|
+
# Operand must be a numerical expression
|
|
3202
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
3203
|
+
myokit.ASin, 4)
|
|
3204
|
+
self.assertRaisesRegex(
|
|
3205
|
+
myokit.TypeError, r'asin\(\) expects a numerical operand',
|
|
3206
|
+
myokit.ASin, myokit.Equal(myokit.Number(1), myokit.Number(2)))
|
|
3207
|
+
|
|
3036
3208
|
def test_diff(self):
|
|
3037
3209
|
# Tests ASin.diff()
|
|
3038
3210
|
|
|
@@ -3062,6 +3234,14 @@ class ASinTest(unittest.TestCase):
|
|
|
3062
3234
|
class ACosTest(unittest.TestCase):
|
|
3063
3235
|
""" Tests myokit.ACos. """
|
|
3064
3236
|
|
|
3237
|
+
def test_creation(self):
|
|
3238
|
+
# Operand must be a numerical expression
|
|
3239
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
3240
|
+
myokit.ACos, 4)
|
|
3241
|
+
self.assertRaisesRegex(
|
|
3242
|
+
myokit.TypeError, r'acos\(\) expects a numerical operand',
|
|
3243
|
+
myokit.ACos, myokit.Equal(myokit.Number(1), myokit.Number(2)))
|
|
3244
|
+
|
|
3065
3245
|
def test_diff(self):
|
|
3066
3246
|
# Tests ACos.diff()
|
|
3067
3247
|
|
|
@@ -3092,6 +3272,14 @@ class ACosTest(unittest.TestCase):
|
|
|
3092
3272
|
class ATanTest(unittest.TestCase):
|
|
3093
3273
|
""" Tests myokit.ATan. """
|
|
3094
3274
|
|
|
3275
|
+
def test_creation(self):
|
|
3276
|
+
# Operand must be a numerical expression
|
|
3277
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
3278
|
+
myokit.ATan, 4)
|
|
3279
|
+
self.assertRaisesRegex(
|
|
3280
|
+
myokit.TypeError, r'atan\(\) expects a numerical operand',
|
|
3281
|
+
myokit.ATan, myokit.Equal(myokit.Number(1), myokit.Number(2)))
|
|
3282
|
+
|
|
3095
3283
|
def test_diff(self):
|
|
3096
3284
|
# Tests ATan.diff()
|
|
3097
3285
|
|
|
@@ -3122,6 +3310,15 @@ class ATanTest(unittest.TestCase):
|
|
|
3122
3310
|
class FloorTest(unittest.TestCase):
|
|
3123
3311
|
""" Tests myokit.Floor. """
|
|
3124
3312
|
|
|
3313
|
+
def test_creation(self):
|
|
3314
|
+
# Operand must be a numerical expression
|
|
3315
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
3316
|
+
myokit.Floor, 1.2)
|
|
3317
|
+
a = myokit.Equal(myokit.Number(1), myokit.Number(2))
|
|
3318
|
+
self.assertRaisesRegex(
|
|
3319
|
+
myokit.TypeError, r'floor\(\) expects a numerical operand',
|
|
3320
|
+
myokit.Floor, myokit.Equal(myokit.Number(1), myokit.Number(2)))
|
|
3321
|
+
|
|
3125
3322
|
def test_diff(self):
|
|
3126
3323
|
# Tests Floor.diff()
|
|
3127
3324
|
|
|
@@ -3173,6 +3370,14 @@ class FloorTest(unittest.TestCase):
|
|
|
3173
3370
|
class CeilTest(unittest.TestCase):
|
|
3174
3371
|
""" Tests myokit.Ceil. """
|
|
3175
3372
|
|
|
3373
|
+
def test_creation(self):
|
|
3374
|
+
# Operand must be a numerical expression
|
|
3375
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
3376
|
+
myokit.Ceil, 3.4)
|
|
3377
|
+
self.assertRaisesRegex(
|
|
3378
|
+
myokit.TypeError, r'ceil\(\) expects a numerical operand',
|
|
3379
|
+
myokit.Ceil, myokit.LessEqual(myokit.Number(3), myokit.Number(2)))
|
|
3380
|
+
|
|
3176
3381
|
def test_diff(self):
|
|
3177
3382
|
# Tests Ceil.diff()
|
|
3178
3383
|
|
|
@@ -3224,6 +3429,14 @@ class CeilTest(unittest.TestCase):
|
|
|
3224
3429
|
class AbsTest(unittest.TestCase):
|
|
3225
3430
|
""" Tests myokit.Abs. """
|
|
3226
3431
|
|
|
3432
|
+
def test_creation(self):
|
|
3433
|
+
# Operand must be a numerical expression
|
|
3434
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
3435
|
+
myokit.Abs, 3.4)
|
|
3436
|
+
self.assertRaisesRegex(
|
|
3437
|
+
myokit.TypeError, r'abs\(\) expects a numerical operand',
|
|
3438
|
+
myokit.Abs, myokit.Equal(myokit.Number(1), myokit.Number(2)))
|
|
3439
|
+
|
|
3227
3440
|
def test_diff(self):
|
|
3228
3441
|
# Tests Abs.diff()
|
|
3229
3442
|
|
|
@@ -3296,6 +3509,18 @@ class AbsTest(unittest.TestCase):
|
|
|
3296
3509
|
class EqualTest(unittest.TestCase):
|
|
3297
3510
|
""" Tests myokit.Equal. """
|
|
3298
3511
|
|
|
3512
|
+
def test_creation(self):
|
|
3513
|
+
# Operands must be numerical expressions
|
|
3514
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
3515
|
+
myokit.Equal, 1, 1)
|
|
3516
|
+
a = myokit.Equal(myokit.Number(1), myokit.Number(2))
|
|
3517
|
+
self.assertRaisesRegex(
|
|
3518
|
+
myokit.TypeError, 'first operand: expected a numerical',
|
|
3519
|
+
myokit.Equal, a, myokit.Number(1))
|
|
3520
|
+
self.assertRaisesRegex(
|
|
3521
|
+
myokit.TypeError, 'second operand: expected a numerical',
|
|
3522
|
+
myokit.Equal, myokit.Number(1), a)
|
|
3523
|
+
|
|
3299
3524
|
def test_diff(self):
|
|
3300
3525
|
# Tests Equal.diff()
|
|
3301
3526
|
x = myokit.Equal(myokit.Number(1), myokit.Number(1))
|
|
@@ -3314,58 +3539,55 @@ class EqualTest(unittest.TestCase):
|
|
|
3314
3539
|
def test_eval_unit(self):
|
|
3315
3540
|
# Test Equal.eval_unit().
|
|
3316
3541
|
|
|
3317
|
-
#
|
|
3318
|
-
m = myokit.Model()
|
|
3319
|
-
c = m.add_component('c')
|
|
3320
|
-
x = c.add_variable('x')
|
|
3321
|
-
x.set_rhs('3')
|
|
3322
|
-
y = c.add_variable('y')
|
|
3323
|
-
y.set_rhs('3')
|
|
3324
|
-
z = c.add_variable('z')
|
|
3325
|
-
z.set_rhs('x == y')
|
|
3326
|
-
|
|
3327
|
-
# Test in tolerant mode
|
|
3328
|
-
self.assertEqual(z.rhs().eval_unit(), None)
|
|
3329
|
-
x.set_unit(myokit.units.ampere)
|
|
3330
|
-
self.assertEqual(z.rhs().eval_unit(), myokit.units.dimensionless)
|
|
3331
|
-
y.set_unit(myokit.units.ampere)
|
|
3332
|
-
self.assertEqual(z.rhs().eval_unit(), myokit.units.dimensionless)
|
|
3333
|
-
y.set_unit(myokit.units.volt)
|
|
3334
|
-
self.assertRaisesRegex(
|
|
3335
|
-
myokit.IncompatibleUnitError, 'equal units', z.rhs().eval_unit)
|
|
3336
|
-
x.set_unit(None)
|
|
3337
|
-
self.assertEqual(z.rhs().eval_unit(), myokit.units.dimensionless)
|
|
3338
|
-
y.set_unit(None)
|
|
3339
|
-
self.assertEqual(z.rhs().eval_unit(), None)
|
|
3340
|
-
|
|
3341
|
-
# Test in strict mode
|
|
3542
|
+
# None and None is always fine
|
|
3342
3543
|
s = myokit.UNIT_STRICT
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
self.
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
self.
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
self.
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3544
|
+
e = myokit.Equal(myokit.Number(1), myokit.Number(2))
|
|
3545
|
+
d = myokit.units.dimensionless
|
|
3546
|
+
self.assertEqual(e.eval_unit(), d)
|
|
3547
|
+
self.assertEqual(e.eval_unit(s), d)
|
|
3548
|
+
# None and dimensionless is always fine
|
|
3549
|
+
e = myokit.Equal(myokit.Number(1), myokit.Number(2, d))
|
|
3550
|
+
self.assertEqual(e.eval_unit(), d)
|
|
3551
|
+
self.assertEqual(e.eval_unit(s), d)
|
|
3552
|
+
# Equal is always fine
|
|
3553
|
+
e = myokit.Equal(myokit.Number(1, d), myokit.Number(2, d))
|
|
3554
|
+
self.assertEqual(e.eval_unit(), d)
|
|
3555
|
+
self.assertEqual(e.eval_unit(s), d)
|
|
3556
|
+
a = myokit.units.ampere
|
|
3557
|
+
e = myokit.Equal(myokit.Number(1, a), myokit.Number(2, a))
|
|
3558
|
+
self.assertEqual(e.eval_unit(), d)
|
|
3559
|
+
self.assertEqual(e.eval_unit(s), d)
|
|
3560
|
+
# Unequal is never fine
|
|
3561
|
+
e = myokit.Equal(myokit.Number(1, d), myokit.Number(2, a))
|
|
3562
|
+
self.assertRaises(myokit.IncompatibleUnitError, e.eval_unit)
|
|
3563
|
+
self.assertRaises(myokit.IncompatibleUnitError, e.eval_unit, s)
|
|
3564
|
+
# One None one not-dimensionless is only fine in tolerant mode
|
|
3565
|
+
e = myokit.Equal(myokit.Number(1, a), myokit.Number(2))
|
|
3566
|
+
self.assertEqual(e.eval_unit(), d)
|
|
3567
|
+
self.assertRaises(myokit.IncompatibleUnitError, e.eval_unit, s)
|
|
3357
3568
|
|
|
3358
3569
|
def test_tree_str(self):
|
|
3359
3570
|
# Test Equal.tree_str().
|
|
3360
3571
|
x = myokit.Equal(myokit.Number(1), myokit.Number(2))
|
|
3361
3572
|
self.assertEqual(x.tree_str(), '==\n 1\n 2\n')
|
|
3362
|
-
|
|
3363
|
-
self.assertEqual(x.tree_str(), '+\n 3\n ==\n 1\n 2\n')
|
|
3573
|
+
self.assertEqual(myokit.Not(x).tree_str(), 'not\n ==\n 1\n 2\n')
|
|
3364
3574
|
|
|
3365
3575
|
|
|
3366
3576
|
class NotEqualTest(unittest.TestCase):
|
|
3367
3577
|
""" Tests myokit.NotEqual. """
|
|
3368
3578
|
|
|
3579
|
+
def test_creation(self):
|
|
3580
|
+
# Operands must be numerical expressions
|
|
3581
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
3582
|
+
myokit.NotEqual, 1, 1)
|
|
3583
|
+
a = myokit.Equal(myokit.Number(1), myokit.Number(2))
|
|
3584
|
+
self.assertRaisesRegex(
|
|
3585
|
+
myokit.TypeError, 'first operand: expected a numerical',
|
|
3586
|
+
myokit.NotEqual, a, myokit.Number(1))
|
|
3587
|
+
self.assertRaisesRegex(
|
|
3588
|
+
myokit.TypeError, 'second operand: expected a numerical',
|
|
3589
|
+
myokit.NotEqual, myokit.Number(1), a)
|
|
3590
|
+
|
|
3369
3591
|
def test_eval(self):
|
|
3370
3592
|
# Test NotEqual.eval().
|
|
3371
3593
|
x = myokit.NotEqual(myokit.Number(1), myokit.Number(1))
|
|
@@ -3377,12 +3599,25 @@ class NotEqualTest(unittest.TestCase):
|
|
|
3377
3599
|
# Test NotEqual.tree_str().
|
|
3378
3600
|
x = myokit.NotEqual(myokit.Number(1), myokit.Number(2))
|
|
3379
3601
|
self.assertEqual(x.tree_str(), '!=\n 1\n 2\n')
|
|
3380
|
-
|
|
3381
|
-
|
|
3602
|
+
self.assertEqual(myokit.Not(x).tree_str(),
|
|
3603
|
+
'not\n !=\n 1\n 2\n')
|
|
3382
3604
|
|
|
3383
3605
|
|
|
3384
3606
|
class MoreTest(unittest.TestCase):
|
|
3385
3607
|
""" Tests myokit.More. """
|
|
3608
|
+
|
|
3609
|
+
def test_creation(self):
|
|
3610
|
+
# Operands must be numerical expressions
|
|
3611
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
3612
|
+
myokit.More, 1, 1)
|
|
3613
|
+
a = myokit.Equal(myokit.Number(1), myokit.Number(2))
|
|
3614
|
+
self.assertRaisesRegex(
|
|
3615
|
+
myokit.TypeError, 'first operand: expected a numerical',
|
|
3616
|
+
myokit.More, a, myokit.Number(1))
|
|
3617
|
+
self.assertRaisesRegex(
|
|
3618
|
+
myokit.TypeError, 'second operand: expected a numerical',
|
|
3619
|
+
myokit.More, myokit.Number(1), a)
|
|
3620
|
+
|
|
3386
3621
|
def test_eval(self):
|
|
3387
3622
|
# Test More.eval().
|
|
3388
3623
|
x = myokit.More(myokit.Number(1), myokit.Number(1))
|
|
@@ -3394,12 +3629,24 @@ class MoreTest(unittest.TestCase):
|
|
|
3394
3629
|
# Test More.tree_str().
|
|
3395
3630
|
x = myokit.More(myokit.Number(1), myokit.Number(2))
|
|
3396
3631
|
self.assertEqual(x.tree_str(), '>\n 1\n 2\n')
|
|
3397
|
-
|
|
3398
|
-
self.assertEqual(x.tree_str(), '+\n 3\n >\n 1\n 2\n')
|
|
3632
|
+
self.assertEqual(myokit.Not(x).tree_str(), 'not\n >\n 1\n 2\n')
|
|
3399
3633
|
|
|
3400
3634
|
|
|
3401
3635
|
class LessTest(unittest.TestCase):
|
|
3402
3636
|
""" Tests myokit.Less. """
|
|
3637
|
+
|
|
3638
|
+
def test_creation(self):
|
|
3639
|
+
# Operands must be expressions
|
|
3640
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
3641
|
+
myokit.Less, 1, 1)
|
|
3642
|
+
a = myokit.Equal(myokit.Number(1), myokit.Number(2))
|
|
3643
|
+
self.assertRaisesRegex(
|
|
3644
|
+
myokit.TypeError, 'first operand: expected a numerical',
|
|
3645
|
+
myokit.Less, a, myokit.Number(1))
|
|
3646
|
+
self.assertRaisesRegex(
|
|
3647
|
+
myokit.TypeError, 'second operand: expected a numerical',
|
|
3648
|
+
myokit.Less, myokit.Number(1), a)
|
|
3649
|
+
|
|
3403
3650
|
def test_eval(self):
|
|
3404
3651
|
# Test Less.eval().
|
|
3405
3652
|
x = myokit.Less(myokit.Number(1), myokit.Number(1))
|
|
@@ -3411,13 +3658,24 @@ class LessTest(unittest.TestCase):
|
|
|
3411
3658
|
# Test Less.tree_str().
|
|
3412
3659
|
x = myokit.Less(myokit.Number(1), myokit.Number(2))
|
|
3413
3660
|
self.assertEqual(x.tree_str(), '<\n 1\n 2\n')
|
|
3414
|
-
|
|
3415
|
-
self.assertEqual(x.tree_str(), '+\n 3\n <\n 1\n 2\n')
|
|
3661
|
+
self.assertEqual(myokit.Not(x).tree_str(), 'not\n <\n 1\n 2\n')
|
|
3416
3662
|
|
|
3417
3663
|
|
|
3418
3664
|
class MoreEqualTest(unittest.TestCase):
|
|
3419
3665
|
""" Tests myokit.MoreEqual. """
|
|
3420
3666
|
|
|
3667
|
+
def test_creation(self):
|
|
3668
|
+
# Operands must be numerical expressions
|
|
3669
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
3670
|
+
myokit.MoreEqual, 1, 1)
|
|
3671
|
+
a = myokit.Equal(myokit.Number(1), myokit.Number(2))
|
|
3672
|
+
self.assertRaisesRegex(
|
|
3673
|
+
myokit.TypeError, 'first operand: expected a numerical',
|
|
3674
|
+
myokit.MoreEqual, a, myokit.Number(1))
|
|
3675
|
+
self.assertRaisesRegex(
|
|
3676
|
+
myokit.TypeError, 'second operand: expected a numerical',
|
|
3677
|
+
myokit.MoreEqual, myokit.Number(1), a)
|
|
3678
|
+
|
|
3421
3679
|
def test_eval(self):
|
|
3422
3680
|
# Test MoreEqual.eval().
|
|
3423
3681
|
x = myokit.MoreEqual(myokit.Number(1), myokit.Number(1))
|
|
@@ -3431,13 +3689,24 @@ class MoreEqualTest(unittest.TestCase):
|
|
|
3431
3689
|
# Test MoreEqual.tree_str().
|
|
3432
3690
|
x = myokit.MoreEqual(myokit.Number(1), myokit.Number(2))
|
|
3433
3691
|
self.assertEqual(x.tree_str(), '>=\n 1\n 2\n')
|
|
3434
|
-
|
|
3435
|
-
self.assertEqual(x.tree_str(), '+\n 3\n >=\n 1\n 2\n')
|
|
3692
|
+
self.assertEqual(myokit.Not(x).tree_str(), 'not\n >=\n 1\n 2\n')
|
|
3436
3693
|
|
|
3437
3694
|
|
|
3438
3695
|
class LessEqualTest(unittest.TestCase):
|
|
3439
3696
|
""" Tests myokit.LessEqual. """
|
|
3440
3697
|
|
|
3698
|
+
def test_creation(self):
|
|
3699
|
+
# Operands must be numerical expressions
|
|
3700
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
3701
|
+
myokit.LessEqual, 1, 1)
|
|
3702
|
+
a = myokit.Equal(myokit.Number(1), myokit.Number(2))
|
|
3703
|
+
self.assertRaisesRegex(
|
|
3704
|
+
myokit.TypeError, 'first operand: expected a numerical',
|
|
3705
|
+
myokit.LessEqual, a, myokit.Number(1))
|
|
3706
|
+
self.assertRaisesRegex(
|
|
3707
|
+
myokit.TypeError, 'second operand: expected a numerical',
|
|
3708
|
+
myokit.LessEqual, myokit.Number(1), a)
|
|
3709
|
+
|
|
3441
3710
|
def test_eval(self):
|
|
3442
3711
|
# Test LessEqual.eval().
|
|
3443
3712
|
x = myokit.LessEqual(myokit.Number(1), myokit.Number(1))
|
|
@@ -3451,13 +3720,24 @@ class LessEqualTest(unittest.TestCase):
|
|
|
3451
3720
|
# Test LessEqual.tree_str().
|
|
3452
3721
|
x = myokit.LessEqual(myokit.Number(1), myokit.Number(2))
|
|
3453
3722
|
self.assertEqual(x.tree_str(), '<=\n 1\n 2\n')
|
|
3454
|
-
|
|
3455
|
-
self.assertEqual(x.tree_str(), '+\n 3\n <=\n 1\n 2\n')
|
|
3723
|
+
self.assertEqual(myokit.Not(x).tree_str(), 'not\n <=\n 1\n 2\n')
|
|
3456
3724
|
|
|
3457
3725
|
|
|
3458
3726
|
class AndTest(unittest.TestCase):
|
|
3459
3727
|
""" Tests myokit.And. """
|
|
3460
3728
|
|
|
3729
|
+
def test_creation(self):
|
|
3730
|
+
# Operands must be conditional expressions
|
|
3731
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
3732
|
+
myokit.And, 1, 1)
|
|
3733
|
+
a = myokit.Equal(myokit.Number(1), myokit.Number(2))
|
|
3734
|
+
self.assertRaisesRegex(
|
|
3735
|
+
myokit.TypeError, 'first operand: expected a condition',
|
|
3736
|
+
myokit.And, myokit.Number(1), a)
|
|
3737
|
+
self.assertRaisesRegex(
|
|
3738
|
+
myokit.TypeError, 'second operand: expected a condition',
|
|
3739
|
+
myokit.And, a, myokit.Number(1))
|
|
3740
|
+
|
|
3461
3741
|
def test_diff(self):
|
|
3462
3742
|
# Tests And.diff()
|
|
3463
3743
|
x1 = myokit.Equal(myokit.Number(1), myokit.Number(1))
|
|
@@ -3471,146 +3751,121 @@ class AndTest(unittest.TestCase):
|
|
|
3471
3751
|
|
|
3472
3752
|
def test_eval(self):
|
|
3473
3753
|
# Test And.eval().
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
self.assertFalse(
|
|
3754
|
+
a = myokit.Equal(myokit.Number(2), myokit.Number(2))
|
|
3755
|
+
b = myokit.Equal(myokit.Number(3), myokit.Number(1))
|
|
3756
|
+
self.assertTrue(myokit.And(a, a).eval())
|
|
3757
|
+
self.assertFalse(myokit.And(a, b).eval())
|
|
3758
|
+
self.assertFalse(myokit.And(b, b).eval())
|
|
3478
3759
|
|
|
3479
3760
|
def test_eval_unit(self):
|
|
3480
3761
|
# Test And.eval_unit().
|
|
3481
3762
|
|
|
3482
|
-
#
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
# Test in
|
|
3493
|
-
self.assertEqual(z.rhs().eval_unit(), None)
|
|
3494
|
-
x.set_unit(myokit.units.ampere)
|
|
3495
|
-
self.assertRaisesRegex(
|
|
3496
|
-
myokit.IncompatibleUnitError, 'dimensionless', z.rhs().eval_unit)
|
|
3497
|
-
y.set_unit(myokit.units.ampere)
|
|
3498
|
-
self.assertRaisesRegex(
|
|
3499
|
-
myokit.IncompatibleUnitError, 'dimensionless', z.rhs().eval_unit)
|
|
3500
|
-
x.set_unit(myokit.units.dimensionless)
|
|
3501
|
-
self.assertRaisesRegex(
|
|
3502
|
-
myokit.IncompatibleUnitError, 'dimensionless', z.rhs().eval_unit)
|
|
3503
|
-
y.set_unit(myokit.units.dimensionless)
|
|
3504
|
-
self.assertEqual(z.rhs().eval_unit(), myokit.units.dimensionless)
|
|
3505
|
-
x.set_unit(None)
|
|
3506
|
-
self.assertEqual(z.rhs().eval_unit(), myokit.units.dimensionless)
|
|
3507
|
-
y.set_unit(None)
|
|
3508
|
-
self.assertEqual(z.rhs().eval_unit(), None)
|
|
3509
|
-
|
|
3510
|
-
# Test in strict mode
|
|
3763
|
+
# Test in tolerant mode: no own testing, but should test operands!
|
|
3764
|
+
e = myokit.parse_expression('1 == 1 and 2 == 2')
|
|
3765
|
+
self.assertEqual(e.eval_unit(), myokit.units.dimensionless)
|
|
3766
|
+
e = myokit.parse_expression('1 == 1 [1] and 2 [1] == 2')
|
|
3767
|
+
self.assertEqual(e.eval_unit(), myokit.units.dimensionless)
|
|
3768
|
+
e = myokit.parse_expression('1 [1] == 1 [1] and 2 [1] == 2 [1]')
|
|
3769
|
+
self.assertEqual(e.eval_unit(), myokit.units.dimensionless)
|
|
3770
|
+
e = myokit.parse_expression('1 [1] == 1 [1] and 2 [1] == 2 [mg]')
|
|
3771
|
+
self.assertRaises(myokit.IncompatibleUnitError, e.eval_unit)
|
|
3772
|
+
|
|
3773
|
+
# Test in strict mode: no own testing, but should test operands!
|
|
3511
3774
|
s = myokit.UNIT_STRICT
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
self.
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
self.assertRaisesRegex(
|
|
3521
|
-
myokit.IncompatibleUnitError, 'dimensionles', z.rhs().eval_unit, s)
|
|
3522
|
-
y.set_unit(myokit.units.dimensionless)
|
|
3523
|
-
self.assertEqual(z.rhs().eval_unit(s), myokit.units.dimensionless)
|
|
3524
|
-
x.set_unit(None)
|
|
3525
|
-
self.assertEqual(z.rhs().eval_unit(s), myokit.units.dimensionless)
|
|
3526
|
-
y.set_unit(None)
|
|
3527
|
-
self.assertEqual(z.rhs().eval_unit(s), myokit.units.dimensionless)
|
|
3775
|
+
e = myokit.parse_expression('1 == 1 and 2 == 2')
|
|
3776
|
+
self.assertEqual(e.eval_unit(s), myokit.units.dimensionless)
|
|
3777
|
+
e = myokit.parse_expression('1 == 1 [1] and 2 [1] == 2')
|
|
3778
|
+
self.assertEqual(e.eval_unit(s), myokit.units.dimensionless)
|
|
3779
|
+
e = myokit.parse_expression('1 [1] == 1 [1] and 2 [1] == 2 [1]')
|
|
3780
|
+
self.assertEqual(e.eval_unit(s), myokit.units.dimensionless)
|
|
3781
|
+
e = myokit.parse_expression('1 == 1 [V] and 1 == 1 [1]')
|
|
3782
|
+
self.assertRaises(myokit.IncompatibleUnitError, e.eval_unit, s)
|
|
3528
3783
|
|
|
3529
3784
|
def test_tree_str(self):
|
|
3530
3785
|
# Test And.tree_str().
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3786
|
+
a = myokit.Equal(myokit.Number(1), myokit.Number(2))
|
|
3787
|
+
b = myokit.Less(myokit.Number(4), myokit.Number(3))
|
|
3788
|
+
self.assertEqual(myokit.And(a, b).tree_str(),
|
|
3789
|
+
'and\n ==\n 1\n 2\n <\n 4\n 3\n')
|
|
3790
|
+
self.assertEqual(
|
|
3791
|
+
myokit.Not(myokit.And(b, a)).tree_str(),
|
|
3792
|
+
'not\n and\n <\n 4\n 3\n ==\n 1\n 2\n')
|
|
3535
3793
|
|
|
3536
3794
|
|
|
3537
3795
|
class OrTest(unittest.TestCase):
|
|
3538
3796
|
""" Tests myokit.Or. """
|
|
3539
3797
|
|
|
3798
|
+
def test_creation(self):
|
|
3799
|
+
# Operands must be expressions
|
|
3800
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
3801
|
+
myokit.Or, 1, 1)
|
|
3802
|
+
a = myokit.Equal(myokit.Number(1), myokit.Number(2))
|
|
3803
|
+
self.assertRaisesRegex(
|
|
3804
|
+
myokit.TypeError, 'first operand: expected a condition',
|
|
3805
|
+
myokit.Or, myokit.Number(1), a)
|
|
3806
|
+
self.assertRaisesRegex(
|
|
3807
|
+
myokit.TypeError, 'second operand: expected a condition',
|
|
3808
|
+
myokit.Or, a, myokit.Number(1))
|
|
3809
|
+
|
|
3540
3810
|
def test_eval(self):
|
|
3541
3811
|
# Test Or.eval().
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
self.assertTrue(
|
|
3546
|
-
|
|
3547
|
-
self.assertFalse(x.eval())
|
|
3812
|
+
a = myokit.Equal(myokit.Number(2), myokit.Number(2))
|
|
3813
|
+
b = myokit.Equal(myokit.Number(3), myokit.Number(1))
|
|
3814
|
+
self.assertTrue(myokit.Or(a, a).eval())
|
|
3815
|
+
self.assertTrue(myokit.Or(a, b).eval())
|
|
3816
|
+
self.assertFalse(myokit.Or(b, b).eval())
|
|
3548
3817
|
|
|
3549
3818
|
def test_eval_unit(self):
|
|
3550
3819
|
# Test Or.eval_unit().
|
|
3551
3820
|
|
|
3552
|
-
#
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
# Test in
|
|
3563
|
-
self.assertEqual(z.rhs().eval_unit(), None)
|
|
3564
|
-
x.set_unit(myokit.units.ampere)
|
|
3565
|
-
self.assertRaisesRegex(
|
|
3566
|
-
myokit.IncompatibleUnitError, 'dimensionless', z.rhs().eval_unit)
|
|
3567
|
-
y.set_unit(myokit.units.ampere)
|
|
3568
|
-
self.assertRaisesRegex(
|
|
3569
|
-
myokit.IncompatibleUnitError, 'dimensionless', z.rhs().eval_unit)
|
|
3570
|
-
x.set_unit(myokit.units.dimensionless)
|
|
3571
|
-
self.assertRaisesRegex(
|
|
3572
|
-
myokit.IncompatibleUnitError, 'dimensionless', z.rhs().eval_unit)
|
|
3573
|
-
y.set_unit(myokit.units.dimensionless)
|
|
3574
|
-
self.assertEqual(z.rhs().eval_unit(), myokit.units.dimensionless)
|
|
3575
|
-
x.set_unit(None)
|
|
3576
|
-
self.assertEqual(z.rhs().eval_unit(), myokit.units.dimensionless)
|
|
3577
|
-
y.set_unit(None)
|
|
3578
|
-
self.assertEqual(z.rhs().eval_unit(), None)
|
|
3579
|
-
|
|
3580
|
-
# Test in strict mode
|
|
3821
|
+
# Test in tolerant mode: no own testing, but should test operands!
|
|
3822
|
+
e = myokit.parse_expression('1 == 1 or 2 == 2')
|
|
3823
|
+
self.assertEqual(e.eval_unit(), myokit.units.dimensionless)
|
|
3824
|
+
e = myokit.parse_expression('1 == 1 [1] or 2 [1] == 2')
|
|
3825
|
+
self.assertEqual(e.eval_unit(), myokit.units.dimensionless)
|
|
3826
|
+
e = myokit.parse_expression('1 [1] == 1 [1] or 2 [1] == 2 [1]')
|
|
3827
|
+
self.assertEqual(e.eval_unit(), myokit.units.dimensionless)
|
|
3828
|
+
e = myokit.parse_expression('1 [1] == 1 [1] or 2 [1] == 2 [mg]')
|
|
3829
|
+
self.assertRaises(myokit.IncompatibleUnitError, e.eval_unit)
|
|
3830
|
+
|
|
3831
|
+
# Test in strict mode: no own testing, but should test operands!
|
|
3581
3832
|
s = myokit.UNIT_STRICT
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
self.
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
self.assertRaisesRegex(
|
|
3591
|
-
myokit.IncompatibleUnitError, 'dimensionles', z.rhs().eval_unit, s)
|
|
3592
|
-
y.set_unit(myokit.units.dimensionless)
|
|
3593
|
-
self.assertEqual(z.rhs().eval_unit(s), myokit.units.dimensionless)
|
|
3594
|
-
x.set_unit(None)
|
|
3595
|
-
self.assertEqual(z.rhs().eval_unit(s), myokit.units.dimensionless)
|
|
3596
|
-
y.set_unit(None)
|
|
3597
|
-
self.assertEqual(z.rhs().eval_unit(s), myokit.units.dimensionless)
|
|
3833
|
+
e = myokit.parse_expression('1 == 1 or 2 == 2')
|
|
3834
|
+
self.assertEqual(e.eval_unit(s), myokit.units.dimensionless)
|
|
3835
|
+
e = myokit.parse_expression('1 == 1 [1] or 2 [1] == 2')
|
|
3836
|
+
self.assertEqual(e.eval_unit(s), myokit.units.dimensionless)
|
|
3837
|
+
e = myokit.parse_expression('1 [1] == 1 [1] or 2 [1] == 2 [1]')
|
|
3838
|
+
self.assertEqual(e.eval_unit(s), myokit.units.dimensionless)
|
|
3839
|
+
e = myokit.parse_expression('1 == 1 [A] or 2 [1] == 2 [1]')
|
|
3840
|
+
self.assertRaises(myokit.IncompatibleUnitError, e.eval_unit, s)
|
|
3598
3841
|
|
|
3599
3842
|
def test_tree_str(self):
|
|
3600
3843
|
# Test Or.tree_str().
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
x = myokit.
|
|
3604
|
-
self.assertEqual(
|
|
3844
|
+
a = myokit.Equal(myokit.Number(1), myokit.Number(2))
|
|
3845
|
+
b = myokit.NotEqual(myokit.Number(3), myokit.Number(4))
|
|
3846
|
+
x = myokit.Or(a, b)
|
|
3847
|
+
self.assertEqual(
|
|
3848
|
+
x.tree_str(),
|
|
3849
|
+
'or\n ==\n 1\n 2\n !=\n 3\n 4\n')
|
|
3850
|
+
x = myokit.Not(x)
|
|
3851
|
+
self.assertEqual(
|
|
3852
|
+
x.tree_str(),
|
|
3853
|
+
'not\n or\n ==\n 1\n 2\n !=\n 3\n 4\n')
|
|
3605
3854
|
|
|
3606
3855
|
|
|
3607
3856
|
class NotTest(unittest.TestCase):
|
|
3608
3857
|
""" Tests myokit.Not. """
|
|
3609
3858
|
|
|
3859
|
+
def test_creation(self):
|
|
3860
|
+
# Operand must be an expression
|
|
3861
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
3862
|
+
myokit.Not, 1)
|
|
3863
|
+
self.assertRaisesRegex(
|
|
3864
|
+
myokit.TypeError, 'expected a condition',
|
|
3865
|
+
myokit.Not, myokit.Number(1))
|
|
3866
|
+
|
|
3610
3867
|
def test_code(self):
|
|
3611
3868
|
# Test Not.code().
|
|
3612
|
-
x = myokit.Not(myokit.Number(1))
|
|
3613
|
-
self.assertEqual(x.code(), 'not 1')
|
|
3614
3869
|
x = myokit.Not(myokit.Equal(myokit.Number(1), myokit.Number(1)))
|
|
3615
3870
|
self.assertEqual(x.code(), 'not (1 == 1)')
|
|
3616
3871
|
|
|
@@ -3624,9 +3879,9 @@ class NotTest(unittest.TestCase):
|
|
|
3624
3879
|
|
|
3625
3880
|
def test_eval(self):
|
|
3626
3881
|
# Test Not.eval().
|
|
3627
|
-
x = myokit.Not(myokit.Number(1))
|
|
3882
|
+
x = myokit.Not(myokit.Equal(myokit.Number(1), myokit.Number(1)))
|
|
3628
3883
|
self.assertFalse(x.eval())
|
|
3629
|
-
x = myokit.Not(myokit.Number(0))
|
|
3884
|
+
x = myokit.Not(myokit.Equal(myokit.Number(1), myokit.Number(0)))
|
|
3630
3885
|
self.assertTrue(x.eval())
|
|
3631
3886
|
|
|
3632
3887
|
def test_eval_unit(self):
|
|
@@ -3635,36 +3890,34 @@ class NotTest(unittest.TestCase):
|
|
|
3635
3890
|
# Mini model
|
|
3636
3891
|
m = myokit.Model()
|
|
3637
3892
|
c = m.add_component('c')
|
|
3638
|
-
x = c.add_variable('x')
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
z.set_rhs('not x')
|
|
3893
|
+
x = c.add_variable('x', rhs=1)
|
|
3894
|
+
y = c.add_variable('y', rhs=2)
|
|
3895
|
+
e = myokit.parse_expression('not (x != y)', context=c)
|
|
3642
3896
|
|
|
3643
3897
|
# Test in tolerant mode
|
|
3644
|
-
self.assertEqual(
|
|
3898
|
+
self.assertEqual(e.eval_unit(), myokit.units.dimensionless)
|
|
3645
3899
|
x.set_unit(myokit.units.ampere)
|
|
3900
|
+
y.set_unit(myokit.units.dimensionless)
|
|
3646
3901
|
self.assertRaisesRegex(
|
|
3647
|
-
myokit.IncompatibleUnitError, '
|
|
3902
|
+
myokit.IncompatibleUnitError, 'equal units on both', e.eval_unit)
|
|
3648
3903
|
x.set_unit(myokit.units.dimensionless)
|
|
3649
|
-
self.assertEqual(
|
|
3904
|
+
self.assertEqual(e.eval_unit(), myokit.units.dimensionless)
|
|
3650
3905
|
x.set_unit(None)
|
|
3651
|
-
self.assertEqual(
|
|
3906
|
+
self.assertEqual(e.eval_unit(), myokit.units.dimensionless)
|
|
3652
3907
|
|
|
3653
3908
|
# Test in strict mode
|
|
3654
3909
|
s = myokit.UNIT_STRICT
|
|
3655
|
-
self.assertEqual(
|
|
3910
|
+
self.assertEqual(e.eval_unit(s), myokit.units.dimensionless)
|
|
3656
3911
|
x.set_unit(myokit.units.ampere)
|
|
3657
3912
|
self.assertRaisesRegex(
|
|
3658
|
-
myokit.IncompatibleUnitError, '
|
|
3913
|
+
myokit.IncompatibleUnitError, 'equal units on bot', e.eval_unit, s)
|
|
3659
3914
|
x.set_unit(myokit.units.dimensionless)
|
|
3660
|
-
self.assertEqual(
|
|
3915
|
+
self.assertEqual(e.eval_unit(s), myokit.units.dimensionless)
|
|
3661
3916
|
x.set_unit(None)
|
|
3662
|
-
self.assertEqual(
|
|
3917
|
+
self.assertEqual(e.eval_unit(s), myokit.units.dimensionless)
|
|
3663
3918
|
|
|
3664
3919
|
def test_polish(self):
|
|
3665
3920
|
# Test Not._polish().
|
|
3666
|
-
x = myokit.Not(myokit.Number(1))
|
|
3667
|
-
self.assertEqual(x._polish(), 'not 1')
|
|
3668
3921
|
x = myokit.Not(myokit.Equal(myokit.Number(1), myokit.Number(1)))
|
|
3669
3922
|
self.assertEqual(x._polish(), 'not == 1 1')
|
|
3670
3923
|
|
|
@@ -3686,6 +3939,16 @@ class IfTest(unittest.TestCase):
|
|
|
3686
3939
|
# Test is_conditional()
|
|
3687
3940
|
self.assertTrue(if_.is_conditional())
|
|
3688
3941
|
|
|
3942
|
+
# Operands must be expressions and have right types
|
|
3943
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
3944
|
+
myokit.If, 1, 1, 1)
|
|
3945
|
+
self.assertRaisesRegex(
|
|
3946
|
+
myokit.TypeError, 'first operand', myokit.If, then, then, then)
|
|
3947
|
+
self.assertRaisesRegex(
|
|
3948
|
+
myokit.TypeError, 'second operand', myokit.If, cond, cond, then)
|
|
3949
|
+
self.assertRaisesRegex(
|
|
3950
|
+
myokit.TypeError, 'third operand', myokit.If, cond, then, cond)
|
|
3951
|
+
|
|
3689
3952
|
def test_diff(self):
|
|
3690
3953
|
# Tests If.diff()
|
|
3691
3954
|
|
|
@@ -3731,14 +3994,12 @@ class IfTest(unittest.TestCase):
|
|
|
3731
3994
|
# Mini model
|
|
3732
3995
|
m = myokit.Model()
|
|
3733
3996
|
c = m.add_component('c')
|
|
3734
|
-
v1 = c.add_variable('v1')
|
|
3735
3997
|
v2 = c.add_variable('v2')
|
|
3736
3998
|
v3 = c.add_variable('v3')
|
|
3737
3999
|
v4 = c.add_variable('v4')
|
|
3738
|
-
v1.set_rhs('1 == 1')
|
|
3739
4000
|
v2.set_rhs(2)
|
|
3740
4001
|
v3.set_rhs(3)
|
|
3741
|
-
v4.set_rhs('if(
|
|
4002
|
+
v4.set_rhs('if(1 == 1, v2, v3)')
|
|
3742
4003
|
z = v4.rhs()
|
|
3743
4004
|
|
|
3744
4005
|
# Test in tolerant mode
|
|
@@ -3851,6 +4112,30 @@ class PiecewiseTest(unittest.TestCase):
|
|
|
3851
4112
|
self.assertRaisesRegex(
|
|
3852
4113
|
myokit.IntegrityError, '3 or more', myokit.Piecewise, cond1)
|
|
3853
4114
|
|
|
4115
|
+
# Operands must be expressions
|
|
4116
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be other Express',
|
|
4117
|
+
myokit.Piecewise, 1, 1, 1)
|
|
4118
|
+
|
|
4119
|
+
# Operands must have right types
|
|
4120
|
+
self.assertRaisesRegex(
|
|
4121
|
+
myokit.TypeError, 'operand at index 0 must be a condition',
|
|
4122
|
+
myokit.Piecewise, then1, then2, then3)
|
|
4123
|
+
self.assertRaisesRegex(
|
|
4124
|
+
myokit.TypeError, 'operand at index 1 must be numerical',
|
|
4125
|
+
myokit.Piecewise, cond1, cond1, then1)
|
|
4126
|
+
self.assertRaisesRegex(
|
|
4127
|
+
myokit.TypeError, 'operand at index 2 must be numerical',
|
|
4128
|
+
myokit.Piecewise, cond1, then1, cond2)
|
|
4129
|
+
self.assertRaisesRegex(
|
|
4130
|
+
myokit.TypeError, 'operand at index 2 must be a condition',
|
|
4131
|
+
myokit.Piecewise, cond1, then1, then2, then3, then1)
|
|
4132
|
+
self.assertRaisesRegex(
|
|
4133
|
+
myokit.TypeError, 'operand at index 3 must be numerical',
|
|
4134
|
+
myokit.Piecewise, cond1, then1, cond2, cond3, then2)
|
|
4135
|
+
self.assertRaisesRegex(
|
|
4136
|
+
myokit.TypeError, 'operand at index 4 must be numerical',
|
|
4137
|
+
myokit.Piecewise, cond1, then1, cond2, then2, cond3)
|
|
4138
|
+
|
|
3854
4139
|
def test_diff(self):
|
|
3855
4140
|
# Tests Piecewise.diff()
|
|
3856
4141
|
|
|
@@ -3918,24 +4203,13 @@ class PiecewiseTest(unittest.TestCase):
|
|
|
3918
4203
|
# Mini model
|
|
3919
4204
|
m = myokit.Model()
|
|
3920
4205
|
comp = m.add_component('comp')
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
c2 = comp.add_variable('c2')
|
|
3925
|
-
c1.set_rhs('1 == 2')
|
|
3926
|
-
c2.set_rhs('1 == 2')
|
|
3927
|
-
|
|
3928
|
-
# Create values
|
|
3929
|
-
t1 = comp.add_variable('t1')
|
|
3930
|
-
t2 = comp.add_variable('t2')
|
|
3931
|
-
t3 = comp.add_variable('t3')
|
|
3932
|
-
t1.set_rhs(1)
|
|
3933
|
-
t2.set_rhs(2)
|
|
3934
|
-
t3.set_rhs(3)
|
|
4206
|
+
t1 = comp.add_variable('t1', rhs=1)
|
|
4207
|
+
t2 = comp.add_variable('t2', rhs=2)
|
|
4208
|
+
t3 = comp.add_variable('t3', rhs=3)
|
|
3935
4209
|
|
|
3936
4210
|
# Create piecewise
|
|
3937
4211
|
pw = comp.add_variable('pw')
|
|
3938
|
-
pw.set_rhs('piecewise(
|
|
4212
|
+
pw.set_rhs('piecewise(1 == 2, t1, 1 == 2, t2, t3)')
|
|
3939
4213
|
z = pw.rhs()
|
|
3940
4214
|
|
|
3941
4215
|
# Test in tolerant mode
|
|
@@ -4007,6 +4281,13 @@ class EquationTest(unittest.TestCase):
|
|
|
4007
4281
|
rhs = myokit.Number('3')
|
|
4008
4282
|
myokit.Equation(lhs, rhs)
|
|
4009
4283
|
|
|
4284
|
+
# Operands must be expressions
|
|
4285
|
+
# Operands must be expressions
|
|
4286
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be myokit.Expres',
|
|
4287
|
+
myokit.Equation, 1.2, 3.4)
|
|
4288
|
+
self.assertRaisesRegex(myokit.IntegrityError, 'must be myokit.Express',
|
|
4289
|
+
myokit.Equation, myokit.Number(3), 1.2)
|
|
4290
|
+
|
|
4010
4291
|
def test_eq(self):
|
|
4011
4292
|
# Test equality checking.
|
|
4012
4293
|
eq1 = myokit.Equation(myokit.Name('x'), myokit.Number('3'))
|