weighted_tail_variate_means.hpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  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. // multiplies 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::fdiv<Weight, Weight>::result_type float_type;
  95. typedef typename numeric::functional::fdiv<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. #ifdef BOOST_NO_CXX98_BINDERS
  148. , std::bind(numeric::functional::divides<typename array_type::value_type const, float_type const>(), std::placeholders::_1, factor)
  149. #else
  150. , std::bind2nd(numeric::functional::divides<typename array_type::value_type const, float_type const>(), factor)
  151. #endif
  152. );
  153. return make_iterator_range(this->tail_means_);
  154. }
  155. // make this accumulator serializeable
  156. template<class Archive>
  157. void serialize(Archive & ar, const unsigned int file_version)
  158. {
  159. ar & tail_means_;
  160. }
  161. private:
  162. mutable array_type tail_means_;
  163. };
  164. } // namespace impl
  165. ///////////////////////////////////////////////////////////////////////////////
  166. // tag::absolute_weighted_tail_variate_means
  167. // tag::relative_weighted_tail_variate_means
  168. //
  169. namespace tag
  170. {
  171. template<typename LeftRight, typename VariateType, typename VariateTag>
  172. struct absolute_weighted_tail_variate_means
  173. : depends_on<non_coherent_weighted_tail_mean<LeftRight>, tail_variate<VariateType, VariateTag, LeftRight>, tail_weights<LeftRight> >
  174. {
  175. typedef accumulators::impl::weighted_tail_variate_means_impl<mpl::_1, mpl::_2, absolute, LeftRight, VariateType> impl;
  176. };
  177. template<typename LeftRight, typename VariateType, typename VariateTag>
  178. struct relative_weighted_tail_variate_means
  179. : depends_on<non_coherent_weighted_tail_mean<LeftRight>, tail_variate<VariateType, VariateTag, LeftRight>, tail_weights<LeftRight> >
  180. {
  181. typedef accumulators::impl::weighted_tail_variate_means_impl<mpl::_1, mpl::_2, relative, LeftRight, VariateType> impl;
  182. };
  183. }
  184. ///////////////////////////////////////////////////////////////////////////////
  185. // extract::weighted_tail_variate_means
  186. // extract::relative_weighted_tail_variate_means
  187. //
  188. namespace extract
  189. {
  190. extractor<tag::abstract_absolute_tail_variate_means> const weighted_tail_variate_means = {};
  191. extractor<tag::abstract_relative_tail_variate_means> const relative_weighted_tail_variate_means = {};
  192. BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_tail_variate_means)
  193. BOOST_ACCUMULATORS_IGNORE_GLOBAL(relative_weighted_tail_variate_means)
  194. }
  195. using extract::weighted_tail_variate_means;
  196. using extract::relative_weighted_tail_variate_means;
  197. // weighted_tail_variate_means<LeftRight, VariateType, VariateTag>(absolute) -> absolute_weighted_tail_variate_means<LeftRight, VariateType, VariateTag>
  198. template<typename LeftRight, typename VariateType, typename VariateTag>
  199. struct as_feature<tag::weighted_tail_variate_means<LeftRight, VariateType, VariateTag>(absolute)>
  200. {
  201. typedef tag::absolute_weighted_tail_variate_means<LeftRight, VariateType, VariateTag> type;
  202. };
  203. // weighted_tail_variate_means<LeftRight, VariateType, VariateTag>(relative) -> relative_weighted_tail_variate_means<LeftRight, VariateType, VariateTag>
  204. template<typename LeftRight, typename VariateType, typename VariateTag>
  205. struct as_feature<tag::weighted_tail_variate_means<LeftRight, VariateType, VariateTag>(relative)>
  206. {
  207. typedef tag::relative_weighted_tail_variate_means<LeftRight, VariateType, VariateTag> type;
  208. };
  209. }} // namespace boost::accumulators
  210. #ifdef _MSC_VER
  211. # pragma warning(pop)
  212. #endif
  213. #endif