2015-10-05 2 views
4

окружающая среда: VS 2013, Повысьте 1,58повышение :: :: аккумуляторы rolling_mean возвращение неправильно среднее значение

Я написал то, что представляет собой более дружественный интерфейс, чтобы повысить аккумулятор, который может быть использован для проекта суммы по окна и вычислить фактическое среднее значение для окна. Во время нажатия, чтобы перейти на 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).

Этот код выполняется правильно в VS 2008 с Boost 1.49 (с заменой вектора инициализации C++ 11, очевидно), но с ошибкой в ​​VS 2012 и VS 2013 с Boost 1.58. Я затрудняюсь объяснить эту ошибку и, следовательно, не могу ее исправить.

Другие интересные моменты:

  • вручную проверить значения памяти внутри аккумулятора показывает, что правильно данные содержатся в кольцевом буфере.
  • Если данные, помещенные в аккумулятор, упорядочены по возрастающей стоимости, значение roll_mean будет правильным.
  • После того, как окно заполнено, если какой-либо новый элемент меньше числа, которое он выбивает из окна, значение roll_mean будет неправильным. Если он равен или больше, значение roll_mean будет правильным.

Кажется, это ошибка Boost, но мне хотелось проверить, что я не делаю что-то глупо, прежде чем сообщать об ошибке или пытаться построить Boost 1.59. Заранее спасибо!

EDIT: Спасибо за ответы, поскольку это похоже на ошибку Boost. Связанный билет Boost - here.. Это проблема, связанная с целыми числами без знака с аккумуляторами. В частности, если значение, добавленное в накопитель после заполнения окна, строго меньше всех значений в окне, вызов roll_mean вернет неверный результат.

Существует обходное решение, которое не должно использовать целые числа без знака с аккумуляторами. Это решает мою проблему, поэтому спасибо за помощь!

+1

Посмотрите на свою диаграмму: это ccccccccccc/4. Плюс немного. Это неинициализированная память стека. Отлаживайте код повышения, пока не увидите, возможно, чтение cccccccc. – Yakk

+0

Я просто обсуждал это с коллегой. Спасибо за совет! Я посмотрю на это. – iamtheddrman

+1

Вот очень уменьшенный образец, который демонстрирует проблему на GCC (4.8-5.2): ** [Live On Coliru] (http://coliru.stacked-crooked.com/a/1fb8265aaac32e12) ** – sehe

ответ

7

Там, очевидно, ошибка таится там, возможно, в компиляторе, но более вероятно, в библиотеке, так как я был в состоянии воспроизвести это на GCC:

Live On 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 

Теперь проблема апелляционная RS, чтобы быть связано с выбора unsigned образца type`: изменение его подписал снимает симптом: Live On Coliru


Короче говоря: Я бы сообщить об этом в списке рассылки подталкивание или Trac: https://svn.boost.org/trac/boost/

+3

Это может быть уже подано в trac: https://svn.boost.org/trac/boost/ticket/11437 –

+0

Это касается всех флажков, если вы меня спрашиваете. Я не могу воспроизвести это на своей домашней рабочей станции (o.O), поэтому сам не смог найти исправление. Спасибо за то, что там работает. – sehe