mxlpy 0.14.0__py3-none-any.whl → 0.15.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.
- mxlpy/linear_label_map.py +2 -2
- mxlpy/meta/codegen_latex.py +1 -3
- mxlpy/meta/codegen_modebase.py +1 -1
- mxlpy/model.py +9 -13
- mxlpy/simulator.py +19 -24
- mxlpy/types.py +31 -26
- {mxlpy-0.14.0.dist-info → mxlpy-0.15.0.dist-info}/METADATA +1 -1
- {mxlpy-0.14.0.dist-info → mxlpy-0.15.0.dist-info}/RECORD +10 -10
- {mxlpy-0.14.0.dist-info → mxlpy-0.15.0.dist-info}/WHEEL +0 -0
- {mxlpy-0.14.0.dist-info → mxlpy-0.15.0.dist-info}/licenses/LICENSE +0 -0
mxlpy/linear_label_map.py
CHANGED
@@ -287,11 +287,11 @@ class LinearLabelMapper:
|
|
287
287
|
stoichiometry = {}
|
288
288
|
if substrate != "EXT":
|
289
289
|
stoichiometry[substrate] = Derived(
|
290
|
-
|
290
|
+
fn=_neg_one_div, args=[substrate.split("__")[0]]
|
291
291
|
)
|
292
292
|
if product != "EXT":
|
293
293
|
stoichiometry[product] = Derived(
|
294
|
-
|
294
|
+
fn=_one_div, args=[product.split("__")[0]]
|
295
295
|
)
|
296
296
|
|
297
297
|
m.add_reaction(
|
mxlpy/meta/codegen_latex.py
CHANGED
@@ -326,9 +326,7 @@ class TexExport:
|
|
326
326
|
parameters={gls.get(k, k): v for k, v in self.parameters.items()},
|
327
327
|
variables={gls.get(k, k): v for k, v in self.variables.items()},
|
328
328
|
derived={
|
329
|
-
gls.get(k, k): Derived(
|
330
|
-
name=k, fn=v.fn, args=[gls.get(i, i) for i in v.args]
|
331
|
-
)
|
329
|
+
gls.get(k, k): Derived(fn=v.fn, args=[gls.get(i, i) for i in v.args])
|
332
330
|
for k, v in self.derived.items()
|
333
331
|
},
|
334
332
|
reactions={
|
mxlpy/meta/codegen_modebase.py
CHANGED
@@ -64,7 +64,7 @@ def generate_mxlpy_code(model: Model) -> str:
|
|
64
64
|
)
|
65
65
|
args = ", ".join(f'"{k}"' for k in stoich.args)
|
66
66
|
stoich = ( # noqa: PLW2901
|
67
|
-
f"""Derived(
|
67
|
+
f"""Derived(fn={fn.__name__}, args=[{args}])"""
|
68
68
|
)
|
69
69
|
stoichiometry.append(f""""{var}": {stoich}""")
|
70
70
|
|
mxlpy/model.py
CHANGED
@@ -908,7 +908,7 @@ class Model:
|
|
908
908
|
|
909
909
|
"""
|
910
910
|
self._insert_id(name=name, ctx="derived")
|
911
|
-
self._derived[name] = Derived(
|
911
|
+
self._derived[name] = Derived(fn=fn, args=args)
|
912
912
|
return self
|
913
913
|
|
914
914
|
def get_derived_parameter_names(self) -> list[str]:
|
@@ -1058,12 +1058,10 @@ class Model:
|
|
1058
1058
|
self._insert_id(name=name, ctx="reaction")
|
1059
1059
|
|
1060
1060
|
stoich: dict[str, Derived | float] = {
|
1061
|
-
k: Derived(
|
1061
|
+
k: Derived(fn=fns.constant, args=[v]) if isinstance(v, str) else v
|
1062
1062
|
for k, v in stoichiometry.items()
|
1063
1063
|
}
|
1064
|
-
self._reactions[name] = Reaction(
|
1065
|
-
name=name, fn=fn, stoichiometry=stoich, args=args
|
1066
|
-
)
|
1064
|
+
self._reactions[name] = Reaction(fn=fn, stoichiometry=stoich, args=args)
|
1067
1065
|
return self
|
1068
1066
|
|
1069
1067
|
def get_reaction_names(self) -> list[str]:
|
@@ -1112,9 +1110,7 @@ class Model:
|
|
1112
1110
|
|
1113
1111
|
if stoichiometry is not None:
|
1114
1112
|
stoich = {
|
1115
|
-
k: Derived(
|
1116
|
-
if isinstance(v, str)
|
1117
|
-
else v
|
1113
|
+
k: Derived(fn=fns.constant, args=[v]) if isinstance(v, str) else v
|
1118
1114
|
for k, v in stoichiometry.items()
|
1119
1115
|
}
|
1120
1116
|
rxn.stoichiometry = stoich
|
@@ -1188,7 +1184,7 @@ class Model:
|
|
1188
1184
|
|
1189
1185
|
"""
|
1190
1186
|
self._insert_id(name=name, ctx="readout")
|
1191
|
-
self._readouts[name] = Readout(
|
1187
|
+
self._readouts[name] = Readout(fn=fn, args=args)
|
1192
1188
|
return self
|
1193
1189
|
|
1194
1190
|
def get_readout_names(self) -> list[str]:
|
@@ -1354,7 +1350,7 @@ class Model:
|
|
1354
1350
|
|
1355
1351
|
containers = self._derived | self._reactions | self._surrogates
|
1356
1352
|
for name in cache.order:
|
1357
|
-
containers[name].calculate_inpl(args)
|
1353
|
+
containers[name].calculate_inpl(name, args)
|
1358
1354
|
|
1359
1355
|
return args
|
1360
1356
|
|
@@ -1399,8 +1395,8 @@ class Model:
|
|
1399
1395
|
)
|
1400
1396
|
|
1401
1397
|
if include_readouts:
|
1402
|
-
for ro in self._readouts.
|
1403
|
-
ro.calculate_inpl(args)
|
1398
|
+
for name, ro in self._readouts.items(): # FIXME: order?
|
1399
|
+
ro.calculate_inpl(name, args)
|
1404
1400
|
|
1405
1401
|
return pd.Series(args, dtype=float)
|
1406
1402
|
|
@@ -1449,7 +1445,7 @@ class Model:
|
|
1449
1445
|
|
1450
1446
|
containers = self._derived | self._reactions | self._surrogates
|
1451
1447
|
for name in cache.order:
|
1452
|
-
containers[name].calculate_inpl_time_course(args)
|
1448
|
+
containers[name].calculate_inpl_time_course(name, args)
|
1453
1449
|
|
1454
1450
|
if include_readouts:
|
1455
1451
|
for name, ro in self._readouts.items():
|
mxlpy/simulator.py
CHANGED
@@ -16,8 +16,10 @@ from typing import TYPE_CHECKING, Literal, Self, cast, overload
|
|
16
16
|
|
17
17
|
import numpy as np
|
18
18
|
import pandas as pd
|
19
|
+
from sympy import lambdify
|
19
20
|
|
20
21
|
from mxlpy.integrators import DefaultIntegrator
|
22
|
+
from mxlpy.symbolic import to_symbolic_model
|
21
23
|
|
22
24
|
__all__ = ["Result", "Simulator"]
|
23
25
|
|
@@ -362,31 +364,24 @@ class Simulator:
|
|
362
364
|
self._initialise_integrator()
|
363
365
|
|
364
366
|
def _initialise_integrator(self) -> None:
|
365
|
-
|
366
|
-
|
367
|
-
from mxlpy.symbolic import to_symbolic_model
|
368
|
-
|
369
|
-
_jacobian = None
|
367
|
+
jac_fn = None
|
370
368
|
if self.use_jacobian:
|
371
369
|
try:
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
#
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
("time", self.model.get_variable_names()),
|
388
|
-
jac.subs(self.model._parameters), # noqa: SLF001
|
389
|
-
)(t, y)
|
370
|
+
_jac = to_symbolic_model(self.model).jacobian()
|
371
|
+
_jac_fn = lambdify(
|
372
|
+
(
|
373
|
+
"time",
|
374
|
+
self.model.get_variable_names(),
|
375
|
+
self.model.get_parameter_names(),
|
376
|
+
),
|
377
|
+
_jac,
|
378
|
+
)
|
379
|
+
jac_fn = lambda t, x: _jac_fn( # noqa: E731
|
380
|
+
t,
|
381
|
+
x,
|
382
|
+
self.model._parameters.values(), # noqa: SLF001
|
383
|
+
)
|
384
|
+
|
390
385
|
except Exception as e: # noqa: BLE001
|
391
386
|
warnings.warn(str(e), stacklevel=2)
|
392
387
|
|
@@ -394,7 +389,7 @@ class Simulator:
|
|
394
389
|
self.integrator = self._integrator_type(
|
395
390
|
self.model,
|
396
391
|
[y0[k] for k in self.model.get_variable_names()],
|
397
|
-
|
392
|
+
jac_fn,
|
398
393
|
)
|
399
394
|
|
400
395
|
def clear_results(self) -> None:
|
mxlpy/types.py
CHANGED
@@ -158,7 +158,6 @@ type IntegratorType = Callable[
|
|
158
158
|
class Derived:
|
159
159
|
"""Container for a derived value."""
|
160
160
|
|
161
|
-
name: str
|
162
161
|
fn: RateFn
|
163
162
|
args: list[str]
|
164
163
|
|
@@ -174,36 +173,35 @@ class Derived:
|
|
174
173
|
"""
|
175
174
|
return cast(float, self.fn(*(dependent[arg] for arg in self.args)))
|
176
175
|
|
177
|
-
def calculate_inpl(self, dependent: dict[str, float]) -> None:
|
176
|
+
def calculate_inpl(self, name: str, dependent: dict[str, float]) -> None:
|
178
177
|
"""Calculate the derived value in place.
|
179
178
|
|
180
179
|
Args:
|
180
|
+
name: Name of the derived variable.
|
181
181
|
dependent: Dictionary of dependent variables.
|
182
182
|
|
183
183
|
"""
|
184
|
-
dependent[
|
185
|
-
float, self.fn(*(dependent[arg] for arg in self.args))
|
186
|
-
)
|
184
|
+
dependent[name] = cast(float, self.fn(*(dependent[arg] for arg in self.args)))
|
187
185
|
|
188
|
-
def calculate_inpl_time_course(self, dependent: pd.DataFrame) -> None:
|
186
|
+
def calculate_inpl_time_course(self, name: str, dependent: pd.DataFrame) -> None:
|
189
187
|
"""Calculate the derived value in place.
|
190
188
|
|
191
189
|
Args:
|
190
|
+
name: Name of the derived variable.
|
192
191
|
dependent: Dictionary of dependent variables.
|
193
192
|
|
194
193
|
"""
|
195
194
|
try:
|
196
|
-
dependent[
|
195
|
+
dependent[name] = self.fn(*dependent.loc[:, self.args].to_numpy().T)
|
197
196
|
except ValueError: # e.g. numpy.where
|
198
197
|
sub = dependent.loc[:, self.args].to_numpy()
|
199
|
-
dependent[
|
198
|
+
dependent[name] = [self.fn(*row) for row in sub]
|
200
199
|
|
201
200
|
|
202
201
|
@dataclass(kw_only=True, slots=True)
|
203
202
|
class Readout:
|
204
203
|
"""Container for a readout."""
|
205
204
|
|
206
|
-
name: str
|
207
205
|
fn: RateFn
|
208
206
|
args: list[str]
|
209
207
|
|
@@ -219,36 +217,35 @@ class Readout:
|
|
219
217
|
"""
|
220
218
|
return cast(float, self.fn(*(dependent[arg] for arg in self.args)))
|
221
219
|
|
222
|
-
def calculate_inpl(self, dependent: dict[str, float]) -> None:
|
220
|
+
def calculate_inpl(self, name: str, dependent: dict[str, float]) -> None:
|
223
221
|
"""Calculate the readout in place.
|
224
222
|
|
225
223
|
Args:
|
224
|
+
name: Name of the derived variable.
|
226
225
|
dependent: Dictionary of dependent variables.
|
227
226
|
|
228
227
|
"""
|
229
|
-
dependent[
|
230
|
-
float, self.fn(*(dependent[arg] for arg in self.args))
|
231
|
-
)
|
228
|
+
dependent[name] = cast(float, self.fn(*(dependent[arg] for arg in self.args)))
|
232
229
|
|
233
|
-
def calculate_inpl_time_course(self, dependent: pd.DataFrame) -> None:
|
230
|
+
def calculate_inpl_time_course(self, name: str, dependent: pd.DataFrame) -> None:
|
234
231
|
"""Calculate the derived value in place.
|
235
232
|
|
236
233
|
Args:
|
234
|
+
name: Name of the derived variable.
|
237
235
|
dependent: Dictionary of dependent variables.
|
238
236
|
|
239
237
|
"""
|
240
238
|
try:
|
241
|
-
dependent[
|
239
|
+
dependent[name] = self.fn(*dependent.loc[:, self.args].to_numpy().T)
|
242
240
|
except ValueError: # e.g. numpy.where
|
243
241
|
sub = dependent.loc[:, self.args].to_numpy()
|
244
|
-
dependent[
|
242
|
+
dependent[name] = [self.fn(*row) for row in sub]
|
245
243
|
|
246
244
|
|
247
245
|
@dataclass(kw_only=True, slots=True)
|
248
246
|
class Reaction:
|
249
247
|
"""Container for a reaction."""
|
250
248
|
|
251
|
-
name: str
|
252
249
|
fn: RateFn
|
253
250
|
stoichiometry: Mapping[str, float | Derived]
|
254
251
|
args: list[str]
|
@@ -272,29 +269,29 @@ class Reaction:
|
|
272
269
|
"""
|
273
270
|
return cast(float, self.fn(*(dependent[arg] for arg in self.args)))
|
274
271
|
|
275
|
-
def calculate_inpl(self, dependent: dict[str, float]) -> None:
|
272
|
+
def calculate_inpl(self, name: str, dependent: dict[str, float]) -> None:
|
276
273
|
"""Calculate the reaction in place.
|
277
274
|
|
278
275
|
Args:
|
276
|
+
name: Name of the derived variable.
|
279
277
|
dependent: Dictionary of dependent variables.
|
280
278
|
|
281
279
|
"""
|
282
|
-
dependent[
|
283
|
-
float, self.fn(*(dependent[arg] for arg in self.args))
|
284
|
-
)
|
280
|
+
dependent[name] = cast(float, self.fn(*(dependent[arg] for arg in self.args)))
|
285
281
|
|
286
|
-
def calculate_inpl_time_course(self, dependent: pd.DataFrame) -> None:
|
282
|
+
def calculate_inpl_time_course(self, name: str, dependent: pd.DataFrame) -> None:
|
287
283
|
"""Calculate the derived value in place.
|
288
284
|
|
289
285
|
Args:
|
286
|
+
name: Name of the derived variable.
|
290
287
|
dependent: Dictionary of dependent variables.
|
291
288
|
|
292
289
|
"""
|
293
290
|
try:
|
294
|
-
dependent[
|
291
|
+
dependent[name] = self.fn(*dependent.loc[:, self.args].to_numpy().T)
|
295
292
|
except ValueError: # e.g. numpy.where
|
296
293
|
sub = dependent.loc[:, self.args].to_numpy()
|
297
|
-
dependent[
|
294
|
+
dependent[name] = [self.fn(*row) for row in sub]
|
298
295
|
|
299
296
|
|
300
297
|
@dataclass(kw_only=True, slots=True)
|
@@ -464,11 +461,19 @@ class AbstractSurrogate:
|
|
464
461
|
)
|
465
462
|
)
|
466
463
|
|
467
|
-
def calculate_inpl(
|
464
|
+
def calculate_inpl(
|
465
|
+
self,
|
466
|
+
name: str, # noqa: ARG002, for API compatibility
|
467
|
+
args: dict[str, float],
|
468
|
+
) -> None:
|
468
469
|
"""Predict outputs based on input data."""
|
469
470
|
args |= self.predict(np.array([args[arg] for arg in self.args]))
|
470
471
|
|
471
|
-
def calculate_inpl_time_course(
|
472
|
+
def calculate_inpl_time_course(
|
473
|
+
self,
|
474
|
+
name: str, # noqa: ARG002, for API compatibility
|
475
|
+
args: pd.DataFrame,
|
476
|
+
) -> None:
|
472
477
|
"""Predict outputs based on input data."""
|
473
478
|
args[list(self.stoichiometries)] = pd.DataFrame(
|
474
479
|
[self.predict(y) for y in args.loc[:, self.args].to_numpy()],
|
@@ -4,10 +4,10 @@ mxlpy/fit.py,sha256=LwSoLfNVrqSlTtuUApwH36LjzGU0HLs4C_2qqTTjXFE,7859
|
|
4
4
|
mxlpy/fns.py,sha256=ct_RFj9koW8vXHyr27GnbZUHUS_zfs4rDysybuFiOaU,4599
|
5
5
|
mxlpy/identify.py,sha256=af52SCG4nlY9sSw22goaIheuvXR09QYK4ksCT24QHWI,1946
|
6
6
|
mxlpy/label_map.py,sha256=urv-QTb0MUEKjwWvKtJSB8H2kvhLn1EKfRIH7awQQ8Y,17769
|
7
|
-
mxlpy/linear_label_map.py,sha256=
|
7
|
+
mxlpy/linear_label_map.py,sha256=DqzN_akacPccZwzYAR3ANIdzAU_GU6Xe6gWV9DHAAWU,10282
|
8
8
|
mxlpy/mc.py,sha256=HWuJq4fV_wfTDERbLJRSF3fjCCYMxzLdqAyO53Z_uF8,16985
|
9
9
|
mxlpy/mca.py,sha256=H0dfV45Kz5nMIW8s2V61op7x6LmI21wWgRf94i6iIY4,9328
|
10
|
-
mxlpy/model.py,sha256
|
10
|
+
mxlpy/model.py,sha256=qzol8nDSbM3HdESh50c4UFjn6Pw5JwcvhQ5AyKnbyvc,57576
|
11
11
|
mxlpy/npe.py,sha256=oiRLA43-qf-AcS2KpQfJIOt7-Ev9Aj5sF6TMq9bJn84,8747
|
12
12
|
mxlpy/parallel.py,sha256=kX4Td5YoovDwZp6kX_3cfO6QtHSS9ieJ0bMZiKs3Xv8,5002
|
13
13
|
mxlpy/parameterise.py,sha256=2jMhhO-bHTFP_0kXercJekeATAZYBg5FrK1MQ_mWGpk,654
|
@@ -16,16 +16,16 @@ mxlpy/plot.py,sha256=4uu-6d8LH-GWX-sG_TlSpkSsnikv1DLTtnjJzA7nuRA,24670
|
|
16
16
|
mxlpy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
17
|
mxlpy/report.py,sha256=h7dhcBzPFydLPxdsEXokzDf7Ce4PirXMsvLqlDZLSWM,7181
|
18
18
|
mxlpy/scan.py,sha256=-1SLyXJOX3U3CxeP1dEC4ytAoBMCH0Ql89wGvsG3LbI,18858
|
19
|
-
mxlpy/simulator.py,sha256=
|
20
|
-
mxlpy/types.py,sha256=
|
19
|
+
mxlpy/simulator.py,sha256=9Ne4P5Jrwgx4oAlljPvCqSCCy98_5Lv1B87y1AkbI4c,21041
|
20
|
+
mxlpy/types.py,sha256=AGWFK59MRRVBOr8I1EmFKGdRpF1DiT8C4lB95-oBk40,14512
|
21
21
|
mxlpy/experimental/__init__.py,sha256=kZTE-92OErpHzNRqmgSQYH4CGXrogGJ5EL35XGZQ81M,206
|
22
22
|
mxlpy/experimental/diff.py,sha256=4bztagJzFMsQJM7dlun_kv-WrWssM8CIw7gcL63hFf8,8952
|
23
23
|
mxlpy/integrators/__init__.py,sha256=kqmV6a0TRyLGR_XqbyAI652AfptYnXAUpqbSFg0CpP8,450
|
24
24
|
mxlpy/integrators/int_assimulo.py,sha256=d-4HHOj4vmGpg8ig2IXMO5CPiIrq89_quEKvCxIKrhw,4747
|
25
25
|
mxlpy/integrators/int_scipy.py,sha256=dFHlYTeb2zX97f3VuNdMJdI7WEYshF4JAIgprKKk2z4,4581
|
26
26
|
mxlpy/meta/__init__.py,sha256=Jyy4063fZy6iT4LSwjPyEAVr4N_3xxcLc8wDBoDPyKc,278
|
27
|
-
mxlpy/meta/codegen_latex.py,sha256=
|
28
|
-
mxlpy/meta/codegen_modebase.py,sha256=
|
27
|
+
mxlpy/meta/codegen_latex.py,sha256=R0OJqzE7PnOCWLk52C3XWuRb-zI2eYTvV2oJZJvPsOE,13414
|
28
|
+
mxlpy/meta/codegen_modebase.py,sha256=_ZAW4NvXhKwJQLGz5hkwwZpL2JMAJlfG-GUWkYIiNvw,3124
|
29
29
|
mxlpy/meta/codegen_py.py,sha256=xSdeuEGPGc-QKRMgJO4VSPGMlxCPEV5prkKjNQ2D2hg,3483
|
30
30
|
mxlpy/meta/source_tools.py,sha256=EN3OoGQaXeIsDTJvA7S15-xDBra3DCIyFZEJ6h0Fy0k,11125
|
31
31
|
mxlpy/nn/__init__.py,sha256=yUc4o-iqfVVzkq9tZCstWwizrCqNlMft0YUwWGFFO-E,219
|
@@ -44,7 +44,7 @@ mxlpy/surrogates/_torch.py,sha256=E_1eDUlPSVFwROkdMDCqYwwHE-61pjNMJWotnhjzge0,58
|
|
44
44
|
mxlpy/symbolic/__init__.py,sha256=3hQjCMw8-6iOxeUdfnCg8449fF_BRF2u6lCM1GPpkRY,222
|
45
45
|
mxlpy/symbolic/strikepy.py,sha256=r6nRtckV1nxKq3i1bYYWZOkzwZ5XeKQuZM5ck44vUo0,20010
|
46
46
|
mxlpy/symbolic/symbolic_model.py,sha256=YL9noEeP3_0DoKXwMPELtfmPuP6mgNcLIJgDRCkyB7A,2434
|
47
|
-
mxlpy-0.
|
48
|
-
mxlpy-0.
|
49
|
-
mxlpy-0.
|
50
|
-
mxlpy-0.
|
47
|
+
mxlpy-0.15.0.dist-info/METADATA,sha256=EXj4l7bToJEQx3jbL26ECI_VuxtSgutyL44zdxLQ4Bg,4564
|
48
|
+
mxlpy-0.15.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
49
|
+
mxlpy-0.15.0.dist-info/licenses/LICENSE,sha256=bEzjyjy1stQhfRDVaVHa3xV1x-V8emwdlbMvYO8Zo84,35073
|
50
|
+
mxlpy-0.15.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|