File indexing completed on 2025-01-18 09:28:22
0001
0002
0003
0004
0005
0006
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)
0035 #endif
0036
0037 namespace boost
0038 {
0039
0040
0041 namespace numeric { namespace functional
0042 {
0043
0044
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
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
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
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
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 }
0196
0197
0198
0199
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
0219
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
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
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 }}
0248
0249 #ifdef _MSC_VER
0250 # pragma warning(pop)
0251 #endif
0252
0253 #endif