moment.hpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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. private:
  69. Sample sum;
  70. };
  71. } // namespace impl
  72. ///////////////////////////////////////////////////////////////////////////////
  73. // tag::moment
  74. //
  75. namespace tag
  76. {
  77. template<int N>
  78. struct moment
  79. : depends_on<count>
  80. {
  81. /// INTERNAL ONLY
  82. ///
  83. typedef accumulators::impl::moment_impl<mpl::int_<N>, mpl::_1> impl;
  84. };
  85. }
  86. ///////////////////////////////////////////////////////////////////////////////
  87. // extract::moment
  88. //
  89. namespace extract
  90. {
  91. BOOST_ACCUMULATORS_DEFINE_EXTRACTOR(tag, moment, (int))
  92. }
  93. using extract::moment;
  94. // So that moment<N> can be automatically substituted with
  95. // weighted_moment<N> when the weight parameter is non-void
  96. template<int N>
  97. struct as_weighted_feature<tag::moment<N> >
  98. {
  99. typedef tag::weighted_moment<N> type;
  100. };
  101. template<int N>
  102. struct feature_of<tag::weighted_moment<N> >
  103. : feature_of<tag::moment<N> >
  104. {
  105. };
  106. }} // namespace boost::accumulators
  107. #endif