簡體   English   中英

boost :: accumulators :: rolling_mean返回錯誤的平均值

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

環境: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";
    }
}

在循環的最后一遍,我沒有得到預期的平均值(1.5),而是得到了一個瘋狂的高值(1431655766.333333)。

此代碼在帶有Boost 1.49的VS 2008中正確執行(顯然已替換了C ++ 11矢量初始化),但在帶有Boost 1.58的VS 2012和VS 2013中失敗。 我無所適從地解釋了這種失敗,因此無法解決。

其他有趣的觀點:

  • 手動檢查累加器內部的內存值可以發現循環緩沖區中包含正確的數據IS。
  • 如果放入累加器的數據按遞增值排序,則rolling_mean將是正確的。
  • 窗口填滿后,如果任何新元素小於要從窗口中剔除的元素個數,rolling_mean將不正確。 如果等於或大於,則rolling_mean將是正確的。

它似乎是一個Boost錯誤,但想在報告該錯誤或嘗試構建Boost 1.59之前驗證我沒有做任何愚蠢的事情。 提前致謝!

編輯:感謝您的答復,因為這確實是一個Boost錯誤。 相關的Boost票證在這里。 這是與累加器的無符號整數有關的問題。 具體來說,如果在窗口已滿后添加到累加器的值嚴格小於窗口中已存在的所有值,那么rolling_mean調用將返回無效結果。

有一種解決方法,即不要對累加器使用無符號整數。 這解決了我的問題,感謝您的幫助!

很明顯,這里有一個潛在的錯誤,可能存在於編譯器中,但更可能存在於庫中,因為我已經能夠在GCC上重現此錯誤:

生活在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";
    }
}

版畫

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

現在問題似乎與unsigned樣本類型選擇有關 :將其更改為已簽名可消除症狀: Live On Coliru


簡而言之 :我會在加速郵件列表或Trac中報告此情況: https : //svn.boost.org/trac/boost/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM