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.