File indexing completed on 2025-01-18 09:28:21
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_ACCUMULATORS_STATISTICS_TAIL_MEAN_HPP_DE_01_01_2006
0009 #define BOOST_ACCUMULATORS_STATISTICS_TAIL_MEAN_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/count.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)
0034 #endif
0035
0036 namespace boost { namespace accumulators
0037 {
0038
0039 namespace impl
0040 {
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061 template<typename Sample, typename LeftRight>
0062 struct coherent_tail_mean_impl
0063 : accumulator_base
0064 {
0065 typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type float_type;
0066
0067 typedef float_type result_type;
0068
0069 coherent_tail_mean_impl(dont_care) {}
0070
0071 template<typename Args>
0072 result_type result(Args const &args) const
0073 {
0074 std::size_t cnt = count(args);
0075
0076 std::size_t n = static_cast<std::size_t>(
0077 std::ceil(
0078 cnt * ( ( is_same<LeftRight, left>::value ) ? args[quantile_probability] : 1. - args[quantile_probability] )
0079 )
0080 );
0081
0082 extractor<tag::non_coherent_tail_mean<LeftRight> > const some_non_coherent_tail_mean = {};
0083
0084 return some_non_coherent_tail_mean(args)
0085 + numeric::fdiv(quantile(args), n)
0086 * (
0087 ( is_same<LeftRight, left>::value ) ? args[quantile_probability] : 1. - args[quantile_probability]
0088 - numeric::fdiv(n, count(args))
0089 );
0090 }
0091
0092
0093 template<class Archive>
0094 void serialize(Archive & ar, const unsigned int file_version) {}
0095 };
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120 template<typename Sample, typename LeftRight>
0121 struct non_coherent_tail_mean_impl
0122 : accumulator_base
0123 {
0124 typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type float_type;
0125
0126 typedef float_type result_type;
0127
0128 non_coherent_tail_mean_impl(dont_care) {}
0129
0130 template<typename Args>
0131 result_type result(Args const &args) const
0132 {
0133 std::size_t cnt = count(args);
0134
0135 std::size_t n = static_cast<std::size_t>(
0136 std::ceil(
0137 cnt * ( ( is_same<LeftRight, left>::value ) ? args[quantile_probability] : 1. - args[quantile_probability] )
0138 )
0139 );
0140
0141
0142 if (n <= static_cast<std::size_t>(tail(args).size()))
0143 return numeric::fdiv(
0144 std::accumulate(
0145 tail(args).begin()
0146 , tail(args).begin() + n
0147 , Sample(0)
0148 )
0149 , n
0150 );
0151 else
0152 {
0153 if (std::numeric_limits<result_type>::has_quiet_NaN)
0154 {
0155 return std::numeric_limits<result_type>::quiet_NaN();
0156 }
0157 else
0158 {
0159 std::ostringstream msg;
0160 msg << "index n = " << n << " is not in valid range [0, " << tail(args).size() << ")";
0161 boost::throw_exception(std::runtime_error(msg.str()));
0162 return Sample(0);
0163 }
0164 }
0165 }
0166
0167
0168 template<class Archive>
0169 void serialize(Archive & ar, const unsigned int file_version) {}
0170 };
0171
0172 }
0173
0174
0175
0176
0177
0178
0179 namespace tag
0180 {
0181 template<typename LeftRight>
0182 struct coherent_tail_mean
0183 : depends_on<count, quantile, non_coherent_tail_mean<LeftRight> >
0184 {
0185 typedef accumulators::impl::coherent_tail_mean_impl<mpl::_1, LeftRight> impl;
0186 };
0187
0188 template<typename LeftRight>
0189 struct non_coherent_tail_mean
0190 : depends_on<count, tail<LeftRight> >
0191 {
0192 typedef accumulators::impl::non_coherent_tail_mean_impl<mpl::_1, LeftRight> impl;
0193 };
0194
0195 struct abstract_non_coherent_tail_mean
0196 : depends_on<>
0197 {
0198 };
0199 }
0200
0201
0202
0203
0204
0205 namespace extract
0206 {
0207 extractor<tag::abstract_non_coherent_tail_mean> const non_coherent_tail_mean = {};
0208 extractor<tag::tail_mean> const coherent_tail_mean = {};
0209
0210 BOOST_ACCUMULATORS_IGNORE_GLOBAL(non_coherent_tail_mean)
0211 BOOST_ACCUMULATORS_IGNORE_GLOBAL(coherent_tail_mean)
0212 }
0213
0214 using extract::non_coherent_tail_mean;
0215 using extract::coherent_tail_mean;
0216
0217
0218
0219 template<typename LeftRight>
0220 struct feature_of<tag::coherent_tail_mean<LeftRight> >
0221 : feature_of<tag::tail_mean>
0222 {
0223 };
0224
0225 template<typename LeftRight>
0226 struct feature_of<tag::non_coherent_tail_mean<LeftRight> >
0227 : feature_of<tag::abstract_non_coherent_tail_mean>
0228 {
0229 };
0230
0231
0232
0233 template<typename LeftRight>
0234 struct as_weighted_feature<tag::non_coherent_tail_mean<LeftRight> >
0235 {
0236 typedef tag::non_coherent_weighted_tail_mean<LeftRight> type;
0237 };
0238
0239 template<typename LeftRight>
0240 struct feature_of<tag::non_coherent_weighted_tail_mean<LeftRight> >
0241 : feature_of<tag::non_coherent_tail_mean<LeftRight> >
0242 {};
0243
0244
0245
0246
0247
0248 }}
0249
0250 #ifdef _MSC_VER
0251 # pragma warning(pop)
0252 #endif
0253
0254 #endif