Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // rolling_mean.hpp Chris@101: // Copyright (C) 2008 Eric Niebler. Chris@101: // Copyright (C) 2012 Pieter Bastiaan Ober (Integricom). Chris@101: // Distributed under the Boost Software License, Version 1.0. Chris@101: // (See accompanying file LICENSE_1_0.txt or copy at Chris@101: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_ACCUMULATORS_STATISTICS_ROLLING_MEAN_HPP_EAN_26_12_2008 Chris@16: #define BOOST_ACCUMULATORS_STATISTICS_ROLLING_MEAN_HPP_EAN_26_12_2008 Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { namespace accumulators Chris@16: { Chris@101: namespace impl Chris@101: { Chris@101: /////////////////////////////////////////////////////////////////////////////// Chris@101: // lazy_rolling_mean_impl Chris@101: // returns the mean over the rolling window and is calculated only Chris@101: // when the result is requested Chris@101: template Chris@101: struct lazy_rolling_mean_impl Chris@101: : accumulator_base Chris@101: { Chris@101: // for boost::result_of Chris@101: typedef typename numeric::functional::fdiv::result_type result_type; Chris@16: Chris@101: lazy_rolling_mean_impl(dont_care) Chris@101: { Chris@101: } Chris@16: Chris@101: template Chris@101: result_type result(Args const &args) const Chris@101: { Chris@101: return numeric::fdiv(rolling_sum(args), rolling_count(args)); Chris@101: } Chris@101: }; Chris@16: Chris@101: /////////////////////////////////////////////////////////////////////////////// Chris@101: // immediate_rolling_mean_impl Chris@101: // The non-lazy version computes the rolling mean recursively when a new Chris@101: // sample is added Chris@101: template Chris@101: struct immediate_rolling_mean_impl Chris@101: : accumulator_base Chris@101: { Chris@101: // for boost::result_of Chris@101: typedef typename numeric::functional::fdiv::result_type result_type; Chris@16: Chris@101: template Chris@101: immediate_rolling_mean_impl(Args const &args) Chris@101: : mean_(numeric::fdiv(args[sample | Sample()],numeric::one::value)) Chris@101: { Chris@101: } Chris@16: Chris@101: template Chris@101: void operator()(Args const &args) Chris@101: { Chris@101: if(is_rolling_window_plus1_full(args)) Chris@101: { Chris@101: mean_ += numeric::fdiv(args[sample]-rolling_window_plus1(args).front(),rolling_count(args)); Chris@101: } Chris@101: else Chris@101: { Chris@101: result_type prev_mean = mean_; Chris@101: mean_ += numeric::fdiv(args[sample]-prev_mean,rolling_count(args)); Chris@101: } Chris@101: } Chris@16: Chris@101: template Chris@101: result_type result(Args const &) const Chris@101: { Chris@101: return mean_; Chris@101: } Chris@16: Chris@101: private: Chris@16: Chris@101: result_type mean_; Chris@101: }; Chris@101: } // namespace impl Chris@16: Chris@101: /////////////////////////////////////////////////////////////////////////////// Chris@101: // tag::lazy_rolling_mean Chris@101: // tag::immediate_rolling_mean Chris@101: // tag::rolling_mean Chris@101: // Chris@101: namespace tag Chris@101: { Chris@101: struct lazy_rolling_mean Chris@101: : depends_on< rolling_sum, rolling_count > Chris@101: { Chris@101: /// INTERNAL ONLY Chris@101: /// Chris@101: typedef accumulators::impl::lazy_rolling_mean_impl< mpl::_1 > impl; Chris@16: Chris@101: #ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED Chris@101: /// tag::rolling_window::window_size named parameter Chris@101: static boost::parameter::keyword const window_size; Chris@101: #endif Chris@101: }; Chris@16: Chris@101: struct immediate_rolling_mean Chris@101: : depends_on< rolling_window_plus1, rolling_count> Chris@101: { Chris@101: /// INTERNAL ONLY Chris@101: /// Chris@101: typedef accumulators::impl::immediate_rolling_mean_impl< mpl::_1> impl; Chris@101: Chris@101: #ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED Chris@101: /// tag::rolling_window::window_size named parameter Chris@101: static boost::parameter::keyword const window_size; Chris@101: #endif Chris@101: }; Chris@101: Chris@101: // make immediate_rolling_mean the default implementation Chris@101: struct rolling_mean : immediate_rolling_mean {}; Chris@101: } // namespace tag Chris@101: Chris@101: /////////////////////////////////////////////////////////////////////////////// Chris@101: // extract::lazy_rolling_mean Chris@101: // extract::immediate_rolling_mean Chris@101: // extract::rolling_mean Chris@101: // Chris@101: namespace extract Chris@101: { Chris@101: extractor const lazy_rolling_mean = {}; Chris@101: extractor const immediate_rolling_mean = {}; Chris@101: extractor const rolling_mean = {}; Chris@101: Chris@101: BOOST_ACCUMULATORS_IGNORE_GLOBAL(lazy_rolling_mean) Chris@101: BOOST_ACCUMULATORS_IGNORE_GLOBAL(immediate_rolling_mean) Chris@101: BOOST_ACCUMULATORS_IGNORE_GLOBAL(rolling_mean) Chris@101: } Chris@101: Chris@101: using extract::lazy_rolling_mean; Chris@101: using extract::immediate_rolling_mean; Chris@101: using extract::rolling_mean; Chris@101: Chris@101: // rolling_mean(lazy) -> lazy_rolling_mean Chris@101: template<> Chris@101: struct as_feature Chris@101: { Chris@101: typedef tag::lazy_rolling_mean type; Chris@101: }; Chris@101: Chris@101: // rolling_mean(immediate) -> immediate_rolling_mean Chris@101: template<> Chris@101: struct as_feature Chris@101: { Chris@101: typedef tag::immediate_rolling_mean type; Chris@101: }; Chris@101: Chris@101: // for the purposes of feature-based dependency resolution, Chris@101: // immediate_rolling_mean provides the same feature as rolling_mean Chris@101: template<> Chris@101: struct feature_of Chris@101: : feature_of Chris@101: { Chris@101: }; Chris@101: Chris@101: // for the purposes of feature-based dependency resolution, Chris@101: // lazy_rolling_mean provides the same feature as rolling_mean Chris@101: template<> Chris@101: struct feature_of Chris@101: : feature_of Chris@101: { Chris@101: }; Chris@16: }} // namespace boost::accumulators Chris@16: Chris@101: #endif