1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // mean.hpp |
3 | // |
4 | // Copyright 2005 Eric Niebler. Distributed under the Boost |
5 | // Software License, Version 1.0. (See accompanying file |
6 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
7 | |
8 | #ifndef BOOST_ACCUMULATORS_STATISTICS_MEAN_HPP_EAN_28_10_2005 |
9 | #define BOOST_ACCUMULATORS_STATISTICS_MEAN_HPP_EAN_28_10_2005 |
10 | |
11 | #include <boost/mpl/placeholders.hpp> |
12 | #include <boost/accumulators/framework/accumulator_base.hpp> |
13 | #include <boost/accumulators/framework/extractor.hpp> |
14 | #include <boost/accumulators/numeric/functional.hpp> |
15 | #include <boost/accumulators/framework/parameters/sample.hpp> |
16 | #include <boost/accumulators/framework/depends_on.hpp> |
17 | #include <boost/accumulators/statistics_fwd.hpp> |
18 | #include <boost/accumulators/statistics/count.hpp> |
19 | #include <boost/accumulators/statistics/sum.hpp> |
20 | |
21 | namespace boost { namespace accumulators |
22 | { |
23 | |
24 | namespace impl |
25 | { |
26 | /////////////////////////////////////////////////////////////////////////////// |
27 | // mean_impl |
28 | // lazy, by default |
29 | template<typename Sample, typename SumFeature> |
30 | struct mean_impl |
31 | : accumulator_base |
32 | { |
33 | // for boost::result_of |
34 | typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type result_type; |
35 | |
36 | mean_impl(dont_care) {} |
37 | |
38 | template<typename Args> |
39 | result_type result(Args const &args) const |
40 | { |
41 | extractor<SumFeature> sum; |
42 | return numeric::fdiv(sum(args), count(args)); |
43 | } |
44 | |
45 | // serialization is done by accumulators it depends on |
46 | template<class Archive> |
47 | void serialize(Archive & ar, const unsigned int file_version) {} |
48 | }; |
49 | |
50 | template<typename Sample, typename Tag> |
51 | struct immediate_mean_impl |
52 | : accumulator_base |
53 | { |
54 | // for boost::result_of |
55 | typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type result_type; |
56 | |
57 | template<typename Args> |
58 | immediate_mean_impl(Args const &args) |
59 | : mean(numeric::fdiv(args[sample | Sample()], numeric::one<std::size_t>::value)) |
60 | { |
61 | } |
62 | |
63 | template<typename Args> |
64 | void operator ()(Args const &args) |
65 | { |
66 | std::size_t cnt = count(args); |
67 | this->mean = numeric::fdiv( |
68 | (this->mean * (cnt - 1)) + args[parameter::keyword<Tag>::get()] |
69 | , cnt |
70 | ); |
71 | } |
72 | |
73 | result_type result(dont_care) const |
74 | { |
75 | return this->mean; |
76 | } |
77 | |
78 | template<class Archive> |
79 | void serialize(Archive & ar, const unsigned int file_version) |
80 | { |
81 | ar & mean; |
82 | } |
83 | |
84 | private: |
85 | result_type mean; |
86 | }; |
87 | |
88 | } // namespace impl |
89 | |
90 | /////////////////////////////////////////////////////////////////////////////// |
91 | // tag::mean |
92 | // tag::immediate_mean |
93 | // tag::mean_of_weights |
94 | // tag::immediate_mean_of_weights |
95 | // tag::mean_of_variates |
96 | // tag::immediate_mean_of_variates |
97 | // |
98 | namespace tag |
99 | { |
100 | struct mean |
101 | : depends_on<count, sum> |
102 | { |
103 | /// INTERNAL ONLY |
104 | /// |
105 | typedef accumulators::impl::mean_impl<mpl::_1, sum> impl; |
106 | }; |
107 | struct immediate_mean |
108 | : depends_on<count> |
109 | { |
110 | /// INTERNAL ONLY |
111 | /// |
112 | typedef accumulators::impl::immediate_mean_impl<mpl::_1, tag::sample> impl; |
113 | }; |
114 | struct mean_of_weights |
115 | : depends_on<count, sum_of_weights> |
116 | { |
117 | typedef mpl::true_ is_weight_accumulator; |
118 | /// INTERNAL ONLY |
119 | /// |
120 | typedef accumulators::impl::mean_impl<mpl::_2, sum_of_weights> impl; |
121 | }; |
122 | struct immediate_mean_of_weights |
123 | : depends_on<count> |
124 | { |
125 | typedef mpl::true_ is_weight_accumulator; |
126 | /// INTERNAL ONLY |
127 | /// |
128 | typedef accumulators::impl::immediate_mean_impl<mpl::_2, tag::weight> impl; |
129 | }; |
130 | template<typename VariateType, typename VariateTag> |
131 | struct mean_of_variates |
132 | : depends_on<count, sum_of_variates<VariateType, VariateTag> > |
133 | { |
134 | /// INTERNAL ONLY |
135 | /// |
136 | typedef mpl::always<accumulators::impl::mean_impl<VariateType, sum_of_variates<VariateType, VariateTag> > > impl; |
137 | }; |
138 | template<typename VariateType, typename VariateTag> |
139 | struct immediate_mean_of_variates |
140 | : depends_on<count> |
141 | { |
142 | /// INTERNAL ONLY |
143 | /// |
144 | typedef mpl::always<accumulators::impl::immediate_mean_impl<VariateType, VariateTag> > impl; |
145 | }; |
146 | } |
147 | |
148 | /////////////////////////////////////////////////////////////////////////////// |
149 | // extract::mean |
150 | // extract::mean_of_weights |
151 | // extract::mean_of_variates |
152 | // |
153 | namespace extract |
154 | { |
155 | extractor<tag::mean> const = {}; |
156 | extractor<tag::mean_of_weights> const = {}; |
157 | BOOST_ACCUMULATORS_DEFINE_EXTRACTOR(tag, , (typename)(typename)) |
158 | |
159 | BOOST_ACCUMULATORS_IGNORE_GLOBAL(mean) |
160 | BOOST_ACCUMULATORS_IGNORE_GLOBAL(mean_of_weights) |
161 | } |
162 | |
163 | using extract::mean; |
164 | using extract::mean_of_weights; |
165 | using extract::mean_of_variates; |
166 | |
167 | // mean(lazy) -> mean |
168 | template<> |
169 | struct as_feature<tag::mean(lazy)> |
170 | { |
171 | typedef tag::mean type; |
172 | }; |
173 | |
174 | // mean(immediate) -> immediate_mean |
175 | template<> |
176 | struct as_feature<tag::mean(immediate)> |
177 | { |
178 | typedef tag::immediate_mean type; |
179 | }; |
180 | |
181 | // mean_of_weights(lazy) -> mean_of_weights |
182 | template<> |
183 | struct as_feature<tag::mean_of_weights(lazy)> |
184 | { |
185 | typedef tag::mean_of_weights type; |
186 | }; |
187 | |
188 | // mean_of_weights(immediate) -> immediate_mean_of_weights |
189 | template<> |
190 | struct as_feature<tag::mean_of_weights(immediate)> |
191 | { |
192 | typedef tag::immediate_mean_of_weights type; |
193 | }; |
194 | |
195 | // mean_of_variates<VariateType, VariateTag>(lazy) -> mean_of_variates<VariateType, VariateTag> |
196 | template<typename VariateType, typename VariateTag> |
197 | struct as_feature<tag::mean_of_variates<VariateType, VariateTag>(lazy)> |
198 | { |
199 | typedef tag::mean_of_variates<VariateType, VariateTag> type; |
200 | }; |
201 | |
202 | // mean_of_variates<VariateType, VariateTag>(immediate) -> immediate_mean_of_variates<VariateType, VariateTag> |
203 | template<typename VariateType, typename VariateTag> |
204 | struct as_feature<tag::mean_of_variates<VariateType, VariateTag>(immediate)> |
205 | { |
206 | typedef tag::immediate_mean_of_variates<VariateType, VariateTag> type; |
207 | }; |
208 | |
209 | // for the purposes of feature-based dependency resolution, |
210 | // immediate_mean provides the same feature as mean |
211 | template<> |
212 | struct feature_of<tag::immediate_mean> |
213 | : feature_of<tag::mean> |
214 | { |
215 | }; |
216 | |
217 | // for the purposes of feature-based dependency resolution, |
218 | // immediate_mean provides the same feature as mean |
219 | template<> |
220 | struct feature_of<tag::immediate_mean_of_weights> |
221 | : feature_of<tag::mean_of_weights> |
222 | { |
223 | }; |
224 | |
225 | // for the purposes of feature-based dependency resolution, |
226 | // immediate_mean provides the same feature as mean |
227 | template<typename VariateType, typename VariateTag> |
228 | struct feature_of<tag::immediate_mean_of_variates<VariateType, VariateTag> > |
229 | : feature_of<tag::mean_of_variates<VariateType, VariateTag> > |
230 | { |
231 | }; |
232 | |
233 | // So that mean can be automatically substituted with |
234 | // weighted_mean when the weight parameter is non-void. |
235 | template<> |
236 | struct as_weighted_feature<tag::mean> |
237 | { |
238 | typedef tag::weighted_mean type; |
239 | }; |
240 | |
241 | template<> |
242 | struct feature_of<tag::weighted_mean> |
243 | : feature_of<tag::mean> |
244 | {}; |
245 | |
246 | // So that immediate_mean can be automatically substituted with |
247 | // immediate_weighted_mean when the weight parameter is non-void. |
248 | template<> |
249 | struct as_weighted_feature<tag::immediate_mean> |
250 | { |
251 | typedef tag::immediate_weighted_mean type; |
252 | }; |
253 | |
254 | template<> |
255 | struct feature_of<tag::immediate_weighted_mean> |
256 | : feature_of<tag::immediate_mean> |
257 | {}; |
258 | |
259 | // So that mean_of_weights<> can be automatically substituted with |
260 | // weighted_mean_of_variates<> when the weight parameter is non-void. |
261 | template<typename VariateType, typename VariateTag> |
262 | struct as_weighted_feature<tag::mean_of_variates<VariateType, VariateTag> > |
263 | { |
264 | typedef tag::weighted_mean_of_variates<VariateType, VariateTag> type; |
265 | }; |
266 | |
267 | template<typename VariateType, typename VariateTag> |
268 | struct feature_of<tag::weighted_mean_of_variates<VariateType, VariateTag> > |
269 | : feature_of<tag::mean_of_variates<VariateType, VariateTag> > |
270 | { |
271 | }; |
272 | |
273 | // So that immediate_mean_of_weights<> can be automatically substituted with |
274 | // immediate_weighted_mean_of_variates<> when the weight parameter is non-void. |
275 | template<typename VariateType, typename VariateTag> |
276 | struct as_weighted_feature<tag::immediate_mean_of_variates<VariateType, VariateTag> > |
277 | { |
278 | typedef tag::immediate_weighted_mean_of_variates<VariateType, VariateTag> type; |
279 | }; |
280 | |
281 | template<typename VariateType, typename VariateTag> |
282 | struct feature_of<tag::immediate_weighted_mean_of_variates<VariateType, VariateTag> > |
283 | : feature_of<tag::immediate_mean_of_variates<VariateType, VariateTag> > |
284 | { |
285 | }; |
286 | |
287 | //////////////////////////////////////////////////////////////////////////// |
288 | //// droppable_accumulator<mean_impl> |
289 | //// need to specialize droppable lazy mean to cache the result at the |
290 | //// point the accumulator is dropped. |
291 | ///// INTERNAL ONLY |
292 | ///// |
293 | //template<typename Sample, typename SumFeature> |
294 | //struct droppable_accumulator<impl::mean_impl<Sample, SumFeature> > |
295 | // : droppable_accumulator_base< |
296 | // with_cached_result<impl::mean_impl<Sample, SumFeature> > |
297 | // > |
298 | //{ |
299 | // template<typename Args> |
300 | // droppable_accumulator(Args const &args) |
301 | // : droppable_accumulator::base(args) |
302 | // { |
303 | // } |
304 | //}; |
305 | |
306 | }} // namespace boost::accumulators |
307 | |
308 | #endif |
309 | |