X-Git-Url: https://git.auder.net/?p=epclust.git;a=blobdiff_plain;f=pkg%2Fsrc%2Ffilter.c;fp=pkg%2Fsrc%2Ffilter.c;h=8ece9c3f439dc7eaf2e23f3962e816fec42e829a;hp=0000000000000000000000000000000000000000;hb=e906736ea27105237e84c904dce6170353726292;hpb=57f337af19cd6251815bb1ff2d62f4c58e8b6078 diff --git a/pkg/src/filter.c b/pkg/src/filter.c new file mode 100644 index 0000000..8ece9c3 --- /dev/null +++ b/pkg/src/filter.c @@ -0,0 +1,70 @@ +#include +#include + +// filterMA +// +// Filter [time-]series by replacing all values by the moving average of values +// centered around current one. Border values are averaged with available data. +// +// @param M_ A real matrix of size LxD +// @param w_ The (odd) number of values to average +// +// @return The filtered matrix, of same size as the input +SEXP filterMA(SEXP M_, SEXP w_) +{ + int L = INTEGER(getAttrib(M_, R_DimSymbol))[0], + D = INTEGER(getAttrib(M_, R_DimSymbol))[1], + w = INTEGER_VALUE(w_), + half_w = (w-1)/2, + i, + nt; //number of terms in the current sum (max: w) + double *M = REAL(M_), + cs, //current sum (max: w terms) + left; //leftward term in the current moving sum + + SEXP fM_; //the filtered result + PROTECT(fM_ = allocMatrix(REALSXP, L, D)); + double* fM = REAL(fM_); //pointer to the encapsulated vector + + // NOTE: unused loop parameter: shifting at the end of the loop is more efficient + for (int col=D-1; col>=0; col--) + { + // Initialization + nt = half_w + 1; + left = M[0]; + cs = 0.; + for (i=half_w; i>=0; i--) + cs += M[i]; + + // Left border + for (i=0; i