1 ///////////////////////////////////////////////////////////////////////////////
2 // weighted_tail_variate_means.hpp
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)
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
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>
33 # pragma warning(push)
34 # pragma warning(disable: 4127) // conditional expression is constant
39 // for _BinaryOperatrion2 in std::inner_product below
40 // mutliplies two values and promotes the result to double
41 namespace numeric
{ namespace functional
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>
53 namespace boost
{ namespace accumulators
59 @brief Estimation of the absolute and relative weighted tail variate means (for both left and right tails)
61 For all \f$j\f$-th variates associated to the
64 \lambda = \inf\left\{ l \left| \frac{1}{\bar{w}_n}\sum_{i=1}^{l} w_i \geq \alpha \right. \right\}
67 smallest samples (left tail) or the weighted mean of the
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\}
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$.
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}
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}
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)}
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)}
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
110 typedef typename
numeric::functional::average
<Weight
, Weight
>::result_type float_type
;
111 typedef typename
numeric::functional::average
<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
;
115 weighted_tail_variate_means_impl(dont_care
) {}
117 template<typename Args
>
118 result_type
result(Args
const &args
) const
120 float_type threshold
= sum_of_weights(args
)
121 * ( ( is_same
<LeftRight
, left
>::value
) ? args
[quantile_probability
] : 1. - args
[quantile_probability
] );
124 Weight sum
= Weight(0);
126 while (sum
< threshold
)
128 if (n
< static_cast<std::size_t>(tail_weights(args
).size()))
130 sum
+= *(tail_weights(args
).begin() + n
);
135 if (std::numeric_limits
<float_type
>::has_quiet_NaN
)
138 this->tail_means_
.begin()
139 , this->tail_means_
.end()
140 , std::numeric_limits
<float_type
>::quiet_NaN()
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()));
152 std::size_t num_variates
= tail_variate(args
).begin()->size();
154 this->tail_means_
.clear();
155 this->tail_means_
.resize(num_variates
, Sample(0));
157 this->tail_means_
= std::inner_product(
158 tail_variate(args
).begin()
159 , tail_variate(args
).begin() + n
160 , tail_weights(args
).begin()
162 , numeric::functional::plus
<array_type
const, array_type
const>()
163 , numeric::functional::multiply_and_promote_to_double
<VariateType
const, Weight
const>()
166 float_type factor
= sum
* ( (is_same
<Impl
, relative
>::value
) ? non_coherent_weighted_tail_mean(args
) : 1. );
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
)
175 return make_iterator_range(this->tail_means_
);
180 mutable array_type tail_means_
;
186 ///////////////////////////////////////////////////////////////////////////////
187 // tag::absolute_weighted_tail_variate_means
188 // tag::relative_weighted_tail_variate_means
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
> >
196 typedef accumulators::impl::weighted_tail_variate_means_impl
<mpl::_1
, mpl::_2
, absolute
, LeftRight
, VariateType
> impl
;
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
> >
202 typedef accumulators::impl::weighted_tail_variate_means_impl
<mpl::_1
, mpl::_2
, relative
, LeftRight
, VariateType
> impl
;
206 ///////////////////////////////////////////////////////////////////////////////
207 // extract::weighted_tail_variate_means
208 // extract::relative_weighted_tail_variate_means
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
= {};
216 using extract::weighted_tail_variate_means
;
217 using extract::relative_weighted_tail_variate_means
;
219 // weighted_tail_variate_means<LeftRight, VariateType, VariateTag>(absolute) -> absolute_weighted_tail_variate_means<LeftRight, VariateType, VariateTag>
220 template<typename LeftRight
, typename VariateType
, typename VariateTag
>
221 struct as_feature
<tag::weighted_tail_variate_means
<LeftRight
, VariateType
, VariateTag
>(absolute
)>
223 typedef tag::absolute_weighted_tail_variate_means
<LeftRight
, VariateType
, VariateTag
> type
;
226 // weighted_tail_variate_means<LeftRight, VariateType, VariateTag>(relative) -> relative_weighted_tail_variate_means<LeftRight, VariateType, VariateTag>
227 template<typename LeftRight
, typename VariateType
, typename VariateTag
>
228 struct as_feature
<tag::weighted_tail_variate_means
<LeftRight
, VariateType
, VariateTag
>(relative
)>
230 typedef tag::relative_weighted_tail_variate_means
<LeftRight
, VariateType
, VariateTag
> type
;
233 }} // namespace boost::accumulators
236 # pragma warning(pop)