【问题标题】:ZeroDivisionError: float divisionZeroDivisionError:浮点除法
【发布时间】:2011-10-25 21:12:19
【问题描述】:

我有这个代码来解决牛顿的方法。但它给出了零除法错误。我无法弄清楚出了什么问题。谢谢你。

import copy

tlist = [0.0, 0.12, 0.16, 0.2, 0.31, 0.34] # list of start time for the phonemes

w = w1 = w2 = w3 = w = 5

def time() :
    frame = 0.04
    for i, start_time in enumerate(tlist) :
        end_time = tlist[i]
        frame = frame * (i + 1)
        poly = poly_coeff(start_time, end_time, frame)
        Newton(poly) 

def poly_coeff(stime, etime, f) :
    """The equation is k6 * u^3 + k5 * u^2 + k4 * u + k0 = 0. Computing the coefficients for this polynomial."""
    """Substituting the required values we get the coefficients."""
    t_u = f
    t0 = stime
    t3 = etime
    t1 = t2 = (stime + etime) / 2
    w0 = w1 = w2 = w3 = w
    k0 = w0 * (t_u - t0)
    k1 = w1 * (t_u - t1)
    k2 = w2 * (t_u - t2)
    k3 = w3 * (t_u - t3)
    k4 = 3 * (k1 - k0)
    k5 = 3 * (k2 - 2 * k1 + k0)
    k6 = k3 - 3 * k2 + 3 * k1 -k0 

    return [[k6,3], [k5,2], [k4,1], [k0,0]]

def poly_differentiate(poly):
    """ Differentiate polynomial. """
    newlist = copy.deepcopy(poly)

    for term in newlist:
        term[0] *= term[1]
        term[1] -= 1

    return newlist

def poly_substitute(poly, x):
    """ Apply value to polynomial. """
    sum = 0.0 

    for term in poly:
        sum += term[0] * (x ** term[1])
    return sum

def Newton(poly):
    """ Returns a root of the polynomial"""
    poly_diff = poly_differentiate(poly) 
    counter = 0
    epsilon = 0.000000000001

    x = float(raw_input("Enter initial guess:"))

    while True:
        x_n = x - (float(poly_substitute(poly, x)) / poly_substitute(poly_diff, x))
        counter += 1
        if abs(x_n - x) < epsilon :
            break
        x = x_n
    print "Number of iterations:", counter
    print "The actual root is:", x_n
    return x_n

if __name__ == "__main__" :
    time()
Enter initial guess:0.5
Traceback (most recent call last):
  File "newton.py", line 79, in <module>
    time()
  File "newton.py", line 18, in time
    Newton(poly) 
  File "newton.py", line 67, in Newton
    x_n = x - (float(poly_substitute(poly, x)) / poly_substitute(poly_diff, x))
ZeroDivisionError: float division

【问题讨论】:

    标签: python newtons-method


    【解决方案1】:

    我已经复制了你的代码并尝试调试一下。

    一般是因为你的代码返回一个零值,然后在除法时尝试使用它。

    如果你仔细检查你的代码你会发现下面的循环:

    for i, start_time in enumerate(tlist) :
            end_time = tlist[i]
    

    将在第一次迭代时为您提供 start_time == 0.0 和 endTime == 0.0。

    这导致以下行:

    poly = poly_coeff(start_time, end_time, frame)
    

    返回你:

    >>> [[0.0, 3], [0.0, 2], [0.0, 1], [0.2, 0]]
    

    这个原因:

    poly_substitute(poly_diff, x)
    

    您在哪里使用以下循环:

    for term in poly:
        sum += term[0] * (x ** term[1])
    

    返回一个零,因为你只是乘以零。

    那么你试图在 0 上删除并得到一个提到的异常。

    这意味着如果您修改代码以安全检查并将 endTime 设置为 tList[i+1],您将消除此错误 - 不要忘记检查 'i+1

    【讨论】:

    • 谢谢。第一次迭代的起始值和结束值应该是 0.0 和 0.12,我肯定编码错了。
    【解决方案2】:

    这里有一个基本错误:

    for i, start_time in enumerate(tlist):
        end_time = tlist[i]
    

    由于enumerate 的性质,start_timeend_time 具有相同的值。这意味着poly_coeff 每次都会返回[[0,3], [0,2], [0,1], [0,0]]。当此结果(通过Newton)传递到poly_differentiate 时,结果将为[[0,2], [0,1], [0,0], [0,-1]]

    这个结果,传递给poly_substitute 将产生一个零和,因为在对它们求和之前将所有列表条目乘以term[0](恰好为零)。然后,将 - 除以零。

    解决方案(根据您的评论编辑)

    使用正确的 start_timeend_time 值。看起来你想要end_time = tlist[i+1]。这种情况的边缘条件是在不评估最终列表条目的情况下突破。你真正想要的是:

    for i, start_time in enumerate(tlist[:-1]):
        end_time = tlist[i+1]
    

    【讨论】:

    • 第一次迭代的开始时间应该是 0.0,结束时间应该是下一个值,即 0.12。然后在下一次迭代中,开始时间是 0.12,结束时间是它旁边的数字,即 0.16,依此类推..
    • 请注意,虽然这应该可以解决这个特定异常,但我认为您的代码可能还有其他一些微妙的问题。我看过你的很多问题(其中很多似乎都围绕着这个音素问题——你的一个项目?),虽然你正朝着更好的方向前进,但我想鼓励你抽出时间学习良好的调试技术,并深入了解软件工程的基础知识。在您前进时,它们将是不可或缺的,并将引导您在未来创建更强大、更强大的设计。
    • 非常感谢您的建议。我知道我不是程序员。它是项目的一部分,所以我必须这样做。但在未来,我不会在学好之前潜入我不知道的东西。就像你说的那样,这解决了问题。
    【解决方案3】:

    一见钟情

     poly_substitue(poly_diff,x) 
    

    对于特殊的 x 似乎为零。尝试通过在每次更新前打印 x 来跟踪迭代。

    但我认为异常是由您的代码中的错误引起的:当多项式中的绝对系数 C*X^0 微分为 0 * X^-1 时,您的 poly_substitute 在 x= 时会引发 ZeroDivisionException 0.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多