Médias móveis (em C++)
A função vetorizada de média móvel, rollmean3(), teve bom desempenho, mas legibilidade muito ruim. É bem difícil notar que esse código calcula uma média móvel, o que torna a função mais difícil de depurar e manter.
A segunda versão, rollmean2(), era mais lenta, mas mais fácil de ler. Se traduzirmos isso para C++, a expectativa é conseguir ao mesmo tempo boa legibilidade e alto desempenho.
rollmean2() está definida no seu ambiente de trabalho; você pode imprimir sua definição para relembrar como ela funciona. Agora você vai traduzir rollmean2() para C++, atribuindo a rollmean4().
Este exercicio faz parte do curso
Otimizando código R com Rcpp
Instruções do exercicio
- Defina
rescomo umNumericVectorcom comprimentone valores fornecidos pelo métodoget_na()deNumericVector. - Calcule
totalcomo os primeiroswindowvalores dex. - Calcule a média em
window - 1como o total dividido pela largura da janela. - No segundo loop, atualize o total subtraindo o elemento
i - windowdexe somando o elementoidex.
exercicio interativo prático
Tente este exercicio completando este código de exemplo.
#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
)
*/