Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // tail_variate_means.hpp Chris@16: // Chris@16: // Copyright 2006 Daniel Egloff, Olivier Gygi. Distributed under the Boost Chris@16: // Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_ACCUMULATORS_STATISTICS_TAIL_VARIATE_MEANS_HPP_DE_01_01_2006 Chris@16: #define BOOST_ACCUMULATORS_STATISTICS_TAIL_VARIATE_MEANS_HPP_DE_01_01_2006 Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #ifdef _MSC_VER Chris@16: # pragma warning(push) Chris@16: # pragma warning(disable: 4127) // conditional expression is constant Chris@16: #endif Chris@16: Chris@16: namespace boost { namespace accumulators Chris@16: { Chris@16: Chris@16: namespace impl Chris@16: { Chris@16: /** Chris@16: @brief Estimation of the absolute and relative tail variate means (for both left and right tails) Chris@16: Chris@16: For all \f$j\f$-th variates associated to the \f$\lceil n(1-\alpha)\rceil\f$ largest samples (or the Chris@16: \f$\lceil n(1-\alpha)\rceil\f$ smallest samples in case of the left tail), the absolute tail means Chris@16: \f$\widehat{ATM}_{n,\alpha}(X, j)\f$ are computed and returned as an iterator range. Alternatively, Chris@16: the relative tail means \f$\widehat{RTM}_{n,\alpha}(X, j)\f$ are returned, which are the absolute Chris@16: tail means normalized with the (non-coherent) sample tail mean \f$\widehat{NCTM}_{n,\alpha}(X)\f$. Chris@16: Chris@16: \f[ Chris@16: \widehat{ATM}_{n,\alpha}^{\mathrm{right}}(X, j) = Chris@16: \frac{1}{\lceil n(1-\alpha) \rceil} Chris@16: \sum_{i=\lceil \alpha n \rceil}^n \xi_{j,i} Chris@16: \f] Chris@16: Chris@16: \f[ Chris@16: \widehat{ATM}_{n,\alpha}^{\mathrm{left}}(X, j) = Chris@16: \frac{1}{\lceil n\alpha \rceil} Chris@16: \sum_{i=1}^{\lceil n\alpha \rceil} \xi_{j,i} Chris@16: \f] Chris@16: Chris@16: \f[ Chris@16: \widehat{RTM}_{n,\alpha}^{\mathrm{right}}(X, j) = Chris@16: \frac{\sum_{i=\lceil n\alpha \rceil}^n \xi_{j,i}} Chris@16: {\lceil n(1-\alpha)\rceil\widehat{NCTM}_{n,\alpha}^{\mathrm{right}}(X)} Chris@16: \f] Chris@16: Chris@16: \f[ Chris@16: \widehat{RTM}_{n,\alpha}^{\mathrm{left}}(X, j) = Chris@16: \frac{\sum_{i=1}^{\lceil n\alpha \rceil} \xi_{j,i}} Chris@16: {\lceil n\alpha\rceil\widehat{NCTM}_{n,\alpha}^{\mathrm{left}}(X)} Chris@16: \f] Chris@16: */ Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // tail_variate_means_impl Chris@16: // by default: absolute tail_variate_means Chris@16: template Chris@16: struct tail_variate_means_impl Chris@16: : accumulator_base Chris@16: { Chris@16: typedef typename numeric::functional::fdiv::result_type float_type; Chris@16: typedef std::vector array_type; Chris@16: // for boost::result_of Chris@16: typedef iterator_range result_type; Chris@16: Chris@16: tail_variate_means_impl(dont_care) {} Chris@16: Chris@16: template Chris@16: result_type result(Args const &args) const Chris@16: { Chris@16: std::size_t cnt = count(args); Chris@16: Chris@16: std::size_t n = static_cast( Chris@16: std::ceil( Chris@16: cnt * ( ( is_same::value ) ? args[quantile_probability] : 1. - args[quantile_probability] ) Chris@16: ) Chris@16: ); Chris@16: Chris@16: std::size_t num_variates = tail_variate(args).begin()->size(); Chris@16: Chris@16: this->tail_means_.clear(); Chris@16: this->tail_means_.resize(num_variates, Sample(0)); Chris@16: Chris@16: // If n is in a valid range, return result, otherwise return NaN or throw exception Chris@16: if (n < static_cast(tail(args).size())) Chris@16: { Chris@16: this->tail_means_ = std::accumulate( Chris@16: tail_variate(args).begin() Chris@16: , tail_variate(args).begin() + n Chris@16: , this->tail_means_ Chris@16: , numeric::plus Chris@16: ); Chris@16: Chris@16: float_type factor = n * ( (is_same::value) ? non_coherent_tail_mean(args) : 1. ); Chris@16: Chris@16: std::transform( Chris@16: this->tail_means_.begin() Chris@16: , this->tail_means_.end() Chris@16: , this->tail_means_.begin() Chris@16: , std::bind2nd(std::divides(), factor) Chris@16: ); Chris@16: } Chris@16: else Chris@16: { Chris@16: if (std::numeric_limits::has_quiet_NaN) Chris@16: { Chris@16: std::fill( Chris@16: this->tail_means_.begin() Chris@16: , this->tail_means_.end() Chris@16: , std::numeric_limits::quiet_NaN() Chris@16: ); Chris@16: } Chris@16: else Chris@16: { Chris@16: std::ostringstream msg; Chris@16: msg << "index n = " << n << " is not in valid range [0, " << tail(args).size() << ")"; Chris@16: boost::throw_exception(std::runtime_error(msg.str())); Chris@16: } Chris@16: } Chris@16: return make_iterator_range(this->tail_means_); Chris@16: } Chris@16: Chris@16: private: Chris@16: Chris@16: mutable array_type tail_means_; Chris@16: Chris@16: }; Chris@16: Chris@16: } // namespace impl Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // tag::absolute_tail_variate_means Chris@16: // tag::relative_tail_variate_means Chris@16: // Chris@16: namespace tag Chris@16: { Chris@16: template Chris@16: struct absolute_tail_variate_means Chris@16: : depends_on, tail_variate > Chris@16: { Chris@16: typedef accumulators::impl::tail_variate_means_impl impl; Chris@16: }; Chris@16: template Chris@16: struct relative_tail_variate_means Chris@16: : depends_on, tail_variate > Chris@16: { Chris@16: typedef accumulators::impl::tail_variate_means_impl impl; Chris@16: }; Chris@16: struct abstract_absolute_tail_variate_means Chris@16: : depends_on<> Chris@16: { Chris@16: }; Chris@16: struct abstract_relative_tail_variate_means Chris@16: : depends_on<> Chris@16: { Chris@16: }; Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // extract::tail_variate_means Chris@16: // extract::relative_tail_variate_means Chris@16: // Chris@16: namespace extract Chris@16: { Chris@16: extractor const tail_variate_means = {}; Chris@16: extractor const relative_tail_variate_means = {}; Chris@16: Chris@16: BOOST_ACCUMULATORS_IGNORE_GLOBAL(tail_variate_means) Chris@16: BOOST_ACCUMULATORS_IGNORE_GLOBAL(relative_tail_variate_means) Chris@16: } Chris@16: Chris@16: using extract::tail_variate_means; Chris@16: using extract::relative_tail_variate_means; Chris@16: Chris@16: // tail_variate_means(absolute) -> absolute_tail_variate_means Chris@16: template Chris@16: struct as_feature(absolute)> Chris@16: { Chris@16: typedef tag::absolute_tail_variate_means type; Chris@16: }; Chris@16: Chris@16: // tail_variate_means(relative) ->relative_tail_variate_means Chris@16: template Chris@16: struct as_feature(relative)> Chris@16: { Chris@16: typedef tag::relative_tail_variate_means type; Chris@16: }; Chris@16: Chris@16: // Provides non-templatized extractor Chris@16: template Chris@16: struct feature_of > Chris@16: : feature_of Chris@16: { Chris@16: }; Chris@16: Chris@16: // Provides non-templatized extractor Chris@16: template Chris@16: struct feature_of > Chris@16: : feature_of Chris@16: { Chris@16: }; Chris@16: Chris@16: // So that absolute_tail_means can be automatically substituted Chris@16: // with absolute_weighted_tail_means when the weight parameter is non-void. Chris@16: template Chris@16: struct as_weighted_feature > Chris@16: { Chris@16: typedef tag::absolute_weighted_tail_variate_means type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct feature_of > Chris@16: : feature_of > Chris@16: { Chris@16: }; Chris@16: Chris@16: // So that relative_tail_means can be automatically substituted Chris@16: // with relative_weighted_tail_means when the weight parameter is non-void. Chris@16: template Chris@16: struct as_weighted_feature > Chris@16: { Chris@16: typedef tag::relative_weighted_tail_variate_means type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct feature_of > Chris@16: : feature_of > Chris@16: { Chris@16: }; Chris@16: Chris@16: }} // namespace boost::accumulators Chris@16: Chris@16: #ifdef _MSC_VER Chris@16: # pragma warning(pop) Chris@16: #endif Chris@16: Chris@16: #endif