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
Instrucciones del ejercicio
- Define
rescomo unNumericVectorde longitudny con valores dados por el métodoget_na()deNumericVector. - Calcula
totalcomo los primeroswindowvalores dex. - Calcula la media en
window - 1como el total dividido por el ancho de la ventana. - En el segundo bucle, actualiza el total restando el elemento
i - windowdexy sumando el elementoidex.
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
)
*/