File indexing completed on 2025-01-18 09:28:21
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_MEAN_HPP_EAN_03_11_2005
0009 #define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_MEAN_HPP_EAN_03_11_2005
0010
0011 #include <boost/mpl/assert.hpp>
0012 #include <boost/mpl/eval_if.hpp>
0013 #include <boost/mpl/placeholders.hpp>
0014 #include <boost/type_traits/is_same.hpp>
0015 #include <boost/accumulators/framework/accumulator_base.hpp>
0016 #include <boost/accumulators/framework/extractor.hpp>
0017 #include <boost/accumulators/numeric/functional.hpp>
0018 #include <boost/accumulators/framework/parameters/weights.hpp>
0019 #include <boost/accumulators/framework/depends_on.hpp>
0020 #include <boost/accumulators/statistics_fwd.hpp>
0021 #include <boost/accumulators/statistics/sum.hpp>
0022 #include <boost/accumulators/statistics/mean.hpp>
0023 #include <boost/accumulators/statistics/weighted_sum.hpp>
0024
0025 namespace boost { namespace accumulators
0026 {
0027
0028 namespace impl
0029 {
0030
0031
0032
0033 template<typename Sample, typename Weight, typename Tag>
0034 struct weighted_mean_impl
0035 : accumulator_base
0036 {
0037 typedef typename numeric::functional::multiplies<Sample, Weight>::result_type weighted_sample;
0038
0039 typedef typename numeric::functional::fdiv<weighted_sample, Weight>::result_type result_type;
0040
0041 weighted_mean_impl(dont_care) {}
0042
0043 template<typename Args>
0044 result_type result(Args const &args) const
0045 {
0046 typedef
0047 typename mpl::if_<
0048 is_same<Tag, tag::sample>
0049 , tag::weighted_sum
0050 , tag::weighted_sum_of_variates<Sample, Tag>
0051 >::type
0052 weighted_sum_tag;
0053
0054 extractor<weighted_sum_tag> const some_weighted_sum = {};
0055
0056 return numeric::fdiv(some_weighted_sum(args), sum_of_weights(args));
0057 }
0058 };
0059
0060
0061
0062
0063 template<typename Sample, typename Weight, typename Tag>
0064 struct immediate_weighted_mean_impl
0065 : accumulator_base
0066 {
0067 typedef typename numeric::functional::multiplies<Sample, Weight>::result_type weighted_sample;
0068
0069 typedef typename numeric::functional::fdiv<weighted_sample, Weight>::result_type result_type;
0070
0071 template<typename Args>
0072 immediate_weighted_mean_impl(Args const &args)
0073 : mean(
0074 numeric::fdiv(
0075 args[parameter::keyword<Tag>::get() | Sample()]
0076 * numeric::one<Weight>::value
0077 , numeric::one<Weight>::value
0078 )
0079 )
0080 {
0081 }
0082
0083 template<typename Args>
0084 void operator ()(Args const &args)
0085 {
0086
0087
0088
0089 Weight w_sum = sum_of_weights(args);
0090 Weight w = args[weight];
0091 weighted_sample const &s = args[parameter::keyword<Tag>::get()] * w;
0092 this->mean = numeric::fdiv(this->mean * (w_sum - w) + s, w_sum);
0093 }
0094
0095 result_type result(dont_care) const
0096 {
0097 return this->mean;
0098 }
0099
0100
0101 template<class Archive>
0102 void serialize(Archive & ar, const unsigned int )
0103 {
0104 ar & mean;
0105 }
0106
0107 private:
0108 result_type mean;
0109 };
0110
0111 }
0112
0113
0114
0115
0116
0117 namespace tag
0118 {
0119 struct weighted_mean
0120 : depends_on<sum_of_weights, weighted_sum>
0121 {
0122
0123
0124 typedef accumulators::impl::weighted_mean_impl<mpl::_1, mpl::_2, tag::sample> impl;
0125 };
0126 struct immediate_weighted_mean
0127 : depends_on<sum_of_weights>
0128 {
0129
0130
0131 typedef accumulators::impl::immediate_weighted_mean_impl<mpl::_1, mpl::_2, tag::sample> impl;
0132 };
0133 template<typename VariateType, typename VariateTag>
0134 struct weighted_mean_of_variates
0135 : depends_on<sum_of_weights, weighted_sum_of_variates<VariateType, VariateTag> >
0136 {
0137
0138
0139 typedef accumulators::impl::weighted_mean_impl<VariateType, mpl::_2, VariateTag> impl;
0140 };
0141 template<typename VariateType, typename VariateTag>
0142 struct immediate_weighted_mean_of_variates
0143 : depends_on<sum_of_weights>
0144 {
0145
0146
0147 typedef accumulators::impl::immediate_weighted_mean_impl<VariateType, mpl::_2, VariateTag> impl;
0148 };
0149 }
0150
0151
0152
0153
0154
0155 namespace extract
0156 {
0157 extractor<tag::mean> const weighted_mean = {};
0158 BOOST_ACCUMULATORS_DEFINE_EXTRACTOR(tag, weighted_mean_of_variates, (typename)(typename))
0159
0160 BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_mean)
0161 }
0162
0163 using extract::weighted_mean;
0164 using extract::weighted_mean_of_variates;
0165
0166
0167 template<>
0168 struct as_feature<tag::weighted_mean(lazy)>
0169 {
0170 typedef tag::weighted_mean type;
0171 };
0172
0173
0174 template<>
0175 struct as_feature<tag::weighted_mean(immediate)>
0176 {
0177 typedef tag::immediate_weighted_mean type;
0178 };
0179
0180
0181 template<typename VariateType, typename VariateTag>
0182 struct as_feature<tag::weighted_mean_of_variates<VariateType, VariateTag>(lazy)>
0183 {
0184 typedef tag::weighted_mean_of_variates<VariateType, VariateTag> type;
0185 };
0186
0187
0188 template<typename VariateType, typename VariateTag>
0189 struct as_feature<tag::weighted_mean_of_variates<VariateType, VariateTag>(immediate)>
0190 {
0191 typedef tag::immediate_weighted_mean_of_variates<VariateType, VariateTag> type;
0192 };
0193
0194 }}
0195
0196 #endif