Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:39:38

0001 //  Copyright John Maddock 2008.
0002 //  Use, modification and distribution are subject to the
0003 //  Boost Software License, Version 1.0. (See accompanying file
0004 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #ifndef BOOST_MATH_DISTIBUTIONS_DETAIL_GENERIC_QUANTILE_HPP
0007 #define BOOST_MATH_DISTIBUTIONS_DETAIL_GENERIC_QUANTILE_HPP
0008 
0009 namespace boost{ namespace math{ namespace detail{
0010 
0011 template <class Dist>
0012 struct generic_quantile_finder
0013 {
0014    using value_type = typename Dist::value_type;
0015    using policy_type = typename Dist::policy_type;
0016 
0017    generic_quantile_finder(const Dist& d, value_type t, bool c)
0018       : dist(d), target(t), comp(c) {}
0019 
0020    value_type operator()(const value_type& x)
0021    {
0022       return comp ?
0023          value_type(target - cdf(complement(dist, x)))
0024          : value_type(cdf(dist, x) - target);
0025    }
0026 
0027 private:
0028    Dist dist;
0029    value_type target;
0030    bool comp;
0031 };
0032 
0033 template <class T, class Policy>
0034 inline T check_range_result(const T& x, const Policy& pol, const char* function)
0035 {
0036    if((x >= 0) && (x < tools::min_value<T>()))
0037    {
0038       return policies::raise_underflow_error<T>(function, nullptr, pol);
0039    }
0040    if(x <= -tools::max_value<T>())
0041    {
0042       return -policies::raise_overflow_error<T>(function, nullptr, pol);
0043    }
0044    if(x >= tools::max_value<T>())
0045    {
0046       return policies::raise_overflow_error<T>(function, nullptr, pol);
0047    }
0048    return x;
0049 }
0050 
0051 template <class Dist>
0052 typename Dist::value_type generic_quantile(const Dist& dist, const typename Dist::value_type& p, const typename Dist::value_type& guess, bool comp, const char* function)
0053 {
0054    using value_type = typename Dist::value_type;
0055    using policy_type = typename Dist::policy_type;
0056    using forwarding_policy = typename policies::normalise<
0057                                                             policy_type,
0058                                                             policies::promote_float<false>,
0059                                                             policies::promote_double<false>,
0060                                                             policies::discrete_quantile<>,
0061                                                             policies::assert_undefined<> >::type;
0062 
0063    //
0064    // Special cases first:
0065    //
0066    if(p == 0)
0067    {
0068       return comp
0069       ? check_range_result(range(dist).second, forwarding_policy(), function)
0070       : check_range_result(range(dist).first, forwarding_policy(), function);
0071    }
0072    if(p == 1)
0073    {
0074       return !comp
0075       ? check_range_result(range(dist).second, forwarding_policy(), function)
0076       : check_range_result(range(dist).first, forwarding_policy(), function);
0077    }
0078 
0079    generic_quantile_finder<Dist> f(dist, p, comp);
0080    tools::eps_tolerance<value_type> tol(policies::digits<value_type, forwarding_policy>() - 3);
0081    std::uintmax_t max_iter = policies::get_max_root_iterations<forwarding_policy>();
0082    std::pair<value_type, value_type> ir = tools::bracket_and_solve_root(
0083       f, guess, value_type(2), true, tol, max_iter, forwarding_policy());
0084    value_type result = ir.first + (ir.second - ir.first) / 2;
0085    if(max_iter >= policies::get_max_root_iterations<forwarding_policy>())
0086    {
0087       return policies::raise_evaluation_error<value_type>(function, "Unable to locate solution in a reasonable time:"
0088          " either there is no answer to quantile"
0089          " or the answer is infinite.  Current best guess is %1%", result, forwarding_policy());
0090    }
0091    return result;
0092 }
0093 
0094 }}} // namespaces
0095 
0096 #endif // BOOST_MATH_DISTIBUTIONS_DETAIL_GENERIC_QUANTILE_HPP
0097