92 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			92 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | //  Copyright John Maddock 2008. | ||
|  | //  Use, modification and distribution are subject to the | ||
|  | //  Boost Software License, Version 1.0. (See accompanying file | ||
|  | //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
|  | 
 | ||
|  | #ifndef BOOST_MATH_DISTIBUTIONS_DETAIL_GENERIC_QUANTILE_HPP | ||
|  | #define BOOST_MATH_DISTIBUTIONS_DETAIL_GENERIC_QUANTILE_HPP | ||
|  | 
 | ||
|  | namespace boost{ namespace math{ namespace detail{ | ||
|  | 
 | ||
|  | template <class Dist> | ||
|  | struct generic_quantile_finder | ||
|  | { | ||
|  |    typedef typename Dist::value_type value_type; | ||
|  |    typedef typename Dist::policy_type policy_type; | ||
|  | 
 | ||
|  |    generic_quantile_finder(const Dist& d, value_type t, bool c) | ||
|  |       : dist(d), target(t), comp(c) {} | ||
|  | 
 | ||
|  |    value_type operator()(const value_type& x) | ||
|  |    { | ||
|  |       return comp ? | ||
|  |          value_type(target - cdf(complement(dist, x))) | ||
|  |          : value_type(cdf(dist, x) - target); | ||
|  |    } | ||
|  | 
 | ||
|  | private: | ||
|  |    Dist dist; | ||
|  |    value_type target; | ||
|  |    bool comp; | ||
|  | }; | ||
|  | 
 | ||
|  | template <class T, class Policy> | ||
|  | inline T check_range_result(const T& x, const Policy& pol, const char* function) | ||
|  | { | ||
|  |    if((x >= 0) && (x < tools::min_value<T>())) | ||
|  |       return policies::raise_underflow_error<T>(function, 0, pol); | ||
|  |    if(x <= -tools::max_value<T>()) | ||
|  |       return -policies::raise_overflow_error<T>(function, 0, pol); | ||
|  |    if(x >= tools::max_value<T>()) | ||
|  |       return policies::raise_overflow_error<T>(function, 0, pol); | ||
|  |    return x; | ||
|  | } | ||
|  | 
 | ||
|  | template <class Dist> | ||
|  | 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) | ||
|  | { | ||
|  |    typedef typename Dist::value_type value_type; | ||
|  |    typedef typename Dist::policy_type policy_type; | ||
|  |    typedef typename policies::normalise< | ||
|  |       policy_type,  | ||
|  |       policies::promote_float<false>,  | ||
|  |       policies::promote_double<false>,  | ||
|  |       policies::discrete_quantile<>, | ||
|  |       policies::assert_undefined<> >::type forwarding_policy; | ||
|  | 
 | ||
|  |    // | ||
|  |    // Special cases first: | ||
|  |    // | ||
|  |    if(p == 0) | ||
|  |    { | ||
|  |       return comp | ||
|  |       ? check_range_result(range(dist).second, forwarding_policy(), function) | ||
|  |       : check_range_result(range(dist).first, forwarding_policy(), function); | ||
|  |    } | ||
|  |    if(p == 1) | ||
|  |    { | ||
|  |       return !comp | ||
|  |       ? check_range_result(range(dist).second, forwarding_policy(), function) | ||
|  |       : check_range_result(range(dist).first, forwarding_policy(), function); | ||
|  |    } | ||
|  | 
 | ||
|  |    generic_quantile_finder<Dist> f(dist, p, comp); | ||
|  |    tools::eps_tolerance<value_type> tol(policies::digits<value_type, forwarding_policy>() - 3); | ||
|  |    boost::uintmax_t max_iter = policies::get_max_root_iterations<forwarding_policy>(); | ||
|  |    std::pair<value_type, value_type> ir = tools::bracket_and_solve_root( | ||
|  |       f, guess, value_type(2), true, tol, max_iter, forwarding_policy()); | ||
|  |    value_type result = ir.first + (ir.second - ir.first) / 2; | ||
|  |    if(max_iter >= policies::get_max_root_iterations<forwarding_policy>()) | ||
|  |    { | ||
|  |       return policies::raise_evaluation_error<value_type>(function, "Unable to locate solution in a reasonable time:" | ||
|  |          " either there is no answer to quantile" | ||
|  |          " or the answer is infinite.  Current best guess is %1%", result, forwarding_policy()); | ||
|  |    } | ||
|  |    return result; | ||
|  | } | ||
|  | 
 | ||
|  | }}} // namespaces | ||
|  | 
 | ||
|  | #endif // BOOST_MATH_DISTIBUTIONS_DETAIL_GENERIC_QUANTILE_HPP | ||
|  | 
 |