MulaiMulai sekarang secara gratis

Rolling mean (di C++)

Fungsi rolling mean tervektorisasi, rollmean3(), memiliki kinerja yang baik tetapi keterbacaan yang sangat buruk. Sulit sekali melihat bahwa kode ini menghitung rolling mean, sehingga fungsi lebih sulit di-debug dan dipelihara.

Versi kedua, rollmean2(), lebih lambat tetapi lebih mudah dibaca. Jika kita terjemahkan ke C++, semoga kita mendapatkan keterbacaan yang mudah dan kinerja yang cepat.

rollmean2() sudah didefinisikan di workspace Anda; Anda dapat mencetak definisinya untuk mengingat cara kerjanya. Sekarang Anda akan menerjemahkan rollmean2() ke C++ dan menamainya rollmean4().

Latihan ini adalah bagian dari kursus

Mengoptimalkan Kode R dengan Rcpp

Lihat Kursus

Petunjuk latihan

  • Atur res sebagai NumericVector dengan panjang n dan nilai yang diberikan oleh metode get_na() milik NumericVector.
  • Hitung total sebagai window nilai pertama dari x.
  • Hitung mean pada window - 1 sebagai total dibagi lebar jendela.
  • Pada loop kedua, perbarui total dengan mengurangkan elemen ke-i - window dari x dan menambahkan elemen ke-i dari x.

Latihan interaktif praktis

Cobalah latihan ini dengan menyelesaikan kode contoh berikut.

#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
   )   
*/
Edit dan Jalankan Kode