所以我最终尝试使用Horner的规则(http://mathworld.wolfram.com/HornersRule.html)来评估多项式,并创建一个函数来评估多项式。无论如何,所以我的问题在于我如何编写函数;它适用于简单的多项式,如3x ^ 2 + 2x ^ 1 + 5等。但是一旦你开始评估一个具有浮点数的多项式(像1.8953343e-20那样疯狂的东西等),它就会失去它的精确度。 因为我使用这个函数来使用牛顿方法(http://tutorial.math.lamar.edu/Classes/CalcI/NewtonsMethod.aspx)来评估多项式的根,所以我需要这个是精确的,因此它不会通过一个方法失去它的价值。小舍入误差和诸如此类的东西。
我已经和另外两个人一起解决了问题在于evaluatePoly()函数,而不是我的其他函数来评估Newton的方法。另外,我最初正常评估多项式(将x乘以度数,乘以常数等),并得出正确的答案。但是,分配需要使用Horner的规则来更容易计算。
这是我的以下代码:
def evaluatePoly(poly, x_):
"""Evaluates the polynomial at x = x_ and returns the result as a floating
point number using Horner's rule"""
#http://mathworld.wolfram.com/HornersRule.html
total = 0.
polyRev = poly[::-1]
for nn in polyRev:
total = total * x_
total = total + nn
return total
注意:我已经尝试使用float()将nn,x_,(total * x_)设置为浮点数。
这是我收到的输出:
Polynomial: 5040x^0 + 1602x^1 + 1127x^2 - 214x^3 - 75x^4 + 4x^5 + 1x^6
Derivative: 1602x^0 + 2254x^1 - 642x^2 - 300x^3 + 20x^4 + 6x^5
(6.9027369297630505, False)
Starting at 100.00, no root found, last estimate was 6.90, giving value f(6.90) = -6.366463e-12
(6.9027369297630505, False)
Starting at 10.00, no root found, last estimate was 6.90, giving value f(6.90) = -6.366463e-12
(-2.6575456505038764, False)
Starting at 0.00, no root found, last estimate was -2.66, giving value f(-2.66) = 8.839758e+03
(-8.106973924480215, False)
Starting at -10.00, no root found, last estimate was -8.11, giving value f(-8.11) = -1.364242e-11
(-8.106973924480215, False)
Starting at -100.00, no root found, last estimate was -8.11, giving value f(-8.11) = -1.364242e-11
这是我需要的输出:
Polynomial: 5040x^0 + 1602x^1 + 1127x^2 - 214x^3 - 75x^4 + 4x^5 + 1x^6
Derivative: 1602x^0 + 2254x^1 - 642x^2 - 300x^3 + 20x^4 + 6x^5
(6.9027369297630505, False)
Starting at 100.00, no root found, last estimate was 6.90,giving value f(6.90) = -2.91038e-11
(6.9027369297630505, False)
Starting at 10.00, no root found, last estimate was 6.90,giving value f(6.90) = -2.91038e-11
(-2.657545650503874, False)
Starting at 0.00, no root found, last estimate was -2.66,giving value f(-2.66) = 8.83976e+03
(-8.106973924480215, True)
Starting at -10.00, root found at x = -8.11, giving value f(-8.11)= 0.000000e+00
(-8.106973924480215, True)
Starting at -100.00, root found at x = -8.11, giving value f(-8.11)= 0.000000e+00
注意:请忽略错误输出的元组;这是我的牛顿方法的结果,其中第一个结果是根,第二个结果表明它是否是根。
答案 0 :(得分:1)
试试这个:
def evaluatePoly(poly, x_):
'''Evaluate the polynomial poly at x = x_ and return the result as a
floating-point number using Horner's rule'''
total= 0
degree =0
for coef in poly:
total += (x_**degree) * coef
degree += 1
答案 1 :(得分:0)
通过构造问题,对靠近根的多项式的评估需要取消大项以产生小的结果。中间项的大小可以在最坏情况意义上通过对多项式的评估来限制,该多项式将其所有系数设置为原始多项式的系数的绝对值。对于第一个提供
的根In [6]: x0=6.9027369297630505
In [7]: evaluatePoly(poly,x0)
Out[7]: -6.366462912410498e-12
In [8]: evaluatePoly([abs(c) for c in poly],abs(x0))
Out[8]: 481315.82997756737
此值是浮点误差的放大系数的第一个估计值,乘以机器epsilon 2.22e-16
,这给出1.07e-10
和x0
的任何评估方法的累积浮点误差的界限实际上,两种评估方法都会在这个范围之下轻松地给出值,表明在浮点格式的能力范围内找到了根。
查看围绕x0
的评估图表,可以看到平滑曲线的基本假设在该放大率下失败,并且x轴在跳跃中交叉,因此{{1}没有更好的值可以找到: