Skip to content

Instantly share code, notes, and snippets.

@waldheinz
Created January 12, 2014 11:41
Show Gist options
  • Save waldheinz/8383609 to your computer and use it in GitHub Desktop.
Save waldheinz/8383609 to your computer and use it in GitHub Desktop.
Gleitender Mittelwert
/*
* compile with C++ 11 support, e.g.:
*
* g++ -std=c++0x -Wall -Wextra -pedantic avg.cpp
*/
#include <iomanip>
#include <iostream>
#include <random>
double smoothing(double value) {
double smoothValue = 0.0;
#define windowSize 19
// gleitender Mittelwert
/* Wir benutzen einen Ringbuffer, um die historischen
* Werte für die Berechnung des Durchschnitts vorzuhalten.
* Dieser wird realisiert durch ein Array mit "windowSize" vielen
* Elementen sowie einem int, in welchem wir uns die nächste
* Schreibposition im Array merken.
*
* Beachte: Wir brauchen siese Variablen *nicht* explizit
* initialisieren. C++ garantiert, dass statischer Speicher
* bei Programmstart mit Nullen initialisiert wird. Das ist
* zufällig genau das, was wir hier brauchen.
*/
static double history[windowSize];
static int position;
/* Den neuen Wert dem Buffer hinzufügen, und die Position
* fürs nächste Schreiben um eins erhöhen.
*/
history[position++] = value;
/* Falls position == windowSize ist, müssen wir sie wieder
* auf 0 zurücksetzen -- sonst schreiben wir beim nächsten
* Aufruf der Funktion über das Ende des Arrays hinaus.
*/
if (position >= windowSize) {
position = 0;
}
/* Summe der gebufferten Werte in smoothValue berechnen. */
for (int i=0; i < windowSize; i++) {
smoothValue += history[i];
}
/* Nun die Summe durch die Anzahl der Summanden teilen, und
* wir haben den gewünschten Durchschnitt. Fertig.
*/
smoothValue /= windowSize;
return smoothValue;
}
/* Ein kleines Testprogramm, was obige Funktion mit Werten
* füttert und das Ergebnis ausgibt.
*/
int main() {
std::uniform_real_distribution<double> unif(-0.1, 0.1);
std::default_random_engine re;
std::cout
<< std::setiosflags(std::ios::fixed)
<< std::setprecision(3);
double val = 0;
for (int i=0; i < 200; i++) {
val += unif(re);
std::cout << i << "\t" << val << "\t" << smoothing(val) << std::endl;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment