在每次迭代中使用列表中的两个连续值
我在下面贴了一部分我的代码。Newton() 函数会调用 Bezier() 函数。Bezier() 函数有一个列表,从这个列表里我获取 p0 和 p3。我的目标是,在第一次循环中,程序应该把列表里的第一个和第二个项目作为 p0 和 p3。然后在第二次循环中,p0 和 p3 就变成第二个和第三个项目,依此类推。每次循环,p0 和 p3 的值都应该改变。就像新的 p0 是旧的 p3。我在代码里没能正确实现这一点。谢谢。
import math
w = 1.0
def Newton(poly):
""" Returns a root of the polynomial"""
x = 0.5 # initial guess value
counter = 0
epsilon = 0.000000000001
poly_diff = poly_differentiate(poly)
while True:
x_n = x - (float(poly_substitute(poly, x)) / float(poly_substitute(poly_diff, x)))
counter += 1
if abs(x_n - x) < epsilon :
break
x = x_n
print "\tIteration " , counter , " : ", x_n
print "u: ", x_n
Bezier(x_n)
def Bezier(x_n) :
""" Calculating sampling points using rational bezier curve equation"""
u = x_n
plist = [0.5, 0.1, 0.4, 0.35, 0.8, 0.6, 1.0, 0.2, 0.7, 0.9] # list of parameter values of the phonemes
for i in range(len(plist) - 1) :
p0 = plist[i]
p3 = plist[i + 1]
p1 = p0
p2 = p3
print p0, p3
p_u = math.pow(1 - u, 3) * p0 + 3 * u * math.pow(1 - u, 2) * p1 \
+ 3 * (1 - u) * math.pow(u, 2) * p2 + math.pow(u, 3) * p3
p_u = p_u * w
d = math.pow(1 - u, 3) * w + 3 * u * w * math.pow(1 - u, 2) + 3 * (1 - u) * w * math.pow(u, 2) + math.pow(u, 3) * w
p_u = p_u / d
print "p(u): ", p_u
return plist
if __name__ == "__main__" :
5 个回答
4
也许可以试试来自itertools
库的pairwise
迭代器,它可能会对你有帮助?
from itertools import izip, tee
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return izip(a, b)
8
>>> p = [1, 2, 3, 4, 5]
>>> for p1, p2 in zip(p, p[1:]):
... print p1, p2
...
1 2
2 3
3 4
4 5
这样做有帮助吗?
2
把你的 Bezier
函数的开头改成下面这个样子:
def Bezier(x_n, p0, p3) :
""" Calculating sampling points using rational bezier curve equation"""
u = x_n
p1 = p0
p2 = p3
这样就可以去掉那个循环和 plist
了。
接着,在你的 time
函数里(这是我之前回答你问题时提到的 如何从另一个列表获取项目的边界),把它改成下面这样:
def time() :
tlist = [0.0, 0.12, 0.16, 0.2, 0.31, 0.34, 0.38, 0.46, 0.51] # list of start time for the phonemes
plist = [0.5, 0.1, 0.4, 0.35, 0.8, 0.6, 1.0, 0.2, 0.7, 0.9] # list of parameter values of the phonemes
total_frames = math.floor(tlist[-1] / 0.04)
t_u = 0.0
i = 0
while i < len(tlist) - 1:
# if the number is in the range
# do the calculations and move to the next number
if t_u > tlist[i] and t_u < tlist[i + 1] :
print "\n The t_u value:", t_u, 'is between',
print "start:", tlist[i], " and end: ", tlist[i+1]
poly = poly_coeff(tlist[i], tlist[i + 1], t_u)
Newton(poly, plist[i], plist[i+1])
t_u = t_u + 0.04 # regular time interval
# if the number is at the lower boundary of the range no need of calculation as u = 0
elif t_u == tlist[i] :
print "\n The t_u value:", t_u, 'is on the boundary of',
print "start:", tlist[i], " and end: ", tlist[i+1]
print "u : 0"
Bezier(0, plist[i], plist[i+1])
t_u = t_u + 0.04 # regular time interval
# if the number is at the upper boundary of the range no need of calculation as u = 1
elif t_u == tlist[i + 1] :
print "\n The t_u value:", t_u, 'is on the boundary of',
print "start:", tlist[i], " and end: ", tlist[i+1]
print " u : 1"
Bezier(1, plist[i], plist[i+1])
t_u = t_u + 0.04 # regular time interval
# if the number isn't in the range, move to the next range
else :
i += 1
唯一的变化就是把 plist
放到这里,并把 plist
的值传递给 Newton
和 Bezier
。
你对 Newton
函数的唯一修改是把第一行改成:
def Newton(poly, p0, p3):
最后一行改成:
Bezier(x_n, p0, p3)