forked from jMotif/jmotif-R
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathznorm.cpp
More file actions
63 lines (55 loc) · 2.08 KB
/
znorm.cpp
File metadata and controls
63 lines (55 loc) · 2.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <RcppArmadillo.h>
using namespace Rcpp ;
//
#include <jmotif.h>
//
//' Z-normalizes a time series by subtracting its mean and dividing by the standard deviation.
//'
//' @param ts the input time series.
//' @param threshold the z-normalization threshold value, if the input time series' standard
//' deviation will be found less than this value, the procedure will not be applied,
//' so the "under-threshold-noise" would not get amplified.
//' @useDynLib jmotif
//' @export
//' @references Dina Goldin and Paris Kanellakis,
//' On similarity queries for time-series data: Constraint specification and implementation.
//' In Principles and Practice of Constraint Programming (CP 1995), pages 137-153. (1995)
//' @examples
//' x = seq(0, pi*4, 0.02)
//' y = sin(x) * 5 + rnorm(length(x))
//' plot(x, y, type="l", col="blue")
//' lines(x, znorm(y, 0.01), type="l", col="red")
// [[Rcpp::export]]
NumericVector znorm(NumericVector ts, double threshold = 0.01) {
// double ts_sd = sd(ts);
// if (ts_sd < threshold){
// return clone(ts);
// }
// Rcout << " mean1 " << mean(ts) << "\n";
// Rcout << " stdev1 " << ts_sd << "\n";
// return (ts - mean(ts)) / ts_sd;
return wrap(_znorm(Rcpp::as< std::vector<double> >(ts), threshold));
}
// this is the main implementation, above is the wrapper
//
std::vector<double> _znorm(std::vector<double> ts, double threshold) {
double sum = std::accumulate(std::begin(ts), std::end(ts), 0.0);
double mean = sum / ts.size();
// Rcout << " mean2 " << mean << "\n";
std::vector<double> diff(ts.size());
//std::transform(ts.begin(), ts.end(), diff.begin(), std::bind2nd(std::minus<double>(), mean));
for(unsigned i=0; i<ts.size(); i++)
diff[i] = ts[i]-mean;
double sq_sum = std::inner_product(diff.begin(), diff.end(), diff.begin(), 0.0);
double stdev = std::sqrt(sq_sum / (ts.size()-1));
// Rcout << " stdev2 " << stdev << "\n";
if (stdev < threshold){
std::vector<double> res(ts);
return res;
}
std::vector<double> res(ts.size());
for(unsigned i=0; i<ts.size(); i++){
res[i] = (ts[i]-mean)/stdev;
}
return res;
}