Gleitende Mittelwerte (in C++)
Die Vektorvariante der Funktion für gleitende Mittelwerte, rollmean3(), war zwar performant, aber kaum lesbar. Es ist wirklich schwer zu erkennen, dass dieser Code einen gleitenden Mittelwert berechnet – das erschwert sowohl das Debuggen als auch die Pflege.
Die zweite Version, rollmean2(), war langsamer, aber leichter zu lesen. Wenn wir sie nach C++ übersetzen, bekommen wir hoffentlich gute Lesbarkeit und schnelle Ausführung.
rollmean2() ist in deinem Workspace definiert; du kannst dir die Definition ausgeben lassen, um dich an die Funktionsweise zu erinnern. Jetzt übersetzt du rollmean2() nach C++ und weist sie rollmean4() zu.
Diese Übung ist Teil des Kurses
R-Code mit Rcpp optimieren
Anleitung zur Übung
- Setze
resalsNumericVectormit Längenund Werten, die durch die Methodeget_na()desNumericVectorvorgegeben sind. - Berechne
totalals Summe der erstenwindowWerte vonx. - Berechne den Mittelwert an Position
window - 1alstotalgeteilt durch die Breite des Fensters. - Aktualisiere im zweiten Loop
total, indem du dasi - window-te Element vonxabziehst und dasi-te Element vonxhinzufügst.
Interaktive Übung
Vervollständige den Beispielcode, um diese Übung erfolgreich abzuschließen.
#include
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector rollmean4(NumericVector x, int window) {
int n = x.size();
// Set res as a NumericVector of NAs with length n
NumericVector res(___, ___::___());
// Sum the first window worth of values of x
double total = 0.0;
for(int i = 0; i < window; i++) {
total += ___;
}
// Treat the first case seperately
res[window - 1] = ___ / window;
// Iteratively update the total and recalculate the mean
for(int i = window; i < n; i++) {
// Remove the (i - window)th case, and add the ith case
total += - ___ + ___;
// Calculate the mean at the ith position
res[i] = total / window;
}
return res;
}
/*** R
# Compare rollmean2, rollmean3 and rollmean4
set.seed(42)
x <- rnorm(1e4)
microbenchmark(
rollmean2(x, 4),
rollmean3(x, 4),
rollmean4(x, 4),
times = 5
)
*/