weighted_mean.hpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // weighted_mean.hpp
  3. //
  4. // Copyright 2006 Eric Niebler, Olivier Gygi. 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. #ifndef BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_MEAN_HPP_EAN_03_11_2005
  8. #define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_MEAN_HPP_EAN_03_11_2005
  9. #include <boost/mpl/assert.hpp>
  10. #include <boost/mpl/eval_if.hpp>
  11. #include <boost/mpl/placeholders.hpp>
  12. #include <boost/type_traits/is_same.hpp>
  13. #include <boost/accumulators/framework/accumulator_base.hpp>
  14. #include <boost/accumulators/framework/extractor.hpp>
  15. #include <boost/accumulators/numeric/functional.hpp>
  16. #include <boost/accumulators/framework/parameters/weights.hpp>
  17. #include <boost/accumulators/framework/depends_on.hpp>
  18. #include <boost/accumulators/statistics_fwd.hpp>
  19. #include <boost/accumulators/statistics/sum.hpp>
  20. #include <boost/accumulators/statistics/mean.hpp>
  21. #include <boost/accumulators/statistics/weighted_sum.hpp>
  22. namespace boost { namespace accumulators
  23. {
  24. namespace impl
  25. {
  26. ///////////////////////////////////////////////////////////////////////////////
  27. // weighted_mean_impl
  28. // lazy, by default
  29. template<typename Sample, typename Weight, typename Tag>
  30. struct weighted_mean_impl
  31. : accumulator_base
  32. {
  33. typedef typename numeric::functional::multiplies<Sample, Weight>::result_type weighted_sample;
  34. // for boost::result_of
  35. typedef typename numeric::functional::fdiv<weighted_sample, Weight>::result_type result_type;
  36. weighted_mean_impl(dont_care) {}
  37. template<typename Args>
  38. result_type result(Args const &args) const
  39. {
  40. typedef
  41. typename mpl::if_<
  42. is_same<Tag, tag::sample>
  43. , tag::weighted_sum
  44. , tag::weighted_sum_of_variates<Sample, Tag>
  45. >::type
  46. weighted_sum_tag;
  47. extractor<weighted_sum_tag> const some_weighted_sum = {};
  48. return numeric::fdiv(some_weighted_sum(args), sum_of_weights(args));
  49. }
  50. };
  51. ///////////////////////////////////////////////////////////////////////////////
  52. // immediate_weighted_mean_impl
  53. // immediate
  54. template<typename Sample, typename Weight, typename Tag>
  55. struct immediate_weighted_mean_impl
  56. : accumulator_base
  57. {
  58. typedef typename numeric::functional::multiplies<Sample, Weight>::result_type weighted_sample;
  59. // for boost::result_of
  60. typedef typename numeric::functional::fdiv<weighted_sample, Weight>::result_type result_type;
  61. template<typename Args>
  62. immediate_weighted_mean_impl(Args const &args)
  63. : mean(
  64. numeric::fdiv(
  65. args[parameter::keyword<Tag>::get() | Sample()]
  66. * numeric::one<Weight>::value
  67. , numeric::one<Weight>::value
  68. )
  69. )
  70. {
  71. }
  72. template<typename Args>
  73. void operator ()(Args const &args)
  74. {
  75. // Matthias:
  76. // need to pass the argument pack since the weight might be an external
  77. // accumulator set passed as a named parameter
  78. Weight w_sum = sum_of_weights(args);
  79. Weight w = args[weight];
  80. weighted_sample const &s = args[parameter::keyword<Tag>::get()] * w;
  81. this->mean = numeric::fdiv(this->mean * (w_sum - w) + s, w_sum);
  82. }
  83. result_type result(dont_care) const
  84. {
  85. return this->mean;
  86. }
  87. // make this accumulator serializeable
  88. template<class Archive>
  89. void serialize(Archive & ar, const unsigned int file_version)
  90. {
  91. ar & mean;
  92. }
  93. private:
  94. result_type mean;
  95. };
  96. } // namespace impl
  97. ///////////////////////////////////////////////////////////////////////////////
  98. // tag::weighted_mean
  99. // tag::immediate_weighted_mean
  100. //
  101. namespace tag
  102. {
  103. struct weighted_mean
  104. : depends_on<sum_of_weights, weighted_sum>
  105. {
  106. /// INTERNAL ONLY
  107. ///
  108. typedef accumulators::impl::weighted_mean_impl<mpl::_1, mpl::_2, tag::sample> impl;
  109. };
  110. struct immediate_weighted_mean
  111. : depends_on<sum_of_weights>
  112. {
  113. /// INTERNAL ONLY
  114. ///
  115. typedef accumulators::impl::immediate_weighted_mean_impl<mpl::_1, mpl::_2, tag::sample> impl;
  116. };
  117. template<typename VariateType, typename VariateTag>
  118. struct weighted_mean_of_variates
  119. : depends_on<sum_of_weights, weighted_sum_of_variates<VariateType, VariateTag> >
  120. {
  121. /// INTERNAL ONLY
  122. ///
  123. typedef accumulators::impl::weighted_mean_impl<VariateType, mpl::_2, VariateTag> impl;
  124. };
  125. template<typename VariateType, typename VariateTag>
  126. struct immediate_weighted_mean_of_variates
  127. : depends_on<sum_of_weights>
  128. {
  129. /// INTERNAL ONLY
  130. ///
  131. typedef accumulators::impl::immediate_weighted_mean_impl<VariateType, mpl::_2, VariateTag> impl;
  132. };
  133. }
  134. ///////////////////////////////////////////////////////////////////////////////
  135. // extract::weighted_mean
  136. // extract::weighted_mean_of_variates
  137. //
  138. namespace extract
  139. {
  140. extractor<tag::mean> const weighted_mean = {};
  141. BOOST_ACCUMULATORS_DEFINE_EXTRACTOR(tag, weighted_mean_of_variates, (typename)(typename))
  142. BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_mean)
  143. }
  144. using extract::weighted_mean;
  145. using extract::weighted_mean_of_variates;
  146. // weighted_mean(lazy) -> weighted_mean
  147. template<>
  148. struct as_feature<tag::weighted_mean(lazy)>
  149. {
  150. typedef tag::weighted_mean type;
  151. };
  152. // weighted_mean(immediate) -> immediate_weighted_mean
  153. template<>
  154. struct as_feature<tag::weighted_mean(immediate)>
  155. {
  156. typedef tag::immediate_weighted_mean type;
  157. };
  158. // weighted_mean_of_variates<VariateType, VariateTag>(lazy) -> weighted_mean_of_variates<VariateType, VariateTag>
  159. template<typename VariateType, typename VariateTag>
  160. struct as_feature<tag::weighted_mean_of_variates<VariateType, VariateTag>(lazy)>
  161. {
  162. typedef tag::weighted_mean_of_variates<VariateType, VariateTag> type;
  163. };
  164. // weighted_mean_of_variates<VariateType, VariateTag>(immediate) -> immediate_weighted_mean_of_variates<VariateType, VariateTag>
  165. template<typename VariateType, typename VariateTag>
  166. struct as_feature<tag::weighted_mean_of_variates<VariateType, VariateTag>(immediate)>
  167. {
  168. typedef tag::immediate_weighted_mean_of_variates<VariateType, VariateTag> type;
  169. };
  170. }} // namespace boost::accumulators
  171. #endif