我试图求解方程式
1600 = 0.41 + 6.31*d**-1.54 + 2.42*d**-3
Mathematica可以在不到1秒的时间内给我d=6.4673
。但是我无法通过python符号计算获得答案。
使用sympy的“解决”方法可以永久使用。有什么办法可以通过使用python符号计算来解决这个方程式吗?似乎问题主要来自非整数的负功率。
答案 0 :(得分:1)
第一个要问的问题是:您想要符号解决方案还是数字解决方案。
对于符号解决方案:没有。替换x = d**(-1/50)
后,方程变为A*x**150 + B*x**77 + C == 0
。没有用于求解此类高阶多项式方程的符号公式。
对于数字解决方案:您不需要SymPy,因为SymPy用于符号计算。用SciPy查找根。作为起点:
from scipy.optimize import root
root(lambda d: 0.41 + 6.31*d**(-1.54) + 2.42*d**(-3) - 1600, 0.1)
这为0.1191005
提供了解决方案。起始点必须是一个小的正数,否则求解器将无法收敛。正如WIP所说,Mathematica以此方式失败了,其答案是虚假的。
但是最好使用专门的求解器来处理标量方程,例如brentq
,尤其是因为您在这里具有单调函数。此求解器需要一个包围时间间隔开头:函数为正的一个点,负函数为的另一个点。如果没有计算器,人们会注意到0.1给出一个正值(其中一项是2.42*1000
),而1给出一个负值(三个小数减去1600)。因此,
from scipy.optimize import brentq
brentq(lambda d: 0.41 + 6.31*d**(-1.54) + 2.42*d**(-3) - 1600, 0.1, 1)
,它以0.11910050394499523
快速可靠地返回。
答案 1 :(得分:1)
SymPy通过mpmath
库提供数值计算。这包括通过nsolve
进行数值根查找。在这种情况下,由于分子修饰符中有一个d
,因此我们按照nsolve
的文档字符串建议的方式进行操作,并使用表达式的分子进行初步猜测。可以很快找到已经被引用的根:
>>> f
-6.31*d**(-1.54) + 1599.59 - 2.42/d**3
>>> nsolve(f.as_numer_denom()[0], 1)
0.119100503944930