summaryrefslogtreecommitdiff
path: root/boost/accumulators/statistics/rolling_window.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/accumulators/statistics/rolling_window.hpp')
-rw-r--r--boost/accumulators/statistics/rolling_window.hpp169
1 files changed, 169 insertions, 0 deletions
diff --git a/boost/accumulators/statistics/rolling_window.hpp b/boost/accumulators/statistics/rolling_window.hpp
new file mode 100644
index 0000000000..d2f4b0dfe1
--- /dev/null
+++ b/boost/accumulators/statistics/rolling_window.hpp
@@ -0,0 +1,169 @@
+///////////////////////////////////////////////////////////////////////////////
+// rolling_window.hpp
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_ACCUMULATORS_STATISTICS_ROLLING_WINDOW_HPP_EAN_26_12_2008
+#define BOOST_ACCUMULATORS_STATISTICS_ROLLING_WINDOW_HPP_EAN_26_12_2008
+
+#include <cstddef>
+#include <boost/version.hpp>
+#include <boost/assert.hpp>
+#include <boost/circular_buffer.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/accumulators/framework/extractor.hpp>
+#include <boost/accumulators/framework/depends_on.hpp>
+#include <boost/accumulators/framework/accumulator_base.hpp>
+#include <boost/accumulators/framework/parameters/sample.hpp>
+#include <boost/accumulators/framework/parameters/accumulator.hpp>
+#include <boost/accumulators/numeric/functional.hpp>
+#include <boost/accumulators/statistics_fwd.hpp>
+
+namespace boost { namespace accumulators
+{
+
+///////////////////////////////////////////////////////////////////////////////
+// tag::rolling_window::size named parameter
+BOOST_PARAMETER_NESTED_KEYWORD(tag, rolling_window_size, window_size)
+
+namespace impl
+{
+ ///////////////////////////////////////////////////////////////////////////////
+ // rolling_window_plus1_impl
+ // stores the latest N+1 samples, where N is specified at construction time
+ // with the rolling_window_size named parameter
+ template<typename Sample>
+ struct rolling_window_plus1_impl
+ : accumulator_base
+ {
+ typedef typename circular_buffer<Sample>::const_iterator const_iterator;
+ typedef iterator_range<const_iterator> result_type;
+
+ template<typename Args>
+ rolling_window_plus1_impl(Args const & args)
+ : buffer_(args[rolling_window_size] + 1)
+ {}
+
+ #if BOOST_VERSION < 103600
+ // Before Boost 1.36, copying a circular buffer didn't copy
+ // it's capacity, and we need that behavior.
+ rolling_window_plus1_impl(rolling_window_plus1_impl const &that)
+ : buffer_(that.buffer_)
+ {
+ this->buffer_.set_capacity(that.buffer_.capacity());
+ }
+
+ rolling_window_plus1_impl &operator =(rolling_window_plus1_impl const &that)
+ {
+ this->buffer_ = that.buffer_;
+ this->buffer_.set_capacity(that.buffer_.capacity());
+ }
+ #endif
+
+ template<typename Args>
+ void operator ()(Args const &args)
+ {
+ this->buffer_.push_back(args[sample]);
+ }
+
+ bool full() const
+ {
+ return this->buffer_.full();
+ }
+
+ // The result of a shifted rolling window is the range including
+ // everything except the most recently added element.
+ result_type result(dont_care) const
+ {
+ return result_type(this->buffer_.begin(), this->buffer_.end());
+ }
+
+ private:
+ circular_buffer<Sample> buffer_;
+ };
+
+ template<typename Args>
+ bool is_rolling_window_plus1_full(Args const &args)
+ {
+ return find_accumulator<tag::rolling_window_plus1>(args[accumulator]).full();
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////
+ // rolling_window_impl
+ // stores the latest N samples, where N is specified at construction type
+ // with the rolling_window_size named parameter
+ template<typename Sample>
+ struct rolling_window_impl
+ : accumulator_base
+ {
+ typedef typename circular_buffer<Sample>::const_iterator const_iterator;
+ typedef iterator_range<const_iterator> result_type;
+
+ rolling_window_impl(dont_care)
+ {}
+
+ template<typename Args>
+ result_type result(Args const &args) const
+ {
+ return rolling_window_plus1(args).advance_begin(is_rolling_window_plus1_full(args));
+ }
+ };
+
+} // namespace impl
+
+///////////////////////////////////////////////////////////////////////////////
+// tag::rolling_window_plus1
+// tag::rolling_window
+//
+namespace tag
+{
+ struct rolling_window_plus1
+ : depends_on<>
+ , tag::rolling_window_size
+ {
+ /// INTERNAL ONLY
+ ///
+ typedef accumulators::impl::rolling_window_plus1_impl< mpl::_1 > impl;
+
+ #ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
+ /// tag::rolling_window::size named parameter
+ static boost::parameter::keyword<tag::rolling_window_size> const window_size;
+ #endif
+ };
+
+ struct rolling_window
+ : depends_on< rolling_window_plus1 >
+ {
+ /// INTERNAL ONLY
+ ///
+ typedef accumulators::impl::rolling_window_impl< mpl::_1 > impl;
+
+ #ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
+ /// tag::rolling_window::size named parameter
+ static boost::parameter::keyword<tag::rolling_window_size> const window_size;
+ #endif
+ };
+
+} // namespace tag
+
+///////////////////////////////////////////////////////////////////////////////
+// extract::rolling_window_plus1
+// extract::rolling_window
+//
+namespace extract
+{
+ extractor<tag::rolling_window_plus1> const rolling_window_plus1 = {};
+ extractor<tag::rolling_window> const rolling_window = {};
+
+ BOOST_ACCUMULATORS_IGNORE_GLOBAL(rolling_window_plus1)
+ BOOST_ACCUMULATORS_IGNORE_GLOBAL(rolling_window)
+}
+
+using extract::rolling_window_plus1;
+using extract::rolling_window;
+
+}} // namespace boost::accumulators
+
+#endif