1 ///////////////////////////////////////////////////////////////////////////////
2 // rolling_moment.hpp
3 // Copyright 2005 Eric Niebler.
4 // Copyright (C) 2014 Pieter Bastiaan Ober (Integricom).
5 // Distributed under the Boost Software License, Version 1.0.
6 // (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 
9 #ifndef BOOST_ACCUMULATORS_STATISTICS_ROLLING_MOMENT_HPP_EAN_27_11_2005
10 #define BOOST_ACCUMULATORS_STATISTICS_ROLLING_MOMENT_HPP_EAN_27_11_2005
11 
12 #include <boost/config/no_tr1/cmath.hpp>
13 #include <boost/mpl/int.hpp>
14 #include <boost/mpl/assert.hpp>
15 #include <boost/mpl/placeholders.hpp>
16 #include <boost/accumulators/framework/accumulator_base.hpp>
17 #include <boost/accumulators/framework/extractor.hpp>
18 #include <boost/accumulators/numeric/functional.hpp>
19 #include <boost/accumulators/framework/parameters/sample.hpp>
20 #include <boost/accumulators/framework/depends_on.hpp>
21 #include <boost/accumulators/statistics_fwd.hpp>
22 #include <boost/accumulators/statistics/moment.hpp>
23 #include <boost/accumulators/statistics/rolling_count.hpp>
24 
25 namespace boost { namespace accumulators
26 {
27 namespace impl
28 {
29     ///////////////////////////////////////////////////////////////////////////////
30     // rolling_moment_impl
31     template<typename N, typename Sample>
32     struct rolling_moment_impl
33       : accumulator_base
34     {
35         BOOST_MPL_ASSERT_RELATION(N::value, >, 0);
36         // for boost::result_of
37         typedef typename numeric::functional::fdiv<Sample, std::size_t,void,void>::result_type result_type;
38 
39         template<typename Args>
rolling_moment_implboost::accumulators::impl::rolling_moment_impl40         rolling_moment_impl(Args const &args)
41           : sum_(args[sample | Sample()])
42         {
43         }
44 
45         template<typename Args>
operator ()boost::accumulators::impl::rolling_moment_impl46         void operator ()(Args const &args)
47         {
48             if(is_rolling_window_plus1_full(args))
49             {
50                 this->sum_ -= numeric::pow(rolling_window_plus1(args).front(), N());
51             }
52             this->sum_ += numeric::pow(args[sample], N());
53         }
54 
55         template<typename Args>
resultboost::accumulators::impl::rolling_moment_impl56         result_type result(Args const &args) const
57         {
58             return numeric::fdiv(this->sum_, rolling_count(args));
59         }
60 
61         // make this accumulator serializeable
62         template<class Archive>
serializeboost::accumulators::impl::rolling_moment_impl63         void serialize(Archive & ar, const unsigned int file_version)
64         {
65             ar & sum_;
66         }
67 
68     private:
69         result_type sum_;
70     };
71 } // namespace impl
72 
73 ///////////////////////////////////////////////////////////////////////////////
74 // tag::rolling_moment
75 //
76 namespace tag
77 {
78     template<int N>
79     struct rolling_moment
80       : depends_on< rolling_window_plus1, rolling_count>
81     {
82         /// INTERNAL ONLY
83         ///
84         typedef accumulators::impl::rolling_moment_impl<mpl::int_<N>, mpl::_1> impl;
85 
86         #ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
87         /// tag::rolling_window::window_size named parameter
88         static boost::parameter::keyword<tag::rolling_window_size> const window_size;
89         #endif
90     };
91 }
92 
93 ///////////////////////////////////////////////////////////////////////////////
94 // extract::rolling_moment
95 //
96 namespace extract
97 {
98     BOOST_ACCUMULATORS_DEFINE_EXTRACTOR(tag, rolling_moment, (int))
99 }
100 
101 using extract::rolling_moment;
102 
103 // There is no weighted_rolling_moment (yet)...
104 //
105 //// So that rolling_moment<N> can be automatically substituted with
106 //// weighted_rolling_moment<N> when the weight parameter is non-void
107 //template<int N>
108 //struct as_weighted_feature<tag::rolling_moment<N> >
109 //{
110 //    typedef tag::weighted_rolling_moment<N> type;
111 //};
112 //
113 //template<int N>
114 //struct feature_of<tag::weighted_rolling_moment<N> >
115 //  : feature_of<tag::rolling_moment<N> >
116 //{
117 //};
118 }} // namespace boost::accumulators
119 
120 #endif
121