1 /////////////////////////////////////////////////////////////////////////////// 2 // weighted_moment.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 8 #ifndef BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_MOMENT_HPP_EAN_15_11_2005 9 #define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_MOMENT_HPP_EAN_15_11_2005 10 11 #include <boost/config/no_tr1/cmath.hpp> 12 #include <boost/mpl/int.hpp> 13 #include <boost/mpl/assert.hpp> 14 #include <boost/mpl/placeholders.hpp> 15 #include <boost/preprocessor/arithmetic/inc.hpp> 16 #include <boost/preprocessor/repetition/repeat_from_to.hpp> 17 #include <boost/preprocessor/repetition/enum_trailing_params.hpp> 18 #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp> 19 #include <boost/accumulators/framework/accumulator_base.hpp> 20 #include <boost/accumulators/framework/extractor.hpp> 21 #include <boost/accumulators/numeric/functional.hpp> 22 #include <boost/accumulators/framework/parameters/sample.hpp> 23 #include <boost/accumulators/framework/depends_on.hpp> 24 #include <boost/accumulators/statistics_fwd.hpp> 25 #include <boost/accumulators/statistics/count.hpp> 26 #include <boost/accumulators/statistics/moment.hpp> // for pow() 27 #include <boost/accumulators/statistics/sum.hpp> 28 29 namespace boost { namespace accumulators 30 { 31 32 namespace impl 33 { 34 /////////////////////////////////////////////////////////////////////////////// 35 // weighted_moment_impl 36 template<typename N, typename Sample, typename Weight> 37 struct weighted_moment_impl 38 : accumulator_base // TODO: also depends_on sum of powers 39 { 40 BOOST_MPL_ASSERT_RELATION(N::value, >, 0); 41 typedef typename numeric::functional::multiplies<Sample, Weight>::result_type weighted_sample; 42 // for boost::result_of 43 typedef typename numeric::functional::fdiv<weighted_sample, Weight>::result_type result_type; 44 45 template<typename Args> weighted_moment_implboost::accumulators::impl::weighted_moment_impl46 weighted_moment_impl(Args const &args) 47 : sum(args[sample | Sample()] * numeric::one<Weight>::value) 48 { 49 } 50 51 template<typename Args> operator ()boost::accumulators::impl::weighted_moment_impl52 void operator ()(Args const &args) 53 { 54 this->sum += args[weight] * numeric::pow(args[sample], N()); 55 } 56 57 template<typename Args> resultboost::accumulators::impl::weighted_moment_impl58 result_type result(Args const &args) const 59 { 60 return numeric::fdiv(this->sum, sum_of_weights(args)); 61 } 62 63 // make this accumulator serializeable 64 template<class Archive> serializeboost::accumulators::impl::weighted_moment_impl65 void serialize(Archive & ar, const unsigned int file_version) 66 { 67 ar & sum; 68 } 69 70 private: 71 weighted_sample sum; 72 }; 73 74 } // namespace impl 75 76 /////////////////////////////////////////////////////////////////////////////// 77 // tag::weighted_moment 78 // 79 namespace tag 80 { 81 template<int N> 82 struct weighted_moment 83 : depends_on<count, sum_of_weights> 84 { 85 /// INTERNAL ONLY 86 /// 87 typedef accumulators::impl::weighted_moment_impl<mpl::int_<N>, mpl::_1, mpl::_2> impl; 88 }; 89 } 90 91 /////////////////////////////////////////////////////////////////////////////// 92 // extract::weighted_moment 93 // 94 namespace extract 95 { 96 BOOST_ACCUMULATORS_DEFINE_EXTRACTOR(tag, weighted_moment, (int)) 97 } 98 99 using extract::weighted_moment; 100 101 }} // namespace boost::accumulators 102 103 #endif 104