Zacznij terazZacznij za darmo

Średnie kroczące (w C++)

Wektoryzowana funkcja średniej kroczącej rollmean3() działała wydajnie, ale była bardzo trudna w odczycie. Ciężko się domyślić, że ten kod oblicza średnią kroczącą, co utrudnia debugowanie i utrzymanie funkcji.

Druga wersja, rollmean2(), była wolniejsza, ale znacznie czytelniejsza. Jeśli przeniesiemy ją do C++, powinniśmy uzyskać zarówno czytelność kodu, jak i wysoką wydajność.

rollmean2() jest zdefiniowana w twoim środowisku pracy – możesz wyświetlić jej definicję, aby przypomnieć sobie, jak działa. Teraz przetłumacz rollmean2() na C++, przypisując wynik do rollmean4().

To ćwiczenie jest częścią kursu

Optymalizacja kodu R za pomocą Rcpp

Zobacz kurs

Instrukcje do ćwiczenia

  • Ustaw res jako NumericVector o długości n i wartościach zwracanych przez metodę get_na() obiektu NumericVector.
  • Oblicz total jako sumę pierwszych window wartości x.
  • Oblicz średnią przy indeksie window - 1 jako total podzielone przez szerokość okna.
  • W drugiej pętli zaktualizuj sumę, odejmując i - window-ty element x i dodając i-ty element x.

Interaktywne ćwiczenie praktyczne

Spróbuj tego ćwiczenia, uzupełniając ten przykładowy kod.

#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
   )   
*/
Edytuj i uruchom kod