Skip to content

Commit fd01339

Browse files
dweindlclaude
andcommitted
Add petab_symbol
Add `petab.v1.math.petab_symbol` (also available from `petab.v2.math`), which creates a sympy symbol with the same assumptions as the symbols created by `sympify_petab` (currently `real=True`). Use it in the parser and in `calculate`, instead of repeating `real=True`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 1307856 commit fd01339

7 files changed

Lines changed: 32 additions & 14 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@
6969
* `petab.v2.Problem.get_unused_id` returns an identifier that is not yet
7070
used in the problem or its model
7171
(by @dweindl in https://github.com/PEtab-dev/libpetab-python/pull/561)
72+
* `petab.v1.math.petab_symbol` (also in `petab.v2.math`) creates sympy
73+
symbols with the same assumptions as `sympify_petab`
74+
(by @dweindl in https://github.com/PEtab-dev/libpetab-python/pull/563)
7275

7376
## 0.9 series
7477

‎petab/v1/calculate.py‎

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import petab.v1 as petab
1212

1313
from .C import *
14-
from .math import sympify_petab
14+
from .math import petab_symbol, sympify_petab
1515

1616
__all__ = [
1717
"calculate_chi2",
@@ -202,18 +202,16 @@ def evaluate_noise_formula(
202202
)
203203
# fill in measurement specific parameters
204204
overrides = {
205-
sp.Symbol(
206-
f"noiseParameter{i_obs_par + 1}_{observable_id}", real=True
207-
): obs_par
205+
petab_symbol(f"noiseParameter{i_obs_par + 1}_{observable_id}"): obs_par
208206
for i_obs_par, obs_par in enumerate(observable_parameter_overrides)
209207
}
210208

211209
# fill in observables
212-
overrides[sp.Symbol(observable_id, real=True)] = simulation
210+
overrides[petab_symbol(observable_id)] = simulation
213211

214212
# fill in general parameters
215213
for row in parameter_df.itertuples():
216-
overrides[sp.Symbol(row.Index, real=True)] = row.nominalValue
214+
overrides[petab_symbol(row.Index)] = row.nominalValue
217215

218216
# replace parametric measurement specific parameters
219217
for key, value in overrides.items():

‎petab/v1/math/SympyVisitor.py‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from ._generated.PetabMathExprParser import PetabMathExprParser
77
from ._generated.PetabMathExprParserVisitor import PetabMathExprParserVisitor
88

9-
__all__ = ["MathVisitorSympy"]
9+
__all__ = ["MathVisitorSympy", "petab_symbol"]
1010

1111
# Mappings of PEtab math functions to sympy functions
1212

@@ -65,6 +65,18 @@
6565
}
6666

6767

68+
def petab_symbol(name: str) -> sp.Symbol:
69+
"""Create a sympy symbol for a PEtab identifier.
70+
71+
The symbol has the same assumptions as the symbols created by
72+
:func:`sympify_petab`.
73+
74+
:param name: The identifier.
75+
:return: The symbol.
76+
"""
77+
return sp.Symbol(name, real=True)
78+
79+
6880
class MathVisitorSympy(PetabMathExprParserVisitor):
6981
"""
7082
ANTLR4 visitor for PEtab-math-to-sympy conversion.
@@ -101,7 +113,7 @@ def visitVar(self, ctx: PetabMathExprParser.VarContext) -> sp.Symbol:
101113
"""Convert identifier to sympy Symbol."""
102114
if ctx.getText().lower() in _reserved_names:
103115
raise ValueError(f"Use of reserved name {ctx.getText()!r}")
104-
return sp.Symbol(ctx.getText(), real=True)
116+
return petab_symbol(ctx.getText())
105117

106118
def visitMultExpr(
107119
self, ctx: PetabMathExprParser.MultExprContext

‎petab/v1/math/__init__.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22

33
from .printer import PetabStrPrinter, petab_math_str # noqa: F401
44
from .sympify import sympify_petab # noqa: F401
5+
from .SympyVisitor import petab_symbol # noqa: F401

‎petab/v1/math/sympify.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def sympify_petab(
3434
.. note::
3535
3636
All symbols in the returned expression will have the ``real=True``
37-
assumption.
37+
assumption, as created by :func:`petab_symbol`.
3838
3939
:example:
4040
>>> from petab.v1.math import sympify_petab

‎petab/v2/calculate.py‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from petab.v1 import is_empty, split_parameter_replacement_list
1212

1313
from .C import *
14-
from .math import sympify_petab
14+
from .math import petab_symbol, sympify_petab
1515

1616
__all__ = [
1717
"calculate_chi2",
@@ -226,7 +226,7 @@ def evaluate_noise_formula(
226226

227227
# fill in measurement specific parameters
228228
overrides = {
229-
sp.Symbol(placeholder, real=True): override
229+
petab_symbol(placeholder): override
230230
for placeholder, override in zip(
231231
[
232232
p.strip()
@@ -240,11 +240,11 @@ def evaluate_noise_formula(
240240
}
241241

242242
# fill in observables
243-
overrides[sp.Symbol(observable_id, real=True)] = simulation
243+
overrides[petab_symbol(observable_id)] = simulation
244244

245245
# fill in general parameters
246246
for row in parameter_df.itertuples():
247-
overrides[sp.Symbol(row.Index, real=True)] = row.nominalValue
247+
overrides[petab_symbol(row.Index)] = row.nominalValue
248248

249249
# replace parametric measurement specific parameters
250250
for key, value in overrides.items():

‎tests/v1/math/test_math.py‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from sympy.abc import _clash
99
from sympy.logic.boolalg import Boolean, BooleanFalse, BooleanTrue
1010

11-
from petab.v1.math import petab_math_str, sympify_petab
11+
from petab.v1.math import petab_math_str, petab_symbol, sympify_petab
1212

1313

1414
def test_sympify_numpy():
@@ -36,6 +36,10 @@ def test_assumptions():
3636
# non-real symbols are changed to real
3737
assert sympify_petab(sp.Symbol("x", real=False)).is_real
3838

39+
# `petab_symbol` creates the same symbols as the parser
40+
assert petab_symbol("x") == sympify_petab("x")
41+
assert petab_symbol("x") != sp.Symbol("x")
42+
3943

4044
def test_printer():
4145
a, b, c, d = sp.symbols("a b c d", real=True)

0 commit comments

Comments
 (0)