为什么 sympy 不能收敛于 Python 中的解决方案?
Why can't sympy converge on a solution in Python?
我有一个方程,我想找出这个方程的导数等于 1 的位置。
我使用 sympy 的 solve 并从方程中减去 1 来求解 0,但它永远不会收敛到一个解,在这种情况下,对于 f'(x)=1 应该是 x=260.806。
为什么它找不到这个解决方案,除了 sympy 之外,我可以在不重写的情况下改变什么?它不会抛出任何错误,只是无限期地尝试。
import sympy as sym
from sympy import symbol, symbols, solve, init_printing, diff, lambdify, exp
import matplotlib.pyplot as plt
import numpy as np
x_sym = symbols('x')
init_printing(use_unicode=True)
y_sym_orig = x_sym*exp(0.4*(1-x_sym/550))
y_sym_deriv = diff(y_sym_orig, x_sym, 1)
print('Orig=', y_sym_orig)
print('Deriv=', y_sym_deriv)
y_orig = sym.lambdify(x_sym, y_sym_orig)
y_deriv = sym.lambdify(x_sym, y_sym_deriv)
x_sol=solve(y_sym_deriv-1, x_sym)
print('The derivative has y=1 at: ',x_sol)
plt.figure()
x1 = np.arange(0, 300, .1)
y_graph = y_orig(x1)
y_deriv = y_deriv(x1)
plt.ylabel('y')
plt.xlabel('x')
plt.grid(True, which='both')
plt.ylim(0,1)
plt.plot(x1, y_graph, 'r', label='Original')
plt.plot(x1, y_deriv, 'b', label='Derivitive')
plt.title('Original and Derivitives')
plt.legend()
plt.show()
SymPy 非常喜欢有理数而不是浮点数。在公式中添加from sympy import Rational
并将0.4
替换为Rational('0.4')
。
y_sym_orig = x_sym*exp(Rational('0.4')*(1-x_sym/550))
y_sym_deriv = diff(y_sym_orig, x_sym, 1)
x_sol = solve(y_sym_deriv-1, x_sym)
print('The derivative has y=1 at: ', x_sol)
打印
The derivative has y=1 at: [-1375*LambertW(exp(3/5)) + 1375]
备注:
Rational(2, 5)
是在 SymPy 中表示 2/5 的另一种方式。 Rational(0.4)
或 Rational(2/5)
无济于事:两个版本都首先创建一个 Python 浮点数,其有理数形式不是 2/5,而是 3602879701896397/9007199254740992。
在求解之前打印出方程式(就像您所做的那样)是个好主意。这里导数的公式是原始形式的-0.00108496341646638*x*exp(-0.000727272727272727*x) + 1.49182469764127*exp(-0.000727272727272727*x)
和有理形式的-x*exp(-x/1375 + 2/5)/1375 + exp(-x/1375 + 2/5)
。考虑到浮点运算与符号数学规则有多么不同,当方程充满 浮点数 时,用符号 求解方程 是一项艰巨或不可能完成的任务.
- 有关更多信息,请参阅 Python numbers vs. SymPy Numbers。
我有一个方程,我想找出这个方程的导数等于 1 的位置。
我使用 sympy 的 solve 并从方程中减去 1 来求解 0,但它永远不会收敛到一个解,在这种情况下,对于 f'(x)=1 应该是 x=260.806。
为什么它找不到这个解决方案,除了 sympy 之外,我可以在不重写的情况下改变什么?它不会抛出任何错误,只是无限期地尝试。
import sympy as sym
from sympy import symbol, symbols, solve, init_printing, diff, lambdify, exp
import matplotlib.pyplot as plt
import numpy as np
x_sym = symbols('x')
init_printing(use_unicode=True)
y_sym_orig = x_sym*exp(0.4*(1-x_sym/550))
y_sym_deriv = diff(y_sym_orig, x_sym, 1)
print('Orig=', y_sym_orig)
print('Deriv=', y_sym_deriv)
y_orig = sym.lambdify(x_sym, y_sym_orig)
y_deriv = sym.lambdify(x_sym, y_sym_deriv)
x_sol=solve(y_sym_deriv-1, x_sym)
print('The derivative has y=1 at: ',x_sol)
plt.figure()
x1 = np.arange(0, 300, .1)
y_graph = y_orig(x1)
y_deriv = y_deriv(x1)
plt.ylabel('y')
plt.xlabel('x')
plt.grid(True, which='both')
plt.ylim(0,1)
plt.plot(x1, y_graph, 'r', label='Original')
plt.plot(x1, y_deriv, 'b', label='Derivitive')
plt.title('Original and Derivitives')
plt.legend()
plt.show()
SymPy 非常喜欢有理数而不是浮点数。在公式中添加from sympy import Rational
并将0.4
替换为Rational('0.4')
。
y_sym_orig = x_sym*exp(Rational('0.4')*(1-x_sym/550))
y_sym_deriv = diff(y_sym_orig, x_sym, 1)
x_sol = solve(y_sym_deriv-1, x_sym)
print('The derivative has y=1 at: ', x_sol)
打印
The derivative has y=1 at: [-1375*LambertW(exp(3/5)) + 1375]
备注:
Rational(2, 5)
是在 SymPy 中表示 2/5 的另一种方式。Rational(0.4)
或Rational(2/5)
无济于事:两个版本都首先创建一个 Python 浮点数,其有理数形式不是 2/5,而是 3602879701896397/9007199254740992。在求解之前打印出方程式(就像您所做的那样)是个好主意。这里导数的公式是原始形式的
-0.00108496341646638*x*exp(-0.000727272727272727*x) + 1.49182469764127*exp(-0.000727272727272727*x)
和有理形式的-x*exp(-x/1375 + 2/5)/1375 + exp(-x/1375 + 2/5)
。考虑到浮点运算与符号数学规则有多么不同,当方程充满 浮点数 时,用符号 求解方程 是一项艰巨或不可能完成的任务.- 有关更多信息,请参阅 Python numbers vs. SymPy Numbers。