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