myokit 1.33.9__py3-none-any.whl → 1.35.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.
Files changed (229) hide show
  1. myokit/__init__.py +9 -36
  2. myokit/__main__.py +76 -142
  3. myokit/_aux.py +62 -16
  4. myokit/_bin/example.mmt +1 -2
  5. myokit/_bin/install-win/menu.json +7 -7
  6. myokit/_config.py +22 -31
  7. myokit/_datablock.py +30 -74
  8. myokit/_datalog.py +49 -72
  9. myokit/_err.py +25 -24
  10. myokit/_expressions.py +50 -68
  11. myokit/_io.py +15 -27
  12. myokit/_model_api.py +453 -249
  13. myokit/_myokit_version.py +1 -5
  14. myokit/_parsing.py +38 -44
  15. myokit/_progress.py +5 -8
  16. myokit/_protocol.py +99 -9
  17. myokit/_sim/__init__.py +7 -24
  18. myokit/_sim/cable.c +6 -8
  19. myokit/_sim/cable.py +6 -8
  20. myokit/_sim/cmodel.h +125 -70
  21. myokit/_sim/cmodel.py +12 -14
  22. myokit/_sim/compiler.py +1 -4
  23. myokit/_sim/cvodessim.c +196 -118
  24. myokit/_sim/cvodessim.py +130 -103
  25. myokit/_sim/differential.hpp +4 -4
  26. myokit/_sim/fiber_tissue.c +4 -8
  27. myokit/_sim/fiber_tissue.py +11 -13
  28. myokit/_sim/jacobian.cpp +2 -2
  29. myokit/_sim/jacobian.py +11 -8
  30. myokit/_sim/mcl.h +53 -55
  31. myokit/_sim/opencl.py +21 -27
  32. myokit/_sim/openclsim.c +3 -7
  33. myokit/_sim/openclsim.cl +3 -3
  34. myokit/_sim/openclsim.py +49 -40
  35. myokit/_sim/pacing.h +36 -16
  36. myokit/_sim/rhs.c +6 -13
  37. myokit/_sim/rhs.py +5 -14
  38. myokit/_sim/sundials.py +1 -4
  39. myokit/_system.py +10 -16
  40. myokit/_unit.py +4 -13
  41. myokit/float.py +0 -3
  42. myokit/formats/__init__.py +8 -10
  43. myokit/formats/ansic/__init__.py +0 -3
  44. myokit/formats/ansic/_ewriter.py +2 -4
  45. myokit/formats/ansic/_exporter.py +1 -4
  46. myokit/formats/ansic/template/cable.c +4 -4
  47. myokit/formats/ansic/template/euler.c +5 -5
  48. myokit/formats/ansic/template/sim.c +6 -6
  49. myokit/formats/axon/__init__.py +1 -3
  50. myokit/formats/axon/_abf.py +12 -17
  51. myokit/formats/axon/_atf.py +5 -6
  52. myokit/formats/axon/_importer.py +0 -3
  53. myokit/formats/cellml/__init__.py +0 -3
  54. myokit/formats/cellml/_ewriter.py +3 -6
  55. myokit/formats/cellml/_exporter.py +3 -6
  56. myokit/formats/cellml/_importer.py +1 -4
  57. myokit/formats/cellml/v1/__init__.py +0 -4
  58. myokit/formats/cellml/v1/_api.py +8 -11
  59. myokit/formats/cellml/v1/_parser.py +2 -5
  60. myokit/formats/cellml/v1/_writer.py +2 -11
  61. myokit/formats/cellml/v2/__init__.py +0 -3
  62. myokit/formats/cellml/v2/_api.py +8 -17
  63. myokit/formats/cellml/v2/_parser.py +2 -5
  64. myokit/formats/cellml/v2/_writer.py +1 -4
  65. myokit/formats/channelml/__init__.py +0 -3
  66. myokit/formats/channelml/_importer.py +11 -21
  67. myokit/formats/cpp/__init__.py +1 -3
  68. myokit/formats/cpp/_ewriter.py +0 -3
  69. myokit/formats/cuda/__init__.py +0 -3
  70. myokit/formats/cuda/_ewriter.py +2 -4
  71. myokit/formats/cuda/_exporter.py +0 -3
  72. myokit/formats/cuda/template/kernel.cu +8 -5
  73. myokit/formats/easyml/__init__.py +0 -3
  74. myokit/formats/easyml/_ewriter.py +9 -11
  75. myokit/formats/easyml/_exporter.py +2 -5
  76. myokit/formats/html/__init__.py +0 -3
  77. myokit/formats/html/_exporter.py +0 -3
  78. myokit/formats/html/_flatten.py +5 -21
  79. myokit/formats/latex/__init__.py +0 -3
  80. myokit/formats/latex/_ewriter.py +1 -4
  81. myokit/formats/latex/_exporter.py +4 -6
  82. myokit/formats/mathml/__init__.py +0 -3
  83. myokit/formats/mathml/_ewriter.py +2 -11
  84. myokit/formats/mathml/_parser.py +4 -6
  85. myokit/formats/matlab/__init__.py +0 -3
  86. myokit/formats/matlab/_ewriter.py +1 -4
  87. myokit/formats/matlab/_exporter.py +2 -5
  88. myokit/formats/matlab/template/main.m +3 -2
  89. myokit/formats/opencl/__init__.py +0 -3
  90. myokit/formats/opencl/_ewriter.py +2 -4
  91. myokit/formats/opencl/_exporter.py +2 -5
  92. myokit/formats/opencl/template/cable.c +10 -10
  93. myokit/formats/opencl/template/kernel.cl +1 -1
  94. myokit/formats/opencl/template/minilog.py +1 -1
  95. myokit/formats/python/__init__.py +0 -3
  96. myokit/formats/python/_ewriter.py +2 -5
  97. myokit/formats/python/_exporter.py +0 -3
  98. myokit/formats/python/template/sim.py +14 -14
  99. myokit/formats/sbml/__init__.py +0 -3
  100. myokit/formats/sbml/_api.py +50 -44
  101. myokit/formats/sbml/_importer.py +1 -4
  102. myokit/formats/sbml/_parser.py +2 -5
  103. myokit/formats/stan/__init__.py +0 -3
  104. myokit/formats/stan/_ewriter.py +2 -4
  105. myokit/formats/stan/_exporter.py +2 -5
  106. myokit/formats/stan/template/cell.stan +3 -3
  107. myokit/formats/sympy/__init__.py +0 -3
  108. myokit/formats/sympy/_ereader.py +1 -4
  109. myokit/formats/sympy/_ewriter.py +2 -5
  110. myokit/formats/wcp/__init__.py +0 -3
  111. myokit/formats/wcp/_wcp.py +2 -8
  112. myokit/formats/xml/__init__.py +0 -3
  113. myokit/formats/xml/_exporter.py +0 -3
  114. myokit/formats/xml/_split.py +0 -3
  115. myokit/gui/__init__.py +80 -246
  116. myokit/gui/datablock_viewer.py +103 -86
  117. myokit/gui/datalog_viewer.py +214 -66
  118. myokit/gui/explorer.py +15 -21
  119. myokit/gui/ide.py +171 -144
  120. myokit/gui/progress.py +9 -9
  121. myokit/gui/source.py +406 -375
  122. myokit/gui/vargrapher.py +2 -12
  123. myokit/lib/deps.py +12 -13
  124. myokit/lib/guess.py +3 -4
  125. myokit/lib/hh.py +20 -18
  126. myokit/lib/markov.py +21 -20
  127. myokit/lib/multi.py +1 -3
  128. myokit/lib/plots.py +20 -9
  129. myokit/pacing.py +0 -3
  130. myokit/pype.py +7 -18
  131. myokit/tests/__init__.py +3 -6
  132. myokit/tests/ansic_event_based_pacing.py +1 -4
  133. myokit/tests/ansic_fixed_form_pacing.py +3 -6
  134. myokit/tests/data/beeler-1977-model-compare-b.mmt +2 -2
  135. myokit/tests/data/clancy-1999-fitting.mmt +1 -0
  136. myokit/tests/test_aux.py +13 -28
  137. myokit/tests/test_cellml_v1_api.py +4 -19
  138. myokit/tests/test_cellml_v1_parser.py +0 -15
  139. myokit/tests/test_cellml_v1_writer.py +0 -9
  140. myokit/tests/test_cellml_v2_api.py +4 -19
  141. myokit/tests/test_cellml_v2_parser.py +0 -15
  142. myokit/tests/test_cellml_v2_writer.py +0 -9
  143. myokit/tests/test_cmodel.py +16 -22
  144. myokit/tests/test_compiler_detection.py +1 -11
  145. myokit/tests/test_component.py +108 -56
  146. myokit/tests/test_config.py +34 -67
  147. myokit/tests/test_datablock.py +1 -9
  148. myokit/tests/test_datalog.py +19 -24
  149. myokit/tests/test_dependency_checking.py +8 -23
  150. myokit/tests/test_expressions.py +0 -9
  151. myokit/tests/test_float.py +1 -5
  152. myokit/tests/test_formats.py +0 -9
  153. myokit/tests/test_formats_axon.py +1 -9
  154. myokit/tests/test_formats_cellml.py +0 -15
  155. myokit/tests/test_formats_channelml.py +0 -15
  156. myokit/tests/test_formats_easyml.py +0 -14
  157. myokit/tests/test_formats_exporters.py +1 -16
  158. myokit/tests/test_formats_expression_writers.py +1 -17
  159. myokit/tests/test_formats_html.py +0 -3
  160. myokit/tests/test_formats_importers.py +1 -16
  161. myokit/tests/test_formats_mathml_content.py +0 -9
  162. myokit/tests/test_formats_mathml_presentation.py +0 -9
  163. myokit/tests/test_formats_opencl.py +0 -10
  164. myokit/tests/test_formats_sbml.py +0 -15
  165. myokit/tests/test_formats_sympy.py +0 -9
  166. myokit/tests/test_formats_wcp.py +1 -3
  167. myokit/tests/test_io.py +27 -27
  168. myokit/tests/test_jacobian_calculator.py +6 -14
  169. myokit/tests/test_jacobian_tracer.py +0 -9
  170. myokit/tests/test_lib_deps.py +0 -9
  171. myokit/tests/test_lib_guess.py +0 -9
  172. myokit/tests/test_lib_hh.py +18 -12
  173. myokit/tests/test_lib_markov.py +21 -13
  174. myokit/tests/test_lib_multi.py +0 -9
  175. myokit/tests/test_lib_plots.py +13 -8
  176. myokit/tests/test_meta.py +0 -3
  177. myokit/tests/test_model.py +390 -96
  178. myokit/tests/test_model_building.py +44 -96
  179. myokit/tests/test_opencl_info.py +5 -14
  180. myokit/tests/test_pacing_factory.py +0 -3
  181. myokit/tests/test_pacing_system_c.py +1 -23
  182. myokit/tests/test_pacing_system_py.py +0 -9
  183. myokit/tests/test_parsing.py +139 -56
  184. myokit/tests/test_progress_reporters.py +0 -3
  185. myokit/tests/test_protocol.py +0 -9
  186. myokit/tests/test_protocol_floating_point.py +1 -10
  187. myokit/tests/test_protocol_time_series.py +82 -0
  188. myokit/tests/test_pype.py +0 -9
  189. myokit/tests/test_quantity.py +0 -9
  190. myokit/tests/test_rhs_benchmarker.py +1 -9
  191. myokit/tests/test_sbml_api.py +27 -42
  192. myokit/tests/test_sbml_parser.py +4 -19
  193. myokit/tests/test_simulation_1d.py +45 -25
  194. myokit/tests/test_simulation_cvodes.py +321 -55
  195. myokit/tests/test_simulation_cvodes_from_disk.py +0 -3
  196. myokit/tests/test_simulation_fiber_tissue.py +39 -12
  197. myokit/tests/test_simulation_log_interval.py +1 -431
  198. myokit/tests/test_simulation_opencl.py +69 -48
  199. myokit/tests/test_simulation_opencl_log_interval.py +1 -3
  200. myokit/tests/test_simulation_opencl_vs_cvode.py +1 -10
  201. myokit/tests/test_simulation_opencl_vs_sim1d.py +1 -10
  202. myokit/tests/test_system_info.py +1 -11
  203. myokit/tests/test_tools.py +0 -9
  204. myokit/tests/test_unit.py +1 -10
  205. myokit/tests/test_user_functions.py +0 -10
  206. myokit/tests/test_variable.py +231 -27
  207. myokit/tools.py +5 -21
  208. myokit/units.py +5 -3
  209. {myokit-1.33.9.dist-info → myokit-1.35.0.dist-info}/METADATA +12 -15
  210. myokit-1.35.0.dist-info/RECORD +391 -0
  211. {myokit-1.33.9.dist-info → myokit-1.35.0.dist-info}/WHEEL +1 -1
  212. {myokit-1.33.9.dist-info → myokit-1.35.0.dist-info}/entry_points.txt +0 -1
  213. myokit/_exec_new.py +0 -15
  214. myokit/_exec_old.py +0 -15
  215. myokit/_sim/cvodesim.c +0 -1551
  216. myokit/_sim/cvodesim.py +0 -674
  217. myokit/_sim/icsim.cpp +0 -563
  218. myokit/_sim/icsim.py +0 -363
  219. myokit/_sim/psim.cpp +0 -656
  220. myokit/_sim/psim.py +0 -493
  221. myokit/lib/common.py +0 -1094
  222. myokit/tests/test_lib_common.py +0 -130
  223. myokit/tests/test_simulation_cvode.py +0 -612
  224. myokit/tests/test_simulation_ic.py +0 -108
  225. myokit/tests/test_simulation_p.py +0 -223
  226. myokit-1.33.9.dist-info/RECORD +0 -403
  227. /myokit/formats/opencl/template/{test → test.sh} +0 -0
  228. {myokit-1.33.9.dist-info → myokit-1.35.0.dist-info}/LICENSE.txt +0 -0
  229. {myokit-1.33.9.dist-info → myokit-1.35.0.dist-info}/top_level.txt +0 -0
