이동 평균(rolling mean) 계산(C++)
벡터화한 이동 평균 함수 rollmean3()는 성능은 좋았지만 가독성이 매우 떨어졌어요. 이 코드가 이동 평균을 계산한다는 사실을 파악하기 어렵기 때문에 디버깅과 유지 보수가 힘들어집니다.
두 번째 버전인 rollmean2()는 더 느리지만 읽기가 쉬웠죠. 이를 C++로 옮기면, 읽기 쉬우면서도 빠른 성능을 기대할 수 있습니다.
rollmean2()는 작업 공간에 정의되어 있으니, 동작을 다시 확인하려면 정의를 출력해 보세요. 이제 rollmean2()를 C++로 옮겨 rollmean4()에 할당해 보겠습니다.
이 연습은 강의의 일부입니다
Rcpp로 R 코드 최적화하기
연습 안내
res를 길이가n이고 값이NumericVector의get_na()메서드로 주어지는NumericVector로 설정하세요.total을x의 처음window개 값의 합으로 계산하세요.- 인덱스
window - 1에서의 평균을 합계를 윈도 크기(window)로 나눈 값으로 계산하세요. - 두 번째 루프에서는 합계를 업데이트할 때
x의i - window번째 요소를 빼고i번째 요소를 더하세요.
실습형 인터랙티브 연습
이 예제를 이 샘플 코드를 완성하여 풀어보세요.
#include
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector rollmean4(NumericVector x, int window) {
int n = x.size();
// Set res as a NumericVector of NAs with length n
NumericVector res(___, ___::___());
// Sum the first window worth of values of x
double total = 0.0;
for(int i = 0; i < window; i++) {
total += ___;
}
// Treat the first case seperately
res[window - 1] = ___ / window;
// Iteratively update the total and recalculate the mean
for(int i = window; i < n; i++) {
// Remove the (i - window)th case, and add the ith case
total += - ___ + ___;
// Calculate the mean at the ith position
res[i] = total / window;
}
return res;
}
/*** R
# Compare rollmean2, rollmean3 and rollmean4
set.seed(42)
x <- rnorm(1e4)
microbenchmark(
rollmean2(x, 4),
rollmean3(x, 4),
rollmean4(x, 4),
times = 5
)
*/