Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:28:21

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // weighted_mean.hpp
0003 //
0004 //  Copyright 2006 Eric Niebler, Olivier Gygi. Distributed under the Boost
0005 //  Software License, Version 1.0. (See accompanying file
0006 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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     // weighted_mean_impl
0032     //      lazy, by default
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         // for boost::result_of
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     // immediate_weighted_mean_impl
0062     //      immediate
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         // for boost::result_of
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             // Matthias:
0087             //  need to pass the argument pack since the weight might be an external
0088             //  accumulator set passed as a named parameter
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         // make this accumulator serializeable
0101         template<class Archive>
0102         void serialize(Archive & ar, const unsigned int /* file_version */)
0103         { 
0104             ar & mean;
0105         }
0106 
0107     private:
0108         result_type mean;
0109     };
0110 
0111 } // namespace impl
0112 
0113 ///////////////////////////////////////////////////////////////////////////////
0114 // tag::weighted_mean
0115 // tag::immediate_weighted_mean
0116 //
0117 namespace tag
0118 {
0119     struct weighted_mean
0120       : depends_on<sum_of_weights, weighted_sum>
0121     {
0122         /// INTERNAL ONLY
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         /// INTERNAL ONLY
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         /// INTERNAL ONLY
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         /// INTERNAL ONLY
0146         ///
0147         typedef accumulators::impl::immediate_weighted_mean_impl<VariateType, mpl::_2, VariateTag> impl;
0148     };
0149 }
0150 
0151 ///////////////////////////////////////////////////////////////////////////////
0152 // extract::weighted_mean
0153 // extract::weighted_mean_of_variates
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 // weighted_mean(lazy) -> weighted_mean
0167 template<>
0168 struct as_feature<tag::weighted_mean(lazy)>
0169 {
0170     typedef tag::weighted_mean type;
0171 };
0172 
0173 // weighted_mean(immediate) -> immediate_weighted_mean
0174 template<>
0175 struct as_feature<tag::weighted_mean(immediate)>
0176 {
0177     typedef tag::immediate_weighted_mean type;
0178 };
0179 
0180 // weighted_mean_of_variates<VariateType, VariateTag>(lazy) -> weighted_mean_of_variates<VariateType, VariateTag>
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 // weighted_mean_of_variates<VariateType, VariateTag>(immediate) -> immediate_weighted_mean_of_variates<VariateType, VariateTag>
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 }} // namespace boost::accumulators
0195 
0196 #endif