File indexing completed on 2025-01-18 09:28:20
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_ACCUMULATORS_STATISTICS_PEAKS_OVER_THRESHOLD_HPP_DE_01_01_2006
0009 #define BOOST_ACCUMULATORS_STATISTICS_PEAKS_OVER_THRESHOLD_HPP_DE_01_01_2006
0010
0011 #include <vector>
0012 #include <limits>
0013 #include <numeric>
0014 #include <functional>
0015 #include <boost/config/no_tr1/cmath.hpp> // pow
0016 #include <sstream> // stringstream
0017 #include <stdexcept> // runtime_error
0018 #include <boost/throw_exception.hpp>
0019 #include <boost/range.hpp>
0020 #include <boost/mpl/if.hpp>
0021 #include <boost/mpl/int.hpp>
0022 #include <boost/mpl/placeholders.hpp>
0023 #include <boost/parameter/keyword.hpp>
0024 #include <boost/tuple/tuple.hpp>
0025 #include <boost/accumulators/accumulators_fwd.hpp>
0026 #include <boost/accumulators/framework/accumulator_base.hpp>
0027 #include <boost/accumulators/framework/extractor.hpp>
0028 #include <boost/accumulators/numeric/functional.hpp>
0029 #include <boost/accumulators/framework/parameters/sample.hpp>
0030 #include <boost/accumulators/framework/depends_on.hpp>
0031 #include <boost/accumulators/statistics_fwd.hpp>
0032 #include <boost/accumulators/statistics/parameters/quantile_probability.hpp>
0033 #include <boost/accumulators/statistics/count.hpp>
0034 #include <boost/accumulators/statistics/tail.hpp>
0035
0036 #ifdef _MSC_VER
0037 # pragma warning(push)
0038 # pragma warning(disable: 4127)
0039 #endif
0040
0041 namespace boost { namespace accumulators
0042 {
0043
0044
0045
0046
0047 BOOST_PARAMETER_NESTED_KEYWORD(tag, pot_threshold_value, threshold_value)
0048 BOOST_PARAMETER_NESTED_KEYWORD(tag, pot_threshold_probability, threshold_probability)
0049
0050 BOOST_ACCUMULATORS_IGNORE_GLOBAL(pot_threshold_value)
0051 BOOST_ACCUMULATORS_IGNORE_GLOBAL(pot_threshold_probability)
0052
0053 namespace impl
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
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
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124 template<typename Sample, typename LeftRight>
0125 struct peaks_over_threshold_impl
0126 : accumulator_base
0127 {
0128 typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type float_type;
0129
0130 typedef boost::tuple<float_type, float_type, float_type> result_type;
0131
0132 typedef mpl::int_<is_same<LeftRight, left>::value ? -1 : 1> sign;
0133
0134 template<typename Args>
0135 peaks_over_threshold_impl(Args const &args)
0136 : Nu_(0)
0137 , mu_(sign::value * numeric::fdiv(args[sample | Sample()], (std::size_t)1))
0138 , sigma2_(numeric::fdiv(args[sample | Sample()], (std::size_t)1))
0139 , threshold_(sign::value * args[pot_threshold_value])
0140 , fit_parameters_(boost::make_tuple(0., 0., 0.))
0141 , is_dirty_(true)
0142 {
0143 }
0144
0145 template<typename Args>
0146 void operator ()(Args const &args)
0147 {
0148 this->is_dirty_ = true;
0149
0150 if (sign::value * args[sample] > this->threshold_)
0151 {
0152 this->mu_ += args[sample];
0153 this->sigma2_ += args[sample] * args[sample];
0154 ++this->Nu_;
0155 }
0156 }
0157
0158 template<typename Args>
0159 result_type result(Args const &args) const
0160 {
0161 if (this->is_dirty_)
0162 {
0163 this->is_dirty_ = false;
0164
0165 std::size_t cnt = count(args);
0166
0167 this->mu_ = sign::value * numeric::fdiv(this->mu_, this->Nu_);
0168 this->sigma2_ = numeric::fdiv(this->sigma2_, this->Nu_);
0169 this->sigma2_ -= this->mu_ * this->mu_;
0170
0171 float_type threshold_probability = numeric::fdiv(cnt - this->Nu_, cnt);
0172
0173 float_type tmp = numeric::fdiv(( this->mu_ - this->threshold_ )*( this->mu_ - this->threshold_ ), this->sigma2_);
0174 float_type xi_hat = 0.5 * ( 1. - tmp );
0175 float_type beta_hat = 0.5 * ( this->mu_ - this->threshold_ ) * ( 1. + tmp );
0176 float_type beta_bar = beta_hat * std::pow(1. - threshold_probability, xi_hat);
0177 float_type u_bar = this->threshold_ - beta_bar * ( std::pow(1. - threshold_probability, -xi_hat) - 1.)/xi_hat;
0178 this->fit_parameters_ = boost::make_tuple(u_bar, beta_bar, xi_hat);
0179 }
0180
0181 return this->fit_parameters_;
0182 }
0183
0184
0185
0186 template<class Archive>
0187 void serialize(Archive & ar, const unsigned int file_version)
0188 {
0189 ar & Nu_;
0190 ar & mu_;
0191 ar & sigma2_;
0192 ar & threshold_;
0193 ar & get<0>(fit_parameters_);
0194 ar & get<1>(fit_parameters_);
0195 ar & get<2>(fit_parameters_);
0196 ar & is_dirty_;
0197 }
0198
0199 private:
0200 std::size_t Nu_;
0201 mutable float_type mu_;
0202 mutable float_type sigma2_;
0203 float_type threshold_;
0204 mutable result_type fit_parameters_;
0205 mutable bool is_dirty_;
0206 };
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219 template<typename Sample, typename LeftRight>
0220 struct peaks_over_threshold_prob_impl
0221 : accumulator_base
0222 {
0223 typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type float_type;
0224
0225 typedef boost::tuple<float_type, float_type, float_type> result_type;
0226
0227 typedef mpl::int_<is_same<LeftRight, left>::value ? -1 : 1> sign;
0228
0229 template<typename Args>
0230 peaks_over_threshold_prob_impl(Args const &args)
0231 : mu_(sign::value * numeric::fdiv(args[sample | Sample()], (std::size_t)1))
0232 , sigma2_(numeric::fdiv(args[sample | Sample()], (std::size_t)1))
0233 , threshold_probability_(args[pot_threshold_probability])
0234 , fit_parameters_(boost::make_tuple(0., 0., 0.))
0235 , is_dirty_(true)
0236 {
0237 }
0238
0239 void operator ()(dont_care)
0240 {
0241 this->is_dirty_ = true;
0242 }
0243
0244 template<typename Args>
0245 result_type result(Args const &args) const
0246 {
0247 if (this->is_dirty_)
0248 {
0249 this->is_dirty_ = false;
0250
0251 std::size_t cnt = count(args);
0252
0253
0254 std::size_t n = static_cast<std::size_t>(
0255 std::ceil(
0256 cnt * ( ( is_same<LeftRight, left>::value ) ? this->threshold_probability_ : 1. - this->threshold_probability_ )
0257 )
0258 );
0259
0260
0261 if ( n >= static_cast<std::size_t>(tail(args).size()))
0262 {
0263 if (std::numeric_limits<float_type>::has_quiet_NaN)
0264 {
0265 return boost::make_tuple(
0266 std::numeric_limits<float_type>::quiet_NaN()
0267 , std::numeric_limits<float_type>::quiet_NaN()
0268 , std::numeric_limits<float_type>::quiet_NaN()
0269 );
0270 }
0271 else
0272 {
0273 std::ostringstream msg;
0274 msg << "index n = " << n << " is not in valid range [0, " << tail(args).size() << ")";
0275 boost::throw_exception(std::runtime_error(msg.str()));
0276 return boost::make_tuple(Sample(0), Sample(0), Sample(0));
0277 }
0278 }
0279 else
0280 {
0281 float_type u = *(tail(args).begin() + n - 1) * sign::value;
0282
0283
0284 for (std::size_t i = 0; i < n; ++i)
0285 {
0286 mu_ += *(tail(args).begin() + i);
0287 sigma2_ += *(tail(args).begin() + i) * (*(tail(args).begin() + i));
0288 }
0289
0290 this->mu_ = sign::value * numeric::fdiv(this->mu_, n);
0291 this->sigma2_ = numeric::fdiv(this->sigma2_, n);
0292 this->sigma2_ -= this->mu_ * this->mu_;
0293
0294 if (is_same<LeftRight, left>::value)
0295 this->threshold_probability_ = 1. - this->threshold_probability_;
0296
0297 float_type tmp = numeric::fdiv(( this->mu_ - u )*( this->mu_ - u ), this->sigma2_);
0298 float_type xi_hat = 0.5 * ( 1. - tmp );
0299 float_type beta_hat = 0.5 * ( this->mu_ - u ) * ( 1. + tmp );
0300 float_type beta_bar = beta_hat * std::pow(1. - threshold_probability_, xi_hat);
0301 float_type u_bar = u - beta_bar * ( std::pow(1. - threshold_probability_, -xi_hat) - 1.)/xi_hat;
0302 this->fit_parameters_ = boost::make_tuple(u_bar, beta_bar, xi_hat);
0303 }
0304 }
0305
0306 return this->fit_parameters_;
0307 }
0308
0309
0310
0311 template<class Archive>
0312 void serialize(Archive & ar, const unsigned int file_version)
0313 {
0314 ar & mu_;
0315 ar & sigma2_;
0316 ar & threshold_probability_;
0317 ar & get<0>(fit_parameters_);
0318 ar & get<1>(fit_parameters_);
0319 ar & get<2>(fit_parameters_);
0320 ar & is_dirty_;
0321 }
0322
0323 private:
0324 mutable float_type mu_;
0325 mutable float_type sigma2_;
0326 mutable float_type threshold_probability_;
0327 mutable result_type fit_parameters_;
0328 mutable bool is_dirty_;
0329 };
0330
0331 }
0332
0333
0334
0335
0336 namespace tag
0337 {
0338 template<typename LeftRight>
0339 struct peaks_over_threshold
0340 : depends_on<count>
0341 , pot_threshold_value
0342 {
0343
0344
0345 typedef accumulators::impl::peaks_over_threshold_impl<mpl::_1, LeftRight> impl;
0346 };
0347
0348 template<typename LeftRight>
0349 struct peaks_over_threshold_prob
0350 : depends_on<count, tail<LeftRight> >
0351 , pot_threshold_probability
0352 {
0353
0354
0355 typedef accumulators::impl::peaks_over_threshold_prob_impl<mpl::_1, LeftRight> impl;
0356 };
0357
0358 struct abstract_peaks_over_threshold
0359 : depends_on<>
0360 {
0361 };
0362 }
0363
0364
0365
0366
0367 namespace extract
0368 {
0369 extractor<tag::abstract_peaks_over_threshold> const peaks_over_threshold = {};
0370
0371 BOOST_ACCUMULATORS_IGNORE_GLOBAL(peaks_over_threshold)
0372 }
0373
0374 using extract::peaks_over_threshold;
0375
0376
0377 template<typename LeftRight>
0378 struct as_feature<tag::peaks_over_threshold<LeftRight>(with_threshold_value)>
0379 {
0380 typedef tag::peaks_over_threshold<LeftRight> type;
0381 };
0382
0383
0384 template<typename LeftRight>
0385 struct as_feature<tag::peaks_over_threshold<LeftRight>(with_threshold_probability)>
0386 {
0387 typedef tag::peaks_over_threshold_prob<LeftRight> type;
0388 };
0389
0390 template<typename LeftRight>
0391 struct feature_of<tag::peaks_over_threshold<LeftRight> >
0392 : feature_of<tag::abstract_peaks_over_threshold>
0393 {
0394 };
0395
0396 template<typename LeftRight>
0397 struct feature_of<tag::peaks_over_threshold_prob<LeftRight> >
0398 : feature_of<tag::abstract_peaks_over_threshold>
0399 {
0400 };
0401
0402
0403
0404 template<typename LeftRight>
0405 struct as_weighted_feature<tag::peaks_over_threshold<LeftRight> >
0406 {
0407 typedef tag::weighted_peaks_over_threshold<LeftRight> type;
0408 };
0409
0410 template<typename LeftRight>
0411 struct feature_of<tag::weighted_peaks_over_threshold<LeftRight> >
0412 : feature_of<tag::peaks_over_threshold<LeftRight> >
0413 {};
0414
0415
0416
0417 template<typename LeftRight>
0418 struct as_weighted_feature<tag::peaks_over_threshold_prob<LeftRight> >
0419 {
0420 typedef tag::weighted_peaks_over_threshold_prob<LeftRight> type;
0421 };
0422
0423 template<typename LeftRight>
0424 struct feature_of<tag::weighted_peaks_over_threshold_prob<LeftRight> >
0425 : feature_of<tag::peaks_over_threshold_prob<LeftRight> >
0426 {};
0427
0428 }}
0429
0430 #ifdef _MSC_VER
0431 # pragma warning(pop)
0432 #endif
0433
0434 #endif