I have a userdefined language containing mathematical expressions in python syntax but with wrapper special mathematical functions, e.g.
instead of
sqrt(y) - x
I have _math.foo(y) - x
I want to be able to use sympy.parse_expr on these strings and handle them the same way. I tried two different things with not yet the correct result:
import sympy
import math
import sympy.utilities
from sympy.utilities.lambdify import implemented_function
class Math:
foo = math.sqrt
bar = implemented_function("sqrt", math.sqrt)
input = "sqrt(y) - x"
input = "_math.bar(y) - x"
input = "_math.foo(y) - x"
expr = sympy.parse_expr(input, {"_math" : Math})
print(expr)
print(sympy.solveset(expr, sympy.Symbol("y")))
print(sympy.solveset(expr, sympy.Symbol("x")))
With input = "sqrt(y) - x"
I do get the result:
-x + sqrt(y)
{x**2}
{sqrt(y)}
which is the result I want.
The approach input = "_math.bar(y) - x"
gives me the output:
-x + sqrt(y)
ConditionSet(y, Eq(-x + sqrt(y), 0), Complexes)
{sqrt(y)}
which I do not fully understand, but is not th same as the one above
and the last approach input = "_math.foo(y) - x"
gives me TypeError("Cannot convert expression to float")
inside eval.
Note that the string representation of the first two approaches is the same.
Copilot for the win. SymPy actually has math functions available (just not a very good documentation) that can directly be used for symbols. Other methods that are not directly available can be composed.
class Math:
foo = sympy.sqrt
@staticmethod
def mydiv(a: Any, b: Any) -> Any:
"""sympy division operation"""
return sympy.Mul(a, sympy.Pow(b, -1))