ZeroDivisionError: деление с плаваща единица

Имам този код за решаване на метода на Нютон. Но дава грешка при деление на нула. Не мога да разбера какво не е наред. Благодаря ти.

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

person zingy    schedule 12.08.2011    source източник


Отговори (3)


Тук имате основен бъг:

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, ще даде сума от НУЛА, защото умножавате всички записи в списъка по term[0] (което случайно е нула), преди да ги сумирате. След това разделяте - на нула.

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

Използвайте правилните стойности start_time и end_time. Изглежда, че искате end_time = tlist[i+1]. Крайното условие за това е да излезете, без да оценявате окончателния запис в списъка. Това, което наистина искате е следното:

for i, start_time in enumerate(tlist[:-1]):
    end_time = tlist[i+1]
person Nate    schedule 12.08.2011
comment
Началният час за първата итерация трябва да бъде 0,0, а крайният час трябва да бъде следващата стойност, която е 0,12. След това в следващата итерация началният час ще бъде 0,12, а крайният час - числото до него, което е 0,16 и така нататък. - person zingy; 12.08.2011
comment
Имайте предвид, че въпреки че това трябва да коригира това специфично изключение, мисля, че вашият код може да има някои други, фини проблеми. Видях много от вашите въпроси (много от които изглежда се въртят около този проблем с фонемата - ваш проект?) и въпреки че се движите в по-добра посока, бих искал да ви насърча да отделите време да научите добри техники за отстраняване на грешки и да получите солидно разбиране на основите на софтуерното инженерство. Те ще бъдат незаменими, докато вървите напред, и ще ви водят към създаването на по-здрави, способни дизайни в бъдеще. - person Nate; 12.08.2011
comment
Благодаря ви много за предложението. Знам, че не съм програмист. Това е част от проекта, така че трябва да го направя. Но в бъдеще не бих се гмурнал в нещо, което не знам, преди да съм го научил добре. Както казахте, това реши проблема. - person zingy; 12.08.2011

На пръв поглед

 poly_substitue(poly_diff,x) 

изглежда е нула за специално x. Опитайте се да проследите итерацията, като отпечатате x преди всяка актуализация.

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

person rocksportrocker    schedule 12.08.2011

person    schedule
comment
Благодаря ти. Началната и крайната стойност трябва да бъдат 0,0 и 0,12 за първата итерация, която със сигурност съм кодирал погрешно. - person zingy; 12.08.2011