1 /////////////////////////////////////////////////////////////////////////////// 2 // pot_tail_mean.hpp 3 // 4 // Copyright 2006 Daniel Egloff, Olivier Gygi. Distributed under the Boost 5 // Software License, Version 1.0. (See accompanying file 6 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 8 #ifndef BOOST_ACCUMULATORS_STATISTICS_POT_TAIL_MEAN_HPP_DE_01_01_2006 9 #define BOOST_ACCUMULATORS_STATISTICS_POT_TAIL_MEAN_HPP_DE_01_01_2006 10 11 #include <vector> 12 #include <limits> 13 #include <numeric> 14 #include <functional> 15 #include <boost/range.hpp> 16 #include <boost/parameter/keyword.hpp> 17 #include <boost/tuple/tuple.hpp> 18 #include <boost/mpl/if.hpp> 19 #include <boost/mpl/placeholders.hpp> 20 #include <boost/type_traits/is_same.hpp> 21 #include <boost/accumulators/framework/accumulator_base.hpp> 22 #include <boost/accumulators/framework/extractor.hpp> 23 #include <boost/accumulators/numeric/functional.hpp> 24 #include <boost/accumulators/framework/parameters/sample.hpp> 25 #include <boost/accumulators/statistics_fwd.hpp> 26 #include <boost/accumulators/statistics/peaks_over_threshold.hpp> 27 #include <boost/accumulators/statistics/weighted_peaks_over_threshold.hpp> 28 #include <boost/accumulators/statistics/pot_quantile.hpp> 29 #include <boost/accumulators/statistics/tail_mean.hpp> 30 31 namespace boost { namespace accumulators 32 { 33 34 namespace impl 35 { 36 /////////////////////////////////////////////////////////////////////////////// 37 // pot_tail_mean_impl 38 // 39 /** 40 @brief Estimation of the (coherent) tail mean based on the peaks over threshold method (for both left and right tails) 41 42 Computes an estimate for the (coherent) tail mean 43 \f[ 44 \widehat{CTM}_{\alpha} = \hat{q}_{\alpha} - \frac{\bar{\beta}}{\xi-1}(1-\alpha)^{-\xi}, 45 \f] 46 where \f$\bar[u]\f$, \f$\bar{\beta}\f$ and \f$\xi\f$ are the parameters of the 47 generalized Pareto distribution that approximates the right tail of the distribution (or the 48 mirrored left tail, in case the left tail is used). In the latter case, the result is mirrored 49 back, yielding the correct result. 50 */ 51 template<typename Sample, typename Impl, typename LeftRight> 52 struct pot_tail_mean_impl 53 : accumulator_base 54 { 55 typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type float_type; 56 // for boost::result_of 57 typedef float_type result_type; 58 pot_tail_mean_implboost::accumulators::impl::pot_tail_mean_impl59 pot_tail_mean_impl(dont_care) 60 : sign_((is_same<LeftRight, left>::value) ? -1 : 1) 61 { 62 } 63 64 template<typename Args> resultboost::accumulators::impl::pot_tail_mean_impl65 result_type result(Args const &args) const 66 { 67 typedef 68 typename mpl::if_< 69 is_same<Impl, weighted> 70 , tag::weighted_peaks_over_threshold<LeftRight> 71 , tag::peaks_over_threshold<LeftRight> 72 >::type 73 peaks_over_threshold_tag; 74 75 typedef 76 typename mpl::if_< 77 is_same<Impl, weighted> 78 , tag::weighted_pot_quantile<LeftRight> 79 , tag::pot_quantile<LeftRight> 80 >::type 81 pot_quantile_tag; 82 83 extractor<peaks_over_threshold_tag> const some_peaks_over_threshold = {}; 84 extractor<pot_quantile_tag> const some_pot_quantile = {}; 85 86 float_type beta_bar = some_peaks_over_threshold(args).template get<1>(); 87 float_type xi_hat = some_peaks_over_threshold(args).template get<2>(); 88 89 return some_pot_quantile(args) - this->sign_ * beta_bar/( xi_hat - 1. ) * std::pow( 90 is_same<LeftRight, left>::value ? args[quantile_probability] : 1. - args[quantile_probability] 91 , -xi_hat); 92 } 93 94 // make this accumulator serializeable 95 template<class Archive> serializeboost::accumulators::impl::pot_tail_mean_impl96 void serialize(Archive & ar, const unsigned int file_version) 97 { 98 ar & sign_; 99 } 100 101 private: 102 short sign_; // if the fit parameters from the mirrored left tail extreme values are used, mirror back the result 103 }; 104 } // namespace impl 105 106 /////////////////////////////////////////////////////////////////////////////// 107 // tag::pot_tail_mean 108 // tag::pot_tail_mean_prob 109 // 110 namespace tag 111 { 112 template<typename LeftRight> 113 struct pot_tail_mean 114 : depends_on<peaks_over_threshold<LeftRight>, pot_quantile<LeftRight> > 115 { 116 /// INTERNAL ONLY 117 /// 118 typedef accumulators::impl::pot_tail_mean_impl<mpl::_1, unweighted, LeftRight> impl; 119 }; 120 template<typename LeftRight> 121 struct pot_tail_mean_prob 122 : depends_on<peaks_over_threshold_prob<LeftRight>, pot_quantile_prob<LeftRight> > 123 { 124 /// INTERNAL ONLY 125 /// 126 typedef accumulators::impl::pot_tail_mean_impl<mpl::_1, unweighted, LeftRight> impl; 127 }; 128 template<typename LeftRight> 129 struct weighted_pot_tail_mean 130 : depends_on<weighted_peaks_over_threshold<LeftRight>, weighted_pot_quantile<LeftRight> > 131 { 132 /// INTERNAL ONLY 133 /// 134 typedef accumulators::impl::pot_tail_mean_impl<mpl::_1, weighted, LeftRight> impl; 135 }; 136 template<typename LeftRight> 137 struct weighted_pot_tail_mean_prob 138 : depends_on<weighted_peaks_over_threshold_prob<LeftRight>, weighted_pot_quantile_prob<LeftRight> > 139 { 140 /// INTERNAL ONLY 141 /// 142 typedef accumulators::impl::pot_tail_mean_impl<mpl::_1, weighted, LeftRight> impl; 143 }; 144 } 145 146 // pot_tail_mean<LeftRight>(with_threshold_value) -> pot_tail_mean<LeftRight> 147 template<typename LeftRight> 148 struct as_feature<tag::pot_tail_mean<LeftRight>(with_threshold_value)> 149 { 150 typedef tag::pot_tail_mean<LeftRight> type; 151 }; 152 153 // pot_tail_mean<LeftRight>(with_threshold_probability) -> pot_tail_mean_prob<LeftRight> 154 template<typename LeftRight> 155 struct as_feature<tag::pot_tail_mean<LeftRight>(with_threshold_probability)> 156 { 157 typedef tag::pot_tail_mean_prob<LeftRight> type; 158 }; 159 160 // weighted_pot_tail_mean<LeftRight>(with_threshold_value) -> weighted_pot_tail_mean<LeftRight> 161 template<typename LeftRight> 162 struct as_feature<tag::weighted_pot_tail_mean<LeftRight>(with_threshold_value)> 163 { 164 typedef tag::weighted_pot_tail_mean<LeftRight> type; 165 }; 166 167 // weighted_pot_tail_mean<LeftRight>(with_threshold_probability) -> weighted_pot_tail_mean_prob<LeftRight> 168 template<typename LeftRight> 169 struct as_feature<tag::weighted_pot_tail_mean<LeftRight>(with_threshold_probability)> 170 { 171 typedef tag::weighted_pot_tail_mean_prob<LeftRight> type; 172 }; 173 174 // for the purposes of feature-based dependency resolution, 175 // pot_tail_mean<LeftRight> and pot_tail_mean_prob<LeftRight> provide 176 // the same feature as tail_mean 177 template<typename LeftRight> 178 struct feature_of<tag::pot_tail_mean<LeftRight> > 179 : feature_of<tag::tail_mean> 180 { 181 }; 182 183 template<typename LeftRight> 184 struct feature_of<tag::pot_tail_mean_prob<LeftRight> > 185 : feature_of<tag::tail_mean> 186 { 187 }; 188 189 // So that pot_tail_mean can be automatically substituted 190 // with weighted_pot_tail_mean when the weight parameter is non-void. 191 template<typename LeftRight> 192 struct as_weighted_feature<tag::pot_tail_mean<LeftRight> > 193 { 194 typedef tag::weighted_pot_tail_mean<LeftRight> type; 195 }; 196 197 template<typename LeftRight> 198 struct feature_of<tag::weighted_pot_tail_mean<LeftRight> > 199 : feature_of<tag::pot_tail_mean<LeftRight> > 200 { 201 }; 202 203 // So that pot_tail_mean_prob can be automatically substituted 204 // with weighted_pot_tail_mean_prob when the weight parameter is non-void. 205 template<typename LeftRight> 206 struct as_weighted_feature<tag::pot_tail_mean_prob<LeftRight> > 207 { 208 typedef tag::weighted_pot_tail_mean_prob<LeftRight> type; 209 }; 210 211 template<typename LeftRight> 212 struct feature_of<tag::weighted_pot_tail_mean_prob<LeftRight> > 213 : feature_of<tag::pot_tail_mean_prob<LeftRight> > 214 { 215 }; 216 217 }} // namespace boost::accumulators 218 219 #endif 220