Câu trả lời này có thể liên quan nhiều hơn bạn muốn, nhưng ít nhất nó không phải là thái quá vì tôi sợ nó có thể xuất hiện. Ý tưởng sẽ là bắt đầu bằng cách tạo một loại trình lặp hoạt động như một bộ chuyển đổi từ các thuật toán "bình thường" sang kiểu trình tăng cường các thuật toán Boost. Đây là phần được bật ra đơn giản hơn một chút so với tôi thực sự mong đợi:
#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
Sau đó là một phần không may mắn. Thư viện chuẩn có thuật toán adjacent_difference
được cho là tạo luồng bạn muốn (sự khác biệt giữa các mục liền kề trong bộ sưu tập). Tuy nhiên, nó có một vấn đề nghiêm trọng : ai đó nghĩ rằng nó sẽ hữu ích cho nó để tạo ra một bộ sưu tập kết quả có cùng kích thước với bộ sưu tập đầu vào (mặc dù có một đầu vào rõ ràng hơn kết quả). Để làm điều đó, adjacent_difference
để lại mục đầu tiên trong kết quả với một số giá trị không xác định, vì vậy bạn phải bỏ qua giá trị đầu tiên để nhận bất kỳ thứ gì hữu ích từ nó.
Để bù đắp cho điều đó, tôi lại thực hiện một thuật toán nhưstd::adjacent_difference
với một sự khác biệt oh-so-nhỏ: vì không rõ ràng là một kết quả ít hơn đầu vào, nó chỉ sản xuất kết quả một ít hơn đầu vào, và không đưa ra giá trị vô nghĩa, không xác định trong kết quả. Kết hợp cả hai, chúng tôi nhận được:
#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;
}
Nguồn
2010-03-31 00:48:27
Điều gì đó tương tự hoặc chính xác? Trung bình của sự khác biệt chỉ là sự khác biệt giữa mẫu đầu tiên và cuối cùng, chia cho (số lượng mẫu -1) ;-p –
@Steve Jessop, tôi cũng muốn tính toán độ lệch chuẩn. Do đó sử dụng khung tích lũy. –