ZeroDivisionError: деление поплавка

1

У меня есть этот код для решения метода Ньютона. Но он дает ошибку с нулевым делением. Я не могу понять, что не так. Спасибо.

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
Теги:
newtons-method

3 ответа

6
Лучший ответ

У вас есть основная ошибка здесь:

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

Из-за природы enumerate, start_time и end_time имеют одинаковое значение. Это означает, что poly_coeff будет возвращать [[0,3], [0,2], [0,1], [0,0]] каждый раз. Когда этот результат передается (через Newton) в poly_differentiate, результат будет [[0,2], [0,1], [0,0], [0,-1]].

Этот результат, переданный в poly_substitute, даст сумму ZERO, потому что перед их суммированием вы умножаете все записи списка по term[0] (который оказывается равным нулю). Затем вы делите - на ноль.

РЕШЕНИЕ (отредактировано за ваш комментарий):

Используйте правильные значения start_time и end_time. Похоже, вы хотите end_time = tlist[i+1]. Крайнее условие этого состоит в том, чтобы выйти из строя, не оценивая конечную запись в списке. Что вы действительно хотите, так это:

for i, start_time in enumerate(tlist[:-1]):
    end_time = tlist[i+1]
  • 0
    Время начала для первой итерации должно составлять 0,0, а время окончания должно быть следующим значением, равным 0,12. Тогда на следующей итерации время начала будет равно 0,12, а время окончания - число рядом с ним, равное 0,16 и т. Д.
  • 0
    Обратите внимание, что хотя это должно исправить это конкретное исключение, я думаю, что у вашего кода могут быть некоторые другие, тонкие проблемы. Я видел много ваших вопросов (многие из которых, кажется, вращаются вокруг этой проблемы фонем - вашего проекта?), И хотя вы движетесь в лучшем направлении, я хотел бы призвать вас взять время изучить хорошие методы отладки и получить четкое представление об основах разработки программного обеспечения. Они будут незаменимыми по мере продвижения вперед и приведут вас к созданию более надежных, способных конструкций в будущем.
Показать ещё 1 комментарий
3

Я скопировал ваш код и немного пытался его отладить.

В общем, это потому, что ваш код возвращает нулевое значение, а затем попытался использовать его во время деления.

Если вы внимательно просмотрите свой код, вы увидите, что следующий цикл:

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 и 0,12 для первой итерации, которую я наверняка кодировал неправильно.
0

На первый взгляд

 poly_substitue(poly_diff,x) 

представляется для нуля равным нулю. Попробуйте отследить итерацию, напечатав x перед каждым обновлением.

Но я думаю, что исключение вызвано ошибкой в вашем коде: поскольку абсолютный коэффициент C * X ^ 0 в полиноме дифференцируется на 0 * X ^ -1, ваш poly_substitute вызывает ZeroDivisionException при x = 0.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню