Skip to main content
edited tags; edited title
Link
200_success
  • 144.2k
  • 22
  • 188
  • 473

Optimizing moving Moving average function in C++ for use with R

Source Link
Frostic
  • 163
  • 3

Optimizing moving average function

I am trying to improve the code and speed up in C++ (Rcpp) a (centered) weighted moving average function I coded.

An example of what the roll_mean function does. Note that the function works no matter what the size of x is and adapts to both tails of my data

w=c(1/2,1,1/2)
x=c(4,2,6,12)
res=c(2,5,7,3) 
res=c((x[1:2]*w[2:3])/sum(w[2:3]),x[1:3]*w[1:3]/sum(w[1:3]),x[2:4]*w[1:3]/sum(w[1:3]),x[3:4]*w[1:2]/sum(w[1:2]))

The file PartialMA.cpp

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
NumericVector roll_mean(const NumericVector& x,
                        const NumericVector& w) {

  int n = x.size();
  int w_size = w.size();
  int size = (w_size - 1) / 2;

  NumericVector res(n);
  int i, ind_x, ind_w;

  double tmp_wsum, tmp_xwsum, tmp_w;

  for (i = 0; i < n; i++) {
    tmp_xwsum = 0;
    tmp_wsum = 0;
    for (ind_x = i - size, ind_w = 0; ind_x < i + size; ind_x++, ind_w++) {
      if((ind_x >= 0) & (ind_x < n)){
      tmp_w = w(ind_w);
      tmp_xwsum += x(ind_x) *  tmp_w;
      tmp_wsum += tmp_w;
      }
    }
    res[i] = tmp_xwsum / tmp_wsum;
  }

  return res;
}

I tried to replace the loop + if statement with this to minimize the number of iteration:

for (ind_x = std::max(0, i - size), ind_w = std::max(0, size-1); ind_x < std::min(n, i + size); ind_x++, ind_w++) {

I feel like I am not rigorous enough and I would be very grateful if someone could help me improving my code and eventually speed up the function as much as possible.