result_type result(Args const &args) const { float_type threshold = sum_of_weights(args) * ( ( is_same<LeftRight, left>::value ) ? args[quantile_probability] : 1. - args[quantile_probability] ); std::size_t n = 0; Weight sum = Weight(0); while (sum < threshold) { if (n < static_cast<std::size_t>(tail_weights(args).size())) { sum += *(tail_weights(args).begin() + n); n++; } else { if (std::numeric_limits<result_type>::has_quiet_NaN) { return std::numeric_limits<result_type>::quiet_NaN(); } else { std::ostringstream msg; msg << "index n = " << n << " is not in valid range [0, " << tail(args).size() << ")"; boost::throw_exception(std::runtime_error(msg.str())); return Sample(0); } } } // Note that the cached samples of the left are sorted in ascending order, // whereas the samples of the right tail are sorted in descending order return *(boost::begin(tail(args)) + n - 1); }
result_type result(Args const &args) const { float_type threshold = sum_of_weights(args) * ( ( is_same<LeftRight, left>::value ) ? args[quantile_probability] : 1. - args[quantile_probability] ); std::size_t n = 0; Weight sum = Weight(0); while (sum < threshold) { if (n < static_cast<std::size_t>(tail_weights(args).size())) { sum += *(tail_weights(args).begin() + n); n++; } else { if (std::numeric_limits<float_type>::has_quiet_NaN) { std::fill( this->tail_means_.begin() , this->tail_means_.end() , std::numeric_limits<float_type>::quiet_NaN() ); } else { std::ostringstream msg; msg << "index n = " << n << " is not in valid range [0, " << tail(args).size() << ")"; boost::throw_exception(std::runtime_error(msg.str())); } } } std::size_t num_variates = tail_variate(args).begin()->size(); this->tail_means_.clear(); this->tail_means_.resize(num_variates, Sample(0)); this->tail_means_ = std::inner_product( tail_variate(args).begin() , tail_variate(args).begin() + n , tail_weights(args).begin() , this->tail_means_ , numeric::functional::plus<array_type const, array_type const>() , numeric::functional::multiply_and_promote_to_double<VariateType const, Weight const>() ); float_type factor = sum * ( (is_same<Impl, relative>::value) ? non_coherent_weighted_tail_mean(args) : 1. ); std::transform( this->tail_means_.begin() , this->tail_means_.end() , this->tail_means_.begin() , std::bind2nd(numeric::functional::divides<typename array_type::value_type const, float_type const>(), factor) ); return make_iterator_range(this->tail_means_); }
result_type result(Args const &args) const { float_type threshold = sum_of_weights(args) * ( ( is_same<LeftRight, left>::value ) ? args[quantile_probability] : 1. - args[quantile_probability] ); std::size_t n = 0; Weight sum = Weight(0); while (sum < threshold) { if (n < static_cast<std::size_t>(tail_weights(args).size())) { sum += *(tail_weights(args).begin() + n); n++; } else { if (std::numeric_limits<result_type>::has_quiet_NaN) { return std::numeric_limits<result_type>::quiet_NaN(); } else { std::ostringstream msg; msg << "index n = " << n << " is not in valid range [0, " << tail(args).size() << ")"; boost::throw_exception(std::runtime_error(msg.str())); return result_type(0); } } } return numeric::average( std::inner_product( tail(args).begin() , tail(args).begin() + n , tail_weights(args).begin() , weighted_sample(0) ) , sum ); }
result_type result(Args const &args) const { if (this->is_dirty_) { this->is_dirty_ = false; float_type threshold = sum_of_weights(args) * ( ( is_same<LeftRight, left>::value ) ? this->threshold_probability_ : 1. - this->threshold_probability_ ); std::size_t n = 0; Weight sum = Weight(0); while (sum < threshold) { if (n < static_cast<std::size_t>(tail_weights(args).size())) { mu_ += *(tail_weights(args).begin() + n) * *(tail(args).begin() + n); sigma2_ += *(tail_weights(args).begin() + n) * *(tail(args).begin() + n) * (*(tail(args).begin() + n)); sum += *(tail_weights(args).begin() + n); n++; } else { if (std::numeric_limits<float_type>::has_quiet_NaN) { return boost::make_tuple( std::numeric_limits<float_type>::quiet_NaN() , std::numeric_limits<float_type>::quiet_NaN() , std::numeric_limits<float_type>::quiet_NaN() ); } else { std::ostringstream msg; msg << "index n = " << n << " is not in valid range [0, " << tail(args).size() << ")"; boost::throw_exception(std::runtime_error(msg.str())); return boost::make_tuple(Sample(0), Sample(0), Sample(0)); } } } float_type u = *(tail(args).begin() + n - 1) * this->sign_; this->mu_ = this->sign_ * numeric::average(this->mu_, sum); this->sigma2_ = numeric::average(this->sigma2_, sum); this->sigma2_ -= this->mu_ * this->mu_; if (is_same<LeftRight, left>::value) this->threshold_probability_ = 1. - this->threshold_probability_; float_type tmp = numeric::average(( this->mu_ - u )*( this->mu_ - u ), this->sigma2_); float_type xi_hat = 0.5 * ( 1. - tmp ); float_type beta_hat = 0.5 * ( this->mu_ - u ) * ( 1. + tmp ); float_type beta_bar = beta_hat * std::pow(1. - threshold_probability_, xi_hat); float_type u_bar = u - beta_bar * ( std::pow(1. - threshold_probability_, -xi_hat) - 1.)/xi_hat; this->fit_parameters_ = boost::make_tuple(u_bar, beta_bar, xi_hat); } return this->fit_parameters_; }