Reputation: 23
I'm trying to perform the derivative of an equation with sympy, but, while if I write the equation by hand the derivative is correct; when I pass the equation as a string, the output is wrong. Can anyone explain me how to solve this issue? I'm using python 3.6 and sympy 1.5.1.
>>>from sympy import *
>>>from operator import *
>>> x1 = symbols('x1')
>>> f = add(sin(x1), mul(x1, x1))
>>> diff(f, x1)
2*x1 + cos(x1) ## Correct output
>>>> f = 'add(sin(x1), mul(x1, x1))' ## Equation provided as string
>>>> diff(f, x1)
(Subs(Derivative(mul(_xi_1, x1), _xi_1), _xi_1, x1) + Subs(Derivative(mul(x1, _xi_2), _xi_2), _xi_2, x1))*Subs(Derivative(add(sin(x1), _xi_2), _xi_2), _xi_2, mul(x1, x1)) + cos(x1)*Subs(Derivative(add(_xi_1, mul(x1, x1)), _xi_1), _xi_1, sin(x1)) ## Wrong output
Upvotes: 2
Views: 316
Reputation: 4975
Sympy provides parser functions to turn string into sympy object, see doc parse_expr.
For custom functions translation you can make a mapping with those provide by sympy and pass it as argument, local_dict
, to the parser.
from sympy import Add, Mul, sin
from sympy.parsing.sympy_parser import parse_expr
f = parse_expr('add(sin(x1), mul(x1, x1))', local_dict={'add': Add, 'mul': Mul})
f.diff('x1')
Output
2x1 + cos(x1)
Upvotes: 0
Reputation: 91550
You shouldn't pass strings directly to SymPy functions. Rather, first parse them with sympify
(which is the same as S
). You can pass a dictionary of names as the second argument to sympify
if you want non-standard names like add
to map to existing SymPy ones, like
sympify('add(x, y)', {'add': Add}) # Gives x + y
Otherwise sympify will assume that any unknown functions are undefined functions like f(x).
Upvotes: 0
Reputation: 19057
If you want to write it in this fashion, be sure to use the actual SymPy object names (which are capitalized). I use S(...)
to interpret the expression and that is the same thing that any function would do, too:
>>> S('Add(sin(x1), Mul(x1, x1))')
x1**2 + sin(x1)
But you can also use the mathematical operators +
and *
:
>>> S('sin(x1) + x1*x1')
x1**2 + sin(x1)
Upvotes: 1
Reputation: 14516
This is happening because f = 'add(sin(x1), mul(x1, x1))'
is not a valid mathematical equation that can be parsed by parse_expr
. This function is designed to parse equations written in mathematical syntax, not in terms of Sympy functions. To get this function in particular to be parsed correctly, you would need to use, for example:
>>> f = 'sin(x1) + x1^2'
>>> diff(f, x1)
2*x1 + cos(x1)
If you really need to use that specific string, you could use eval()
:
>>> f = 'add(sin(x1), mul(x1, x1))'
>>> diff(eval(f), x1)
2*x1 + cos(x1)
Upvotes: 1