用python解负幂或非整数幂的多项式方程

时间:2018-10-30 09:53:19

标签: python math sympy

我试图求解方程式

1600 = 0.41 + 6.31*d**-1.54 + 2.42*d**-3 

Mathematica可以在不到1秒的时间内给我d=6.4673。但是我无法通过python符号计算获得答案。

使用sympy的“解决”方法可以永久使用。有什么办法可以通过使用python符号计算来解决这个方程式吗?似乎问题主要来自非整数的负功率。

2 个答案:

答案 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