Python中的精度错误

时间:2016-10-29 22:50:26

标签: python-3.x precision

所以我最终尝试使用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

注意:请忽略错误输出的元组;这是我的牛顿方法的结果,其中第一个结果是根,第二个结果表明它是否是根。

2 个答案:

答案 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-10x0的任何评估方法的累积浮点误差的界限实际上,两种评估方法都会在这个范围之下轻松地给出值,表明在浮点格式的能力范围内找到了根。

查看围绕x0的评估图表,可以看到平滑曲线的基本假设在该放大率下失败,并且x轴在跳跃中交叉,因此{{1}没有更好的值可以找到:

graph of polynomial evaluation close to the root