我有这个程序来解牛顿法。但它给出了一个零除法误差。我搞不清出了什么事。谢谢您。
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
我已经复制了你的代码并试着调试了一下。
一般来说,这是因为代码返回一个零值,然后在除法时尝试使用它。
如果仔细检查代码,您会发现以下循环:
将在第一次迭代中为您提供开始时间==0.0和结束时间==0.0。
这将引出以下行:
要归还您:
这是因为:
使用以下循环的位置:
因为你只乘以零。
因此,您正尝试在0上删除,并得到一个提到的异常。
这意味着,如果您将修改代码以安全检查并将endTime设置为tList[i+1],您将消除此错误-不要忘记检查'i+1
这里有一个基本的bug:
由于
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]
。边缘条件是在不计算最终列表项的情况下爆发。你真正想要的是:一见钟情
对于特殊的x,似乎为零。请在每次更新之前打印x来跟踪迭代。
但我认为异常是由代码中的错误引起的:当X=0时,由于多项式中的绝对系数C*X^0被区分为0*X^-1,则
poly_substitute
会引发ZeroDivisionException
。相关问题 更多 >
编程相关推荐