2010-03-30 2 views
5

다음 샘플마다 몇 가지 값 (이 경우 3, 1, 3)이 증가하는 N 개의 샘플 (예 : 13, 16, 17, 20)) 그리고 두 번째 시퀀스의 다양한 통계를 찾고 싶습니다.boost :: accumulators를 사용하여 값 사이의 델타 샘플링

샘플은 점진적으로 수집되는 타임 스탬프입니다. 즉, 모든 샘플을 한 번에 사용할 수있는 것은 아니므로 boost::accumulators::accumulator_set을 청구서에 맞는 모양으로 사용하고 싶습니다.

나는 이런 식으로 뭔가를 할 수 있도록하려면 :

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

... 하지만 대신 실제 값의 차이를 샘플링.

수동으로 마지막 값을 추적하지 않고 accumulator_set으로 어떻게 할 수 있습니까?

+0

그런가요? 차이의 평균은 처음 샘플과 마지막 샘플을 (샘플 수 -1)로 나눈 값의 차이입니다 .-p –

+0

@Steve Jessop, 표준 편차도 계산하고 싶습니다. 따라서 accumulators 프레임 워크를 사용하십시오. –

답변

1

이 답변은 내가 원했던 것보다 다소 복잡 할 수 있지만, 적어도 그것이 드러날 까봐 두렵기 만 한 것은 아닙니다. 이 아이디어는 "정상적인"알고리즘에서부터 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; 
} 
+0

내 질문에 더 많은 정보를 제공해야한다고 생각합니다. 내 실제 문제는 대기 시간에 민감한 시스템에서 타임 스탬프 샘플을 지속적으로 수집하고 지터를 측정하려는 것이므로 통계를 점진적으로 업데이트해야합니다. 따라서 샘플 컬렉션을 갖는 것은이 경우 바람직하지 않습니다. –

+0

@Checkers :'diffs'는 단순히'input_iterator'로부터 입력을 받아서'output_iterator'에 결과를 씁니다.데모/테스팅의 경우,'input_iterator'는 콜렉션에 연결되지만, 디스크 나 네트워크 연결에서 파일의 데이터를 쉽게 읽을 수 있습니다. –

관련 문제