симпатия: простое решение символического уравнения с последующей заменой числами

#sympy

Вопрос:

У меня есть уравнение 1 x 2 y=40 . Я хотел бы решить ее за y (т. е. приведите его в форму y=…) А затем подставьте числа вместо x, чтобы получить числа для y. Мое текущее полуавтоматическое решение выглядит следующим образом:

 import matplotlib.pyplot as plt
import numpy as np
from sympy import symbols, solve

m=40
pa=1
pb=2

x, y = symbols('x, y')
eq = pa*x pb*y-m

y= solve(eq, y)
print(y)
print(type(y))
print(type(y[0]))

# then watch on screen what y is and substitute by hand
x=np.linspace(1,4,41)
y=2-x/2

plt.plot(x,y)
 

Есть ли лучший способ заменить числа x в решении и получить числа для y? (после «решить» y, похоже, относится к списку типов с одним элементом мистического типа «симпатия.ядро.добавить.Добавить»)

Terveisin, Markus

Ответ №1:

solve Функция возвращает список выражений. Он возвращает список, потому что в общем случае может быть более одного решения уравнения:

 In [17]: solve(x**2 - 2, x)
Out[17]: [-√2, √2]
 

Если вы знаете, что должно быть только одно решение, вы можете извлечь его из списка любым удобным для вас способом, например:

 In [12]: m=40
    ...: pa=1
    ...: pb=2
    ...: 
    ...: x, y = symbols('x, y')
    ...: eq = pa*x pb*y-m
    ...: 
    ...: [soly] = solve(eq, y)

In [13]: soly
Out[13]: 
     x
20 - ─
     2
 

Решение приведено здесь в виде символического выражения, включающего символ x. Вы можете заменить значения x с помощью подстановок:

 In [14]: soly.subs(x, 2)
Out[14]: 19
 

subs Метод выполняет символическую подстановку, которая может обрабатывать подстановку других символических выражений для x :

 In [19]: soly.subs(x, sqrt(2))
Out[19]: 
     √2
20 - ──
     2 
 

Для эффективной оценки выражения в обычной точке с плавающей запятой для многих возможных значений x с помощью вы можете использовать lambdify :

 In [15]: yfx = lambdify([x], soly, 'numpy')

In [16]: yfx(np.arange(10))
Out[16]: array([20. , 19.5, 19. , 18.5, 18. , 17.5, 17. , 16.5, 16. , 15.5])
 

Обратите внимание, что перезаписывать переменную, которую вы используете для такого символа, — плохая идея:

 y = solve(eq, y)  # use a different name like ysol
 

Это плохая идея, потому что любое последующее использование переменной y Python больше не ссылается на исходный символ y , что является частой причиной путаницы для неопытных пользователей SymPy.

Большинство пунктов, о которых я упоминал выше, освещены в официальном руководстве, которое я рекомендую прочитать:

https://docs.sympy.org/latest/tutorial/index.html

lambdify Функция задокументирована с подробным объяснением здесь:

https://docs.sympy.org/latest/modules/utilities/lambdify.html#sympy.utilities.лямбдифи.лямбдифи

Ответ №2:

Спасибо, я не смог найти эту самую основную информацию в учебных пособиях или в документации.

Вот полный рабочий пример, основанный на предыдущем ответе:

 from sympy import symbols, solve, lambdify
import numpy as np

m=40
pa=1
pb=2

x, y = symbols('x, y')
eq = pa*x pb*y-m

[soly]= solve(eq, y)
print(f"y= {soly}")

print(f"y(2)= {soly.subs(x, 2)}")

yfx = lambdify([x], soly, 'numpy')

print(f"y(np.arange(10))= {yfx(np.arange(10))}")