简体   繁体   English

boost :: accumulators :: rolling_mean返回错误的平均值

[英]boost::accumulators::rolling_mean returning incorrect mean value

Environment: VS 2013, Boost 1.58 环境:VS 2013,Boost 1.58

I've written something that presents a more friendly interface to Boost's accumulator, which can be used to project a sum over a window, and calculate the actual rolling mean over the window. 我写了一些东西,为Boost的累加器提供了一个更友好的界面,该界面可用于在窗口上投影总和,并计算窗口上的实际滚动平均值。 During a push to get to VS 2013 as our main compiler, one of the unit tests for this class started failing. 在努力将VS 2013作为主要编译器的过程中,此类的单元测试之一开始失败。 Peeling off the layers, I've narrowed it down to this minimal example: 剥离这些层,我将其范围缩小到以下最小示例:

#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";
    }
}

On the final pass of the loop, I don't get the expected mean value (1.5), but instead get a crazy high value (1431655766.333333). 在循环的最后一遍,我没有得到预期的平均值(1.5),而是得到了一个疯狂的高值(1431655766.333333)。

This code executes correctly in VS 2008 with Boost 1.49 (with C++11 vector initialization replaced, obviously), but fails in VS 2012 and VS 2013 with Boost 1.58. 此代码在带有Boost 1.49的VS 2008中正确执行(显然已替换了C ++ 11矢量初始化),但在带有Boost 1.58的VS 2012和VS 2013中失败。 I'm at a loss to explain this failure and thus can't fix it. 我无所适从地解释了这种失败,因此无法解决。

Other interesting points: 其他有趣的观点:

  • Manually inspecting the memory values inside the accumulator reveals that the correct data IS contained in its circular buffer. 手动检查累加器内部的内存值可以发现循环缓冲区中包含正确的数据IS。
  • If the data put into the accumulator is ordered in increasing value, the rolling_mean will be correct. 如果放入累加器的数据按递增值排序,则rolling_mean将是正确的。
  • Once the window is full, if any new element is smaller than the number it is knocking out of the window, the rolling_mean will be incorrect. 窗口填满后,如果任何新元素小于要从窗口中剔除的元素个数,rolling_mean将不正确。 If it is equal or greater, the rolling_mean will be correct. 如果等于或大于,则rolling_mean将是正确的。

It seems to be a Boost bug, but wanted to verify that I'm not doing something stupid before reporting the bug or attempting to build Boost 1.59. 它似乎是一个Boost错误,但想在报告该错误或尝试构建Boost 1.59之前验证我没有做任何愚蠢的事情。 Thanks in advance! 提前致谢!

EDIT: Thanks for the responses, as this does appear to be a Boost bug. 编辑:感谢您的答复,因为这确实是一个Boost错误。 The associated Boost ticket is here. 相关的Boost票证在这里。 . It's an issue related to unsigned integers with accumulators. 这是与累加器的无符号整数有关的问题。 Specifically, if a value added to the accumulator after the window is full is strictly less than all values in the window already, the rolling_mean call will return an invalid result. 具体来说,如果在窗口已满后添加到累加器的值严格小于窗口中已存在的所有值,那么rolling_mean调用将返回无效结果。

There is a workaround, which is to not use unsigned integers with accumulators. 有一种解决方法,即不要对累加器使用无符号整数。 This solves my problem, so thanks for the help! 这解决了我的问题,感谢您的帮助!

There's obviously a bug lurking there, possibly in the compiler, but more likely in the library, as I've been able to reproduce this on GCC: 很明显,这里有一个潜在的错误,可能存在于编译器中,但更可能存在于库中,因为我已经能够在GCC上重现此错误:

Live On Coliru 生活在Coliru

#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 : { 252, 189, 248, 154, 620, 885, 939, 196 }) {
        acc(i);
        std::cout << i << " actualMean: " << std::fixed << boost::accumulators::rolling_mean(acc) << "\n";
    }
}

Prints 版画

g++-5.2 -std=c++1y -O2 -Wall -pedantic main.cpp && ./a.out
252 actualMean: 252.000000
189 actualMean: 220.500000
248 actualMean: 229.666667
154 actualMean: 210.750000
620 actualMean: 292.600000
885 actualMean: 419.200000
939 actualMean: 569.200000
196 actualMean: 858994018.000000

Now the problem appears to be related to the choice of unsigned sample type` : changing it to signed removes the symptom: Live On Coliru 现在问题似乎与unsigned样本类型选择有关 :将其更改为已签名可消除症状: Live On Coliru


In short : I'd report this at the boost mailing list or Trac: https://svn.boost.org/trac/boost/ 简而言之 :我会在加速邮件列表或Trac中报告此情况: https : //svn.boost.org/trac/boost/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM