From eada362cd4909f7a5be708e596b17beefc2c35b9 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Wed, 12 Nov 2025 09:57:00 +0100 Subject: [PATCH] Faster substitutions with `smart_subs_dict` * Disable evaluation during substitution * Use xreplace instead of subs For my current benchmark, this reduces the time for one `smart_subs_dict` call from over 21h (still running...) to ~12min. Disabling evaluation during substitution may prevent simplification of some expressions during substitution, but those can be simplified later on. --- python/sdist/amici/importers/utils.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/python/sdist/amici/importers/utils.py b/python/sdist/amici/importers/utils.py index 67a160ff70..a4348783a8 100644 --- a/python/sdist/amici/importers/utils.py +++ b/python/sdist/amici/importers/utils.py @@ -421,17 +421,21 @@ def smart_subs_dict( :return: Substituted symbolic expression """ - s = [ - (eid, expr[field] if field is not None else expr) - for eid, expr in subs.items() - ] + if field is None: + s = [(eid, expr) for eid, expr in subs.items()] + else: + s = [(eid, expr[field]) for eid, expr in subs.items()] + if reverse: s.reverse() - for substitution in s: - # note that substitution may change free symbols, so we have to do - # this recursively - if sym.has(substitution[0]): - sym = sym.subs(*substitution) + + with sp.evaluate(False): + for old, new in s: + # note that substitution may change free symbols, so we have to do + # this recursively + if sym.has(old): + sym = sym.xreplace({old: new}) + return sym