2011-08-16 4 views
0

J'ai ce code pour résoudre la méthode de Newton et dans la dernière itération, les valeurs de sortie se sont trompées. Ces valeurs ne devraient pas être négatives car je l'ai vérifié manuellement sur papier. Pour autant que je sais le code est juste, mais je ne peux pas comprendre pourquoi il affiche des valeurs négatives et aussi la valeur finale u devrait idéalement être une valeur positive entre 0 et 1. Voici le code:Sortie inattendue de la méthode de Newton

import copy 
import math 

tlist = [0.0, 0.07, 0.13, 0.15, 0.2, 0.22] # list of start time for the phonemes 

w = 1.0 

def time() : 
    t_u = 0.0 
    for i in range(len(tlist)- 1) : 
     t_u = t_u + 0.04 # regular time interval 
     print t_u 
     print tlist[i], ' ' , tlist[i+1], ' ', tlist[i -1] 
     if t_u >= tlist[i] and t_u <= tlist[i + 1] : 
      poly = poly_coeff(tlist[i], tlist[i + 1], t_u) 
      Newton(poly) 
     else : 
      poly = poly_coeff(tlist[i - 1], tlist[i], t_u) 
      Newton(poly) 

def poly_coeff(start_time, end_time, t_u) : 
    """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.""" 
    t0 = start_time 
    t3 = end_time 
    t1 = t2 = (t0 + t3)/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 

    print k0, k1, k2, k3, k4, k5, k6 
    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""" 
    x = 0.5 # initial guess value 
    epsilon = 0.000000000001 
    poly_diff = poly_differentiate(poly) 

    while True: 
     x_n = x - (float(poly_substitute(poly, x))/float(poly_substitute(poly_diff, x))) 

     if abs(x_n - x) < epsilon : 
      break 
     x = x_n 
     print x_n 
    print "u: ", x_n 
    return x_n 

if __name__ == "__main__" : 
    time() 

la sortie de la dernière itération est la suivante,

où k6 = -0,02, k5 = 0,03, k4 = -0,03 et k0 = 0,0

0.2 
0.2 0.22 0.15 
0.0 -0.01 -0.01 -0.02 -0.03 0.03 -0.02 
-0.166666666667 
-0.0244444444444 
-0.000587577730193 
-3.45112269878e-07 
-1.19102451449e-13 
u: -1.42121180685e-26 

la valeur de la donnée initiale est de 0,5, donc s'il est substitué dans le polynôme alors la sortie est -0.005.

Puis de nouveau la même valeur initiale est substituée dans le polynôme différencié. Le résultat est de -0,015.

Maintenant ces valeurs sont substituées dans l'équation de Newton alors la réponse devrait être de 0.166666667. Mais la réponse réelle est une valeur négative.

Merci.

+1

** 1 **: Pouvez-vous expliquer 'poly_coeff'? D'où vient cet algorithme? Tout le reste de vos calculs est correct pour autant que je sache, et j'obtiens les réponses que vous avez postées. ** 2 **: Vous dites que vous avez vérifié manuellement sur papier - pouvez-vous poster ces calculs, afin que nous puissions voir quelle est la différence entre le prévu et le réel? – Nate

+0

@Nate le poly_coeff() calcule les coefficients pour un polynôme donné dans les commentaires. Ensuite, la racine de ce polynôme est calculée en utilisant la méthode de Newton. Je vais éditer la question montrant mon calcul manuel. Merci – zingy

Répondre

0

Ah, je vois maintenant.

Tout comme vous dites,

float(poly_substitute(poly, x)) 

est évaluée à -0.015. Ensuite,

float(poly_substitute(poly_diff, x)) 

est évalué à -0.01. Ainsi, substituez ces valeurs et pour x,

x_n = 0.5 - ((-0.015)/(-0.01)) 
x_n = 0.5 - 0.6666666... 
x_n = -0.166666... 

Votre maths manuel était ce qui était en faute, pas le code.

+0

Oui, j'ai découvert que le code est correct. Aussi ses problèmes de virgule flottante python qui ont donné le résultat inattendu. Merci – zingy

0

Le polynôme tel que donné a une seule solution à x = 0. Le code fonctionne bien.