modelbase2 0.1.79__py3-none-any.whl → 0.2.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 (58) hide show
  1. modelbase2/__init__.py +138 -26
  2. modelbase2/distributions.py +306 -0
  3. modelbase2/experimental/__init__.py +17 -0
  4. modelbase2/experimental/codegen.py +239 -0
  5. modelbase2/experimental/diff.py +227 -0
  6. modelbase2/experimental/notes.md +4 -0
  7. modelbase2/experimental/tex.py +521 -0
  8. modelbase2/fit.py +284 -0
  9. modelbase2/fns.py +185 -0
  10. modelbase2/integrators/__init__.py +19 -0
  11. modelbase2/integrators/int_assimulo.py +146 -0
  12. modelbase2/integrators/int_scipy.py +147 -0
  13. modelbase2/label_map.py +610 -0
  14. modelbase2/linear_label_map.py +301 -0
  15. modelbase2/mc.py +548 -0
  16. modelbase2/mca.py +280 -0
  17. modelbase2/model.py +1621 -0
  18. modelbase2/npe.py +343 -0
  19. modelbase2/parallel.py +171 -0
  20. modelbase2/parameterise.py +28 -0
  21. modelbase2/paths.py +36 -0
  22. modelbase2/plot.py +829 -0
  23. modelbase2/sbml/__init__.py +14 -0
  24. modelbase2/sbml/_data.py +77 -0
  25. modelbase2/sbml/_export.py +656 -0
  26. modelbase2/sbml/_import.py +585 -0
  27. modelbase2/sbml/_mathml.py +691 -0
  28. modelbase2/sbml/_name_conversion.py +52 -0
  29. modelbase2/sbml/_unit_conversion.py +74 -0
  30. modelbase2/scan.py +616 -0
  31. modelbase2/scope.py +96 -0
  32. modelbase2/simulator.py +635 -0
  33. modelbase2/surrogates/__init__.py +32 -0
  34. modelbase2/surrogates/_poly.py +66 -0
  35. modelbase2/surrogates/_torch.py +249 -0
  36. modelbase2/surrogates.py +316 -0
  37. modelbase2/types.py +352 -11
  38. modelbase2-0.2.0.dist-info/METADATA +81 -0
  39. modelbase2-0.2.0.dist-info/RECORD +42 -0
  40. {modelbase2-0.1.79.dist-info → modelbase2-0.2.0.dist-info}/WHEEL +1 -1
  41. modelbase2/core/__init__.py +0 -29
  42. modelbase2/core/algebraic_module_container.py +0 -130
  43. modelbase2/core/constant_container.py +0 -113
  44. modelbase2/core/data.py +0 -109
  45. modelbase2/core/name_container.py +0 -29
  46. modelbase2/core/reaction_container.py +0 -115
  47. modelbase2/core/utils.py +0 -28
  48. modelbase2/core/variable_container.py +0 -24
  49. modelbase2/ode/__init__.py +0 -13
  50. modelbase2/ode/integrator.py +0 -80
  51. modelbase2/ode/mca.py +0 -270
  52. modelbase2/ode/model.py +0 -470
  53. modelbase2/ode/simulator.py +0 -153
  54. modelbase2/utils/__init__.py +0 -0
  55. modelbase2/utils/plotting.py +0 -372
  56. modelbase2-0.1.79.dist-info/METADATA +0 -44
  57. modelbase2-0.1.79.dist-info/RECORD +0 -22
  58. {modelbase2-0.1.79.dist-info → modelbase2-0.2.0.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,147 @@
1
+ """Scipy integrator for solving ODEs."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass, field
6
+
7
+ __all__ = [
8
+ "Scipy",
9
+ ]
10
+
11
+ import copy
12
+ from typing import TYPE_CHECKING, cast
13
+
14
+ import numpy as np
15
+ import scipy.integrate as spi
16
+
17
+ from modelbase2.types import ArrayLike, Float
18
+
19
+ if TYPE_CHECKING:
20
+ from collections.abc import Callable
21
+
22
+
23
+ @dataclass
24
+ class Scipy:
25
+ """Scipy integrator for solving ODEs.
26
+
27
+ Attributes:
28
+ rhs: Right-hand side function of the ODE.
29
+ y0: Initial conditions.
30
+ atol: Absolute tolerance for the solver.
31
+ rtol: Relative tolerance for the solver.
32
+ t0: Initial time point.
33
+ _y0_orig: Original initial conditions.
34
+
35
+ Methods:
36
+ __post_init__: Initialize the Scipy integrator.
37
+ reset: Reset the integrator.
38
+ integrate: Integrate the ODE system.
39
+ integrate_to_steady_state: Integrate the ODE system to steady state.
40
+
41
+ """
42
+
43
+ rhs: Callable
44
+ y0: ArrayLike
45
+ atol: float = 1e-8
46
+ rtol: float = 1e-8
47
+ t0: float = 0.0
48
+ _y0_orig: ArrayLike = field(default_factory=list)
49
+
50
+ def __post_init__(self) -> None:
51
+ """Create copy of initial state.
52
+
53
+ This method creates a copy of the initial state `y0` and stores it in the `_y0_orig` attribute.
54
+ This is useful for preserving the original initial state for future reference or reset operations.
55
+
56
+ """
57
+ self._y0_orig = self.y0.copy()
58
+
59
+ def reset(self) -> None:
60
+ """Reset the integrator."""
61
+ self.t0 = 0
62
+ self.y0 = self._y0_orig.copy()
63
+
64
+ def integrate(
65
+ self,
66
+ *,
67
+ t_end: float,
68
+ steps: int | None = None,
69
+ ) -> tuple[ArrayLike | None, ArrayLike | None]:
70
+ """Integrate the ODE system.
71
+
72
+ Args:
73
+ t_end: Terminal time point for the integration.
74
+ steps: Number of steps for the integration.
75
+ time_points: Array of time points for the integration.
76
+
77
+ Returns:
78
+ tuple[ArrayLike | None, ArrayLike | None]: Tuple containing the time points and the integrated values.
79
+
80
+ """
81
+ # Scipy counts the total amount of return points rather than steps as assimulo
82
+ steps = 100 if steps is None else steps + 1
83
+
84
+ return self.integrate_time_course(
85
+ time_points=np.linspace(self.t0, t_end, steps)
86
+ )
87
+
88
+ def integrate_time_course(
89
+ self, *, time_points: ArrayLike
90
+ ) -> tuple[ArrayLike | None, ArrayLike | None]:
91
+ """Integrate the ODE system over a time course.
92
+
93
+ Args:
94
+ time_points: Time points for the integration.
95
+
96
+ Returns:
97
+ tuple[ArrayLike, ArrayLike]: Tuple containing the time points and the integrated values.
98
+
99
+ """
100
+
101
+ y = spi.odeint(
102
+ func=self.rhs,
103
+ y0=self.y0,
104
+ t=time_points,
105
+ tfirst=True,
106
+ atol=self.atol,
107
+ rtol=self.rtol,
108
+ )
109
+ self.t0 = time_points[-1]
110
+ self.y0 = y[-1, :]
111
+ return time_points, y
112
+
113
+ def integrate_to_steady_state(
114
+ self,
115
+ *,
116
+ tolerance: float,
117
+ rel_norm: bool,
118
+ step_size: int = 100,
119
+ max_steps: int = 1000,
120
+ ) -> tuple[float | None, ArrayLike | None]:
121
+ """Integrate the ODE system to steady state.
122
+
123
+ Args:
124
+ tolerance: Tolerance for determining steady state.
125
+ rel_norm: Whether to use relative normalization.
126
+ step_size: Step size for the integration (default: 100).
127
+ max_steps: Maximum number of steps for the integration (default: 1,000).
128
+ integrator: Name of the integrator to use (default: "lsoda").
129
+
130
+ Returns:
131
+ tuple[float | None, ArrayLike | None]: Tuple containing the final time point and the integrated values at steady state.
132
+
133
+ """
134
+ self.reset()
135
+ integ = spi.ode(self.rhs)
136
+ integ.set_integrator(name="lsoda")
137
+ integ.set_initial_value(self.y0)
138
+ t = self.t0 + step_size
139
+ y1 = copy.deepcopy(self.y0)
140
+ for _ in range(max_steps):
141
+ y2 = integ.integrate(t)
142
+ diff = (y2 - y1) / y1 if rel_norm else y2 - y1
143
+ if np.linalg.norm(diff, ord=2) < tolerance:
144
+ return t, cast(ArrayLike, y2)
145
+ y1 = y2
146
+ t += step_size
147
+ return None, None