1 /////////////////////////////////////////////////////////////////////////////// 2 // moment.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_MOMENT_HPP_EAN_15_11_2005 9 #define BOOST_ACCUMULATORS_STATISTICS_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/accumulators/framework/accumulator_base.hpp> 16 #include <boost/accumulators/framework/extractor.hpp> 17 #include <boost/accumulators/numeric/functional.hpp> 18 #include <boost/accumulators/framework/parameters/sample.hpp> 19 #include <boost/accumulators/framework/depends_on.hpp> 20 #include <boost/accumulators/statistics_fwd.hpp> 21 #include <boost/accumulators/statistics/count.hpp> 22 23 namespace boost { namespace numeric 24 { 25 /// INTERNAL ONLY 26 /// 27 template<typename T> pow(T const & x,mpl::int_<1>)28 T const &pow(T const &x, mpl::int_<1>) 29 { 30 return x; 31 } 32 33 /// INTERNAL ONLY 34 /// 35 template<typename T, int N> pow(T const & x,mpl::int_<N>)36 T pow(T const &x, mpl::int_<N>) 37 { 38 using namespace operators; 39 T y = numeric::pow(x, mpl::int_<N/2>()); 40 T z = y * y; 41 return (N % 2) ? (z * x) : z; 42 } 43 }} 44 45 namespace boost { namespace accumulators 46 { 47 48 namespace impl 49 { 50 /////////////////////////////////////////////////////////////////////////////// 51 // moment_impl 52 template<typename N, typename Sample> 53 struct moment_impl 54 : accumulator_base // TODO: also depends_on sum of powers 55 { 56 BOOST_MPL_ASSERT_RELATION(N::value, >, 0); 57 // for boost::result_of 58 typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type result_type; 59 60 template<typename Args> moment_implboost::accumulators::impl::moment_impl61 moment_impl(Args const &args) 62 : sum(args[sample | Sample()]) 63 { 64 } 65 66 template<typename Args> operator ()boost::accumulators::impl::moment_impl67 void operator ()(Args const &args) 68 { 69 this->sum += numeric::pow(args[sample], N()); 70 } 71 72 template<typename Args> resultboost::accumulators::impl::moment_impl73 result_type result(Args const &args) const 74 { 75 return numeric::fdiv(this->sum, count(args)); 76 } 77 78 // make this accumulator serializeable 79 template<class Archive> serializeboost::accumulators::impl::moment_impl80 void serialize(Archive & ar, const unsigned int file_version) 81 { 82 ar & sum; 83 } 84 85 private: 86 Sample sum; 87 }; 88 89 } // namespace impl 90 91 /////////////////////////////////////////////////////////////////////////////// 92 // tag::moment 93 // 94 namespace tag 95 { 96 template<int N> 97 struct moment 98 : depends_on<count> 99 { 100 /// INTERNAL ONLY 101 /// 102 typedef accumulators::impl::moment_impl<mpl::int_<N>, mpl::_1> impl; 103 }; 104 } 105 106 /////////////////////////////////////////////////////////////////////////////// 107 // extract::moment 108 // 109 namespace extract 110 { 111 BOOST_ACCUMULATORS_DEFINE_EXTRACTOR(tag, moment, (int)) 112 } 113 114 using extract::moment; 115 116 // So that moment<N> can be automatically substituted with 117 // weighted_moment<N> when the weight parameter is non-void 118 template<int N> 119 struct as_weighted_feature<tag::moment<N> > 120 { 121 typedef tag::weighted_moment<N> type; 122 }; 123 124 template<int N> 125 struct feature_of<tag::weighted_moment<N> > 126 : feature_of<tag::moment<N> > 127 { 128 }; 129 130 }} // namespace boost::accumulators 131 132 #endif 133