Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:28:22

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // weighted_tail_variate_means.hpp
0003 //
0004 //  Copyright 2006 Daniel Egloff, Olivier Gygi. Distributed under the Boost
0005 //  Software License, Version 1.0. (See accompanying file
0006 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 
0008 #ifndef BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_TAIL_VARIATE_MEANS_HPP_DE_01_01_2006
0009 #define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_TAIL_VARIATE_MEANS_HPP_DE_01_01_2006
0010 
0011 #include <numeric>
0012 #include <vector>
0013 #include <limits>
0014 #include <functional>
0015 #include <sstream>
0016 #include <stdexcept>
0017 #include <boost/throw_exception.hpp>
0018 #include <boost/parameter/keyword.hpp>
0019 #include <boost/mpl/placeholders.hpp>
0020 #include <boost/type_traits/is_same.hpp>
0021 #include <boost/accumulators/numeric/functional.hpp>
0022 #include <boost/accumulators/framework/accumulator_base.hpp>
0023 #include <boost/accumulators/framework/extractor.hpp>
0024 #include <boost/accumulators/framework/parameters/sample.hpp>
0025 #include <boost/accumulators/statistics_fwd.hpp>
0026 #include <boost/accumulators/statistics/tail.hpp>
0027 #include <boost/accumulators/statistics/tail_variate.hpp>
0028 #include <boost/accumulators/statistics/tail_variate_means.hpp>
0029 #include <boost/accumulators/statistics/weighted_tail_mean.hpp>
0030 #include <boost/accumulators/statistics/parameters/quantile_probability.hpp>
0031 
0032 #ifdef _MSC_VER
0033 # pragma warning(push)
0034 # pragma warning(disable: 4127) // conditional expression is constant
0035 #endif
0036 
0037 namespace boost
0038 {
0039     // for _BinaryOperatrion2 in std::inner_product below
0040     // multiplies two values and promotes the result to double
0041     namespace numeric { namespace functional
0042     {
0043         ///////////////////////////////////////////////////////////////////////////////
0044         // numeric::functional::multiply_and_promote_to_double
0045         template<typename T, typename U>
0046         struct multiply_and_promote_to_double
0047           : multiplies<T, double const>
0048         {
0049         };
0050     }}
0051 }
0052 
0053 namespace boost { namespace accumulators
0054 {
0055 
0056 namespace impl
0057 {
0058     /**
0059         @brief Estimation of the absolute and relative weighted tail variate means (for both left and right tails)
0060 
0061         For all \f$j\f$-th variates associated to the
0062 
0063         \f[
0064             \lambda = \inf\left\{ l \left| \frac{1}{\bar{w}_n}\sum_{i=1}^{l} w_i \geq \alpha \right. \right\}
0065         \f]
0066 
0067         smallest samples (left tail) or the weighted mean of the
0068 
0069         \f[
0070             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\}
0071         \f]
0072 
0073         largest samples (right tail), the absolute weighted tail means \f$\widehat{ATM}_{n,\alpha}(X, j)\f$
0074         are computed and returned as an iterator range. Alternatively, the relative weighted tail means
0075         \f$\widehat{RTM}_{n,\alpha}(X, j)\f$ are returned, which are the absolute weighted tail means
0076         normalized with the weighted (non-coherent) sample tail mean \f$\widehat{NCTM}_{n,\alpha}(X)\f$.
0077 
0078         \f[
0079             \widehat{ATM}_{n,\alpha}^{\mathrm{right}}(X, j) =
0080                 \frac{1}{\sum_{i=\rho}^n w_i}
0081                 \sum_{i=\rho}^n w_i \xi_{j,i}
0082         \f]
0083 
0084         \f[
0085             \widehat{ATM}_{n,\alpha}^{\mathrm{left}}(X, j) =
0086                 \frac{1}{\sum_{i=1}^{\lambda}}
0087                 \sum_{i=1}^{\lambda} w_i \xi_{j,i}
0088         \f]
0089 
0090         \f[
0091             \widehat{RTM}_{n,\alpha}^{\mathrm{right}}(X, j) =
0092                 \frac{\sum_{i=\rho}^n w_i \xi_{j,i}}
0093             {\sum_{i=\rho}^n w_i \widehat{NCTM}_{n,\alpha}^{\mathrm{right}}(X)}
0094         \f]
0095 
0096         \f[
0097             \widehat{RTM}_{n,\alpha}^{\mathrm{left}}(X, j) =
0098                 \frac{\sum_{i=1}^{\lambda} w_i \xi_{j,i}}
0099             {\sum_{i=1}^{\lambda} w_i \widehat{NCTM}_{n,\alpha}^{\mathrm{left}}(X)}
0100         \f]
0101     */
0102 
0103     ///////////////////////////////////////////////////////////////////////////////
0104     // weighted_tail_variate_means_impl
0105     //  by default: absolute weighted_tail_variate_means
0106     template<typename Sample, typename Weight, typename Impl, typename LeftRight, typename VariateType>
0107     struct weighted_tail_variate_means_impl
0108       : accumulator_base
0109     {
0110         typedef typename numeric::functional::fdiv<Weight, Weight>::result_type float_type;
0111         typedef typename numeric::functional::fdiv<typename numeric::functional::multiplies<VariateType, Weight>::result_type, Weight>::result_type array_type;
0112         // for boost::result_of
0113         typedef iterator_range<typename array_type::iterator> result_type;
0114 
0115         weighted_tail_variate_means_impl(dont_care) {}
0116 
0117         template<typename Args>
0118         result_type result(Args const &args) const
0119         {
0120             float_type threshold = sum_of_weights(args)
0121                              * ( ( is_same<LeftRight, left>::value ) ? args[quantile_probability] : 1. - args[quantile_probability] );
0122 
0123             std::size_t n = 0;
0124             Weight sum = Weight(0);
0125 
0126             while (sum < threshold)
0127             {
0128                 if (n < static_cast<std::size_t>(tail_weights(args).size()))
0129                 {
0130                     sum += *(tail_weights(args).begin() + n);
0131                     n++;
0132                 }
0133                 else
0134                 {
0135                     if (std::numeric_limits<float_type>::has_quiet_NaN)
0136                     {
0137                         std::fill(
0138                             this->tail_means_.begin()
0139                           , this->tail_means_.end()
0140                           , std::numeric_limits<float_type>::quiet_NaN()
0141                         );
0142                     }
0143                     else
0144                     {
0145                         std::ostringstream msg;
0146                         msg << "index n = " << n << " is not in valid range [0, " << tail(args).size() << ")";
0147                         boost::throw_exception(std::runtime_error(msg.str()));
0148                     }
0149                 }
0150             }
0151 
0152             std::size_t num_variates = tail_variate(args).begin()->size();
0153 
0154             this->tail_means_.clear();
0155             this->tail_means_.resize(num_variates, Sample(0));
0156 
0157             this->tail_means_ = std::inner_product(
0158                 tail_variate(args).begin()
0159               , tail_variate(args).begin() + n
0160               , tail_weights(args).begin()
0161               , this->tail_means_
0162               , numeric::functional::plus<array_type const, array_type const>()
0163               , numeric::functional::multiply_and_promote_to_double<VariateType const, Weight const>()
0164             );
0165 
0166             float_type factor = sum * ( (is_same<Impl, relative>::value) ? non_coherent_weighted_tail_mean(args) : 1. );
0167 
0168             std::transform(
0169                 this->tail_means_.begin()
0170               , this->tail_means_.end()
0171               , this->tail_means_.begin()
0172 #ifdef BOOST_NO_CXX98_BINDERS
0173               , std::bind(numeric::functional::divides<typename array_type::value_type const, float_type const>(), std::placeholders::_1, factor)
0174 #else
0175               , std::bind2nd(numeric::functional::divides<typename array_type::value_type const, float_type const>(), factor)
0176 #endif
0177             );
0178 
0179             return make_iterator_range(this->tail_means_);
0180         }
0181 
0182         // make this accumulator serializeable
0183         template<class Archive>
0184         void serialize(Archive & ar, const unsigned int file_version)
0185         {
0186             ar & tail_means_;
0187         }
0188 
0189     private:
0190 
0191         mutable array_type tail_means_;
0192 
0193     };
0194 
0195 } // namespace impl
0196 
0197 ///////////////////////////////////////////////////////////////////////////////
0198 // tag::absolute_weighted_tail_variate_means
0199 // tag::relative_weighted_tail_variate_means
0200 //
0201 namespace tag
0202 {
0203     template<typename LeftRight, typename VariateType, typename VariateTag>
0204     struct absolute_weighted_tail_variate_means
0205       : depends_on<non_coherent_weighted_tail_mean<LeftRight>, tail_variate<VariateType, VariateTag, LeftRight>, tail_weights<LeftRight> >
0206     {
0207         typedef accumulators::impl::weighted_tail_variate_means_impl<mpl::_1, mpl::_2, absolute, LeftRight, VariateType> impl;
0208     };
0209     template<typename LeftRight, typename VariateType, typename VariateTag>
0210     struct relative_weighted_tail_variate_means
0211       : depends_on<non_coherent_weighted_tail_mean<LeftRight>, tail_variate<VariateType, VariateTag, LeftRight>, tail_weights<LeftRight> >
0212     {
0213         typedef accumulators::impl::weighted_tail_variate_means_impl<mpl::_1, mpl::_2, relative, LeftRight, VariateType> impl;
0214     };
0215 }
0216 
0217 ///////////////////////////////////////////////////////////////////////////////
0218 // extract::weighted_tail_variate_means
0219 // extract::relative_weighted_tail_variate_means
0220 //
0221 namespace extract
0222 {
0223     extractor<tag::abstract_absolute_tail_variate_means> const weighted_tail_variate_means = {};
0224     extractor<tag::abstract_relative_tail_variate_means> const relative_weighted_tail_variate_means = {};
0225 
0226     BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_tail_variate_means)
0227     BOOST_ACCUMULATORS_IGNORE_GLOBAL(relative_weighted_tail_variate_means)
0228 }
0229 
0230 using extract::weighted_tail_variate_means;
0231 using extract::relative_weighted_tail_variate_means;
0232 
0233 // weighted_tail_variate_means<LeftRight, VariateType, VariateTag>(absolute) -> absolute_weighted_tail_variate_means<LeftRight, VariateType, VariateTag>
0234 template<typename LeftRight, typename VariateType, typename VariateTag>
0235 struct as_feature<tag::weighted_tail_variate_means<LeftRight, VariateType, VariateTag>(absolute)>
0236 {
0237     typedef tag::absolute_weighted_tail_variate_means<LeftRight, VariateType, VariateTag> type;
0238 };
0239 
0240 // weighted_tail_variate_means<LeftRight, VariateType, VariateTag>(relative) -> relative_weighted_tail_variate_means<LeftRight, VariateType, VariateTag>
0241 template<typename LeftRight, typename VariateType, typename VariateTag>
0242 struct as_feature<tag::weighted_tail_variate_means<LeftRight, VariateType, VariateTag>(relative)>
0243 {
0244     typedef tag::relative_weighted_tail_variate_means<LeftRight, VariateType, VariateTag> type;
0245 };
0246 
0247 }} // namespace boost::accumulators
0248 
0249 #ifdef _MSC_VER
0250 # pragma warning(pop)
0251 #endif
0252 
0253 #endif