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

source code of boost/libs/accumulators/include/boost/accumulators/statistics/weighted_tail_variate_means.hpp