summaryrefslogtreecommitdiff
path: root/boost/accumulators/statistics/rolling_mean.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/accumulators/statistics/rolling_mean.hpp')
-rw-r--r--boost/accumulators/statistics/rolling_mean.hpp200
1 files changed, 149 insertions, 51 deletions
diff --git a/boost/accumulators/statistics/rolling_mean.hpp b/boost/accumulators/statistics/rolling_mean.hpp
index ddcbaa39b9..1439da1e2c 100644
--- a/boost/accumulators/statistics/rolling_mean.hpp
+++ b/boost/accumulators/statistics/rolling_mean.hpp
@@ -1,9 +1,10 @@
///////////////////////////////////////////////////////////////////////////////
// rolling_mean.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)
+// Copyright (C) 2008 Eric Niebler.
+// Copyright (C) 2012 Pieter Bastiaan Ober (Integricom).
+// 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_MEAN_HPP_EAN_26_12_2008
#define BOOST_ACCUMULATORS_STATISTICS_ROLLING_MEAN_HPP_EAN_26_12_2008
@@ -20,62 +21,159 @@
namespace boost { namespace accumulators
{
+ namespace impl
+ {
+ ///////////////////////////////////////////////////////////////////////////////
+ // lazy_rolling_mean_impl
+ // returns the mean over the rolling window and is calculated only
+ // when the result is requested
+ template<typename Sample>
+ struct lazy_rolling_mean_impl
+ : accumulator_base
+ {
+ // for boost::result_of
+ typedef typename numeric::functional::fdiv<Sample, std::size_t, void, void>::result_type result_type;
-namespace impl
-{
+ lazy_rolling_mean_impl(dont_care)
+ {
+ }
- ///////////////////////////////////////////////////////////////////////////////
- // rolling_mean_impl
- // returns the unshifted results from the shifted rolling window
- template<typename Sample>
- struct rolling_mean_impl
- : accumulator_base
- {
- typedef typename numeric::functional::average<Sample, std::size_t>::result_type result_type;
+ template<typename Args>
+ result_type result(Args const &args) const
+ {
+ return numeric::fdiv(rolling_sum(args), rolling_count(args));
+ }
+ };
- rolling_mean_impl(dont_care)
- {}
+ ///////////////////////////////////////////////////////////////////////////////
+ // immediate_rolling_mean_impl
+ // The non-lazy version computes the rolling mean recursively when a new
+ // sample is added
+ template<typename Sample>
+ struct immediate_rolling_mean_impl
+ : accumulator_base
+ {
+ // for boost::result_of
+ typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type result_type;
- template<typename Args>
- result_type result(Args const &args) const
- {
- return numeric::average(rolling_sum(args), rolling_count(args));
- }
- };
+ template<typename Args>
+ immediate_rolling_mean_impl(Args const &args)
+ : mean_(numeric::fdiv(args[sample | Sample()],numeric::one<std::size_t>::value))
+ {
+ }
-} // namespace impl
+ template<typename Args>
+ void operator()(Args const &args)
+ {
+ if(is_rolling_window_plus1_full(args))
+ {
+ mean_ += numeric::fdiv(args[sample]-rolling_window_plus1(args).front(),rolling_count(args));
+ }
+ else
+ {
+ result_type prev_mean = mean_;
+ mean_ += numeric::fdiv(args[sample]-prev_mean,rolling_count(args));
+ }
+ }
-///////////////////////////////////////////////////////////////////////////////
-// tag::rolling_mean
-//
-namespace tag
-{
- struct rolling_mean
- : depends_on< rolling_sum, rolling_count >
- {
- /// INTERNAL ONLY
- ///
- typedef accumulators::impl::rolling_mean_impl< mpl::_1 > impl;
-
- #ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
- /// tag::rolling_window::window_size named parameter
- static boost::parameter::keyword<tag::rolling_window_size> const window_size;
- #endif
- };
-} // namespace tag
+ template<typename Args>
+ result_type result(Args const &) const
+ {
+ return mean_;
+ }
-///////////////////////////////////////////////////////////////////////////////
-// extract::rolling_mean
-//
-namespace extract
-{
- extractor<tag::rolling_mean> const rolling_mean = {};
+ private:
- BOOST_ACCUMULATORS_IGNORE_GLOBAL(rolling_mean)
-}
+ result_type mean_;
+ };
+ } // namespace impl
-using extract::rolling_mean;
+ ///////////////////////////////////////////////////////////////////////////////
+ // tag::lazy_rolling_mean
+ // tag::immediate_rolling_mean
+ // tag::rolling_mean
+ //
+ namespace tag
+ {
+ struct lazy_rolling_mean
+ : depends_on< rolling_sum, rolling_count >
+ {
+ /// INTERNAL ONLY
+ ///
+ typedef accumulators::impl::lazy_rolling_mean_impl< mpl::_1 > impl;
-}} // namespace boost::accumulators
+#ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
+ /// tag::rolling_window::window_size named parameter
+ static boost::parameter::keyword<tag::rolling_window_size> const window_size;
+#endif
+ };
+ struct immediate_rolling_mean
+ : depends_on< rolling_window_plus1, rolling_count>
+ {
+ /// INTERNAL ONLY
+ ///
+ typedef accumulators::impl::immediate_rolling_mean_impl< mpl::_1> impl;
+
+#ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
+ /// tag::rolling_window::window_size named parameter
+ static boost::parameter::keyword<tag::rolling_window_size> const window_size;
#endif
+ };
+
+ // make immediate_rolling_mean the default implementation
+ struct rolling_mean : immediate_rolling_mean {};
+ } // namespace tag
+
+ ///////////////////////////////////////////////////////////////////////////////
+ // extract::lazy_rolling_mean
+ // extract::immediate_rolling_mean
+ // extract::rolling_mean
+ //
+ namespace extract
+ {
+ extractor<tag::lazy_rolling_mean> const lazy_rolling_mean = {};
+ extractor<tag::immediate_rolling_mean> const immediate_rolling_mean = {};
+ extractor<tag::rolling_mean> const rolling_mean = {};
+
+ BOOST_ACCUMULATORS_IGNORE_GLOBAL(lazy_rolling_mean)
+ BOOST_ACCUMULATORS_IGNORE_GLOBAL(immediate_rolling_mean)
+ BOOST_ACCUMULATORS_IGNORE_GLOBAL(rolling_mean)
+ }
+
+ using extract::lazy_rolling_mean;
+ using extract::immediate_rolling_mean;
+ using extract::rolling_mean;
+
+ // rolling_mean(lazy) -> lazy_rolling_mean
+ template<>
+ struct as_feature<tag::rolling_mean(lazy)>
+ {
+ typedef tag::lazy_rolling_mean type;
+ };
+
+ // rolling_mean(immediate) -> immediate_rolling_mean
+ template<>
+ struct as_feature<tag::rolling_mean(immediate)>
+ {
+ typedef tag::immediate_rolling_mean type;
+ };
+
+ // for the purposes of feature-based dependency resolution,
+ // immediate_rolling_mean provides the same feature as rolling_mean
+ template<>
+ struct feature_of<tag::immediate_rolling_mean>
+ : feature_of<tag::rolling_mean>
+ {
+ };
+
+ // for the purposes of feature-based dependency resolution,
+ // lazy_rolling_mean provides the same feature as rolling_mean
+ template<>
+ struct feature_of<tag::lazy_rolling_mean>
+ : feature_of<tag::rolling_mean>
+ {
+ };
+}} // namespace boost::accumulators
+
+#endif \ No newline at end of file