mxlpy 0.12.0__py3-none-any.whl → 0.14.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/plot.py CHANGED
@@ -52,7 +52,7 @@ __all__ = [
52
52
 
53
53
  import itertools as it
54
54
  import math
55
- from typing import TYPE_CHECKING, Literal, cast
55
+ from typing import TYPE_CHECKING, Any, Literal, cast
56
56
 
57
57
  import numpy as np
58
58
  import pandas as pd
@@ -292,15 +292,19 @@ def reset_prop_cycle(ax: Axes) -> None:
292
292
  def context(
293
293
  colors: list[str] | None = None,
294
294
  line_width: float | None = None,
295
+ line_style: Linestyle | None = None,
296
+ rc: dict[str, Any] | None = None,
295
297
  ) -> Generator[None, None, None]:
296
298
  """Context manager to set the defaults for plots.
297
299
 
298
300
  Args:
299
301
  colors: colors to use for the plot.
300
302
  line_width: line width to use for the plot.
303
+ line_style: line style to use for the plot.
304
+ rc: additional keyword arguments to pass to the rc context.
301
305
 
302
306
  """
303
- rc = {}
307
+ rc = {} if rc is None else rc
304
308
 
305
309
  if colors is not None:
306
310
  rc["axes.prop_cycle"] = cycler(color=colors)
@@ -308,6 +312,9 @@ def context(
308
312
  if line_width is not None:
309
313
  rc["lines.linewidth"] = line_width
310
314
 
315
+ if line_style is not None:
316
+ rc["lines.linestyle"] = line_style
317
+
311
318
  with plt.rc_context(rc):
312
319
  yield
313
320
 
@@ -476,19 +483,17 @@ def lines(
476
483
  ) -> FigAx:
477
484
  """Plot multiple lines on the same axis."""
478
485
  fig, ax = _default_fig_ax(ax=ax, grid=grid)
479
- ax.plot(
486
+ _lines = ax.plot(
480
487
  x.index,
481
488
  x,
482
- # linestyle=linestyle,
483
- # linewidth=linewidth,
484
489
  alpha=alpha,
485
490
  )
486
491
  _default_labels(ax, xlabel=x.index.name, ylabel=None)
487
492
  if legend:
488
- if isinstance(x, pd.Series):
489
- ax.legend([str(x.name)])
490
- else:
491
- ax.legend(x.columns)
493
+ names = x.columns if isinstance(x, pd.DataFrame) else [str(x.name)]
494
+ for line, name in zip(_lines, names, strict=True):
495
+ line.set_label(name)
496
+ ax.legend()
492
497
  return fig, ax
493
498
 
494
499
 
mxlpy/simulator.py CHANGED
@@ -10,6 +10,7 @@ Classes:
10
10
 
11
11
  from __future__ import annotations
12
12
 
13
+ import warnings
13
14
  from dataclasses import dataclass, field
14
15
  from typing import TYPE_CHECKING, Literal, Self, cast, overload
15
16
 
@@ -319,6 +320,7 @@ class Simulator:
319
320
  variables: list[pd.DataFrame] | None
320
321
  dependent: list[pd.DataFrame] | None
321
322
  simulation_parameters: list[dict[str, float]] | None
323
+ use_jacobian: bool
322
324
 
323
325
  # For resets (e.g. update variable)
324
326
  _integrator_type: IntegratorType
@@ -330,6 +332,7 @@ class Simulator:
330
332
  y0: dict[str, float] | None = None,
331
333
  integrator: IntegratorType = DefaultIntegrator,
332
334
  *,
335
+ use_jacobian: bool = False,
333
336
  test_run: bool = True,
334
337
  ) -> None:
335
338
  """Initialize the Simulator.
@@ -339,6 +342,7 @@ class Simulator:
339
342
  y0: Initial conditions for the model variables.
340
343
  If None, the initial conditions are obtained from the model.
341
344
  integrator: The integrator to use for the simulation.
345
+ use_jacobian: Whether to use the Jacobian for the simulation.
342
346
  test_run (bool, optional): If True, performs a test run for better error messages
343
347
 
344
348
  """
@@ -348,7 +352,9 @@ class Simulator:
348
352
  self._integrator_type = integrator
349
353
  self._time_shift = None
350
354
  self.variables = None
355
+ self.dependent = None
351
356
  self.simulation_parameters = None
357
+ self.use_jacobian = use_jacobian
352
358
 
353
359
  if test_run:
354
360
  self.model.get_right_hand_side(self.y0, time=0)
@@ -360,16 +366,29 @@ class Simulator:
360
366
 
361
367
  from mxlpy.symbolic import to_symbolic_model
362
368
 
363
- try:
364
- jac = to_symbolic_model(self.model).jacobian()
365
-
366
- _jacobian = lambda t, y: lambdify( # noqa: E731
367
- ("time", self.model.get_variable_names()),
368
- jac.subs(self.model._parameters), # noqa: SLF001
369
- )(t, y)
370
-
371
- except: # noqa: E722
372
- _jacobian = None # type: ignore
369
+ _jacobian = None
370
+ if self.use_jacobian:
371
+ try:
372
+ # NOTE: this implementation is not correct in the sense
373
+ # that it does not take parameter updates into account
374
+ # jac = (
375
+ # to_symbolic_model(self.model)
376
+ # .jacobian()
377
+ # .subs(self.model._parameters)
378
+ # )
379
+ # _jacobian = lambdify(
380
+ # ("time", self.model.get_variable_names()),
381
+ # jac,
382
+ # )
383
+
384
+ # NOTE: this implementation is correct, but slow as hell
385
+ jac = to_symbolic_model(self.model).jacobian()
386
+ _jacobian = lambda t, y: lambdify( # noqa: E731
387
+ ("time", self.model.get_variable_names()),
388
+ jac.subs(self.model._parameters), # noqa: SLF001
389
+ )(t, y)
390
+ except Exception as e: # noqa: BLE001
391
+ warnings.warn(str(e), stacklevel=2)
373
392
 
374
393
  y0 = self.y0
375
394
  self.integrator = self._integrator_type(
mxlpy/types.py CHANGED
@@ -192,7 +192,11 @@ class Derived:
192
192
  dependent: Dictionary of dependent variables.
193
193
 
194
194
  """
195
- dependent[self.name] = self.fn(*dependent.loc[:, self.args].to_numpy().T)
195
+ try:
196
+ dependent[self.name] = self.fn(*dependent.loc[:, self.args].to_numpy().T)
197
+ except ValueError: # e.g. numpy.where
198
+ sub = dependent.loc[:, self.args].to_numpy()
199
+ dependent[self.name] = [self.fn(*row) for row in sub]
196
200
 
197
201
 
198
202
  @dataclass(kw_only=True, slots=True)
@@ -233,7 +237,11 @@ class Readout:
233
237
  dependent: Dictionary of dependent variables.
234
238
 
235
239
  """
236
- dependent[self.name] = self.fn(*dependent.loc[:, self.args].to_numpy().T)
240
+ try:
241
+ dependent[self.name] = self.fn(*dependent.loc[:, self.args].to_numpy().T)
242
+ except ValueError: # e.g. numpy.where
243
+ sub = dependent.loc[:, self.args].to_numpy()
244
+ dependent[self.name] = [self.fn(*row) for row in sub]
237
245
 
238
246
 
239
247
  @dataclass(kw_only=True, slots=True)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mxlpy
3
- Version: 0.12.0
3
+ Version: 0.14.0
4
4
  Summary: A package to build metabolic models
5
5
  Author-email: Marvin van Aalst <marvin.vanaalst@gmail.com>
6
6
  Maintainer-email: Marvin van Aalst <marvin.vanaalst@gmail.com>
@@ -12,12 +12,12 @@ 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
14
14
  mxlpy/paths.py,sha256=TK2wO4N9lG-UV1JGfeB64q48JVDbwqIUj63rl55MKuQ,1022
15
- mxlpy/plot.py,sha256=z1JW7Si1JQyNMj_MMLkgbLkOkSjVcfAZJGjm_WqCgT4,24355
15
+ 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=CeMmm5SdgJphQWWBygnv0rxiXjBUJPWHV8-bh6miJNM,20494
20
- mxlpy/types.py,sha256=aWDtWOTZo4UQJ3rYGq1m6aV4hGxIjvycfJGc8CIDQLE,13775
19
+ mxlpy/simulator.py,sha256=vuTLuVanCIGAEqW8NUdGQvVKgoyvd45O-xBsbUoKaCI,21372
20
+ mxlpy/types.py,sha256=RRhi1s6T9Yy8uZdLkWi7pvQTLmyPOlCgGTF8URYQGVA,14149
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
@@ -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.12.0.dist-info/METADATA,sha256=Ul9QrtiIlIBZSsRGrTF2J-D_ssjpQtpsw_4IA3LR_lg,4564
48
- mxlpy-0.12.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
49
- mxlpy-0.12.0.dist-info/licenses/LICENSE,sha256=bEzjyjy1stQhfRDVaVHa3xV1x-V8emwdlbMvYO8Zo84,35073
50
- mxlpy-0.12.0.dist-info/RECORD,,
47
+ mxlpy-0.14.0.dist-info/METADATA,sha256=WyKwohN13eTY0JZRyWaNpVFJfAD4z0gviWZ212aAKbo,4564
48
+ mxlpy-0.14.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
49
+ mxlpy-0.14.0.dist-info/licenses/LICENSE,sha256=bEzjyjy1stQhfRDVaVHa3xV1x-V8emwdlbMvYO8Zo84,35073
50
+ mxlpy-0.14.0.dist-info/RECORD,,
File without changes