開始使用免費開始

移動平均(C++)

向量化的移動平均函式 rollmean3() 效能不錯,但可讀性很差。從這段程式碼看出它在計算移動平均非常不容易,讓除錯與維護都更困難。

第二個版本 rollmean2() 較慢,但更容易閱讀。若把它翻成 C++,理想情況下能同時兼顧易讀性與高效能。

rollmean2() 已定義在你的工作空間;你可以印出它的定義來回想其運作方式。接下來你要把 rollmean2() 轉寫成 C++,並指定為 rollmean4()

本練習屬於課程

用 Rcpp 最佳化 R 程式碼

檢視課程

練習說明

  • res 設為長度為 nNumericVector,其初始值由 NumericVectorget_na() 方法提供。
  • total 設為 x 的前 window 個值的總和。
  • 在索引 window - 1 的位置計算平均數,做法是用總和除以視窗寬度。
  • 在第二個迴圈中,透過減去 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
   )   
*/
編輯並執行程式碼