Chris@16
|
1 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 // rolling_mean.hpp
|
Chris@101
|
3 // Copyright (C) 2008 Eric Niebler.
|
Chris@101
|
4 // Copyright (C) 2012 Pieter Bastiaan Ober (Integricom).
|
Chris@101
|
5 // Distributed under the Boost Software License, Version 1.0.
|
Chris@101
|
6 // (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@101
|
7 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8
|
Chris@16
|
9 #ifndef BOOST_ACCUMULATORS_STATISTICS_ROLLING_MEAN_HPP_EAN_26_12_2008
|
Chris@16
|
10 #define BOOST_ACCUMULATORS_STATISTICS_ROLLING_MEAN_HPP_EAN_26_12_2008
|
Chris@16
|
11
|
Chris@16
|
12 #include <boost/mpl/placeholders.hpp>
|
Chris@16
|
13 #include <boost/accumulators/framework/accumulator_base.hpp>
|
Chris@16
|
14 #include <boost/accumulators/framework/extractor.hpp>
|
Chris@16
|
15 #include <boost/accumulators/numeric/functional.hpp>
|
Chris@16
|
16 #include <boost/accumulators/framework/parameters/sample.hpp>
|
Chris@16
|
17 #include <boost/accumulators/framework/depends_on.hpp>
|
Chris@16
|
18 #include <boost/accumulators/statistics_fwd.hpp>
|
Chris@16
|
19 #include <boost/accumulators/statistics/rolling_sum.hpp>
|
Chris@16
|
20 #include <boost/accumulators/statistics/rolling_count.hpp>
|
Chris@16
|
21
|
Chris@16
|
22 namespace boost { namespace accumulators
|
Chris@16
|
23 {
|
Chris@101
|
24 namespace impl
|
Chris@101
|
25 {
|
Chris@101
|
26 ///////////////////////////////////////////////////////////////////////////////
|
Chris@101
|
27 // lazy_rolling_mean_impl
|
Chris@101
|
28 // returns the mean over the rolling window and is calculated only
|
Chris@101
|
29 // when the result is requested
|
Chris@101
|
30 template<typename Sample>
|
Chris@101
|
31 struct lazy_rolling_mean_impl
|
Chris@101
|
32 : accumulator_base
|
Chris@101
|
33 {
|
Chris@101
|
34 // for boost::result_of
|
Chris@101
|
35 typedef typename numeric::functional::fdiv<Sample, std::size_t, void, void>::result_type result_type;
|
Chris@16
|
36
|
Chris@101
|
37 lazy_rolling_mean_impl(dont_care)
|
Chris@101
|
38 {
|
Chris@101
|
39 }
|
Chris@16
|
40
|
Chris@101
|
41 template<typename Args>
|
Chris@101
|
42 result_type result(Args const &args) const
|
Chris@101
|
43 {
|
Chris@101
|
44 return numeric::fdiv(rolling_sum(args), rolling_count(args));
|
Chris@101
|
45 }
|
Chris@101
|
46 };
|
Chris@16
|
47
|
Chris@101
|
48 ///////////////////////////////////////////////////////////////////////////////
|
Chris@101
|
49 // immediate_rolling_mean_impl
|
Chris@101
|
50 // The non-lazy version computes the rolling mean recursively when a new
|
Chris@101
|
51 // sample is added
|
Chris@101
|
52 template<typename Sample>
|
Chris@101
|
53 struct immediate_rolling_mean_impl
|
Chris@101
|
54 : accumulator_base
|
Chris@101
|
55 {
|
Chris@101
|
56 // for boost::result_of
|
Chris@101
|
57 typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type result_type;
|
Chris@16
|
58
|
Chris@101
|
59 template<typename Args>
|
Chris@101
|
60 immediate_rolling_mean_impl(Args const &args)
|
Chris@101
|
61 : mean_(numeric::fdiv(args[sample | Sample()],numeric::one<std::size_t>::value))
|
Chris@101
|
62 {
|
Chris@101
|
63 }
|
Chris@16
|
64
|
Chris@101
|
65 template<typename Args>
|
Chris@101
|
66 void operator()(Args const &args)
|
Chris@101
|
67 {
|
Chris@101
|
68 if(is_rolling_window_plus1_full(args))
|
Chris@101
|
69 {
|
Chris@101
|
70 mean_ += numeric::fdiv(args[sample]-rolling_window_plus1(args).front(),rolling_count(args));
|
Chris@101
|
71 }
|
Chris@101
|
72 else
|
Chris@101
|
73 {
|
Chris@101
|
74 result_type prev_mean = mean_;
|
Chris@101
|
75 mean_ += numeric::fdiv(args[sample]-prev_mean,rolling_count(args));
|
Chris@101
|
76 }
|
Chris@101
|
77 }
|
Chris@16
|
78
|
Chris@101
|
79 template<typename Args>
|
Chris@101
|
80 result_type result(Args const &) const
|
Chris@101
|
81 {
|
Chris@101
|
82 return mean_;
|
Chris@101
|
83 }
|
Chris@16
|
84
|
Chris@101
|
85 private:
|
Chris@16
|
86
|
Chris@101
|
87 result_type mean_;
|
Chris@101
|
88 };
|
Chris@101
|
89 } // namespace impl
|
Chris@16
|
90
|
Chris@101
|
91 ///////////////////////////////////////////////////////////////////////////////
|
Chris@101
|
92 // tag::lazy_rolling_mean
|
Chris@101
|
93 // tag::immediate_rolling_mean
|
Chris@101
|
94 // tag::rolling_mean
|
Chris@101
|
95 //
|
Chris@101
|
96 namespace tag
|
Chris@101
|
97 {
|
Chris@101
|
98 struct lazy_rolling_mean
|
Chris@101
|
99 : depends_on< rolling_sum, rolling_count >
|
Chris@101
|
100 {
|
Chris@101
|
101 /// INTERNAL ONLY
|
Chris@101
|
102 ///
|
Chris@101
|
103 typedef accumulators::impl::lazy_rolling_mean_impl< mpl::_1 > impl;
|
Chris@16
|
104
|
Chris@101
|
105 #ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
|
Chris@101
|
106 /// tag::rolling_window::window_size named parameter
|
Chris@101
|
107 static boost::parameter::keyword<tag::rolling_window_size> const window_size;
|
Chris@101
|
108 #endif
|
Chris@101
|
109 };
|
Chris@16
|
110
|
Chris@101
|
111 struct immediate_rolling_mean
|
Chris@101
|
112 : depends_on< rolling_window_plus1, rolling_count>
|
Chris@101
|
113 {
|
Chris@101
|
114 /// INTERNAL ONLY
|
Chris@101
|
115 ///
|
Chris@101
|
116 typedef accumulators::impl::immediate_rolling_mean_impl< mpl::_1> impl;
|
Chris@101
|
117
|
Chris@101
|
118 #ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
|
Chris@101
|
119 /// tag::rolling_window::window_size named parameter
|
Chris@101
|
120 static boost::parameter::keyword<tag::rolling_window_size> const window_size;
|
Chris@101
|
121 #endif
|
Chris@101
|
122 };
|
Chris@101
|
123
|
Chris@101
|
124 // make immediate_rolling_mean the default implementation
|
Chris@101
|
125 struct rolling_mean : immediate_rolling_mean {};
|
Chris@101
|
126 } // namespace tag
|
Chris@101
|
127
|
Chris@101
|
128 ///////////////////////////////////////////////////////////////////////////////
|
Chris@101
|
129 // extract::lazy_rolling_mean
|
Chris@101
|
130 // extract::immediate_rolling_mean
|
Chris@101
|
131 // extract::rolling_mean
|
Chris@101
|
132 //
|
Chris@101
|
133 namespace extract
|
Chris@101
|
134 {
|
Chris@101
|
135 extractor<tag::lazy_rolling_mean> const lazy_rolling_mean = {};
|
Chris@101
|
136 extractor<tag::immediate_rolling_mean> const immediate_rolling_mean = {};
|
Chris@101
|
137 extractor<tag::rolling_mean> const rolling_mean = {};
|
Chris@101
|
138
|
Chris@101
|
139 BOOST_ACCUMULATORS_IGNORE_GLOBAL(lazy_rolling_mean)
|
Chris@101
|
140 BOOST_ACCUMULATORS_IGNORE_GLOBAL(immediate_rolling_mean)
|
Chris@101
|
141 BOOST_ACCUMULATORS_IGNORE_GLOBAL(rolling_mean)
|
Chris@101
|
142 }
|
Chris@101
|
143
|
Chris@101
|
144 using extract::lazy_rolling_mean;
|
Chris@101
|
145 using extract::immediate_rolling_mean;
|
Chris@101
|
146 using extract::rolling_mean;
|
Chris@101
|
147
|
Chris@101
|
148 // rolling_mean(lazy) -> lazy_rolling_mean
|
Chris@101
|
149 template<>
|
Chris@101
|
150 struct as_feature<tag::rolling_mean(lazy)>
|
Chris@101
|
151 {
|
Chris@101
|
152 typedef tag::lazy_rolling_mean type;
|
Chris@101
|
153 };
|
Chris@101
|
154
|
Chris@101
|
155 // rolling_mean(immediate) -> immediate_rolling_mean
|
Chris@101
|
156 template<>
|
Chris@101
|
157 struct as_feature<tag::rolling_mean(immediate)>
|
Chris@101
|
158 {
|
Chris@101
|
159 typedef tag::immediate_rolling_mean type;
|
Chris@101
|
160 };
|
Chris@101
|
161
|
Chris@101
|
162 // for the purposes of feature-based dependency resolution,
|
Chris@101
|
163 // immediate_rolling_mean provides the same feature as rolling_mean
|
Chris@101
|
164 template<>
|
Chris@101
|
165 struct feature_of<tag::immediate_rolling_mean>
|
Chris@101
|
166 : feature_of<tag::rolling_mean>
|
Chris@101
|
167 {
|
Chris@101
|
168 };
|
Chris@101
|
169
|
Chris@101
|
170 // for the purposes of feature-based dependency resolution,
|
Chris@101
|
171 // lazy_rolling_mean provides the same feature as rolling_mean
|
Chris@101
|
172 template<>
|
Chris@101
|
173 struct feature_of<tag::lazy_rolling_mean>
|
Chris@101
|
174 : feature_of<tag::rolling_mean>
|
Chris@101
|
175 {
|
Chris@101
|
176 };
|
Chris@16
|
177 }} // namespace boost::accumulators
|
Chris@16
|
178
|
Chris@101
|
179 #endif |