Неожиданное поведение при разборе строки с симптом - PullRequest
2 голосов
/ 31 января 2020

Я пытаюсь выполнить производную уравнения с sympy, но, если я напишу уравнение от руки, производная верна; когда я передаю уравнение в виде строки, вывод неправильный. Может кто-нибудь объяснить мне, как решить эту проблему? Я пользуюсь python 3.6 и 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

Ответы [ 3 ]

1 голос
/ 31 января 2020

Если вы хотите написать это таким образом, обязательно используйте фактические имена объектов SymPy (которые пишутся с большой буквы). Я использую S(...) для интерпретации выражения, и это то же самое, что и любая функция:

>>> S('Add(sin(x1), Mul(x1, x1))')
x1**2 + sin(x1)

Но вы также можете использовать математические операторы + и *:

>>> S('sin(x1) + x1*x1')
x1**2 + sin(x1)
1 голос
/ 31 января 2020

Это происходит потому, что f = 'add(sin(x1), mul(x1, x1))' не является допустимым математическим уравнением, которое может быть проанализировано с помощью parse_expr. Эта функция предназначена для анализа уравнений, написанных в математическом синтаксисе, а не в терминах функций Симпи. В частности, чтобы правильно проанализировать эту функцию, вам нужно использовать, например:

>>> f = 'sin(x1) +  x1^2'
>>> diff(f, x1)
2*x1 + cos(x1)

Если вам действительно нужно использовать эту указанную c строку, вы можете использовать eval():

>>> f = 'add(sin(x1), mul(x1, x1))'
>>> diff(eval(f), x1)
2*x1 + cos(x1)
0 голосов
/ 03 февраля 2020

Вы не должны передавать строки напрямую в функции SymPy. Вместо этого сначала проанализируйте их с помощью sympify (что совпадает с S). Вы можете передать словарь имен в качестве второго аргумента sympify, если хотите, чтобы нестандартные имена, такие как add, отображались на существующие SymPy, такие как

sympify('add(x, y)', {'add': Add}) # Gives x + y

В противном случае sympify будет предполагать, что любой неизвестный функции являются неопределенными функциями, такими как f (x).

...