moment.hpp 3.4 KB

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