/Src/Dependencies/Boost/boost/accumulators/statistics/weighted_tail_variate_means.hpp

http://hadesmem.googlecode.com/ · C++ Header · 242 lines · 144 code · 30 blank · 68 comment · 3 complexity · c7cc5d593d0aa9acb6e28b99f5e2ecb7 MD5 · raw file

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // weighted_tail_variate_means.hpp
  3. //
  4. // Copyright 2006 Daniel Egloff, 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. #ifndef BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_TAIL_VARIATE_MEANS_HPP_DE_01_01_2006
  8. #define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_TAIL_VARIATE_MEANS_HPP_DE_01_01_2006
  9. #include <numeric>
  10. #include <vector>
  11. #include <limits>
  12. #include <functional>
  13. #include <sstream>
  14. #include <stdexcept>
  15. #include <boost/throw_exception.hpp>
  16. #include <boost/parameter/keyword.hpp>
  17. #include <boost/mpl/placeholders.hpp>
  18. #include <boost/type_traits/is_same.hpp>
  19. #include <boost/accumulators/numeric/functional.hpp>
  20. #include <boost/accumulators/framework/accumulator_base.hpp>
  21. #include <boost/accumulators/framework/extractor.hpp>
  22. #include <boost/accumulators/framework/parameters/sample.hpp>
  23. #include <boost/accumulators/statistics_fwd.hpp>
  24. #include <boost/accumulators/statistics/tail.hpp>
  25. #include <boost/accumulators/statistics/tail_variate.hpp>
  26. #include <boost/accumulators/statistics/tail_variate_means.hpp>
  27. #include <boost/accumulators/statistics/weighted_tail_mean.hpp>
  28. #include <boost/accumulators/statistics/parameters/quantile_probability.hpp>
  29. #ifdef _MSC_VER
  30. # pragma warning(push)
  31. # pragma warning(disable: 4127) // conditional expression is constant
  32. #endif
  33. namespace boost
  34. {
  35. // for _BinaryOperatrion2 in std::inner_product below
  36. // mutliplies two values and promotes the result to double
  37. namespace numeric { namespace functional
  38. {
  39. ///////////////////////////////////////////////////////////////////////////////
  40. // numeric::functional::multiply_and_promote_to_double
  41. template<typename T, typename U>
  42. struct multiply_and_promote_to_double
  43. : multiplies<T, double const>
  44. {
  45. };
  46. }}
  47. }
  48. namespace boost { namespace accumulators
  49. {
  50. namespace impl
  51. {
  52. /**
  53. @brief Estimation of the absolute and relative weighted tail variate means (for both left and right tails)
  54. For all \f$j\f$-th variates associated to the
  55. \f[
  56. \lambda = \inf\left\{ l \left| \frac{1}{\bar{w}_n}\sum_{i=1}^{l} w_i \geq \alpha \right. \right\}
  57. \f]
  58. smallest samples (left tail) or the weighted mean of the
  59. \f[
  60. n + 1 - \rho = n + 1 - \sup\left\{ r \left| \frac{1}{\bar{w}_n}\sum_{i=r}^{n} w_i \geq (1 - \alpha) \right. \right\}
  61. \f]
  62. largest samples (right tail), the absolute weighted tail means \f$\widehat{ATM}_{n,\alpha}(X, j)\f$
  63. are computed and returned as an iterator range. Alternatively, the relative weighted tail means
  64. \f$\widehat{RTM}_{n,\alpha}(X, j)\f$ are returned, which are the absolute weighted tail means
  65. normalized with the weighted (non-coherent) sample tail mean \f$\widehat{NCTM}_{n,\alpha}(X)\f$.
  66. \f[
  67. \widehat{ATM}_{n,\alpha}^{\mathrm{right}}(X, j) =
  68. \frac{1}{\sum_{i=\rho}^n w_i}
  69. \sum_{i=\rho}^n w_i \xi_{j,i}
  70. \f]
  71. \f[
  72. \widehat{ATM}_{n,\alpha}^{\mathrm{left}}(X, j) =
  73. \frac{1}{\sum_{i=1}^{\lambda}}
  74. \sum_{i=1}^{\lambda} w_i \xi_{j,i}
  75. \f]
  76. \f[
  77. \widehat{RTM}_{n,\alpha}^{\mathrm{right}}(X, j) =
  78. \frac{\sum_{i=\rho}^n w_i \xi_{j,i}}
  79. {\sum_{i=\rho}^n w_i \widehat{NCTM}_{n,\alpha}^{\mathrm{right}}(X)}
  80. \f]
  81. \f[
  82. \widehat{RTM}_{n,\alpha}^{\mathrm{left}}(X, j) =
  83. \frac{\sum_{i=1}^{\lambda} w_i \xi_{j,i}}
  84. {\sum_{i=1}^{\lambda} w_i \widehat{NCTM}_{n,\alpha}^{\mathrm{left}}(X)}
  85. \f]
  86. */
  87. ///////////////////////////////////////////////////////////////////////////////
  88. // weighted_tail_variate_means_impl
  89. // by default: absolute weighted_tail_variate_means
  90. template<typename Sample, typename Weight, typename Impl, typename LeftRight, typename VariateType>
  91. struct weighted_tail_variate_means_impl
  92. : accumulator_base
  93. {
  94. typedef typename numeric::functional::average<Weight, Weight>::result_type float_type;
  95. typedef typename numeric::functional::average<typename numeric::functional::multiplies<VariateType, Weight>::result_type, Weight>::result_type array_type;
  96. // for boost::result_of
  97. typedef iterator_range<typename array_type::iterator> result_type;
  98. weighted_tail_variate_means_impl(dont_care) {}
  99. template<typename Args>
  100. result_type result(Args const &args) const
  101. {
  102. float_type threshold = sum_of_weights(args)
  103. * ( ( is_same<LeftRight, left>::value ) ? args[quantile_probability] : 1. - args[quantile_probability] );
  104. std::size_t n = 0;
  105. Weight sum = Weight(0);
  106. while (sum < threshold)
  107. {
  108. if (n < static_cast<std::size_t>(tail_weights(args).size()))
  109. {
  110. sum += *(tail_weights(args).begin() + n);
  111. n++;
  112. }
  113. else
  114. {
  115. if (std::numeric_limits<float_type>::has_quiet_NaN)
  116. {
  117. std::fill(
  118. this->tail_means_.begin()
  119. , this->tail_means_.end()
  120. , std::numeric_limits<float_type>::quiet_NaN()
  121. );
  122. }
  123. else
  124. {
  125. std::ostringstream msg;
  126. msg << "index n = " << n << " is not in valid range [0, " << tail(args).size() << ")";
  127. boost::throw_exception(std::runtime_error(msg.str()));
  128. }
  129. }
  130. }
  131. std::size_t num_variates = tail_variate(args).begin()->size();
  132. this->tail_means_.clear();
  133. this->tail_means_.resize(num_variates, Sample(0));
  134. this->tail_means_ = std::inner_product(
  135. tail_variate(args).begin()
  136. , tail_variate(args).begin() + n
  137. , tail_weights(args).begin()
  138. , this->tail_means_
  139. , numeric::functional::plus<array_type const, array_type const>()
  140. , numeric::functional::multiply_and_promote_to_double<VariateType const, Weight const>()
  141. );
  142. float_type factor = sum * ( (is_same<Impl, relative>::value) ? non_coherent_weighted_tail_mean(args) : 1. );
  143. std::transform(
  144. this->tail_means_.begin()
  145. , this->tail_means_.end()
  146. , this->tail_means_.begin()
  147. , std::bind2nd(numeric::functional::divides<typename array_type::value_type const, float_type const>(), factor)
  148. );
  149. return make_iterator_range(this->tail_means_);
  150. }
  151. private:
  152. mutable array_type tail_means_;
  153. };
  154. } // namespace impl
  155. ///////////////////////////////////////////////////////////////////////////////
  156. // tag::absolute_weighted_tail_variate_means
  157. // tag::relative_weighted_tail_variate_means
  158. //
  159. namespace tag
  160. {
  161. template<typename LeftRight, typename VariateType, typename VariateTag>
  162. struct absolute_weighted_tail_variate_means
  163. : depends_on<non_coherent_weighted_tail_mean<LeftRight>, tail_variate<VariateType, VariateTag, LeftRight>, tail_weights<LeftRight> >
  164. {
  165. typedef accumulators::impl::weighted_tail_variate_means_impl<mpl::_1, mpl::_2, absolute, LeftRight, VariateType> impl;
  166. };
  167. template<typename LeftRight, typename VariateType, typename VariateTag>
  168. struct relative_weighted_tail_variate_means
  169. : depends_on<non_coherent_weighted_tail_mean<LeftRight>, tail_variate<VariateType, VariateTag, LeftRight>, tail_weights<LeftRight> >
  170. {
  171. typedef accumulators::impl::weighted_tail_variate_means_impl<mpl::_1, mpl::_2, relative, LeftRight, VariateType> impl;
  172. };
  173. }
  174. ///////////////////////////////////////////////////////////////////////////////
  175. // extract::weighted_tail_variate_means
  176. // extract::relative_weighted_tail_variate_means
  177. //
  178. namespace extract
  179. {
  180. extractor<tag::abstract_absolute_tail_variate_means> const weighted_tail_variate_means = {};
  181. extractor<tag::abstract_relative_tail_variate_means> const relative_weighted_tail_variate_means = {};
  182. BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_tail_variate_means)
  183. BOOST_ACCUMULATORS_IGNORE_GLOBAL(relative_weighted_tail_variate_means)
  184. }
  185. using extract::weighted_tail_variate_means;
  186. using extract::relative_weighted_tail_variate_means;
  187. // weighted_tail_variate_means<LeftRight, VariateType, VariateTag>(absolute) -> absolute_weighted_tail_variate_means<LeftRight, VariateType, VariateTag>
  188. template<typename LeftRight, typename VariateType, typename VariateTag>
  189. struct as_feature<tag::weighted_tail_variate_means<LeftRight, VariateType, VariateTag>(absolute)>
  190. {
  191. typedef tag::absolute_weighted_tail_variate_means<LeftRight, VariateType, VariateTag> type;
  192. };
  193. // weighted_tail_variate_means<LeftRight, VariateType, VariateTag>(relative) -> relative_weighted_tail_variate_means<LeftRight, VariateType, VariateTag>
  194. template<typename LeftRight, typename VariateType, typename VariateTag>
  195. struct as_feature<tag::weighted_tail_variate_means<LeftRight, VariateType, VariateTag>(relative)>
  196. {
  197. typedef tag::relative_weighted_tail_variate_means<LeftRight, VariateType, VariateTag> type;
  198. };
  199. }} // namespace boost::accumulators
  200. #ifdef _MSC_VER
  201. # pragma warning(pop)
  202. #endif
  203. #endif