mxlpy 0.20.0__py3-none-any.whl → 0.22.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/__init__.py +5 -1
- mxlpy/carousel.py +166 -0
- mxlpy/compare.py +2 -6
- mxlpy/experimental/diff.py +1 -1
- mxlpy/fit.py +386 -44
- mxlpy/identify.py +20 -16
- mxlpy/integrators/int_scipy.py +3 -0
- mxlpy/label_map.py +5 -5
- mxlpy/linear_label_map.py +3 -1
- mxlpy/mc.py +24 -20
- mxlpy/mca.py +9 -7
- mxlpy/meta/__init__.py +5 -3
- mxlpy/meta/codegen_latex.py +44 -30
- mxlpy/meta/codegen_model.py +174 -0
- mxlpy/meta/{codegen_modebase.py → codegen_mxlpy.py} +35 -29
- mxlpy/meta/source_tools.py +408 -167
- mxlpy/meta/sympy_tools.py +117 -0
- mxlpy/model.py +528 -224
- mxlpy/parallel.py +7 -6
- mxlpy/report.py +153 -90
- mxlpy/sbml/_export.py +11 -8
- mxlpy/sbml/_import.py +7 -7
- mxlpy/scan.py +32 -20
- mxlpy/simulator.py +240 -59
- mxlpy/symbolic/symbolic_model.py +29 -17
- mxlpy/types.py +45 -20
- mxlpy/units.py +128 -0
- {mxlpy-0.20.0.dist-info → mxlpy-0.22.0.dist-info}/METADATA +3 -1
- mxlpy-0.22.0.dist-info/RECORD +58 -0
- mxlpy/meta/codegen_py.py +0 -115
- mxlpy-0.20.0.dist-info/RECORD +0 -55
- {mxlpy-0.20.0.dist-info → mxlpy-0.22.0.dist-info}/WHEEL +0 -0
- {mxlpy-0.20.0.dist-info → mxlpy-0.22.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,117 @@
|
|
1
|
+
"""Tools for working with sympy expressions."""
|
2
|
+
|
3
|
+
from __future__ import annotations
|
4
|
+
|
5
|
+
from typing import TYPE_CHECKING, cast
|
6
|
+
|
7
|
+
import sympy
|
8
|
+
from sympy.printing import rust_code
|
9
|
+
from sympy.printing.pycode import pycode
|
10
|
+
|
11
|
+
from mxlpy.meta.source_tools import fn_to_sympy
|
12
|
+
from mxlpy.types import Derived
|
13
|
+
|
14
|
+
if TYPE_CHECKING:
|
15
|
+
from collections.abc import Iterable, Mapping
|
16
|
+
|
17
|
+
__all__ = [
|
18
|
+
"list_of_symbols",
|
19
|
+
"stoichiometries_to_sympy",
|
20
|
+
"sympy_to_inline_py",
|
21
|
+
"sympy_to_inline_rust",
|
22
|
+
"sympy_to_python_fn",
|
23
|
+
]
|
24
|
+
|
25
|
+
|
26
|
+
def list_of_symbols(args: Iterable[str]) -> list[sympy.Symbol | sympy.Expr]:
|
27
|
+
"""Convert list of strings to list of symbols."""
|
28
|
+
return [sympy.Symbol(arg) for arg in args]
|
29
|
+
|
30
|
+
|
31
|
+
def sympy_to_inline_py(expr: sympy.Expr) -> str:
|
32
|
+
"""Convert a sympy expression to inline Python code.
|
33
|
+
|
34
|
+
Parameters
|
35
|
+
----------
|
36
|
+
expr
|
37
|
+
The sympy expression to convert
|
38
|
+
|
39
|
+
Returns
|
40
|
+
-------
|
41
|
+
str
|
42
|
+
Python code string for the expression
|
43
|
+
|
44
|
+
Examples
|
45
|
+
--------
|
46
|
+
>>> import sympy
|
47
|
+
>>> x = sympy.Symbol('x')
|
48
|
+
>>> expr = x**2 + 2*x + 1
|
49
|
+
>>> sympy_to_inline(expr)
|
50
|
+
'x**2 + 2*x + 1'
|
51
|
+
|
52
|
+
"""
|
53
|
+
return cast(str, pycode(expr, fully_qualified_modules=True))
|
54
|
+
|
55
|
+
|
56
|
+
def sympy_to_inline_rust(expr: sympy.Expr) -> str:
|
57
|
+
"""Create rust code from sympy expression."""
|
58
|
+
return cast(str, rust_code(expr))
|
59
|
+
|
60
|
+
|
61
|
+
def sympy_to_python_fn(
|
62
|
+
*,
|
63
|
+
fn_name: str,
|
64
|
+
args: list[str],
|
65
|
+
expr: sympy.Expr,
|
66
|
+
) -> str:
|
67
|
+
"""Convert a sympy expression to a python function.
|
68
|
+
|
69
|
+
Parameters
|
70
|
+
----------
|
71
|
+
fn_name
|
72
|
+
Name of the function to generate
|
73
|
+
args
|
74
|
+
List of argument names for the function
|
75
|
+
expr
|
76
|
+
Sympy expression to convert to a function body
|
77
|
+
|
78
|
+
Returns
|
79
|
+
-------
|
80
|
+
str
|
81
|
+
String representation of the generated function
|
82
|
+
|
83
|
+
Examples
|
84
|
+
--------
|
85
|
+
>>> import sympy
|
86
|
+
>>> x, y = sympy.symbols('x y')
|
87
|
+
>>> expr = x**2 + y
|
88
|
+
>>> print(sympy_to_fn(fn_name="square_plus_y", args=["x", "y"], expr=expr))
|
89
|
+
def square_plus_y(x: float, y: float) -> float:
|
90
|
+
return x**2 + y
|
91
|
+
|
92
|
+
"""
|
93
|
+
fn_args = ", ".join(f"{i}: float" for i in args)
|
94
|
+
|
95
|
+
return f"""def {fn_name}({fn_args}) -> float:
|
96
|
+
return {pycode(expr)}
|
97
|
+
"""
|
98
|
+
|
99
|
+
|
100
|
+
def stoichiometries_to_sympy(
|
101
|
+
origin: str,
|
102
|
+
stoichs: Mapping[str, float | Derived],
|
103
|
+
) -> sympy.Expr:
|
104
|
+
"""Convert mxlpy stoichiometries to single expression."""
|
105
|
+
expr = sympy.Integer(0)
|
106
|
+
|
107
|
+
for rxn_name, rxn_stoich in stoichs.items():
|
108
|
+
if isinstance(rxn_stoich, Derived):
|
109
|
+
sympy_fn = fn_to_sympy(
|
110
|
+
rxn_stoich.fn,
|
111
|
+
origin=origin,
|
112
|
+
model_args=list_of_symbols(rxn_stoich.args),
|
113
|
+
)
|
114
|
+
expr = expr + sympy_fn * sympy.Symbol(rxn_name) # type: ignore
|
115
|
+
else:
|
116
|
+
expr = expr + rxn_stoich * sympy.Symbol(rxn_name) # type: ignore
|
117
|
+
return expr
|