Использование SymPy для общего разбора и решения уравнений

Я хочу иметь возможность анализировать строковые уравнения (равные 0), а затем решать их, используя словарь переменных, к которому у меня есть доступ.

Например:

s = '(x/z)-y'
eq = parse(s)
eq.solve({'x': 10, 'y': 5})
print(eq)
>>> {'z': 2}

Месяц назад я написал код, который делал что-то подобное, но я просто не могу его найти. Однако я помню, что использовал SymPy и его функцию sympify, а также его функцию решения. Я проверил документацию по этим функциям, но не смог понять, как заставить их работать так, как я хочу.

И дополнительный вопрос: Можно ли как-то обернуть переменные, чтобы я мог использовать для них что-то большее, чем просто буква? Пример: вместо «x» я мог бы использовать «{myvar-42}».

РЕДАКТИРОВАТЬ:

Хорошо, мне наконец удалось написать код, который делал то, что я хотел:

eq = sympify('(x/y)-z', locals={'x': 10, 'z': 5})
solution = solve(eq, dict=True)
print(solution)
>>> [{'z': 2}]

Но мой "лишний" вопрос остается.


person fgblomqvist    schedule 12.01.2014    source источник
comment
'myvar-42' - просто разобрать строку.   -  person aIKid    schedule 12.01.2014
comment
@alKid Как? Если я использую sympify для строки, содержащей скобки, это выдаст мне ошибки (потому что она думает, что это словарь или что-то в этом роде). Однако я нашел одно решение: я мог бы заменить регулярным выражением все {*} и заменить их буквами, а затем, после завершения решения, я мог бы просто поместить их обратно, используя словарь, который я создал во время замены.   -  person fgblomqvist    schedule 12.01.2014


Ответы (1)


Как вы уже поняли, sympify преобразует строки в выражения SymPy.

Чтобы ответить на ваш другой вопрос, имена символов могут быть любыми, но sympify будет анализировать только действительные идентификаторы Python для имен символов. Но ты можешь сделать

>>> Symbol('{myvar-42}') + 1
{myvar-42} + 1

И обратите внимание, что действительные идентификаторы Python не обязательно должны состоять из одной буквы. Это может быть любая комбинация букв, цифр и знаков подчеркивания, которая не начинается с цифры, например x_2 или abc123.

Если вам все еще нужно выполнять синтаксический анализ строк, но вы хотите использовать недопустимые идентификаторы Python в качестве имен символов, вероятно, самым чистым способом было бы использовать обычные имена и заменять их другими, например

>>> expr = sympify('x + 1')
>>> expr.subs(Symbol('x'), Symbol('{myvar-42}')
{myvar-42} + 1

Наконец, чтобы заменить символы буквами, вы можете использовать аргумент locals для упрощения, как вы это сделали, или, если вы хотите заменить их позже, использовать подпрограммы:

>>> x, y, z = symbols('x y z')
>>> expr = sympify('x/z - y')
>>> expr.subs({x: 10, y: 5})
10/z - 5
person asmeurer    schedule 12.01.2014
comment
Я считаю, что он перехватывает NameErrors и повторно запускает выражение с неопределенными именами, определенными как символы. - person asmeurer; 29.01.2015