Boost.Accumulators累加器的簡單使用
Boost.Accumulators是一個累加器,實現的功能很簡單,就是對一組數據進行操作,然後可以得到一些特徵數據。
由於累加器默認不對數據進行儲存操作,所以不能把它作為一個簡單的容器使用。
簡單使用
從實際使用上來看,它應該是一個header only庫,所以可以直接include,不需要在最後的時候進行鏈接操作。
它的一般操作步驟如下:
- 定義一個累加器
- 輸入數據
- 獲取結果
先來看一個簡單的例子吧。
#include <iostream>
#include <string>
#include <vector>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/sum.hpp>
namespace ba = boost::accumulators;
int main() {
ba::accumulator_set<double, ba::stats<ba::tag::mean, ba::tag::sum>> acc;
acc(100);
acc(101);
acc(102);
std::cout << ba::mean(acc) << " " << ba::sum(acc) << std::endl;
return 0;
}
這個例子實現了一個簡單的求平均和求和的累加器。
首先來看main函數裡面的第一句,這裡定義了一個名為acc的累加器。
ba::accumulator_set<double, ba::stats<ba::tag::mean, ba::tag::sum>> acc;
accumulator_set的定義為
template< typename Sample, typename Features, typename Weight = void >
struct accumulator_set;
模板裡面第一個參數為數據的類型;第二個參數是在運行中需要計算的特徵,它是Boost::MPL里的模板向量;第三個參數是權重的類型,這一個我們在後面討論。
然後就是向累加器裡面添加數據,可以看到定義好的累加器是作為一個函數對象使用的(重載了()操作符)。因此也可以如下操作:
std::vector data({1, 2, 3, 4});
std::for_each(data.begin(), data.end(), acc);
這樣操作可以很方便的對data裡面的數據進行遍歷操作。
在添加完數據之後,便是獲取最後的結果:
std::cout << ba::mean(acc) << " " << ba::sum(acc) << std::endl;
這裡我們使用了對應特徵的函數,來獲取對應的特徵結果。
官方給出的可以使用的特徵有很多種,詳細的資訊可以訪問The Statistical Accumulators Library,裡面有每一種特徵詳細的定義和使用方法。
加權
在統計中,我們也經常會遇到需要加權統計的情況。從之前的accumulator_set的定義中,我們也可以很清晰的看到,其也有權重的類型。所以他也是可以使用權重來對數據進行操作的。
使用加權的累加器和使用普通的累加器
#include <iostream>
#include <string>
#include <vector>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/sum.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics.hpp>
namespace ba = boost::accumulators;
int main() {
ba::accumulator_set<double, ba::stats<ba::tag::mean, ba::tag::sum>, double> acc;
acc(10.2, ba::weight = 1.5);
acc(20.1, ba::weight = 100);
acc(30, ba::weight = 2);
std::cout << ba::mean(acc) << " " << ba::sum(acc) << std::endl;
return 0;
}
主要的不同表現在定義和輸入階段。首先是定義,相比之前的定義,加權的累加器增加了權重的類型(第三個模板參數)。其實第二個參數,也是有一些不同的,應該使用加權的特徵,但是一些巧妙的設計,讓它們看起來一致。
然後是在輸入的階段,輸入階段要增加一個參數,數據的權重。看起來有點像python了,但是區別還是很大的。它其實是輸入了一個結構體,但是看起來的確很優雅。
進階使用
以上就是累加器的簡單使用,需要更進一步的使用,就可以自己定義累加器或者是特徵了。

