mxlpy 0.21.0__py3-none-any.whl → 0.23.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.
@@ -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, full_prec=False))
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, full_prec=False))
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, fully_qualified_modules=True, full_prec=False)}
97
+ """.replace("math.factorial", "scipy.special.factorial")
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.subs(1.0, 1) # type: ignore