2009-09-25 5 views
3

순환 순서의 계산 최적화

로 정의 된 순환 순서를 계산하는 가장 빠른 방법은 무엇입니까?
x[1] <- x1 
x[n] <- f(x[n-1]) 

적절한 길이의 벡터 x가 미리 할당되었다고 가정합니다. 그냥 반복하는 것보다 똑똑한 방법이 있습니까?

변형 : 벡터로 확장 :

 x[,1] <- x1 
x[,n] <- f(x[,n-1]) 
+0

는 F (cumsum의 조합으로서 X) 발현()의, cumprod()의? –

+0

몇 가지 의견 : i) 여기 반복하는 것보다는 반복하는 것이 많은 시간을 절약하는 것이 아닙니다. ii) 속도를 향상시키는 유일한 방법은 아마도 C 인 코드 일 것입니다. 나는 표현 방식으로 나를 위해 일할 수있는 패키지가 있기를 바랐다. 그렇지 않다. – gappy

+0

f()가 매우 느리거나 n이 매우 큰 문제입니까?후자의 경우 R에서 개선 할 수 있습니다. 그렇지만 C에서 f()를 다시 쓰는 것이 필요할 수도 있습니다 ... – Harlan

답변

1

을 잘 당신이 할 수있는 방법을 빨리 전체 시퀀스가 ​​필요하다면? 함수가 O (1)라고 가정하면, O (n)보다 더 잘할 수 없으며, 루핑을 통해 여러분은 그 점을 알 수 있습니다.

+0

그래, 일반적으로 O()보다 약간의 상수가 있습니다. – gappy

+0

더 나쁜 것은, 여러분이 때때로 그 부분을 수정할 때마다 전체 객체를 바꾸는 것과 같은 일을한다면 R에서 O (n^2)를 얻을 수 있다는 것입니다. 나는 원래의 문제가 그 문제를 피하는 것에 관한 것이라고 생각한다 ... – Harlan

1

일반적으로 구문 x $ y < - f (z)는 x를 매번 재 할당해야하며, x가 큰 개체 인 경우 매우 느립니다. 그러나 R에 몇 가지 트릭이있어서 목록 대체 기능 [[<-이 매번 전체 목록을 재 할당하지 않는다는 것이 밝혀졌습니다.

x[[1]] <- x1 
for (m in seq(2, n)) 
    x[[m]] <- f(x[[m-1]]) 

여기 만 낭비 측면에서는 적합하지 않습니다 루프에 대한에 대한 길이 n-1의 배열을 생성해야한다는 것입니다, 그러나 아마 아니다 : 그래서 당신이 합리적으로 효율적으로 할 수 있다고 생각 거대한 문제. 원하는 경우 while 루프로 대체 할 수 있습니다. 일반적인 벡터화 트릭 (lapply 등)

이 (이중 괄호는 당신에게 당신은 아마 오히려 단일 목록보다, 원하는 것입니다 목록의 요소를 제공합니다.) ... 여기 작동하지 않습니다

자세한 내용은 Chambers (2008)를 참조하십시오. 데이터 분석 용 소프트웨어. 피. 473-474.

1

C/C++/Fortran으로 작성하고 편리한 inline 패키지를 사용하여 컴파일, 링크 및로드를 처리 할 수 ​​있습니다.

물론 f() 함수는 R 함수를 유지해야하는 경우 실제 제약 조건이 될 수 있습니다. Rcpp에는 C++에서 R으로의 콜백 예제가 있지만 인라인을 사용하는 것보다 더 많은 작업이 필요합니다.

+0

더크, C에 R 함수 포인터 하나 전달할 수 있습니까? 나는 생각하지 않았다. – gappy

+0

예, Rcpp 소스에서 다시 살펴 보았습니다. 그것은 내가 재구성해야 할 문서에서 좀 지저분 해 - Rcpp가로드되면 'example (RcppExample)'의 예제 끝을 살펴보고 src/RcppExample.cpp의 해당 코드와 Rcpp.h 및 Rcpp.cpp. 사소하지는 않지만 할 수 있습니다. 타이밍 운동으로 좋을 것입니다. –

4

이것이 어떤 방식 으로든 완전히 "벡터화"될 수 있는지에 대한 질문에서 나는 그 대답이 아마 "아니오"라고 생각한다. 배열 프로그래밍의 근본적인 아이디어는 조작이 동시에 전체 값 세트에 적용된다는 것입니다. "embarassingly parallel"계산에 대한 질문에서도 마찬가지입니다. 이 경우 재귀 알고리즘은 이전 상태에 따라 다르므로 병렬 처리에서 속도를 얻을 수있는 방법이 없습니다. 직렬로 실행해야합니다.

즉, 프로그램 속도 향상에 대한 일반적인 조언이 적용됩니다. 예를 들어 가능한 한 재귀 함수 밖에서 많은 계산을 수행하십시오. 모든 것을 정렬하십시오. 루핑 중에 커질 필요가 없도록 배열 길이를 미리 정의하십시오. 등 See this question for a similar discussion. Tim Hesterberg's article on efficient S-Plus Programming에는 의사 코드 예제가 있습니다. 재발 관계 해결