]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/accumulators/include/boost/accumulators/statistics/weighted_tail_variate_means.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / accumulators / include / boost / accumulators / statistics / weighted_tail_variate_means.hpp
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
37 namespace 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
53 namespace boost { namespace accumulators
54 {
55
56 namespace 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(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 , std::bind2nd(numeric::functional::divides<typename array_type::value_type const, float_type const>(), factor)
173 );
174
175 return make_iterator_range(this->tail_means_);
176 }
177
178 private:
179
180 mutable array_type tail_means_;
181
182 };
183
184 } // namespace impl
185
186 ///////////////////////////////////////////////////////////////////////////////
187 // tag::absolute_weighted_tail_variate_means
188 // tag::relative_weighted_tail_variate_means
189 //
190 namespace tag
191 {
192 template<typename LeftRight, typename VariateType, typename VariateTag>
193 struct absolute_weighted_tail_variate_means
194 : depends_on<non_coherent_weighted_tail_mean<LeftRight>, tail_variate<VariateType, VariateTag, LeftRight>, tail_weights<LeftRight> >
195 {
196 typedef accumulators::impl::weighted_tail_variate_means_impl<mpl::_1, mpl::_2, absolute, LeftRight, VariateType> impl;
197 };
198 template<typename LeftRight, typename VariateType, typename VariateTag>
199 struct relative_weighted_tail_variate_means
200 : depends_on<non_coherent_weighted_tail_mean<LeftRight>, tail_variate<VariateType, VariateTag, LeftRight>, tail_weights<LeftRight> >
201 {
202 typedef accumulators::impl::weighted_tail_variate_means_impl<mpl::_1, mpl::_2, relative, LeftRight, VariateType> impl;
203 };
204 }
205
206 ///////////////////////////////////////////////////////////////////////////////
207 // extract::weighted_tail_variate_means
208 // extract::relative_weighted_tail_variate_means
209 //
210 namespace extract
211 {
212 extractor<tag::abstract_absolute_tail_variate_means> const weighted_tail_variate_means = {};
213 extractor<tag::abstract_relative_tail_variate_means> const relative_weighted_tail_variate_means = {};
214
215 BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_tail_variate_means)
216 BOOST_ACCUMULATORS_IGNORE_GLOBAL(relative_weighted_tail_variate_means)
217 }
218
219 using extract::weighted_tail_variate_means;
220 using extract::relative_weighted_tail_variate_means;
221
222 // weighted_tail_variate_means<LeftRight, VariateType, VariateTag>(absolute) -> absolute_weighted_tail_variate_means<LeftRight, VariateType, VariateTag>
223 template<typename LeftRight, typename VariateType, typename VariateTag>
224 struct as_feature<tag::weighted_tail_variate_means<LeftRight, VariateType, VariateTag>(absolute)>
225 {
226 typedef tag::absolute_weighted_tail_variate_means<LeftRight, VariateType, VariateTag> type;
227 };
228
229 // weighted_tail_variate_means<LeftRight, VariateType, VariateTag>(relative) -> relative_weighted_tail_variate_means<LeftRight, VariateType, VariateTag>
230 template<typename LeftRight, typename VariateType, typename VariateTag>
231 struct as_feature<tag::weighted_tail_variate_means<LeftRight, VariateType, VariateTag>(relative)>
232 {
233 typedef tag::relative_weighted_tail_variate_means<LeftRight, VariateType, VariateTag> type;
234 };
235
236 }} // namespace boost::accumulators
237
238 #ifdef _MSC_VER
239 # pragma warning(pop)
240 #endif
241
242 #endif