Back to home page

EIC code displayed by LXR

 
 

    


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

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // 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_TAIL_VARIATE_MEANS_HPP_DE_01_01_2006
0009 #define BOOST_ACCUMULATORS_STATISTICS_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/framework/accumulator_base.hpp>
0022 #include <boost/accumulators/framework/extractor.hpp>
0023 #include <boost/accumulators/numeric/functional.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_mean.hpp>
0029 #include <boost/accumulators/statistics/parameters/quantile_probability.hpp>
0030 #include <boost/serialization/vector.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 { namespace accumulators
0038 {
0039 
0040 namespace impl
0041 {
0042     /**
0043         @brief Estimation of the absolute and relative tail variate means (for both left and right tails)
0044 
0045         For all \f$j\f$-th variates associated to the \f$\lceil n(1-\alpha)\rceil\f$ largest samples (or the
0046         \f$\lceil n(1-\alpha)\rceil\f$ smallest samples in case of the left tail), the absolute tail means
0047         \f$\widehat{ATM}_{n,\alpha}(X, j)\f$ are computed and returned as an iterator range. Alternatively,
0048         the relative tail means \f$\widehat{RTM}_{n,\alpha}(X, j)\f$ are returned, which are the absolute
0049         tail means normalized with the (non-coherent) sample tail mean \f$\widehat{NCTM}_{n,\alpha}(X)\f$.
0050 
0051         \f[
0052             \widehat{ATM}_{n,\alpha}^{\mathrm{right}}(X, j) =
0053                 \frac{1}{\lceil n(1-\alpha) \rceil}
0054                 \sum_{i=\lceil \alpha n \rceil}^n \xi_{j,i}
0055         \f]
0056 
0057         \f[
0058             \widehat{ATM}_{n,\alpha}^{\mathrm{left}}(X, j) =
0059                 \frac{1}{\lceil n\alpha \rceil}
0060                 \sum_{i=1}^{\lceil n\alpha \rceil} \xi_{j,i}
0061         \f]
0062 
0063         \f[
0064             \widehat{RTM}_{n,\alpha}^{\mathrm{right}}(X, j) =
0065                 \frac{\sum_{i=\lceil n\alpha \rceil}^n \xi_{j,i}}
0066             {\lceil n(1-\alpha)\rceil\widehat{NCTM}_{n,\alpha}^{\mathrm{right}}(X)}
0067         \f]
0068 
0069         \f[
0070             \widehat{RTM}_{n,\alpha}^{\mathrm{left}}(X, j) =
0071                 \frac{\sum_{i=1}^{\lceil n\alpha \rceil} \xi_{j,i}}
0072             {\lceil n\alpha\rceil\widehat{NCTM}_{n,\alpha}^{\mathrm{left}}(X)}
0073         \f]
0074     */
0075 
0076     ///////////////////////////////////////////////////////////////////////////////
0077     // tail_variate_means_impl
0078     //  by default: absolute tail_variate_means
0079     template<typename Sample, typename Impl, typename LeftRight, typename VariateTag>
0080     struct tail_variate_means_impl
0081       : accumulator_base
0082     {
0083         typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type float_type;
0084         typedef std::vector<float_type> array_type;
0085         // for boost::result_of
0086         typedef iterator_range<typename array_type::iterator> result_type;
0087 
0088         tail_variate_means_impl(dont_care) {}
0089 
0090         template<typename Args>
0091         result_type result(Args const &args) const
0092         {
0093             std::size_t cnt = count(args);
0094 
0095             std::size_t n = static_cast<std::size_t>(
0096                 std::ceil(
0097                     cnt * ( ( is_same<LeftRight, left>::value ) ? args[quantile_probability] : 1. - args[quantile_probability] )
0098                 )
0099             );
0100 
0101             std::size_t num_variates = tail_variate(args).begin()->size();
0102 
0103             this->tail_means_.clear();
0104             this->tail_means_.resize(num_variates, Sample(0));
0105 
0106             // If n is in a valid range, return result, otherwise return NaN or throw exception
0107             if (n < static_cast<std::size_t>(tail(args).size()))
0108             {
0109                 this->tail_means_ = std::accumulate(
0110                     tail_variate(args).begin()
0111                   , tail_variate(args).begin() + n
0112                   , this->tail_means_
0113                   , numeric::plus
0114                 );
0115 
0116                 float_type factor = n * ( (is_same<Impl, relative>::value) ? non_coherent_tail_mean(args) : 1. );
0117 
0118                 std::transform(
0119                     this->tail_means_.begin()
0120                   , this->tail_means_.end()
0121                   , this->tail_means_.begin()
0122 #ifdef BOOST_NO_CXX98_BINDERS
0123                   , std::bind(std::divides<float_type>(), std::placeholders::_1, factor)
0124 #else
0125                   , std::bind2nd(std::divides<float_type>(), factor)
0126 #endif
0127                 );
0128             }
0129             else
0130             {
0131                 if (std::numeric_limits<float_type>::has_quiet_NaN)
0132                 {
0133                     std::fill(
0134                         this->tail_means_.begin()
0135                       , this->tail_means_.end()
0136                       , std::numeric_limits<float_type>::quiet_NaN()
0137                     );
0138                 }
0139                 else
0140                 {
0141                     std::ostringstream msg;
0142                     msg << "index n = " << n << " is not in valid range [0, " << tail(args).size() << ")";
0143                     boost::throw_exception(std::runtime_error(msg.str()));
0144                 }
0145             }
0146             return make_iterator_range(this->tail_means_);
0147         }
0148 
0149         // make this accumulator serializeable
0150         template<class Archive>
0151         void serialize(Archive & ar, const unsigned int file_version)
0152         { 
0153             ar & tail_means_;
0154         }
0155 
0156     private:
0157 
0158         mutable array_type tail_means_;
0159 
0160     };
0161 
0162 } // namespace impl
0163 
0164 ///////////////////////////////////////////////////////////////////////////////
0165 // tag::absolute_tail_variate_means
0166 // tag::relative_tail_variate_means
0167 //
0168 namespace tag
0169 {
0170     template<typename LeftRight, typename VariateType, typename VariateTag>
0171     struct absolute_tail_variate_means
0172       : depends_on<count, non_coherent_tail_mean<LeftRight>, tail_variate<VariateType, VariateTag, LeftRight> >
0173     {
0174         typedef accumulators::impl::tail_variate_means_impl<mpl::_1, absolute, LeftRight, VariateTag> impl;
0175     };
0176     template<typename LeftRight, typename VariateType, typename VariateTag>
0177     struct relative_tail_variate_means
0178       : depends_on<count, non_coherent_tail_mean<LeftRight>, tail_variate<VariateType, VariateTag, LeftRight> >
0179     {
0180         typedef accumulators::impl::tail_variate_means_impl<mpl::_1, relative, LeftRight, VariateTag> impl;
0181     };
0182     struct abstract_absolute_tail_variate_means
0183       : depends_on<>
0184     {
0185     };
0186     struct abstract_relative_tail_variate_means
0187       : depends_on<>
0188     {
0189     };
0190 }
0191 
0192 ///////////////////////////////////////////////////////////////////////////////
0193 // extract::tail_variate_means
0194 // extract::relative_tail_variate_means
0195 //
0196 namespace extract
0197 {
0198     extractor<tag::abstract_absolute_tail_variate_means> const tail_variate_means = {};
0199     extractor<tag::abstract_relative_tail_variate_means> const relative_tail_variate_means = {};
0200 
0201     BOOST_ACCUMULATORS_IGNORE_GLOBAL(tail_variate_means)
0202     BOOST_ACCUMULATORS_IGNORE_GLOBAL(relative_tail_variate_means)
0203 }
0204 
0205 using extract::tail_variate_means;
0206 using extract::relative_tail_variate_means;
0207 
0208 // tail_variate_means<LeftRight, VariateType, VariateTag>(absolute) -> absolute_tail_variate_means<LeftRight, VariateType, VariateTag>
0209 template<typename LeftRight, typename VariateType, typename VariateTag>
0210 struct as_feature<tag::tail_variate_means<LeftRight, VariateType, VariateTag>(absolute)>
0211 {
0212     typedef tag::absolute_tail_variate_means<LeftRight, VariateType, VariateTag> type;
0213 };
0214 
0215 // tail_variate_means<LeftRight, VariateType, VariateTag>(relative) ->relative_tail_variate_means<LeftRight, VariateType, VariateTag>
0216 template<typename LeftRight, typename VariateType, typename VariateTag>
0217 struct as_feature<tag::tail_variate_means<LeftRight, VariateType, VariateTag>(relative)>
0218 {
0219     typedef tag::relative_tail_variate_means<LeftRight, VariateType, VariateTag> type;
0220 };
0221 
0222 // Provides non-templatized extractor
0223 template<typename LeftRight, typename VariateType, typename VariateTag>
0224 struct feature_of<tag::absolute_tail_variate_means<LeftRight, VariateType, VariateTag> >
0225   : feature_of<tag::abstract_absolute_tail_variate_means>
0226 {
0227 };
0228 
0229 // Provides non-templatized extractor
0230 template<typename LeftRight, typename VariateType, typename VariateTag>
0231 struct feature_of<tag::relative_tail_variate_means<LeftRight, VariateType, VariateTag> >
0232   : feature_of<tag::abstract_relative_tail_variate_means>
0233 {
0234 };
0235 
0236 // So that absolute_tail_means can be automatically substituted
0237 // with absolute_weighted_tail_means when the weight parameter is non-void.
0238 template<typename LeftRight, typename VariateType, typename VariateTag>
0239 struct as_weighted_feature<tag::absolute_tail_variate_means<LeftRight, VariateType, VariateTag> >
0240 {
0241     typedef tag::absolute_weighted_tail_variate_means<LeftRight, VariateType, VariateTag> type;
0242 };
0243 
0244 template<typename LeftRight, typename VariateType, typename VariateTag>
0245 struct feature_of<tag::absolute_weighted_tail_variate_means<LeftRight, VariateType, VariateTag> >
0246   : feature_of<tag::absolute_tail_variate_means<LeftRight, VariateType, VariateTag> >
0247 {
0248 };
0249 
0250 // So that relative_tail_means can be automatically substituted
0251 // with relative_weighted_tail_means when the weight parameter is non-void.
0252 template<typename LeftRight, typename VariateType, typename VariateTag>
0253 struct as_weighted_feature<tag::relative_tail_variate_means<LeftRight, VariateType, VariateTag> >
0254 {
0255     typedef tag::relative_weighted_tail_variate_means<LeftRight, VariateType, VariateTag> type;
0256 };
0257 
0258 template<typename LeftRight, typename VariateType, typename VariateTag>
0259 struct feature_of<tag::relative_weighted_tail_variate_means<LeftRight, VariateType, VariateTag> >
0260   : feature_of<tag::relative_tail_variate_means<LeftRight, VariateType, VariateTag> >
0261 {
0262 };
0263 
0264 }} // namespace boost::accumulators
0265 
0266 #ifdef _MSC_VER
0267 # pragma warning(pop)
0268 #endif
0269 
0270 #endif