Comece agoraComece grátis

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

Ver curso

Instruções do exercicio

  • Defina res como um NumericVector com comprimento n e valores fornecidos pelo método get_na() de NumericVector.
  • Calcule total como os primeiros window valores de x.
  • Calcule a média em window - 1 como o total dividido pela largura da janela.
  • No segundo loop, atualize o total subtraindo o elemento i - window de x e somando o elemento i de x.

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
   )   
*/
Editar e Executar Código