Bắt đầu ngayBắt đầu miễn phí

Trung bình trượt (bằng C++)

Hàm trung bình trượt dạng vector hóa, rollmean3() chạy khá nhanh nhưng lại rất khó đọc. Rất khó nhận ra đây là mã tính trung bình trượt, khiến hàm khó gỡ lỗi và bảo trì.

Phiên bản thứ hai, rollmean2(), chậm hơn nhưng dễ đọc hơn. Nếu ta chuyển nó sang C++, hy vọng sẽ vừa dễ đọc vừa chạy nhanh.

rollmean2() đã được định nghĩa sẵn trong không gian làm việc; bạn có thể in định nghĩa của nó để nhớ lại cách hoạt động. Giờ bạn sẽ dịch rollmean2() sang C++, gán thành rollmean4().

Bài tập này là một phần của khóa học

Tối ưu hóa mã R với Rcpp

Xem khóa học

Hướng dẫn bài tập

  • Gán res là một NumericVector có độ dài n và các giá trị được cung cấp bởi phương thức get_na() của NumericVector.
  • Tính total là tổng của window giá trị đầu tiên của x.
  • Tính giá trị trung bình tại vị trí window - 1 bằng tổng chia cho độ rộng cửa sổ.
  • Trong vòng lặp thứ hai, cập nhật tổng bằng cách trừ phần tử thứ i - window của x và cộng phần tử thứ i của x.

Bài tập tương tác thực hành trực tiếp

Hãy thử làm bài tập này bằng cách hoàn thành đoạn mã mẫu này.

#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
   )   
*/
Chỉnh sửa và Chạy Mã