diff options
Diffstat (limited to 'boost/accumulators/statistics/rolling_mean.hpp')
-rw-r--r-- | boost/accumulators/statistics/rolling_mean.hpp | 200 |
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 |