Reputation: 21474
I would like to generate equations symbolically, then sub in values with types from libraries like uncertainties
(but could be any library with custom types) however it seems that using .evalf(subs={...})
method fails with a rather odd error message:
>>> from uncertainties import ufloat
>>> from sympy.abc import x
>>> (x**2).evalf(subs={x: ufloat(5,1)})
Traceback (most recent call last):
...
File "<string>", line 1
Float ('5.0' )+/-Float ('1.0' )
^
SyntaxError: invalid syntax
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<pyshell#116>", line 1, in <module>
(x**2).evalf(subs={x: ufloat(5,1)})
...
sympy.core.sympify.SympifyError: Sympify of expression 'could not parse '5.0+/-1.0'' failed, because of exception being raised:
SyntaxError: invalid syntax (<string>, line 1)
str(ufloat(5,1))
gives '5.0+/-1.0'
so it obviously wants the string representation of my substitute value will look like a symbolic expression.I know that many sympy operations (like differentiation) wouldn't be possible to support this and it would only be possible if all free symbols were substituted since the two types don't play nice:
>>> x + ufloat(5,1)
Traceback (most recent call last):
File "<pyshell#117>", line 1, in <module>
x + ufloat(5,1)
TypeError: unsupported operand type(s) for +: 'Symbol' and 'Variable'
But assuming I leave no symbolic operations/variables is it possible to simply evaluate a sympy expression with the python equivalent operations?
Upvotes: 0
Views: 721
Reputation: 3741
maybe you want more, but you can just create ordinary functions from sympy expressions and then use uncertainties
from uncertainties import ufloat
from sympy.abc import x
from sympy.utilities.lambdify import lambdify
expr = x**2
f = lambdify(x, expr)
f(ufloat(5,1))
Out[5]: 25.0+/-10.0
Upvotes: 2
Reputation: 21474
My current solution is just using a loose call to eval
which does not seem like a good idea, especially since Sympy is fine with Basic.__str__
method being monkey patched.
import math, operator
eval_globals = {"Mod":operator.mod}
eval_globals.update(vars(math))
def eval_sympy_expr(expr, **subs):
return eval(str(expr), eval_globals, subs)
and for uncertainties
support I'd just do import uncertainties.umath as math
instead of the default math module.
Upvotes: 0