我最近发现了优秀的库boost :: accumulators,我想用它来代替我积累统计数据的一些代码.
我在文档中找不到的一件事是能够对两个累加器集合求和,如operator + =
例:
using namespace boost::accumulators;
typedef accumulator_set<double, features<tag::variance> > AccumSet;
class Foo {
AccumSet acc;
public:
Foo& operator+=(const Foo& that) {
this->acc += that.acc; // error! no such operator
return *this;
}
double GetVariance() { return variance(acc); }
};
Run Code Online (Sandbox Code Playgroud)
如何使用可用的API实现此目的?我不知道这是否可以实现库中所有类型的累加器(可能不是尾部),但它肯定可以用于重要的事情,如计数,总和,平均值,时刻,协方差等
我有一些代码使用Boost累加器来跟踪滚动窗口的平均值 - "滚动平均值".除了滚动平均值,我想跟踪同一滚动窗口的最小值和最大值.
有没有办法用Boost累加器计算滚动最小值和滚动最大值?我没有看到方法......
我已经尝试将min和max标签添加到用于rolling_mean的累加器中,但这并没有给我我想要的东西.
typedef accumulator_set<uint32_t, stats<tag::rolling_mean> > rollingMeanAcc_t;
Run Code Online (Sandbox Code Playgroud)
变
typedef accumulator_set<uint32_t, stats<tag::rolling_mean,tag::min,tag::max> > rollingMeanAcc_t;
Run Code Online (Sandbox Code Playgroud)
但是,此处提供的最小值和最大值是在整个累加器上计算的,而不是限制在与平均值相同的滚动窗口.
Boost 文档说明在所有样本中计算最小值和最大值,不限于滚动窗口.它们似乎没有提供限制或加重样品的方法.
我希望能够在滚动窗口中报告平均值/最小值/最大值.
我目前正在使用Boost版本1.48.0.我查看了最新版本(1.54.0)的文档,并没有看到在那里实现滚动最小/最大.
我发现了一种非Boost方式来跟踪最小滑动窗口,但这似乎也不是我想要的.我不想仅因为它们大于/小于之前的最小值/最大值而删除值,因为这会使rolling_mean不准确.
环境:VS 2013,Boost 1.58
我写了一些东西,它为Boost的累加器提供了一个更友好的界面,可用于在窗口上投影和,并计算窗口上的实际滚动平均值.在推动将VS 2013作为我们的主编译器的过程中,该类的一个单元测试开始失败.剥离层,我把它缩小到这个最小的例子:
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
#include <boost/accumulators/statistics/rolling_mean.hpp>
namespace ba = boost::accumulators;
namespace bt = ba::tag;
typedef ba::accumulator_set < uint32_t, ba::stats <bt::rolling_mean > > MeanAccumulator;
int main() {
MeanAccumulator acc(bt::rolling_window::window_size = 5u);
for (uint32_t i : { 3, 2, 1, 0 }) {
acc(i);
std::cout << i << " actualMean: " << std::fixed << boost::accumulators::rolling_mean(acc) << "\n";
}
}
Run Code Online (Sandbox Code Playgroud)
在循环的最后一次传递中,我没有得到预期的平均值(1.5),而是得到一个疯狂的高值(1431655766.333333).
此代码在VS 2008中使用Boost 1.49正确执行(显然已替换C++ 11向量初始化),但在VS 2012和VS 2013中使用Boost 1.58失败.我无法解释这种失败,因此无法修复它.
其他有趣的观点:
它似乎是一个Boost错误,但是想要在报告错误或尝试构建Boost 1.59之前验证我没有做一些愚蠢的事情.提前致谢!
编辑:感谢您的回复,因为这似乎是一个Boost错误.相关的Boost票在这里..这是与带累加器的无符号整数相关的问题.具体来说,如果在窗口已满后添加到累加器的值严格小于窗口中的所有值,则rolling_mean调用将返回无效结果.
有一种解决方法,即不使用带累加器的无符号整数.这解决了我的问题,谢谢你的帮助!
我正在尝试使用增压累加器来计算滚动平均值.当我像这样声明变量内联时:
#include <iostream>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/rolling_mean.hpp>
using namespace boost::accumulators;
int main()
{
// Define rolling_mean accumulator
accumulator_set<double, stats<tag::rolling_mean > > acc(tag::rolling_window::window_size = 5);
// push in some data ...
acc(1.2);
acc(2.3);
acc(3.4);
acc(4.5);
// Display the results ...
std::cout << "Mean: " << rolling_mean(acc) << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它工作得很好.当我将累加器声明为类的成员时,如下所示:
#include <iostream>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/rolling_mean.hpp>
using namespace boost::accumulators;
class DoMean {
private:
accumulator_set<double, stats<tag::rolling_mean > > m_acc(tag::rolling_window::window_size = 5);
public:
void addData(double val) { …Run Code Online (Sandbox Code Playgroud) 由于没有找到在 C++ 中重置累加器的“升压”方法,我遇到了一段似乎重置升压累加器的代码。但不明白它是如何实现的。代码如下 -
#include <iostream>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
using namespace boost::accumulators;
template< typename DEFAULT_INITIALIZABLE >
inline void clear( DEFAULT_INITIALIZABLE& object )
{
object.DEFAULT_INITIALIZABLE::~DEFAULT_INITIALIZABLE() ;
::new ( boost::addressof(object) ) DEFAULT_INITIALIZABLE() ;
}
int main()
{
// Define an accumulator set for calculating the mean
accumulator_set<double, stats<tag::mean> > acc;
float tmp = 1.2;
// push in some data ...
acc(tmp);
acc(2.3);
acc(3.4);
acc(4.5);
// Display the results ...
std::cout << "Mean: " << mean(acc) << std::endl;
// clear …Run Code Online (Sandbox Code Playgroud)