Boost.Accumulators bietet Klassen an, die Proben oder Messwerte verarbeiten können. So kann zum Beispiel der größte oder kleinste Wert gefunden oder die Summe aller Werte gebildet werden. Während dies auch mit Algorithmen aus der Standardbibliothek möglich ist, unterstützt Boost.Accumulators zahlreiche Berechnungen aus der Statistik. So kann zum Beispiel der Mittelwert oder die Standardabweichung berechnet werden.
Die Bibliothek heißt Boost.Accumulators, weil ein wesentliches Konzept der Akkumulator ist. Ein Akkumulator ist vergleichbar mit einem Container, der Ergebnisse neu berechnet, wenn Sie einen neuen Wert übergeben. Der Wert wird nicht zwangsläufig im Akkumulator gespeichert. Stattdessen berechnet der Akkumulator Zwischenergebnisse ständig neu, wenn Sie ihn mit Werten füttern.
Die Bibliothek Boost.Accumulators besteht aus drei Teilen:
Das Framework definiert die grundsätzliche Struktur der Bibliothek. Es stellt die Klasse boost::accumulators::accumulator_set
zur Verfügung, die immer zum Einsatz kommt, wenn Sie Boost.Accumulators verwenden. Während Sie diese und einige andere Klassen aus dem Framework kennen müssen, müssen Sie sich mit den Details des Frameworks nur dann vertraut machen, wenn Sie eigene Akkumulatoren entwickeln möchten.
Um Zugriff auf boost::accumulators::accumulator_set
und andere Klassen des Frameworks zu erhalten, binden Sie die Headerdatei boost/accumulators/accumulators.hpp
ein.
Boost.Accumulators stellt zahlreiche Akkumulatoren zur Verfügung, die Berechnungen ausführen. Sie können auf diese Akkumulatoren zugreifen und sie sofort verwenden.
Über die Headerdatei boost/accumulators/statistics.hpp
haben Sie Zugriff auf alle angebotenen Akkumulatoren.
Boost.Accumulators stellt Operatoren zur Verfügung, um zum Beispiel komplexe Zahlen vom Typ std::complex
mit einem int
-Wert multiplizieren oder zwei Vektoren addieren zu können. So bietet die Headerdatei boost/accumulators/numeric/functional.hpp
Zugriff auf Operatoren für std::complex
, std::valarray
und std::vector
. Sie müssen diese Headerdatei nicht selbst einbinden, da sie von den Headerdateien der Akkumulatoren eingebunden wird. Sie müssen jedoch die Macros BOOST_NUMERIC_FUNCTIONAL_STD_COMPLEX_SUPPORT
, BOOST_NUMERIC_FUNCTIONAL_STD_VALARRAY_SUPPORT
und BOOST_NUMERIC_FUNCTIONAL_STD_VECTOR_SUPPORT
definieren, wenn die Operatoren für die entsprechenden Klassen verfügbar sein sollen.
Alle von Boost.Accumulators angebotenen Klassen und Funktionen befinden sich in boost::accumulators
oder darunter liegenden Namensräumen. So sind zum Beispiel alle Akkumulatoren im Namensraum boost::accumulators::tag
definiert.
boost::accumulators::tag::count
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
#include <iostream>
using namespace boost::accumulators;
int main()
{
accumulator_set<int, features<tag::count>> acc;
acc(4);
acc(-6);
acc(9);
std::cout << count(acc) << '\n';
}
Im Beispiel 58.1 kommt mit boost::accumulators::tag::count
ein einfacher Akkumulator zum Einsatz: Er zählt die Werte, die dem Akkumulator übergeben werden. So gibt das Beispielprogramm 3
aus, wenn Sie es ausführen.
Wenn Sie einen Akkumulator verwenden möchten, greifen Sie auf die Klasse boost::accumulators::accumulator_set
zu. Bei dieser Klasse handelt es sich um ein Template, dem Sie als ersten Parameter den Typ übergeben, den Sie für die Werte verwenden möchten, die verrechnet werden sollen. Im Beispiel 58.1 ist dies int
.
Als zweiten Parameter geben Sie die Akkumulatoren an, die Sie verwenden möchten. Beachten Sie, dass Sie mehrere Akkumulatoren verwenden können. Der Name der Klasse boost::accumulators::accumulator_set
deutet es an, dass beliebig viele Akkumulatoren verwaltet werden können.
Genau genommen geben Sie keine Akkumulatoren an, sondern Features. Mit Features legen Sie fest, was berechnet werden soll. Sie bestimmen das Was, nicht das Wie. So kann es für Features unterschiedliche Implementationen geben. Bei diesen Implementationen handelt es sich um Akkumulatoren.
Im Beispiel 58.1 wird mit boost::accumulators::tag::count
angegeben, dass ein Akkumulator verwendet werden soll, der Werte zählt. Existieren mehrere Akkumulatoren, die Werte zählen können, wählt Boost.Accumulators einen Standardakkumulator aus.
Beachten Sie, dass Sie Features nicht direkt als zweiten Parameter an boost::accumulators::accumulator_set
übergeben, sondern über boost::accumulators::features
.
Wenn Sie ein Objekt vom Typ boost::accumulators::accumulator_set
erstellt haben, können Sie es wie eine Funktion verwenden und über den Operator operator()
Werte übergeben. Diese werden sofort von dem oder den verwendeten Akkumulatoren verrechnet. Die Werte, die Sie übergeben, müssen zu dem Typ passen, den Sie als ersten Parameter an boost::accumulators::accumulator_set
übergeben haben.
Für jedes Feature existiert ein gleichnamiger Extractor. Es handelt sich dabei um eine Funktion, die Sie aufrufen können, um das aktuelle Ergebnis eines Akkumulators zu erhalten. Im Beispiel 58.1 wird der Extractor boost::accumulators::count()
aufgerufen und ihm als einziger Parameter acc übergeben. boost::accumulators::count()
gibt daraufhin 3 zurück.
mean
und variance
errechnen#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
#include <iostream>
using namespace boost::accumulators;
int main()
{
accumulator_set<double, features<tag::mean, tag::variance>> acc;
acc(8);
acc(9);
acc(10);
acc(11);
acc(12);
std::cout << mean(acc) << '\n';
std::cout << variance(acc) << '\n';
}
Im Beispiel 58.2 werden die beiden Features boost::accumulators::tag::mean
und boost::accumulators::tag::variance
eingesetzt, um Durchschnitt und Varianz für fünf Werte zu errechnen. Wenn Sie das Beispielprogramm ausführen, wird 10
und 2
ausgegeben.
Die Varianz von 2 kommt zustande, weil Boost.Accumulators für jeden der fünf Werte ein Gewicht von 0,2 annimmt. Der mit boost::accumulators::tag::variance
ausgewählte Akkumulator gehört zu denjenigen, die mit Gewichten arbeiten. Wird kein Gewicht explizit angegeben, erhält jeder Wert automatisch das gleiche Gewicht.
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
#include <iostream>
using namespace boost::accumulators;
int main()
{
accumulator_set<double, features<tag::mean, tag::variance>, int> acc;
acc(8, weight = 1);
acc(9, weight = 1);
acc(10, weight = 4);
acc(11, weight = 1);
acc(12, weight = 1);
std::cout << mean(acc) << '\n';
std::cout << variance(acc) << '\n';
}
Im Beispiel 58.3 wird mit int
ein dritter Template-Parameter an boost::accumulators::accumulator_set
übergeben. Dieser Parameter beschreibt den Typ der Gewichte. So kann in diesem Beispiel jeder Wert mit einer Ganzzahl gewichtet werden.
Boost.Accumulators verwendet Boost.Parameter, um zusätzliche Angaben wie Gewichte als Name/Wert-Paare zu übergeben. Der Parameter für Gewichte heißt weight. Sie können den Parameter wie eine Variable behandeln und ihm einen Wert zuweisen. Das Name/Wert-Paar wird als zusätzlicher Parameter hinter jedem Wert an den Akkumulator übergeben.
Im Beispiel hat der Wert 10 ein Gewicht von 4, während alle anderen Werte ein Gewicht von 1 haben. Der Durchschnitt ist unverändert 10, da Gewichte für die Berechnung des Durchschnitts keine Rolle spielen. Die Varianz ist nun jedoch 1,25. Sie hat sich im Vergleich zum vorherigen Beispiel verringert, da der mittlere Wert stärker gewichtet ist als die anderen.
Boost.Accumulators bietet zahlreiche weitere Akkumulatoren an. Diese werden ähnlich wie die oben vorgestellten Akkumulatoren verwendet. Die Dokumentation der Bibliothek enthält eine Referenz, um einen Überblick über die verfügbaren Akkumulatoren zu erhalten.