2013-07-19 2 views
4

이전 반복에서 값을 업데이트하는 이중 루프의 속도를 높이는 방법이 있습니까? 코드에서파이썬에서 이중 루프 속도 향상

: 보시 외부 루프는 X마다 다른 값으로 시작하면서

def calc(N, m): 
    x = 1.0 
    y = 2.0 
    container = np.zeros((N, 2)) 
    for i in range(N): 
     for j in range(m): 
     x=np.random.gamma(3,1.0/(y*y+4)) 
     y=np.random.normal(1.0/(x+1),1.0/sqrt(x+1)) 
     container[i, 0] = x 
     container[i, 1] = y 
    return container 

calc(10, 5) 

하면, 내부 루프는 변수 X와 Y가 갱신된다. 나는 이것이 벡터화 가능하다고 생각하지 않지만 아마도 다른 가능한 개선이있을 수 있습니다.

감사합니다.

+0

"두 번째 루프는 변수 x와 y를 업데이트하는 반면 첫 번째 루프는 매 x 다른 값으로 시작한다."- 나는 당신이 무엇인지 잘 모르겠다. 그것으로 말입니다. 특히 "매번 다른 x의 값으로 시작"하고 "첫 번째"또는 "두 번째"루프가 "내부"또는 "외부"와 비교하여 다소 불분명하다는 것을 의미하는 것을 알지 못합니다. 나는 어느 것이 확실하지 않다. – user2357112

+0

죄송합니다.'range'를'xrange'로 바꾸는 것 이상을 생각할 수 없습니다. 아마도 당신은'numpy' 전문가를 유치하기 위해 질문에 현상액을 넣어야합니다 – inspectorG4dget

+0

죄송합니다. 네가 옳아. 첫 번째 또는 두 번째 루프를 변경합니다. 각각의 time_에서 다른 값을 가진 _starts는 외부 루프의 첫 번째 반복이 x = 1.0으로 시작한다는 것을 의미합니다. 그러나 x는 내부 루프에서 수정됩니다. 따라서 외부 루프의 두 번째 반복에서 x는 다른 값입니다. –

답변

1

나는 중요한 최대 속도까지 추가 할 거라고 생각하지 않지만, 당신은 당신이 당신의 감마를 생성하고 일반적으로 한 번에 임의의 값을 분산하는 경우 일부 기능 통화를 저장할 수 있습니다. 만약 감마부터 (K, 1) 분포 값 x을 그리면, 다음 c*x는 감마 (K, C) 분포로부터 그려 값되도록

감마 함수는 scaling property있다. 마찬가지로, 정규 분포를 사용하면 일반 (0, 1) 분포에서 그려진 y 값을 가져와 x*s + m을 수행하는 일반 (m, s) 분포에서 그려진 값으로 변환 할 수 있습니다. 다음과 같이 그래서 당신은 당신의 기능을 다시 작성할 수 있습니다 :

def calc(N, m): 
    x = 1.0 
    y = 2.0 
    container = np.zeros((N, 2)) 
    nm = N*m 
    gamma_vals = np.random.gamma(3, 1, size=(nm,)) 
    norm_vals = np.random.normal(0, 1, size=(nm,)) 
    for i in xrange(N): 
     for j in xrange(m): 
      ij = i*j 
      x = gamma_vals[ij]/(y*y+4) 
      y = norm_vals[ij]/np.sqrt(x+1) + 1/(x+1) 
     container[i, 0] = x 
     container[i, 1] = y 
    return container 

당신의 배포판의 실제 매개 변수가 간단한 표현이 있다면, 당신은 실제로 np.cumprod 등의 몇 가지 정교한 양식을 사용하고, 자신에게 루프를 절약 할 수 있습니다. 나는 이렇게하는 방법을 알아낼 수 없다. ...

+0

불행히도 내부 루프에서 np.random.gamma 및 np.random.normal을 사용하는 방식보다 2 배 느립니다. 아마 같은 결과를 내지 않기 때문에 실수가있을 수 있습니다. –

+0

임의의 숫자를 그리기 때문에 결과가 다르지 않습니다. 난수 생성기를 시드해도 다른 순서로 사용하기 때문에 매우 정상적입니다. 성능에 관해서라면, 이것은 문제를 일으키지 않는 루프를 제거 할 수 있다면 사용하기위한 깔끔한 트릭이 될 것입니다. – Jaime

+0

1+ 네가 옳아. 감사. 이것을 더 이상 최적화 할 방법이 없다고 생각하십니까? –

0

이 방법이 효과가 있습니까?

for i in xrange(N): 
    # xrange is an iterator, range makes a new list. 
    # You save linear space and `malloc`ing time by doing this 

    x += m*y # a simple algebra hack. Compute this line of the loop just once instead of `m` times 
    y -= m*x 
    y *= -1 # another simple algebra hack. Compute this line of the loop just once instead of `m` times 
    container[i,0] = x 
    container[i,1] = y 
return container 
+0

답변 해 주셔서 감사합니다. xrange는 좋은 생각입니다. 그러나 대수 파트는 제가 최적화하려고하는 실제 루프에는 적용되지 않습니다. (감마 함수 포함) –

+0

@RobertSmith : 죄송합니다. 지금 당장은별로 생각할 수 없습니다. – inspectorG4dget

+0

@RobertSmith : 게시 할 수 있습니까? 진짜 코드? – user2357112