Boost.Accumulators累加器的簡單使用

Boost.Accumulators是一個累加器,實現的功能很簡單,就是對一組數據進行操作,然後可以得到一些特徵數據。

由於累加器默認不對數據進行儲存操作,所以不能把它作為一個簡單的容器使用。

簡單使用

從實際使用上來看,它應該是一個header only庫,所以可以直接include,不需要在最後的時候進行鏈接操作。

它的一般操作步驟如下:

  1. 定義一個累加器
  2. 輸入數據
  3. 獲取結果

先來看一個簡單的例子吧。

#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了,但是區別還是很大的。它其實是輸入了一個結構體,但是看起來的確很優雅。

進階使用

以上就是累加器的簡單使用,需要更進一步的使用,就可以自己定義累加器或者是特徵了。

Tags: