2011-08-18 1 views
4

아래 코드 중 일부를 게시했습니다. Newton() 함수는 Bezier() 함수를 호출합니다. Bezier() 함수에는 p0과 p3을 얻을 수있는 곳의 목록이 있습니다. 내가하려는 것은 첫 번째 반복에서 프로그램은 plist에서 첫 번째와 두 번째 항목을 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__" : 

답변

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 함수에서처럼 보이도록 변경 (내 대답에서 이전 질문 getting a boundary of an item from another list에) :

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을 넣고 Newtonplist 값을 전달하고, Bezier. 당신 Newton 기능

유일한 변화는 내 코드가 비슷한 것 같다

Bezier(x_n, p0, p3) 
+0

여분의 변수'td = 0.04' (* timedelta *)를 추가하면 조금 덜 반복됩니다;) – plaes

+0

가능한 한 작게 변경하여 작동하도록했습니다. 질문자는 다른 추상화를 도입하지 않고도 충분한 시간을 보내고 있습니다. 질문의 역사를 살펴보십시오. – agf

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 

도움이됩니까?

+0

def Newton(poly, p0, p3): 

과 마지막 줄에 첫 번째 줄을 변경할 수 있습니다. 이 코드를 내 코드에 포함 시키면 지금 가지고있는 것과 같은 결과물을 얻을 수 있습니다. 감사합니다 – zingy

4

아마 pairwise 반복자 itertools recipes에서 도움이 될까요?

발전기는 아마 이것에 대한 선택의 나의 방법이 될 것입니다
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) 
+0

@ lazyr 예이게 도움이되지만 나는 간단한 방법으로 그것을 원합니다. 나는 itertools를 제대로 이해하지 못합니다. 나는 간단한 출구가있을 것이라고 확신한다. 감사합니다. – zingy

+0

@cvani :'itertools'를 사용하는 것은 관용적 인 python에 필수적입니다. 어느 쪽도 이해하기가 어렵지 않습니다. – pillmuncher

+0

'itertools.tee'는 반복자를 취하여 기본 반복기의 다른 위치에있을 수있는 * 2 개의 반복자를 반환합니다. 'next'는 반복자를 다음 위치로 진행합니다 (이 경우 반복되는 값은 무시됩니다).'itertools.izip'은'zip'과 똑같은데, 인수의 각 반복자로부터 값을 포함하는 튜플을 생성합니다. 차이점은 izip은 요청에 따라 인수를 반복하지만 zip은 한꺼번에 목록을 작성하고 모든 것을 반환하며 이는 입력에 따라 다르지만 izip은 시스템 메모리를 모두 차지하지 않습니다. – SingleNegationElimination

1

, 그들은 간단하고 쉽습니다, 다음이 수 싸서 및 루프

>>> def solution_pairs(list): 
...  for p0, p3 in zip(list, list[1:]): 
...   yield (p0, p3) 

을 위해 내장 된보다 더 모듈화 할 수있다 루프

>>> list = [1, 2, 3, 4, 5] 
>>> for p0, p3 in solution_pairs(list): 
...  print p0, p3 
1 2 
2 3 
3 4 
4 5 

의에 sussinctly 사용자 코드에서 사용할 수 당신은 현재 발전기에 있고 당신이 그렇게 경사 인 경우는 p_u를 얻을 수있는 루프 전체를 포장 할 수있다.

+0

@ Jeff이 내용을 이해했지만이 내용을 제 코드에 포함시킬 수 없습니다. 만약 내가 할 경우 각 반복에서 모든 쌍을 취하는 10 p_u 값 또는 목록에서 마지막 쌍을 취하는 1 p_u 값을 생성합니다. 하지만 Bezier()가 호출 될 때마다 하나의 쌍만 호출되어 하나의 p_u 값을 제공하는 것과 같아야합니다. 고마워 – zingy

+0

@ cvani 따라서 Bezier()가 호출 될 때마다 루프가 1 씩 진행되어야합니다. 그렇다면 왜 for 루프를 사용하고, Bezier를 생성자 또는 반복 가능한 항목으로 만들고, 호출 모듈에서 수동으로 '__next__'를 호출하십시오. –

3
실제로, 얼마 전에 itertools 조리법에 존재 창 슬라이딩 라고 요구하는 알고리즘은

:

from itertools import islice 

def window(seq, n=2): 
    "Returns a sliding window (of width n) over data from the iterable" 
    " s -> (s0,s1,...s[n-1]), (s1,s2,...,sn), ...     " 
    it = iter(seq) 
    result = tuple(islice(it, n)) 
    if len(result) == n: 
     yield result  
    for elem in it: 
     result = result[1:] + (elem,) 
     yield result 
관련 문제