-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
allows for fast and easy RunningMean Calculation in C++
- Loading branch information
Showing
5 changed files
with
115 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
.onUnload <- function(libpath) { | ||
library.dynam.unload("arduinor", libpath) | ||
} | ||
} | ||
|
||
Rcpp::loadModule("RunningMeanModule", TRUE) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#include "RunningMean.h" | ||
|
||
|
||
RunningMean::RunningMean() : n(0) { | ||
stop("n (size of window) must be supplied"); | ||
} | ||
|
||
// Initiates a new Running Mean class of size n (constant) | ||
RunningMean::RunningMean(int n) : n(n) { | ||
if (n <= 0) stop("n (size of window) must be supplied"); | ||
deq.resize(n); | ||
n_values = 0; | ||
sum = 0; | ||
} | ||
|
||
// inserts a new value into the internal deque. Deletes the oldest value | ||
void RunningMean::insert(double v) { | ||
if (n == 0) stop("n (size of window) must be larger than zero"); | ||
|
||
// TODO: What happens if we insert a missing value? | ||
if (!R_IsNA(v) && !R_IsNaN(v)) { | ||
n_values++; | ||
sum += v - deq.back(); | ||
deq.push_front(v); | ||
deq.pop_back(); | ||
} | ||
} | ||
|
||
// Returns the running mean of the values in the deque | ||
// if the size is 0, return NA, if the number of already inserted values (n_values) | ||
// is smaller than the size of the deque, use n_values. This allows the running mean | ||
// to return values even if the number of values is smaller than window lengths | ||
// could also be set to NA if needed... | ||
double RunningMean::get_mean() { | ||
if (n == 0) return NA_REAL; | ||
if (n_values < n) return(sum / n_values); | ||
return sum / n; | ||
} | ||
|
||
// prints the values of the deque | ||
void RunningMean::show() { | ||
Rcout << "RunningMean object <" << static_cast<const void*>(this) << | ||
"> window size " << n << ", number of inserts " << n_values << "\n" << | ||
deq[0]; | ||
for (int i = 1; i < n; ++i) { | ||
Rcout << " " << deq[i]; | ||
} | ||
Rcout << "\n"; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
#include <Rcpp.h> | ||
using namespace Rcpp; | ||
|
||
/* | ||
* Example R Code | ||
* | ||
* # Initiate the Class with a window-length of size 3 | ||
* obj <- arduinor:::RunningMean$new(3) | ||
* | ||
* # insert a new value | ||
* obj$insert(1.03) | ||
* obj$insert(1.05) | ||
* obj$insert(1.04) | ||
* | ||
* # inspect the object | ||
* obj | ||
* | ||
* # get the running mean | ||
* obj$get_mean() | ||
* | ||
* # add another value, effectively removing the first insert (1.03) | ||
* obj$insert(1.06) | ||
* obj | ||
* obj$get_mean() | ||
* | ||
*/ | ||
|
||
// defines the RunningMean class | ||
class RunningMean{ | ||
public: | ||
RunningMean(); | ||
RunningMean(int n); | ||
|
||
void insert(double val); | ||
double get_mean(); | ||
void show(); | ||
|
||
private: | ||
std::deque<double> deq; | ||
const int n; | ||
int n_values; | ||
double sum; | ||
}; | ||
|
||
// Exposes the class | ||
RCPP_MODULE(RunningMeanModule) { | ||
class_<RunningMean>("RunningMean") | ||
.default_constructor("Default constructor") | ||
.constructor<int>("Constructor with an argument") | ||
.method("insert", &RunningMean::insert) | ||
.method("get_mean", &RunningMean::get_mean) | ||
.method("show", &RunningMean::show) | ||
; | ||
} | ||
|