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 mean_implboost::accumulators::impl::mean_impl36 mean_impl(dont_care) {} 37 38 template<typename Args> resultboost::accumulators::impl::mean_impl39 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> serializeboost::accumulators::impl::mean_impl47 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> immediate_mean_implboost::accumulators::impl::immediate_mean_impl58 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> operator ()boost::accumulators::impl::immediate_mean_impl64 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 resultboost::accumulators::impl::immediate_mean_impl73 result_type result(dont_care) const 74 { 75 return this->mean; 76 } 77 78 template<class Archive> serializeboost::accumulators::impl::immediate_mean_impl79 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 mean = {}; 156 extractor<tag::mean_of_weights> const mean_of_weights = {}; 157 BOOST_ACCUMULATORS_DEFINE_EXTRACTOR(tag, mean_of_variates, (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