【问题标题】:Solve polynomial equation with negative power or non-integer power with python用python求解具有负幂或非整数幂的多项式方程
【发布时间】:2018-10-30 09:53:19
【问题描述】:

我试图解方程

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

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

使用 sympy 的“解决”需要永远。有没有办法通过使用 python 符号计算来解决这个方程?似乎问题主要来自非整数负幂。

【问题讨论】:

  • 也许如果您包含您的 Python 代码,有人将能够提出改进建议。
  • 你真的需要用符号计算来解决它吗?如果你只想要四位数的精度 numpy 可以用来数值求解。
  • Python符号计算是什么意思?您可以使用 scipy.optimize.fsolve 来查找根...
  • 我认为 Mathematica 默默地失败了:这就是 python 所说的 >>> d = 6.4673 >>> 0.41 + 6.31*d**-1.54 + 2.42*d**-3 0.7750004079825832 >>> d = 0.1191 >>> 0.41 + 6.31*d**-1.54 + 2.42*d**-3 1600.0192723624311

标签: python math sympy


【解决方案1】:

要问的第一个问题是:你想要符号解还是数值解。

对于象征性解决方案:没有。在替换x = d**(-1/50) 之后,等式变为A*x**150 + B*x**77 + C == 0。求解此类高次多项式方程没有符号公式。

对于 numeric 解决方案:您不需要 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 快速可靠地返回。

【讨论】:

    【解决方案2】:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-10
      • 1970-01-01
      • 1970-01-01
      • 2020-09-11
      • 2011-12-31
      • 2023-03-22
      • 1970-01-01
      • 2015-09-06
      相关资源
      最近更新 更多