簡體   English   中英

使用boost :: accumulators對值之間的增量進行采樣

[英]Sample the deltas between values using boost::accumulators

我有一個包含N個樣本的數據集(比如說,13,16,17,20),其中每個下一個樣本都會增加一些值(在這種情況下為3,1,3),我想找到第二個序列的各種統計數據。

樣本是以遞增方式收集的時間戳(即並非所有樣本都可以一次獲得),因此我想使用boost::accumulators::accumulator_set看起來像是適合賬單的東西。

我希望能夠做到這樣的事情:

accumulator_set< double, features< tag::mean > > acc;
...
acc(13);
acc(16);
acc(17);
acc(20);

... 但是采樣差異而不是實際值。

如何在不跟蹤最后一個值的情況下使用accumulator_set執行此操作?

增壓累加器沒有差異統計量。 你可以自己動手:

http://www.boost.org/doc/libs/1_37_0/doc/html/accumulators/user_s_guide.html#accumulators.user_s_guide.the_accumulators_framework.extending_the_accumulators_framework

我認為最好的解決方案就是跟蹤最后添加的值。

這個答案可能比你想要的更多,但至少它並不像我擔心它可能會變得那么離譜。 我們的想法是從創建一個迭代器類型開始,該類型充當從“普通”算法到Boost累加器算法樣式的適配器。 這個部分比我預期的要簡單一些:

#ifndef ACCUM_ITERATOR_H_INCLUDED
#define ACCUM_ITERATOR_H_INCLUDED

#include <iterator>

template <class Accumulator>
class accum_iterator :
    public std::iterator<std::output_iterator_tag,void,void,void,void> {
protected:
    Accumulator &accumulator;
public:
    typedef Accumulator accumulator_type;
    explicit accum_iterator(Accumulator& x) : accumulator(x) {}

    // The only part that really does anything: handle assignment by 
    // calling the accumulator with the value.
    accum_iterator<Accumulator>&
        operator=(typename Accumulator::sample_type value) {
            accumulator(value);
            return *this;
    }
    accum_iterator<Accumulator>& operator*() { return *this; }
    accum_iterator<Accumulator>& operator++() { return *this; }
    accum_iterator<Accumulator> operator++(int) { return *this; }
};

// A convenience function to create an accum_iterator for a given accumulator.    
template <class Accumulator>
accum_iterator<Accumulator> to_accum(Accumulator &accum) { 
    return accum_iterator<Accumulator>(accum);
}

#endif

然后是一個有點不幸的部分。 標准庫有一個adjacent_difference算法,它應該生成你想要的流(集合中相鄰項之間的差異)。 它有一個嚴重的問題:有人認為生成一個與輸入集合大小相同的結果集合會很有用(盡管顯然有一個輸入而不是結果)。 為此, adjacent_difference將結果中的第一項留下一些未指定的值,因此您必須忽略第一個值才能從中獲取任何有用的值。

為了彌補這一點,我重新實現了一個 std::adjacent_difference 這樣的算法,它有一個很小的區別:因為顯然結果比輸入少一個,它只產生比輸入少的結果,並且不給出結果中無意義的,未指定的值。 結合這兩者,我們得到:

#include "accum_iterator.h"
#include <iostream>
#include <vector>

#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/mean.hpp>
using namespace boost::accumulators;

// A re-implementation of std::adjacent_difference, but with sensible outputs.
template <class InIt, class OutIt>
void diffs(InIt in1, InIt in2, OutIt out) { 
    typename InIt::value_type prev = *in1;
    ++in1;
    while (in1 != in2) {
        typename InIt::value_type temp = *in1;
        *out++ = temp - prev;
        prev = temp;
        ++in1;
    }
}

int main() {
    // Create the accumulator.
    accumulator_set<double, features< tag::mean > > acc;  

    // Set up the test values.
    std::vector<double> values;
    values.push_back(13);
    values.push_back(16);
    values.push_back(17);
    values.push_back(20);

    // Use diffs to compute the differences, and feed the results to the 
    // accumulator via the accum_iterator:
    diffs(values.begin(), values.end(), to_accum(acc));

    // And print the result from the accumulator:    
    std::cout << "Mean:   " << mean(acc) << std::endl;
    return 0;
}

暫無
暫無

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

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