Back to home page

EIC code displayed by LXR

 
 

    


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

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // weighted_tail_quantile.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_QUANTILE_HPP_DE_01_01_2006
0009 #define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_TAIL_QUANTILE_HPP_DE_01_01_2006
0010 
0011 #include <vector>
0012 #include <limits>
0013 #include <functional>
0014 #include <sstream>
0015 #include <stdexcept>
0016 #include <boost/throw_exception.hpp>
0017 #include <boost/parameter/keyword.hpp>
0018 #include <boost/mpl/placeholders.hpp>
0019 #include <boost/mpl/if.hpp>
0020 #include <boost/type_traits/is_same.hpp>
0021 #include <boost/accumulators/numeric/functional.hpp>
0022 #include <boost/accumulators/framework/depends_on.hpp>
0023 #include <boost/accumulators/framework/accumulator_base.hpp>
0024 #include <boost/accumulators/framework/extractor.hpp>
0025 #include <boost/accumulators/framework/parameters/sample.hpp>
0026 #include <boost/accumulators/statistics_fwd.hpp>
0027 #include <boost/accumulators/statistics/tail.hpp>
0028 #include <boost/accumulators/statistics/tail_quantile.hpp>
0029 #include <boost/accumulators/statistics/parameters/quantile_probability.hpp>
0030 
0031 #ifdef _MSC_VER
0032 # pragma warning(push)
0033 # pragma warning(disable: 4127) // conditional expression is constant
0034 #endif
0035 
0036 namespace boost { namespace accumulators
0037 {
0038 
0039 namespace impl
0040 {
0041     ///////////////////////////////////////////////////////////////////////////////
0042     // weighted_tail_quantile_impl
0043     //  Tail quantile estimation based on order statistics of weighted samples
0044     /**
0045         @brief Tail quantile estimation based on order statistics of weighted samples (for both left and right tails)
0046 
0047         An estimator \f$\hat{q}\f$ of tail quantiles with level \f$\alpha\f$ based on order statistics
0048         \f$X_{1:n} \leq X_{2:n} \leq\dots\leq X_{n:n}\f$ of weighted samples are given by \f$X_{\lambda:n}\f$ (left tail)
0049         and \f$X_{\rho:n}\f$ (right tail), where
0050 
0051             \f[
0052                 \lambda = \inf\left\{ l \left| \frac{1}{\bar{w}_n}\sum_{i=1}^{l} w_i \geq \alpha \right. \right\}
0053             \f]
0054 
0055         and
0056 
0057             \f[
0058                 \rho = \sup\left\{ r \left| \frac{1}{\bar{w}_n}\sum_{i=r}^{n} w_i \geq (1 - \alpha) \right. \right\},
0059             \f]
0060 
0061         \f$n\f$ being the number of samples and \f$\bar{w}_n\f$ the sum of all weights.
0062 
0063         @param quantile_probability
0064     */
0065     template<typename Sample, typename Weight, typename LeftRight>
0066     struct weighted_tail_quantile_impl
0067       : accumulator_base
0068     {
0069         typedef typename numeric::functional::fdiv<Weight, std::size_t>::result_type float_type;
0070         // for boost::result_of
0071         typedef Sample result_type;
0072 
0073         weighted_tail_quantile_impl(dont_care) {}
0074 
0075         template<typename Args>
0076         result_type result(Args const &args) const
0077         {
0078             float_type threshold = sum_of_weights(args)
0079                              * ( ( is_same<LeftRight, left>::value ) ? args[quantile_probability] : 1. - args[quantile_probability] );
0080 
0081             std::size_t n = 0;
0082             Weight sum = Weight(0);
0083 
0084             while (sum < threshold)
0085             {
0086                 if (n < static_cast<std::size_t>(tail_weights(args).size()))
0087                 {
0088                     sum += *(tail_weights(args).begin() + n);
0089                     n++;
0090                 }
0091                 else
0092                 {
0093                     if (std::numeric_limits<result_type>::has_quiet_NaN)
0094                     {
0095                         return std::numeric_limits<result_type>::quiet_NaN();
0096                     }
0097                     else
0098                     {
0099                         std::ostringstream msg;
0100                         msg << "index n = " << n << " is not in valid range [0, " << tail(args).size() << ")";
0101                         boost::throw_exception(std::runtime_error(msg.str()));
0102                         return Sample(0);
0103                     }
0104                 }
0105             }
0106 
0107             // Note that the cached samples of the left are sorted in ascending order,
0108             // whereas the samples of the right tail are sorted in descending order
0109             return *(boost::begin(tail(args)) + n - 1);
0110         }
0111     };
0112 } // namespace impl
0113 
0114 ///////////////////////////////////////////////////////////////////////////////
0115 // tag::weighted_tail_quantile<>
0116 //
0117 namespace tag
0118 {
0119     template<typename LeftRight>
0120     struct weighted_tail_quantile
0121       : depends_on<sum_of_weights, tail_weights<LeftRight> >
0122     {
0123         /// INTERNAL ONLY
0124         typedef accumulators::impl::weighted_tail_quantile_impl<mpl::_1, mpl::_2, LeftRight> impl;
0125     };
0126 }
0127 
0128 ///////////////////////////////////////////////////////////////////////////////
0129 // extract::weighted_tail_quantile
0130 //
0131 namespace extract
0132 {
0133     extractor<tag::quantile> const weighted_tail_quantile = {};
0134 
0135     BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_tail_quantile)
0136 }
0137 
0138 using extract::weighted_tail_quantile;
0139 
0140 }} // namespace boost::accumulators
0141 
0142 #ifdef _MSC_VER
0143 # pragma warning(pop)
0144 #endif
0145 
0146 #endif