ComenzarEmpieza gratis

Medias móviles (en C++)

La función vectorizada de medias móviles, rollmean3(), tenía buen rendimiento pero una legibilidad muy pobre. Es difícil ver que este código calcula una media móvil, lo que complica depurar y mantener la función.

La segunda versión, rollmean2(), era más lenta pero más fácil de leer. Si la traducimos a C++, idealmente conseguiremos buena legibilidad y un rendimiento rápido.

rollmean2() está definida en tu espacio de trabajo; puedes imprimir su definición para recordar cómo funciona. Ahora traducirás rollmean2() a C++ y la asignarás a rollmean4().

Este ejercicio forma parte del curso

Optimizar código de R con Rcpp

Ver curso

Instrucciones del ejercicio

  • Define res como un NumericVector de longitud n y con valores dados por el método get_na() de NumericVector.
  • Calcula total como los primeros window valores de x.
  • Calcula la media en window - 1 como el total dividido por el ancho de la ventana.
  • En el segundo bucle, actualiza el total restando el elemento i - window de x y sumando el elemento i de x.

Ejercicio interactivo práctico

Prueba este ejercicio y completa el código de muestra.

#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
   )   
*/
Editar y ejecutar código