File indexing completed on 2025-01-18 09:28:22
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_TAIL_MEAN_HPP_DE_01_01_2006
0009 #define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_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/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_mean.hpp>
0028 #include <boost/accumulators/statistics/parameters/quantile_probability.hpp>
0029
0030 #ifdef _MSC_VER
0031 # pragma warning(push)
0032 # pragma warning(disable: 4127)
0033 #endif
0034
0035 namespace boost { namespace accumulators
0036 {
0037
0038 namespace impl
0039 {
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080 template<typename Sample, typename Weight, typename LeftRight>
0081 struct non_coherent_weighted_tail_mean_impl
0082 : accumulator_base
0083 {
0084 typedef typename numeric::functional::multiplies<Sample, Weight>::result_type weighted_sample;
0085 typedef typename numeric::functional::fdiv<Weight, std::size_t>::result_type float_type;
0086
0087 typedef typename numeric::functional::fdiv<weighted_sample, std::size_t>::result_type result_type;
0088
0089 non_coherent_weighted_tail_mean_impl(dont_care) {}
0090
0091 template<typename Args>
0092 result_type result(Args const &args) const
0093 {
0094 float_type threshold = sum_of_weights(args)
0095 * ( ( is_same<LeftRight, left>::value ) ? args[quantile_probability] : 1. - args[quantile_probability] );
0096
0097 std::size_t n = 0;
0098 Weight sum = Weight(0);
0099
0100 while (sum < threshold)
0101 {
0102 if (n < static_cast<std::size_t>(tail_weights(args).size()))
0103 {
0104 sum += *(tail_weights(args).begin() + n);
0105 n++;
0106 }
0107 else
0108 {
0109 if (std::numeric_limits<result_type>::has_quiet_NaN)
0110 {
0111 return std::numeric_limits<result_type>::quiet_NaN();
0112 }
0113 else
0114 {
0115 std::ostringstream msg;
0116 msg << "index n = " << n << " is not in valid range [0, " << tail(args).size() << ")";
0117 boost::throw_exception(std::runtime_error(msg.str()));
0118 return result_type(0);
0119 }
0120 }
0121 }
0122
0123 return numeric::fdiv(
0124 std::inner_product(
0125 tail(args).begin()
0126 , tail(args).begin() + n
0127 , tail_weights(args).begin()
0128 , weighted_sample(0)
0129 )
0130 , sum
0131 );
0132 }
0133 };
0134
0135 }
0136
0137
0138
0139
0140
0141 namespace tag
0142 {
0143 template<typename LeftRight>
0144 struct non_coherent_weighted_tail_mean
0145 : depends_on<sum_of_weights, tail_weights<LeftRight> >
0146 {
0147 typedef accumulators::impl::non_coherent_weighted_tail_mean_impl<mpl::_1, mpl::_2, LeftRight> impl;
0148 };
0149 }
0150
0151
0152
0153
0154 namespace extract
0155 {
0156 extractor<tag::abstract_non_coherent_tail_mean> const non_coherent_weighted_tail_mean = {};
0157
0158 BOOST_ACCUMULATORS_IGNORE_GLOBAL(non_coherent_weighted_tail_mean)
0159 }
0160
0161 using extract::non_coherent_weighted_tail_mean;
0162
0163 }}
0164
0165 #ifdef _MSC_VER
0166 # pragma warning(pop)
0167 #endif
0168
0169 #endif