myokit/_sim/psim.py DELETED
@@ -1,493 +0,0 @@
1
- #
2
- # Runs a simulation with differential objects, to obtain the state and the
3
- # partial derivatives of the state with respect to a list of parameters.
4
- #
5
- # This file is part of Myokit.
6
- # See http://myokit.org for copyright, sharing, and licensing details.
7
- #
8
- from __future__ import absolute_import, division
9
- from __future__ import print_function, unicode_literals
10
-
11
- import os
12
- import myokit
13
- import numpy as np
14
- import platform
15
- import warnings
16
-
17
-
18
- # Location of C template
19
- SOURCE_FILE = 'psim.cpp'
20
-
21
-
22
- class PSimulation(myokit.CppModule):
23
- """
24
- Runs a forward-Euler based simulation and calculates the partial
25
- derivatives of the model variables with respect to a given set of
26
- parameters.
27
-
28
- This class is deprecated. Sensitivities with respect to parameters can now
29
- be calculated with the :class:`Simulation` class.
30
-
31
- The simulation is based on automatic differentiation implemented using a
32
- C++ data type that replaces a single scalar float with a float and a list
33
- of partial derivatives. Any operations on this pair update both the float
34
- and the set of derivatives.
35
-
36
- The resulting output is a set of logged variables plus a matrix of
37
- derivatives ``dy/dp`` where ``y`` is a non-constant variable and ``p`` is
38
- a constant parameter. The variables and parameters to track can be
39
- specified using :class:`myokit.Variable` objects or by their names. The
40
- parameters should be given as a list ``parameters`` while the variables
41
- ``y`` should be given in the list ``variables``.
42
-
43
- N.B. Partial derivatives can not be calculated for the functions ``floor``,
44
- ``ceil`` and ``abs`` or for quotients and remainders. If these are
45
- encountered the resulting derivatives will be yielded as ``NaN``.
46
-
47
- A protocol can be passed in as ``protocol`` or set later using
48
- :meth:`set_protocol`.
49
-
50
- The model and protocol passed to the simulation are cloned and stored
51
- internally. Any changes to the original model or protocol will not affect
52
- the simulation.
53
-
54
- Simulations maintain an internal state consisting of
55
-
56
- - the current simulation time
57
- - the current state
58
- - the partial derivatives of the current state with respect to the
59
- parameters
60
-
61
- When a simulation is created, the simulation time is set to 0 and the
62
- state is obtained from the given model. The derivatives matrix is
63
- initialised as a matrix of size ``(n, m)`` with a row for each of the ``n``
64
- states and a column for each of ``m`` parameters.
65
-
66
- After each call to :meth:`run` the time, state and derivative variables are
67
- updated so that each successive call to run continues where the previous
68
- one left off. A :meth:`reset` method is provided that will set the time
69
- back to 0, revert the current state to the default state and reset the
70
- calculated derivatives.
71
-
72
- The simulation provides two inputs a variable can bind to:
73
-
74
- ``time``
75
- This variable contains the simulation time.
76
- ``pace``
77
- This variable contains the current value of the pacing variable
78
- as given by the protocol passed to the Simulation.
79
-
80
- No labeled variables are required.
81
- """
82
- _index = 0 # Unique id for generated module
83
-
84
- def __init__(
85
- self, model, protocol=None, variables=None, parameters=None):
86
- super(PSimulation, self).__init__()
87
-
88
- # Deprecated on 2021-02-25
89
- warnings.warn(
90
- 'The class `PSimulation` is deprecated. Sensitivities with'
91
- ' respect to parameters can now be calculated with the single cell'
92
- ' myokit.Simulation class.')
93
-
94
- # Check presence of variables and parameters arguments (are required
95
- # arguments but protocol is not...)
96
- if variables is None:
97
- raise ValueError(
98
- 'Please specify a set of variables whose derivatives should be'
99
- ' tracked.')
100
- if parameters is None:
101
- raise ValueError('Please specify a set of parameters.')
102
-
103
- # Require a valid model
104
- if not model.is_valid():
105
- model.validate()
106
- model = model.clone()
107
- self._model = model
108
-
109
- # Set protocol
110
- self.set_protocol(protocol)
111
-
112
- # Check tracked variables
113
- if len(variables) != len(set(variables)):
114
- raise ValueError('Duplicate variable in `variables`.')
115
- self._variables = []
116
- for v in variables:
117
- if isinstance(v, myokit.Variable):
118
- v = v.qname()
119
- v = self._model.get(v, myokit.Variable)
120
- if not (v.is_state() or v.is_intermediary()):
121
- if v.is_bound():
122
- raise ValueError(
123
- 'Variables to track cannot be bound to external'
124
- ' inputs.')
125
- else:
126
- raise ValueError('Variables to track cannot be constants.')
127
- self._variables.append(v)
128
-
129
- # Check parameters
130
- if len(parameters) != len(set(parameters)):
131
- raise ValueError('Duplicate parameter in `parameters`.')
132
- self._parameters = []
133
- for p in parameters:
134
- if isinstance(p, myokit.Variable):
135
- p = p.qname()
136
- p = self._model.get(p, myokit.Variable)
137
- if not p.is_literal():
138
- if p.is_bound():
139
- raise ValueError(
140
- 'Parameters cannot be bound to external inputs.')
141
- else:
142
- raise ValueError('Parameters must be literal constants.')
143
- self._parameters.append(p)
144
- del parameters
145
-
146
- # Create list of parameter values
147
- self._values = []
148
- for p in self._parameters:
149
- self._values.append(p.rhs().eval())
150
-
151
- # Get state and default state from model
152
- self._state = self._model.state()
153
- self._default_state = list(self._state)
154
-
155
- # Create list of state-parameter-derivatives
156
- ms = len(self._state)
157
- mp = len(self._parameters)
158
- self._state_ddp = [0.0] * (ms * mp)
159
-
160
- # Starting time
161
- self._time = 0
162
-
163
- # Default time step
164
- self._dt = 0
165
- self.set_step_size()
166
-
167
- # Unique simulation id
168
- PSimulation._index += 1
169
- module_name = 'myokit_PSimulation_' + str(PSimulation._index)
170
- module_name += '_' + str(myokit.pid_hash())
171
-
172
- # Arguments
173
- args = {
174
- 'module_name': module_name,
175
- 'model': self._model,
176
- 'variables': self._variables,
177
- 'parameters': self._parameters,
178
- }
179
- fname = os.path.join(myokit.DIR_CFUNC, SOURCE_FILE)
180
-
181
- # Define libraries
182
- libs = []
183
- if platform.system() != 'Windows':
184
- libs.append('m')
185
-
186
- # Create simulation
187
- libd = []
188
- incd = [myokit.DIR_CFUNC]
189
- self._sim = self._compile(module_name, fname, args, libs, libd, incd)
190
-
191
- def block(self, log, derivatives):
192
- """
193
- Takes the output of a simulation (a simulation log and a list of
194
- derivatives) and combines it into a single :class:`DataBlock2d` object.
195
-
196
- Each entry in the log is converted to a 0d entry in the block. The
197
- calculated derivatives are stored as the 2d field ``derivatives``.
198
- """
199
- # Get time data
200
- tvar = self._model.time().qname()
201
- try:
202
- time = log[tvar]
203
- except KeyError:
204
- raise ValueError(
205
- 'The given log must contain an entry for <' + tvar + '>.')
206
- # Check shape of derivatives array
207
- n = len(self._variables)
208
- m = len(self._parameters)
209
- shape = (len(time), n, m)
210
- if derivatives.shape != shape:
211
- raise ValueError(
212
- 'Wrong input: Expecting a derivatives array of shape '
213
- + str(shape) + '.')
214
- # Create datablock
215
- block = myokit.DataBlock2d(m, n, time)
216
- for k, v in log.items():
217
- if k != tvar:
218
- block.set0d(k, v)
219
- block.set2d('derivatives', derivatives)
220
- return block
221
-
222
- def default_state(self):
223
- """
224
- Returns the default state.
225
- """
226
- return list(self._default_state)
227
-
228
- def derivatives(self):
229
- """
230
- Return the partial derivatives of the current state with respect to the
231
- parameters. Only works once the simulation has been run!
232
- """
233
- ms = len(self._state)
234
- mp = len(self._parameters)
235
- return np.array(self._state_ddp, copy=True).reshape((ms, mp))
236
-
237
- def reset(self):
238
- """
239
- Resets the simulation:
240
-
241
- - The time variable is set to 0
242
- - The state is set back to the default state
243
- - The derivatives are set to zero
244
-
245
- """
246
- # Reset time
247
- self._time = 0
248
-
249
- # Reset state
250
- self._state = list(self._default_state)
251
-
252
- # Reset state-parameter-derivatives
253
- ms = len(self._state)
254
- mp = len(self._parameters)
255
- self._state_ddp = [0.0] * (ms * mp)
256
-
257
- def run(
258
- self, duration, log=None, log_interval=1, progress=None,
259
- msg='Running PSimulation'):
260
- """
261
- Runs a simulation and returns the logged results. Running a simulation
262
- has the following effects:
263
-
264
- - The internal state is updated to the last state in the simulation.
265
- - The simulation's time variable is updated to reflect the time
266
- elapsed during the simulation.
267
-
268
- The number of time units to simulate can be set with ``duration``.
269
-
270
- The variables to log can be indicated using the ``log`` argument. There
271
- are several options for its value:
272
-
273
- - ``None`` (default), to log all states.
274
- - An integer flag or a combination of flags. Options:
275
- ``myokit.LOG_NONE``, ``myokit.LOG_STATE``, ``myokit.LOG_INTER``,
276
- ``myokit.LOG_BOUND``.
277
- - A list of qnames or variable objects
278
- - A :class:`myokit.DataLog` obtained from a previous simulation.
279
- In this case, the newly logged data will be appended to the existing
280
- log.
281
-
282
- For more details on the ``log`` argument, see the function
283
- :meth:`myokit.prepare_log`.
284
-
285
- The method returns a :class:`myokit.DataLog` and a 3d numpy
286
- array. In the returned array, the first axis represents the time,
287
- the second axis is a tracked variable y and the third is a parameter p
288
- such that the point ``(t, y, p)`` represents ``dy/dp`` at time ``t``.
289
- For example, if ``d`` is the array of derivatives, to get the
290
- derivative of variables ``0`` with respect to parameter 2, use
291
- ``d[:,0,2]``.
292
-
293
- A log entry is created every time *at least* ``log_interval`` time
294
- units have passed. If ``log_interval <= 0`` every step taken is logged.
295
-
296
- To obtain feedback on the simulation progress, an object implementing
297
- the :class:`myokit.ProgressReporter` interface can be passed in.
298
- passed in as ``progress``. An optional description of the current
299
- simulation to use in the ProgressReporter can be passed in as `msg`.
300
- """
301
- # Simulation times
302
- if duration < 0:
303
- raise ValueError('Simulation time can\'t be negative.')
304
- tmin = self._time
305
- tmax = tmin + duration
306
-
307
- # Number of states, state derivatives
308
- ms = len(self._state)
309
- mv = len(self._variables)
310
- mp = len(self._parameters)
311
-
312
- # Final state and final state-parameter-derivative output lists
313
- state = [0.] * ms
314
- state_ddp = [0.] * (ms * mp)
315
-
316
- # Parse log argument
317
- log = myokit.prepare_log(
318
- log,
319
- self._model,
320
- if_empty=myokit.LOG_STATE + myokit.LOG_BOUND,
321
- allowed_classes=myokit.LOG_STATE + myokit.LOG_BOUND
322
- + myokit.LOG_INTER,
323
- )
324
-
325
- # Logging period (0 = log at every step)
326
- log_interval = float(log_interval)
327
- if log_interval < 0:
328
- log_interval = 0
329
-
330
- # Create empty list for variable-parameter-derivative lists
331
- varab_ddp = []
332
-
333
- # Get progress indication function (if any)
334
- if progress is None:
335
- progress = myokit._Simulation_progress
336
- if progress:
337
- if not isinstance(progress, myokit.ProgressReporter):
338
- raise ValueError(
339
- 'The argument `progress` must be either a subclass of'
340
- ' myokit.ProgressReporter or None.')
341
-
342
- # Run simulation
343
- if duration > 0:
344
- # Initialize
345
- self._sim.sim_init(
346
- tmin,
347
- tmax,
348
- self._dt,
349
- list(self._values),
350
- list(self._state),
351
- list(self._state_ddp),
352
- state,
353
- state_ddp,
354
- self._protocol,
355
- log,
356
- varab_ddp,
357
- log_interval,
358
- )
359
- t = tmin
360
- try:
361
- if progress:
362
- # Loop with feedback
363
- with progress.job(msg):
364
- r = 1.0 / duration
365
- while t < tmax:
366
- t = self._sim.sim_step()
367
- if not progress.update(min((t - tmin) * r, 1)):
368
- raise myokit.SimulationCancelledError()
369
- else:
370
- # Loop without feedback
371
- # (But with repeated returns to Python to allow Ctrl-C etc)
372
- while t < tmax:
373
- t = self._sim.sim_step()
374
- finally:
375
- # Clean even after KeyboardInterrupt or other Exception
376
- self._sim.sim_clean()
377
-
378
- # Update internal state
379
- self._state = list(state)
380
- self._state_ddp = list(state_ddp)
381
- self._time += duration
382
-
383
- # Convert derivatives to numpy arrays
384
- varab_ddp = np.array([
385
- np.array(np.array(x).reshape(mv, mp), copy=True)
386
- for x in varab_ddp])
387
-
388
- # Return
389
- return log, varab_ddp
390
-
391
- def set_constant(self, var, value):
392
- """
393
- Changes a model constant. Only literal constants (constants not
394
- dependent on any other variable) can be changed. Constants set as
395
- parameters cannot be changed with this method but may be set using
396
- :meth:`set_parameters`.
397
-
398
- The constant ``var`` can be given as a :class:`Variable` or a string
399
- containing a variable qname. The ``value`` should be given as a float.
400
- """
401
- value = float(value)
402
- if isinstance(var, myokit.Variable):
403
- var = var.qname()
404
- var = self._model.get(var)
405
- if not var.is_literal():
406
- raise ValueError(
407
- 'The given variable <' + var.qname() + '> is not a literal (it'
408
- ' depends on other variables)')
409
- if var in self._parameters:
410
- raise ValueError(
411
- 'The given variable <' + var.qname() + '> is set as a'
412
- ' parameter. Use set_parameters() instead.')
413
-
414
- # Update value in compiled simulation module
415
- self._sim.set_constant(var.qname(), value)
416
-
417
- # Update value in internal model
418
- self._model.set_value(var.qname(), value)
419
-
420
- def set_parameters(self, values):
421
- """
422
- Changes the values of the parameters under investigation.
423
-
424
- The argument ``values`` must either be an ordered sequence containing
425
- the values for every parameter, or a mapping from one or more parameter
426
- names to their new values.
427
-
428
- **N.B. Calling this method will reset the simulation.**
429
- """
430
- if isinstance(values, dict):
431
- # Create list to update so that property change only happens after
432
- # error checks.
433
- new_values = list(self._values)
434
-
435
- # Check all key-value pairs
436
- for k, v in values.items():
437
- if isinstance(k, myokit.Variable):
438
- k = k.qname()
439
- try:
440
- k = self._model.get(k, myokit.Variable)
441
- except KeyError:
442
- raise ValueError('Unknown parameter: <' + str(k) + '>.')
443
- try:
444
- i = self._parameters.index(k)
445
- except ValueError:
446
- raise ValueError(
447
- 'Variable <' + str(k) + '> was not set as a'
448
- ' parameter.')
449
- new_values[i] = float(v)
450
- self._values = new_values
451
-
452
- else:
453
-
454
- # Check size of list & set
455
- if len(values) != len(self._values):
456
- raise ValueError(
457
- 'Argument `values` should be either a dict or a list of '
458
- + str(len(self._values)) + ' values.')
459
- self._values = [float(x) for x in values]
460
-
461
- # Reset the simulation: the stored partial derivatives are no longer
462
- # accurate.
463
- self.reset()
464
-
465
- def set_protocol(self, protocol=None):
466
- """
467
- Changes the pacing protocol used by this simulation.
468
- """
469
- if protocol is None:
470
- self._protocol = None
471
- else:
472
- self._protocol = protocol.clone()
473
-
474
- def set_step_size(self, dt=0.01):
475
- """
476
- Sets the step size used in the forward Euler solving routine.
477
- """
478
- dt = float(dt)
479
- if dt <= 0:
480
- raise ValueError('Step size must be greater than zero.')
481
- self._dt = dt
482
-
483
- def state(self):
484
- """
485
- Returns the current state.
486
- """
487
- return list(self._state)
488
-
489
- def time(self):
490
- """
491
- Returns the current simulation time.
492
- """
493
- return self._time