1000 lines
		
	
	
		
			41 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			1000 lines
		
	
	
		
			41 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								// boost\math\distributions\non_central_chi_squared.hpp
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// 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_SPECIAL_NON_CENTRAL_CHI_SQUARE_HPP
							 | 
						||
| 
								 | 
							
								#define BOOST_MATH_SPECIAL_NON_CENTRAL_CHI_SQUARE_HPP
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <boost/math/distributions/fwd.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/math/special_functions/gamma.hpp> // for incomplete gamma. gamma_q
							 | 
						||
| 
								 | 
							
								#include <boost/math/special_functions/bessel.hpp> // for cyl_bessel_i
							 | 
						||
| 
								 | 
							
								#include <boost/math/special_functions/round.hpp> // for iround
							 | 
						||
| 
								 | 
							
								#include <boost/math/distributions/complement.hpp> // complements
							 | 
						||
| 
								 | 
							
								#include <boost/math/distributions/chi_squared.hpp> // central distribution
							 | 
						||
| 
								 | 
							
								#include <boost/math/distributions/detail/common_error_handling.hpp> // error checks
							 | 
						||
| 
								 | 
							
								#include <boost/math/special_functions/fpclassify.hpp> // isnan.
							 | 
						||
| 
								 | 
							
								#include <boost/math/tools/roots.hpp> // for root finding.
							 | 
						||
| 
								 | 
							
								#include <boost/math/distributions/detail/generic_mode.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/math/distributions/detail/generic_quantile.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace boost
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								   namespace math
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								      class non_central_chi_squared_distribution;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      namespace detail{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         template <class T, class Policy>
							 | 
						||
| 
								 | 
							
								         T non_central_chi_square_q(T x, T f, T theta, const Policy& pol, T init_sum = 0)
							 | 
						||
| 
								 | 
							
								         {
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            // Computes the complement of the Non-Central Chi-Square
							 | 
						||
| 
								 | 
							
								            // Distribution CDF by summing a weighted sum of complements
							 | 
						||
| 
								 | 
							
								            // of the central-distributions.  The weighting factor is
							 | 
						||
| 
								 | 
							
								            // a Poisson Distribution.
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            // This is an application of the technique described in:
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            // Computing discrete mixtures of continuous
							 | 
						||
| 
								 | 
							
								            // distributions: noncentral chisquare, noncentral t
							 | 
						||
| 
								 | 
							
								            // and the distribution of the square of the sample
							 | 
						||
| 
								 | 
							
								            // multiple correlation coeficient.
							 | 
						||
| 
								 | 
							
								            // D. Benton, K. Krishnamoorthy.
							 | 
						||
| 
								 | 
							
								            // Computational Statistics & Data Analysis 43 (2003) 249 - 267
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            BOOST_MATH_STD_USING
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // Special case:
							 | 
						||
| 
								 | 
							
								            if(x == 0)
							 | 
						||
| 
								 | 
							
								               return 1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            // Initialize the variables we'll be using:
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            T lambda = theta / 2;
							 | 
						||
| 
								 | 
							
								            T del = f / 2;
							 | 
						||
| 
								 | 
							
								            T y = x / 2;
							 | 
						||
| 
								 | 
							
								            boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
							 | 
						||
| 
								 | 
							
								            T errtol = boost::math::policies::get_epsilon<T, Policy>();
							 | 
						||
| 
								 | 
							
								            T sum = init_sum;
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            // k is the starting location for iteration, we'll
							 | 
						||
| 
								 | 
							
								            // move both forwards and backwards from this point.
							 | 
						||
| 
								 | 
							
								            // k is chosen as the peek of the Poisson weights, which
							 | 
						||
| 
								 | 
							
								            // will occur *before* the largest term.
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            int k = iround(lambda, pol);
							 | 
						||
| 
								 | 
							
								            // Forwards and backwards Poisson weights:
							 | 
						||
| 
								 | 
							
								            T poisf = boost::math::gamma_p_derivative(static_cast<T>(1 + k), lambda, pol);
							 | 
						||
| 
								 | 
							
								            T poisb = poisf * k / lambda;
							 | 
						||
| 
								 | 
							
								            // Initial forwards central chi squared term:
							 | 
						||
| 
								 | 
							
								            T gamf = boost::math::gamma_q(del + k, y, pol);
							 | 
						||
| 
								 | 
							
								            // Forwards and backwards recursion terms on the central chi squared:
							 | 
						||
| 
								 | 
							
								            T xtermf = boost::math::gamma_p_derivative(del + 1 + k, y, pol);
							 | 
						||
| 
								 | 
							
								            T xtermb = xtermf * (del + k) / y;
							 | 
						||
| 
								 | 
							
								            // Initial backwards central chi squared term:
							 | 
						||
| 
								 | 
							
								            T gamb = gamf - xtermb;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            // Forwards iteration first, this is the
							 | 
						||
| 
								 | 
							
								            // stable direction for the gamma function
							 | 
						||
| 
								 | 
							
								            // recurrences:
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            int i;
							 | 
						||
| 
								 | 
							
								            for(i = k; static_cast<boost::uintmax_t>(i-k) < max_iter; ++i)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								               T term = poisf * gamf;
							 | 
						||
| 
								 | 
							
								               sum += term;
							 | 
						||
| 
								 | 
							
								               poisf *= lambda / (i + 1);
							 | 
						||
| 
								 | 
							
								               gamf += xtermf;
							 | 
						||
| 
								 | 
							
								               xtermf *= y / (del + i + 1);
							 | 
						||
| 
								 | 
							
								               if(((sum == 0) || (fabs(term / sum) < errtol)) && (term >= poisf * gamf))
							 | 
						||
| 
								 | 
							
								                  break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            //Error check:
							 | 
						||
| 
								 | 
							
								            if(static_cast<boost::uintmax_t>(i-k) >= max_iter)
							 | 
						||
| 
								 | 
							
								               return policies::raise_evaluation_error(
							 | 
						||
| 
								 | 
							
								                  "cdf(non_central_chi_squared_distribution<%1%>, %1%)",
							 | 
						||
| 
								 | 
							
								                  "Series did not converge, closest value was %1%", sum, pol);
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            // Now backwards iteration: the gamma
							 | 
						||
| 
								 | 
							
								            // function recurrences are unstable in this
							 | 
						||
| 
								 | 
							
								            // direction, we rely on the terms deminishing in size
							 | 
						||
| 
								 | 
							
								            // faster than we introduce cancellation errors.
							 | 
						||
| 
								 | 
							
								            // For this reason it's very important that we start
							 | 
						||
| 
								 | 
							
								            // *before* the largest term so that backwards iteration
							 | 
						||
| 
								 | 
							
								            // is strictly converging.
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            for(i = k - 1; i >= 0; --i)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								               T term = poisb * gamb;
							 | 
						||
| 
								 | 
							
								               sum += term;
							 | 
						||
| 
								 | 
							
								               poisb *= i / lambda;
							 | 
						||
| 
								 | 
							
								               xtermb *= (del + i) / y;
							 | 
						||
| 
								 | 
							
								               gamb -= xtermb;
							 | 
						||
| 
								 | 
							
								               if((sum == 0) || (fabs(term / sum) < errtol))
							 | 
						||
| 
								 | 
							
								                  break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            return sum;
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         template <class T, class Policy>
							 | 
						||
| 
								 | 
							
								         T non_central_chi_square_p_ding(T x, T f, T theta, const Policy& pol, T init_sum = 0)
							 | 
						||
| 
								 | 
							
								         {
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            // This is an implementation of:
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            // Algorithm AS 275:
							 | 
						||
| 
								 | 
							
								            // Computing the Non-Central #2 Distribution Function
							 | 
						||
| 
								 | 
							
								            // Cherng G. Ding
							 | 
						||
| 
								 | 
							
								            // Applied Statistics, Vol. 41, No. 2. (1992), pp. 478-482.
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            // This uses a stable forward iteration to sum the
							 | 
						||
| 
								 | 
							
								            // CDF, unfortunately this can not be used for large
							 | 
						||
| 
								 | 
							
								            // values of the non-centrality parameter because:
							 | 
						||
| 
								 | 
							
								            // * The first term may underfow to zero.
							 | 
						||
| 
								 | 
							
								            // * We may need an extra-ordinary number of terms
							 | 
						||
| 
								 | 
							
								            //   before we reach the first *significant* term.
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            BOOST_MATH_STD_USING
							 | 
						||
| 
								 | 
							
								            // Special case:
							 | 
						||
| 
								 | 
							
								            if(x == 0)
							 | 
						||
| 
								 | 
							
								               return 0;
							 | 
						||
| 
								 | 
							
								            T tk = boost::math::gamma_p_derivative(f/2 + 1, x/2, pol);
							 | 
						||
| 
								 | 
							
								            T lambda = theta / 2;
							 | 
						||
| 
								 | 
							
								            T vk = exp(-lambda);
							 | 
						||
| 
								 | 
							
								            T uk = vk;
							 | 
						||
| 
								 | 
							
								            T sum = init_sum + tk * vk;
							 | 
						||
| 
								 | 
							
								            if(sum == 0)
							 | 
						||
| 
								 | 
							
								               return sum;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
							 | 
						||
| 
								 | 
							
								            T errtol = boost::math::policies::get_epsilon<T, Policy>();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            int i;
							 | 
						||
| 
								 | 
							
								            T lterm(0), term(0);
							 | 
						||
| 
								 | 
							
								            for(i = 1; static_cast<boost::uintmax_t>(i) < max_iter; ++i)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								               tk = tk * x / (f + 2 * i);
							 | 
						||
| 
								 | 
							
								               uk = uk * lambda / i;
							 | 
						||
| 
								 | 
							
								               vk = vk + uk;
							 | 
						||
| 
								 | 
							
								               lterm = term;
							 | 
						||
| 
								 | 
							
								               term = vk * tk;
							 | 
						||
| 
								 | 
							
								               sum += term;
							 | 
						||
| 
								 | 
							
								               if((fabs(term / sum) < errtol) && (term <= lterm))
							 | 
						||
| 
								 | 
							
								                  break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            //Error check:
							 | 
						||
| 
								 | 
							
								            if(static_cast<boost::uintmax_t>(i) >= max_iter)
							 | 
						||
| 
								 | 
							
								               return policies::raise_evaluation_error(
							 | 
						||
| 
								 | 
							
								                  "cdf(non_central_chi_squared_distribution<%1%>, %1%)",
							 | 
						||
| 
								 | 
							
								                  "Series did not converge, closest value was %1%", sum, pol);
							 | 
						||
| 
								 | 
							
								            return sum;
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         template <class T, class Policy>
							 | 
						||
| 
								 | 
							
								         T non_central_chi_square_p(T y, T n, T lambda, const Policy& pol, T init_sum)
							 | 
						||
| 
								 | 
							
								         {
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            // This is taken more or less directly from:
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            // Computing discrete mixtures of continuous
							 | 
						||
| 
								 | 
							
								            // distributions: noncentral chisquare, noncentral t
							 | 
						||
| 
								 | 
							
								            // and the distribution of the square of the sample
							 | 
						||
| 
								 | 
							
								            // multiple correlation coeficient.
							 | 
						||
| 
								 | 
							
								            // D. Benton, K. Krishnamoorthy.
							 | 
						||
| 
								 | 
							
								            // Computational Statistics & Data Analysis 43 (2003) 249 - 267
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            // We're summing a Poisson weighting term multiplied by
							 | 
						||
| 
								 | 
							
								            // a central chi squared distribution.
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            BOOST_MATH_STD_USING
							 | 
						||
| 
								 | 
							
								            // Special case:
							 | 
						||
| 
								 | 
							
								            if(y == 0)
							 | 
						||
| 
								 | 
							
								               return 0;
							 | 
						||
| 
								 | 
							
								            boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
							 | 
						||
| 
								 | 
							
								            T errtol = boost::math::policies::get_epsilon<T, Policy>();
							 | 
						||
| 
								 | 
							
								            T errorf(0), errorb(0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            T x = y / 2;
							 | 
						||
| 
								 | 
							
								            T del = lambda / 2;
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            // Starting location for the iteration, we'll iterate
							 | 
						||
| 
								 | 
							
								            // both forwards and backwards from this point.  The
							 | 
						||
| 
								 | 
							
								            // location chosen is the maximum of the Poisson weight
							 | 
						||
| 
								 | 
							
								            // function, which ocurrs *after* the largest term in the
							 | 
						||
| 
								 | 
							
								            // sum.
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            int k = iround(del, pol);
							 | 
						||
| 
								 | 
							
								            T a = n / 2 + k;
							 | 
						||
| 
								 | 
							
								            // Central chi squared term for forward iteration:
							 | 
						||
| 
								 | 
							
								            T gamkf = boost::math::gamma_p(a, x, pol);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if(lambda == 0)
							 | 
						||
| 
								 | 
							
								               return gamkf;
							 | 
						||
| 
								 | 
							
								            // Central chi squared term for backward iteration:
							 | 
						||
| 
								 | 
							
								            T gamkb = gamkf;
							 | 
						||
| 
								 | 
							
								            // Forwards Poisson weight:
							 | 
						||
| 
								 | 
							
								            T poiskf = gamma_p_derivative(static_cast<T>(k+1), del, pol);
							 | 
						||
| 
								 | 
							
								            // Backwards Poisson weight:
							 | 
						||
| 
								 | 
							
								            T poiskb = poiskf;
							 | 
						||
| 
								 | 
							
								            // Forwards gamma function recursion term:
							 | 
						||
| 
								 | 
							
								            T xtermf = boost::math::gamma_p_derivative(a, x, pol);
							 | 
						||
| 
								 | 
							
								            // Backwards gamma function recursion term:
							 | 
						||
| 
								 | 
							
								            T xtermb = xtermf * x / a;
							 | 
						||
| 
								 | 
							
								            T sum = init_sum + poiskf * gamkf;
							 | 
						||
| 
								 | 
							
								            if(sum == 0)
							 | 
						||
| 
								 | 
							
								               return sum;
							 | 
						||
| 
								 | 
							
								            int i = 1;
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            // Backwards recursion first, this is the stable
							 | 
						||
| 
								 | 
							
								            // direction for gamma function recurrences:
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            while(i <= k)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								               xtermb *= (a - i + 1) / x;
							 | 
						||
| 
								 | 
							
								               gamkb += xtermb;
							 | 
						||
| 
								 | 
							
								               poiskb = poiskb * (k - i + 1) / del;
							 | 
						||
| 
								 | 
							
								               errorf = errorb;
							 | 
						||
| 
								 | 
							
								               errorb = gamkb * poiskb;
							 | 
						||
| 
								 | 
							
								               sum += errorb;
							 | 
						||
| 
								 | 
							
								               if((fabs(errorb / sum) < errtol) && (errorb <= errorf))
							 | 
						||
| 
								 | 
							
								                  break;
							 | 
						||
| 
								 | 
							
								               ++i;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            i = 1;
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            // Now forwards recursion, the gamma function
							 | 
						||
| 
								 | 
							
								            // recurrence relation is unstable in this direction,
							 | 
						||
| 
								 | 
							
								            // so we rely on the magnitude of successive terms
							 | 
						||
| 
								 | 
							
								            // decreasing faster than we introduce cancellation error.
							 | 
						||
| 
								 | 
							
								            // For this reason it's vital that k is chosen to be *after*
							 | 
						||
| 
								 | 
							
								            // the largest term, so that successive forward iterations
							 | 
						||
| 
								 | 
							
								            // are strictly (and rapidly) converging.
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            do
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								               xtermf = xtermf * x / (a + i - 1);
							 | 
						||
| 
								 | 
							
								               gamkf = gamkf - xtermf;
							 | 
						||
| 
								 | 
							
								               poiskf = poiskf * del / (k + i);
							 | 
						||
| 
								 | 
							
								               errorf = poiskf * gamkf;
							 | 
						||
| 
								 | 
							
								               sum += errorf;
							 | 
						||
| 
								 | 
							
								               ++i;
							 | 
						||
| 
								 | 
							
								            }while((fabs(errorf / sum) > errtol) && (static_cast<boost::uintmax_t>(i) < max_iter));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            //Error check:
							 | 
						||
| 
								 | 
							
								            if(static_cast<boost::uintmax_t>(i) >= max_iter)
							 | 
						||
| 
								 | 
							
								               return policies::raise_evaluation_error(
							 | 
						||
| 
								 | 
							
								                  "cdf(non_central_chi_squared_distribution<%1%>, %1%)",
							 | 
						||
| 
								 | 
							
								                  "Series did not converge, closest value was %1%", sum, pol);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            return sum;
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         template <class T, class Policy>
							 | 
						||
| 
								 | 
							
								         T non_central_chi_square_pdf(T x, T n, T lambda, const Policy& pol)
							 | 
						||
| 
								 | 
							
								         {
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            // As above but for the PDF:
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            BOOST_MATH_STD_USING
							 | 
						||
| 
								 | 
							
								            boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
							 | 
						||
| 
								 | 
							
								            T errtol = boost::math::policies::get_epsilon<T, Policy>();
							 | 
						||
| 
								 | 
							
								            T x2 = x / 2;
							 | 
						||
| 
								 | 
							
								            T n2 = n / 2;
							 | 
						||
| 
								 | 
							
								            T l2 = lambda / 2;
							 | 
						||
| 
								 | 
							
								            T sum = 0;
							 | 
						||
| 
								 | 
							
								            int k = itrunc(l2);
							 | 
						||
| 
								 | 
							
								            T pois = gamma_p_derivative(static_cast<T>(k + 1), l2, pol) * gamma_p_derivative(static_cast<T>(n2 + k), x2);
							 | 
						||
| 
								 | 
							
								            if(pois == 0)
							 | 
						||
| 
								 | 
							
								               return 0;
							 | 
						||
| 
								 | 
							
								            T poisb = pois;
							 | 
						||
| 
								 | 
							
								            for(int i = k; ; ++i)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								               sum += pois;
							 | 
						||
| 
								 | 
							
								               if(pois / sum < errtol)
							 | 
						||
| 
								 | 
							
								                  break;
							 | 
						||
| 
								 | 
							
								               if(static_cast<boost::uintmax_t>(i - k) >= max_iter)
							 | 
						||
| 
								 | 
							
								                  return policies::raise_evaluation_error(
							 | 
						||
| 
								 | 
							
								                     "pdf(non_central_chi_squared_distribution<%1%>, %1%)",
							 | 
						||
| 
								 | 
							
								                     "Series did not converge, closest value was %1%", sum, pol);
							 | 
						||
| 
								 | 
							
								               pois *= l2 * x2 / ((i + 1) * (n2 + i));
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            for(int i = k - 1; i >= 0; --i)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								               poisb *= (i + 1) * (n2 + i) / (l2 * x2);
							 | 
						||
| 
								 | 
							
								               sum += poisb;
							 | 
						||
| 
								 | 
							
								               if(poisb / sum < errtol)
							 | 
						||
| 
								 | 
							
								                  break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            return sum / 2;
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								         inline RealType non_central_chi_squared_cdf(RealType x, RealType k, RealType l, bool invert, const Policy&)
							 | 
						||
| 
								 | 
							
								         {
							 | 
						||
| 
								 | 
							
								            typedef typename policies::evaluation<RealType, Policy>::type value_type;
							 | 
						||
| 
								 | 
							
								            typedef typename policies::normalise<
							 | 
						||
| 
								 | 
							
								               Policy,
							 | 
						||
| 
								 | 
							
								               policies::promote_float<false>,
							 | 
						||
| 
								 | 
							
								               policies::promote_double<false>,
							 | 
						||
| 
								 | 
							
								               policies::discrete_quantile<>,
							 | 
						||
| 
								 | 
							
								               policies::assert_undefined<> >::type forwarding_policy;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            BOOST_MATH_STD_USING
							 | 
						||
| 
								 | 
							
								            value_type result;
							 | 
						||
| 
								 | 
							
								            if(l == 0)
							 | 
						||
| 
								 | 
							
								              return invert == false ? cdf(boost::math::chi_squared_distribution<RealType, Policy>(k), x) : cdf(complement(boost::math::chi_squared_distribution<RealType, Policy>(k), x));
							 | 
						||
| 
								 | 
							
								            else if(x > k + l)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								               // Complement is the smaller of the two:
							 | 
						||
| 
								 | 
							
								               result = detail::non_central_chi_square_q(
							 | 
						||
| 
								 | 
							
								                  static_cast<value_type>(x),
							 | 
						||
| 
								 | 
							
								                  static_cast<value_type>(k),
							 | 
						||
| 
								 | 
							
								                  static_cast<value_type>(l),
							 | 
						||
| 
								 | 
							
								                  forwarding_policy(),
							 | 
						||
| 
								 | 
							
								                  static_cast<value_type>(invert ? 0 : -1));
							 | 
						||
| 
								 | 
							
								               invert = !invert;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else if(l < 200)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								               // For small values of the non-centrality parameter
							 | 
						||
| 
								 | 
							
								               // we can use Ding's method:
							 | 
						||
| 
								 | 
							
								               result = detail::non_central_chi_square_p_ding(
							 | 
						||
| 
								 | 
							
								                  static_cast<value_type>(x),
							 | 
						||
| 
								 | 
							
								                  static_cast<value_type>(k),
							 | 
						||
| 
								 | 
							
								                  static_cast<value_type>(l),
							 | 
						||
| 
								 | 
							
								                  forwarding_policy(),
							 | 
						||
| 
								 | 
							
								                  static_cast<value_type>(invert ? -1 : 0));
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								               // For largers values of the non-centrality
							 | 
						||
| 
								 | 
							
								               // parameter Ding's method will consume an
							 | 
						||
| 
								 | 
							
								               // extra-ordinary number of terms, and worse
							 | 
						||
| 
								 | 
							
								               // may return zero when the result is in fact
							 | 
						||
| 
								 | 
							
								               // finite, use Krishnamoorthy's method instead:
							 | 
						||
| 
								 | 
							
								               result = detail::non_central_chi_square_p(
							 | 
						||
| 
								 | 
							
								                  static_cast<value_type>(x),
							 | 
						||
| 
								 | 
							
								                  static_cast<value_type>(k),
							 | 
						||
| 
								 | 
							
								                  static_cast<value_type>(l),
							 | 
						||
| 
								 | 
							
								                  forwarding_policy(),
							 | 
						||
| 
								 | 
							
								                  static_cast<value_type>(invert ? -1 : 0));
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if(invert)
							 | 
						||
| 
								 | 
							
								               result = -result;
							 | 
						||
| 
								 | 
							
								            return policies::checked_narrowing_cast<RealType, forwarding_policy>(
							 | 
						||
| 
								 | 
							
								               result,
							 | 
						||
| 
								 | 
							
								               "boost::math::non_central_chi_squared_cdf<%1%>(%1%, %1%, %1%)");
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         template <class T, class Policy>
							 | 
						||
| 
								 | 
							
								         struct nccs_quantile_functor
							 | 
						||
| 
								 | 
							
								         {
							 | 
						||
| 
								 | 
							
								            nccs_quantile_functor(const non_central_chi_squared_distribution<T,Policy>& d, T t, bool c)
							 | 
						||
| 
								 | 
							
								               : dist(d), target(t), comp(c) {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            T operator()(const T& x)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								               return comp ?
							 | 
						||
| 
								 | 
							
								                  target - cdf(complement(dist, x))
							 | 
						||
| 
								 | 
							
								                  : cdf(dist, x) - target;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         private:
							 | 
						||
| 
								 | 
							
								            non_central_chi_squared_distribution<T,Policy> dist;
							 | 
						||
| 
								 | 
							
								            T target;
							 | 
						||
| 
								 | 
							
								            bool comp;
							 | 
						||
| 
								 | 
							
								         };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								         RealType nccs_quantile(const non_central_chi_squared_distribution<RealType, Policy>& dist, const RealType& p, bool comp)
							 | 
						||
| 
								 | 
							
								         {
							 | 
						||
| 
								 | 
							
								            BOOST_MATH_STD_USING
							 | 
						||
| 
								 | 
							
								            static const char* function = "quantile(non_central_chi_squared_distribution<%1%>, %1%)";
							 | 
						||
| 
								 | 
							
								            typedef typename policies::evaluation<RealType, Policy>::type value_type;
							 | 
						||
| 
								 | 
							
								            typedef typename policies::normalise<
							 | 
						||
| 
								 | 
							
								               Policy,
							 | 
						||
| 
								 | 
							
								               policies::promote_float<false>,
							 | 
						||
| 
								 | 
							
								               policies::promote_double<false>,
							 | 
						||
| 
								 | 
							
								               policies::discrete_quantile<>,
							 | 
						||
| 
								 | 
							
								               policies::assert_undefined<> >::type forwarding_policy;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            value_type k = dist.degrees_of_freedom();
							 | 
						||
| 
								 | 
							
								            value_type l = dist.non_centrality();
							 | 
						||
| 
								 | 
							
								            value_type r;
							 | 
						||
| 
								 | 
							
								            if(!detail::check_df(
							 | 
						||
| 
								 | 
							
								               function,
							 | 
						||
| 
								 | 
							
								               k, &r, Policy())
							 | 
						||
| 
								 | 
							
								               ||
							 | 
						||
| 
								 | 
							
								            !detail::check_non_centrality(
							 | 
						||
| 
								 | 
							
								               function,
							 | 
						||
| 
								 | 
							
								               l,
							 | 
						||
| 
								 | 
							
								               &r,
							 | 
						||
| 
								 | 
							
								               Policy())
							 | 
						||
| 
								 | 
							
								               ||
							 | 
						||
| 
								 | 
							
								            !detail::check_probability(
							 | 
						||
| 
								 | 
							
								               function,
							 | 
						||
| 
								 | 
							
								               static_cast<value_type>(p),
							 | 
						||
| 
								 | 
							
								               &r,
							 | 
						||
| 
								 | 
							
								               Policy()))
							 | 
						||
| 
								 | 
							
								                  return (RealType)r;
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            // Special cases get short-circuited first:
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            if(p == 0)
							 | 
						||
| 
								 | 
							
								               return comp ? policies::raise_overflow_error<RealType>(function, 0, Policy()) : 0;
							 | 
						||
| 
								 | 
							
								            if(p == 1)
							 | 
						||
| 
								 | 
							
								               return comp ? 0 : policies::raise_overflow_error<RealType>(function, 0, Policy());
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            // This is Pearson's approximation to the quantile, see
							 | 
						||
| 
								 | 
							
								            // Pearson, E. S. (1959) "Note on an approximation to the distribution of
							 | 
						||
| 
								 | 
							
								            // noncentral chi squared", Biometrika 46: 364.
							 | 
						||
| 
								 | 
							
								            // See also:
							 | 
						||
| 
								 | 
							
								            // "A comparison of approximations to percentiles of the noncentral chi2-distribution",
							 | 
						||
| 
								 | 
							
								            // Hardeo Sahai and Mario Miguel Ojeda, Revista de Matematica: Teoria y Aplicaciones 2003 10(1-2) : 57-76.
							 | 
						||
| 
								 | 
							
								            // Note that the latter reference refers to an approximation of the CDF, when they really mean the quantile.
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            value_type b = -(l * l) / (k + 3 * l);
							 | 
						||
| 
								 | 
							
								            value_type c = (k + 3 * l) / (k + 2 * l);
							 | 
						||
| 
								 | 
							
								            value_type ff = (k + 2 * l) / (c * c);
							 | 
						||
| 
								 | 
							
								            value_type guess;
							 | 
						||
| 
								 | 
							
								            if(comp)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								               guess = b + c * quantile(complement(chi_squared_distribution<value_type, forwarding_policy>(ff), p));
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								               guess = b + c * quantile(chi_squared_distribution<value_type, forwarding_policy>(ff), p);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            // Sometimes guess goes very small or negative, in that case we have
							 | 
						||
| 
								 | 
							
								            // to do something else for the initial guess, this approximation
							 | 
						||
| 
								 | 
							
								            // was provided in a private communication from Thomas Luu, PhD candidate,
							 | 
						||
| 
								 | 
							
								            // University College London.  It's an asymptotic expansion for the
							 | 
						||
| 
								 | 
							
								            // quantile which usually gets us within an order of magnitude of the
							 | 
						||
| 
								 | 
							
								            // correct answer.
							 | 
						||
| 
								 | 
							
								            // Fast and accurate parallel computation of quantile functions for random number generation,
							 | 
						||
| 
								 | 
							
								            // Thomas LuuDoctorial Thesis 2016
							 | 
						||
| 
								 | 
							
								            // http://discovery.ucl.ac.uk/1482128/
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            if(guess < 0.005)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								               value_type pp = comp ? 1 - p : p;
							 | 
						||
| 
								 | 
							
								               //guess = pow(pow(value_type(2), (k / 2 - 1)) * exp(l / 2) * pp * k, 2 / k);
							 | 
						||
| 
								 | 
							
								               guess = pow(pow(value_type(2), (k / 2 - 1)) * exp(l / 2) * pp * k * boost::math::tgamma(k / 2, forwarding_policy()), (2 / k));
							 | 
						||
| 
								 | 
							
								               if(guess == 0)
							 | 
						||
| 
								 | 
							
								                  guess = tools::min_value<value_type>();
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            value_type result = detail::generic_quantile(
							 | 
						||
| 
								 | 
							
								               non_central_chi_squared_distribution<value_type, forwarding_policy>(k, l),
							 | 
						||
| 
								 | 
							
								               p,
							 | 
						||
| 
								 | 
							
								               guess,
							 | 
						||
| 
								 | 
							
								               comp,
							 | 
						||
| 
								 | 
							
								               function);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            return policies::checked_narrowing_cast<RealType, forwarding_policy>(
							 | 
						||
| 
								 | 
							
								               result,
							 | 
						||
| 
								 | 
							
								               function);
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								         RealType nccs_pdf(const non_central_chi_squared_distribution<RealType, Policy>& dist, const RealType& x)
							 | 
						||
| 
								 | 
							
								         {
							 | 
						||
| 
								 | 
							
								            BOOST_MATH_STD_USING
							 | 
						||
| 
								 | 
							
								            static const char* function = "pdf(non_central_chi_squared_distribution<%1%>, %1%)";
							 | 
						||
| 
								 | 
							
								            typedef typename policies::evaluation<RealType, Policy>::type value_type;
							 | 
						||
| 
								 | 
							
								            typedef typename policies::normalise<
							 | 
						||
| 
								 | 
							
								               Policy,
							 | 
						||
| 
								 | 
							
								               policies::promote_float<false>,
							 | 
						||
| 
								 | 
							
								               policies::promote_double<false>,
							 | 
						||
| 
								 | 
							
								               policies::discrete_quantile<>,
							 | 
						||
| 
								 | 
							
								               policies::assert_undefined<> >::type forwarding_policy;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            value_type k = dist.degrees_of_freedom();
							 | 
						||
| 
								 | 
							
								            value_type l = dist.non_centrality();
							 | 
						||
| 
								 | 
							
								            value_type r;
							 | 
						||
| 
								 | 
							
								            if(!detail::check_df(
							 | 
						||
| 
								 | 
							
								               function,
							 | 
						||
| 
								 | 
							
								               k, &r, Policy())
							 | 
						||
| 
								 | 
							
								               ||
							 | 
						||
| 
								 | 
							
								            !detail::check_non_centrality(
							 | 
						||
| 
								 | 
							
								               function,
							 | 
						||
| 
								 | 
							
								               l,
							 | 
						||
| 
								 | 
							
								               &r,
							 | 
						||
| 
								 | 
							
								               Policy())
							 | 
						||
| 
								 | 
							
								               ||
							 | 
						||
| 
								 | 
							
								            !detail::check_positive_x(
							 | 
						||
| 
								 | 
							
								               function,
							 | 
						||
| 
								 | 
							
								               (value_type)x,
							 | 
						||
| 
								 | 
							
								               &r,
							 | 
						||
| 
								 | 
							
								               Policy()))
							 | 
						||
| 
								 | 
							
								                  return (RealType)r;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         if(l == 0)
							 | 
						||
| 
								 | 
							
								            return pdf(boost::math::chi_squared_distribution<RealType, forwarding_policy>(dist.degrees_of_freedom()), x);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         // Special case:
							 | 
						||
| 
								 | 
							
								         if(x == 0)
							 | 
						||
| 
								 | 
							
								            return 0;
							 | 
						||
| 
								 | 
							
								         if(l > 50)
							 | 
						||
| 
								 | 
							
								         {
							 | 
						||
| 
								 | 
							
								            r = non_central_chi_square_pdf(static_cast<value_type>(x), k, l, forwarding_policy());
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								         else
							 | 
						||
| 
								 | 
							
								         {
							 | 
						||
| 
								 | 
							
								            r = log(x / l) * (k / 4 - 0.5f) - (x + l) / 2;
							 | 
						||
| 
								 | 
							
								            if(fabs(r) >= tools::log_max_value<RealType>() / 4)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								               r = non_central_chi_square_pdf(static_cast<value_type>(x), k, l, forwarding_policy());
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								               r = exp(r);
							 | 
						||
| 
								 | 
							
								               r = 0.5f * r
							 | 
						||
| 
								 | 
							
								                  * boost::math::cyl_bessel_i(k/2 - 1, sqrt(l * x), forwarding_policy());
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								         return policies::checked_narrowing_cast<RealType, forwarding_policy>(
							 | 
						||
| 
								 | 
							
								               r,
							 | 
						||
| 
								 | 
							
								               function);
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								         struct degrees_of_freedom_finder
							 | 
						||
| 
								 | 
							
								         {
							 | 
						||
| 
								 | 
							
								            degrees_of_freedom_finder(
							 | 
						||
| 
								 | 
							
								               RealType lam_, RealType x_, RealType p_, bool c)
							 | 
						||
| 
								 | 
							
								               : lam(lam_), x(x_), p(p_), comp(c) {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            RealType operator()(const RealType& v)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								               non_central_chi_squared_distribution<RealType, Policy> d(v, lam);
							 | 
						||
| 
								 | 
							
								               return comp ?
							 | 
						||
| 
								 | 
							
								                  RealType(p - cdf(complement(d, x)))
							 | 
						||
| 
								 | 
							
								                  : RealType(cdf(d, x) - p);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								         private:
							 | 
						||
| 
								 | 
							
								            RealType lam;
							 | 
						||
| 
								 | 
							
								            RealType x;
							 | 
						||
| 
								 | 
							
								            RealType p;
							 | 
						||
| 
								 | 
							
								            bool comp;
							 | 
						||
| 
								 | 
							
								         };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								         inline RealType find_degrees_of_freedom(
							 | 
						||
| 
								 | 
							
								            RealType lam, RealType x, RealType p, RealType q, const Policy& pol)
							 | 
						||
| 
								 | 
							
								         {
							 | 
						||
| 
								 | 
							
								            const char* function = "non_central_chi_squared<%1%>::find_degrees_of_freedom";
							 | 
						||
| 
								 | 
							
								            if((p == 0) || (q == 0))
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								               //
							 | 
						||
| 
								 | 
							
								               // Can't a thing if one of p and q is zero:
							 | 
						||
| 
								 | 
							
								               //
							 | 
						||
| 
								 | 
							
								               return policies::raise_evaluation_error<RealType>(function,
							 | 
						||
| 
								 | 
							
								                  "Can't find degrees of freedom when the probability is 0 or 1, only possible answer is %1%",
							 | 
						||
| 
								 | 
							
								                  RealType(std::numeric_limits<RealType>::quiet_NaN()), Policy());
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            degrees_of_freedom_finder<RealType, Policy> f(lam, x, p < q ? p : q, p < q ? false : true);
							 | 
						||
| 
								 | 
							
								            tools::eps_tolerance<RealType> tol(policies::digits<RealType, Policy>());
							 | 
						||
| 
								 | 
							
								            boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            // Pick an initial guess that we know will give us a probability
							 | 
						||
| 
								 | 
							
								            // right around 0.5.
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            RealType guess = x - lam;
							 | 
						||
| 
								 | 
							
								            if(guess < 1)
							 | 
						||
| 
								 | 
							
								               guess = 1;
							 | 
						||
| 
								 | 
							
								            std::pair<RealType, RealType> ir = tools::bracket_and_solve_root(
							 | 
						||
| 
								 | 
							
								               f, guess, RealType(2), false, tol, max_iter, pol);
							 | 
						||
| 
								 | 
							
								            RealType result = ir.first + (ir.second - ir.first) / 2;
							 | 
						||
| 
								 | 
							
								            if(max_iter >= policies::get_max_root_iterations<Policy>())
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								               return policies::raise_evaluation_error<RealType>(function, "Unable to locate solution in a reasonable time:"
							 | 
						||
| 
								 | 
							
								                  " or there is no answer to problem.  Current best guess is %1%", result, Policy());
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            return result;
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								         struct non_centrality_finder
							 | 
						||
| 
								 | 
							
								         {
							 | 
						||
| 
								 | 
							
								            non_centrality_finder(
							 | 
						||
| 
								 | 
							
								               RealType v_, RealType x_, RealType p_, bool c)
							 | 
						||
| 
								 | 
							
								               : v(v_), x(x_), p(p_), comp(c) {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            RealType operator()(const RealType& lam)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								               non_central_chi_squared_distribution<RealType, Policy> d(v, lam);
							 | 
						||
| 
								 | 
							
								               return comp ?
							 | 
						||
| 
								 | 
							
								                  RealType(p - cdf(complement(d, x)))
							 | 
						||
| 
								 | 
							
								                  : RealType(cdf(d, x) - p);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								         private:
							 | 
						||
| 
								 | 
							
								            RealType v;
							 | 
						||
| 
								 | 
							
								            RealType x;
							 | 
						||
| 
								 | 
							
								            RealType p;
							 | 
						||
| 
								 | 
							
								            bool comp;
							 | 
						||
| 
								 | 
							
								         };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								         inline RealType find_non_centrality(
							 | 
						||
| 
								 | 
							
								            RealType v, RealType x, RealType p, RealType q, const Policy& pol)
							 | 
						||
| 
								 | 
							
								         {
							 | 
						||
| 
								 | 
							
								            const char* function = "non_central_chi_squared<%1%>::find_non_centrality";
							 | 
						||
| 
								 | 
							
								            if((p == 0) || (q == 0))
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								               //
							 | 
						||
| 
								 | 
							
								               // Can't do a thing if one of p and q is zero:
							 | 
						||
| 
								 | 
							
								               //
							 | 
						||
| 
								 | 
							
								               return policies::raise_evaluation_error<RealType>(function,
							 | 
						||
| 
								 | 
							
								                  "Can't find non centrality parameter when the probability is 0 or 1, only possible answer is %1%",
							 | 
						||
| 
								 | 
							
								                  RealType(std::numeric_limits<RealType>::quiet_NaN()), Policy());
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            non_centrality_finder<RealType, Policy> f(v, x, p < q ? p : q, p < q ? false : true);
							 | 
						||
| 
								 | 
							
								            tools::eps_tolerance<RealType> tol(policies::digits<RealType, Policy>());
							 | 
						||
| 
								 | 
							
								            boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            // Pick an initial guess that we know will give us a probability
							 | 
						||
| 
								 | 
							
								            // right around 0.5.
							 | 
						||
| 
								 | 
							
								            //
							 | 
						||
| 
								 | 
							
								            RealType guess = x - v;
							 | 
						||
| 
								 | 
							
								            if(guess < 1)
							 | 
						||
| 
								 | 
							
								               guess = 1;
							 | 
						||
| 
								 | 
							
								            std::pair<RealType, RealType> ir = tools::bracket_and_solve_root(
							 | 
						||
| 
								 | 
							
								               f, guess, RealType(2), false, tol, max_iter, pol);
							 | 
						||
| 
								 | 
							
								            RealType result = ir.first + (ir.second - ir.first) / 2;
							 | 
						||
| 
								 | 
							
								            if(max_iter >= policies::get_max_root_iterations<Policy>())
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								               return policies::raise_evaluation_error<RealType>(function, "Unable to locate solution in a reasonable time:"
							 | 
						||
| 
								 | 
							
								                  " or there is no answer to problem.  Current best guess is %1%", result, Policy());
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            return result;
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      template <class RealType = double, class Policy = policies::policy<> >
							 | 
						||
| 
								 | 
							
								      class non_central_chi_squared_distribution
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								      public:
							 | 
						||
| 
								 | 
							
								         typedef RealType value_type;
							 | 
						||
| 
								 | 
							
								         typedef Policy policy_type;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         non_central_chi_squared_distribution(RealType df_, RealType lambda) : df(df_), ncp(lambda)
							 | 
						||
| 
								 | 
							
								         {
							 | 
						||
| 
								 | 
							
								            const char* function = "boost::math::non_central_chi_squared_distribution<%1%>::non_central_chi_squared_distribution(%1%,%1%)";
							 | 
						||
| 
								 | 
							
								            RealType r;
							 | 
						||
| 
								 | 
							
								            detail::check_df(
							 | 
						||
| 
								 | 
							
								               function,
							 | 
						||
| 
								 | 
							
								               df, &r, Policy());
							 | 
						||
| 
								 | 
							
								            detail::check_non_centrality(
							 | 
						||
| 
								 | 
							
								               function,
							 | 
						||
| 
								 | 
							
								               ncp,
							 | 
						||
| 
								 | 
							
								               &r,
							 | 
						||
| 
								 | 
							
								               Policy());
							 | 
						||
| 
								 | 
							
								         } // non_central_chi_squared_distribution constructor.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         RealType degrees_of_freedom() const
							 | 
						||
| 
								 | 
							
								         { // Private data getter function.
							 | 
						||
| 
								 | 
							
								            return df;
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								         RealType non_centrality() const
							 | 
						||
| 
								 | 
							
								         { // Private data getter function.
							 | 
						||
| 
								 | 
							
								            return ncp;
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								         static RealType find_degrees_of_freedom(RealType lam, RealType x, RealType p)
							 | 
						||
| 
								 | 
							
								         {
							 | 
						||
| 
								 | 
							
								            const char* function = "non_central_chi_squared<%1%>::find_degrees_of_freedom";
							 | 
						||
| 
								 | 
							
								            typedef typename policies::evaluation<RealType, Policy>::type eval_type;
							 | 
						||
| 
								 | 
							
								            typedef typename policies::normalise<
							 | 
						||
| 
								 | 
							
								               Policy,
							 | 
						||
| 
								 | 
							
								               policies::promote_float<false>,
							 | 
						||
| 
								 | 
							
								               policies::promote_double<false>,
							 | 
						||
| 
								 | 
							
								               policies::discrete_quantile<>,
							 | 
						||
| 
								 | 
							
								               policies::assert_undefined<> >::type forwarding_policy;
							 | 
						||
| 
								 | 
							
								            eval_type result = detail::find_degrees_of_freedom(
							 | 
						||
| 
								 | 
							
								               static_cast<eval_type>(lam),
							 | 
						||
| 
								 | 
							
								               static_cast<eval_type>(x),
							 | 
						||
| 
								 | 
							
								               static_cast<eval_type>(p),
							 | 
						||
| 
								 | 
							
								               static_cast<eval_type>(1-p),
							 | 
						||
| 
								 | 
							
								               forwarding_policy());
							 | 
						||
| 
								 | 
							
								            return policies::checked_narrowing_cast<RealType, forwarding_policy>(
							 | 
						||
| 
								 | 
							
								               result,
							 | 
						||
| 
								 | 
							
								               function);
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								         template <class A, class B, class C>
							 | 
						||
| 
								 | 
							
								         static RealType find_degrees_of_freedom(const complemented3_type<A,B,C>& c)
							 | 
						||
| 
								 | 
							
								         {
							 | 
						||
| 
								 | 
							
								            const char* function = "non_central_chi_squared<%1%>::find_degrees_of_freedom";
							 | 
						||
| 
								 | 
							
								            typedef typename policies::evaluation<RealType, Policy>::type eval_type;
							 | 
						||
| 
								 | 
							
								            typedef typename policies::normalise<
							 | 
						||
| 
								 | 
							
								               Policy,
							 | 
						||
| 
								 | 
							
								               policies::promote_float<false>,
							 | 
						||
| 
								 | 
							
								               policies::promote_double<false>,
							 | 
						||
| 
								 | 
							
								               policies::discrete_quantile<>,
							 | 
						||
| 
								 | 
							
								               policies::assert_undefined<> >::type forwarding_policy;
							 | 
						||
| 
								 | 
							
								            eval_type result = detail::find_degrees_of_freedom(
							 | 
						||
| 
								 | 
							
								               static_cast<eval_type>(c.dist),
							 | 
						||
| 
								 | 
							
								               static_cast<eval_type>(c.param1),
							 | 
						||
| 
								 | 
							
								               static_cast<eval_type>(1-c.param2),
							 | 
						||
| 
								 | 
							
								               static_cast<eval_type>(c.param2),
							 | 
						||
| 
								 | 
							
								               forwarding_policy());
							 | 
						||
| 
								 | 
							
								            return policies::checked_narrowing_cast<RealType, forwarding_policy>(
							 | 
						||
| 
								 | 
							
								               result,
							 | 
						||
| 
								 | 
							
								               function);
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								         static RealType find_non_centrality(RealType v, RealType x, RealType p)
							 | 
						||
| 
								 | 
							
								         {
							 | 
						||
| 
								 | 
							
								            const char* function = "non_central_chi_squared<%1%>::find_non_centrality";
							 | 
						||
| 
								 | 
							
								            typedef typename policies::evaluation<RealType, Policy>::type eval_type;
							 | 
						||
| 
								 | 
							
								            typedef typename policies::normalise<
							 | 
						||
| 
								 | 
							
								               Policy,
							 | 
						||
| 
								 | 
							
								               policies::promote_float<false>,
							 | 
						||
| 
								 | 
							
								               policies::promote_double<false>,
							 | 
						||
| 
								 | 
							
								               policies::discrete_quantile<>,
							 | 
						||
| 
								 | 
							
								               policies::assert_undefined<> >::type forwarding_policy;
							 | 
						||
| 
								 | 
							
								            eval_type result = detail::find_non_centrality(
							 | 
						||
| 
								 | 
							
								               static_cast<eval_type>(v),
							 | 
						||
| 
								 | 
							
								               static_cast<eval_type>(x),
							 | 
						||
| 
								 | 
							
								               static_cast<eval_type>(p),
							 | 
						||
| 
								 | 
							
								               static_cast<eval_type>(1-p),
							 | 
						||
| 
								 | 
							
								               forwarding_policy());
							 | 
						||
| 
								 | 
							
								            return policies::checked_narrowing_cast<RealType, forwarding_policy>(
							 | 
						||
| 
								 | 
							
								               result,
							 | 
						||
| 
								 | 
							
								               function);
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								         template <class A, class B, class C>
							 | 
						||
| 
								 | 
							
								         static RealType find_non_centrality(const complemented3_type<A,B,C>& c)
							 | 
						||
| 
								 | 
							
								         {
							 | 
						||
| 
								 | 
							
								            const char* function = "non_central_chi_squared<%1%>::find_non_centrality";
							 | 
						||
| 
								 | 
							
								            typedef typename policies::evaluation<RealType, Policy>::type eval_type;
							 | 
						||
| 
								 | 
							
								            typedef typename policies::normalise<
							 | 
						||
| 
								 | 
							
								               Policy,
							 | 
						||
| 
								 | 
							
								               policies::promote_float<false>,
							 | 
						||
| 
								 | 
							
								               policies::promote_double<false>,
							 | 
						||
| 
								 | 
							
								               policies::discrete_quantile<>,
							 | 
						||
| 
								 | 
							
								               policies::assert_undefined<> >::type forwarding_policy;
							 | 
						||
| 
								 | 
							
								            eval_type result = detail::find_non_centrality(
							 | 
						||
| 
								 | 
							
								               static_cast<eval_type>(c.dist),
							 | 
						||
| 
								 | 
							
								               static_cast<eval_type>(c.param1),
							 | 
						||
| 
								 | 
							
								               static_cast<eval_type>(1-c.param2),
							 | 
						||
| 
								 | 
							
								               static_cast<eval_type>(c.param2),
							 | 
						||
| 
								 | 
							
								               forwarding_policy());
							 | 
						||
| 
								 | 
							
								            return policies::checked_narrowing_cast<RealType, forwarding_policy>(
							 | 
						||
| 
								 | 
							
								               result,
							 | 
						||
| 
								 | 
							
								               function);
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								      private:
							 | 
						||
| 
								 | 
							
								         // Data member, initialized by constructor.
							 | 
						||
| 
								 | 
							
								         RealType df; // degrees of freedom.
							 | 
						||
| 
								 | 
							
								         RealType ncp; // non-centrality parameter
							 | 
						||
| 
								 | 
							
								      }; // template <class RealType, class Policy> class non_central_chi_squared_distribution
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      typedef non_central_chi_squared_distribution<double> non_central_chi_squared; // Reserved name of type double.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      // Non-member functions to give properties of the distribution.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								      inline const std::pair<RealType, RealType> range(const non_central_chi_squared_distribution<RealType, Policy>& /* dist */)
							 | 
						||
| 
								 | 
							
								      { // Range of permissible values for random variable k.
							 | 
						||
| 
								 | 
							
								         using boost::math::tools::max_value;
							 | 
						||
| 
								 | 
							
								         return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>()); // Max integer?
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								      inline const std::pair<RealType, RealType> support(const non_central_chi_squared_distribution<RealType, Policy>& /* dist */)
							 | 
						||
| 
								 | 
							
								      { // Range of supported values for random variable k.
							 | 
						||
| 
								 | 
							
								         // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
							 | 
						||
| 
								 | 
							
								         using boost::math::tools::max_value;
							 | 
						||
| 
								 | 
							
								         return std::pair<RealType, RealType>(static_cast<RealType>(0),  max_value<RealType>());
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								      inline RealType mean(const non_central_chi_squared_distribution<RealType, Policy>& dist)
							 | 
						||
| 
								 | 
							
								      { // Mean of poisson distribution = lambda.
							 | 
						||
| 
								 | 
							
								         const char* function = "boost::math::non_central_chi_squared_distribution<%1%>::mean()";
							 | 
						||
| 
								 | 
							
								         RealType k = dist.degrees_of_freedom();
							 | 
						||
| 
								 | 
							
								         RealType l = dist.non_centrality();
							 | 
						||
| 
								 | 
							
								         RealType r;
							 | 
						||
| 
								 | 
							
								         if(!detail::check_df(
							 | 
						||
| 
								 | 
							
								            function,
							 | 
						||
| 
								 | 
							
								            k, &r, Policy())
							 | 
						||
| 
								 | 
							
								            ||
							 | 
						||
| 
								 | 
							
								         !detail::check_non_centrality(
							 | 
						||
| 
								 | 
							
								            function,
							 | 
						||
| 
								 | 
							
								            l,
							 | 
						||
| 
								 | 
							
								            &r,
							 | 
						||
| 
								 | 
							
								            Policy()))
							 | 
						||
| 
								 | 
							
								               return r;
							 | 
						||
| 
								 | 
							
								         return k + l;
							 | 
						||
| 
								 | 
							
								      } // mean
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								      inline RealType mode(const non_central_chi_squared_distribution<RealType, Policy>& dist)
							 | 
						||
| 
								 | 
							
								      { // mode.
							 | 
						||
| 
								 | 
							
								         static const char* function = "mode(non_central_chi_squared_distribution<%1%> const&)";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         RealType k = dist.degrees_of_freedom();
							 | 
						||
| 
								 | 
							
								         RealType l = dist.non_centrality();
							 | 
						||
| 
								 | 
							
								         RealType r;
							 | 
						||
| 
								 | 
							
								         if(!detail::check_df(
							 | 
						||
| 
								 | 
							
								            function,
							 | 
						||
| 
								 | 
							
								            k, &r, Policy())
							 | 
						||
| 
								 | 
							
								            ||
							 | 
						||
| 
								 | 
							
								         !detail::check_non_centrality(
							 | 
						||
| 
								 | 
							
								            function,
							 | 
						||
| 
								 | 
							
								            l,
							 | 
						||
| 
								 | 
							
								            &r,
							 | 
						||
| 
								 | 
							
								            Policy()))
							 | 
						||
| 
								 | 
							
								               return (RealType)r;
							 | 
						||
| 
								 | 
							
								         return detail::generic_find_mode(dist, 1 + k, function);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								      inline RealType variance(const non_central_chi_squared_distribution<RealType, Policy>& dist)
							 | 
						||
| 
								 | 
							
								      { // variance.
							 | 
						||
| 
								 | 
							
								         const char* function = "boost::math::non_central_chi_squared_distribution<%1%>::variance()";
							 | 
						||
| 
								 | 
							
								         RealType k = dist.degrees_of_freedom();
							 | 
						||
| 
								 | 
							
								         RealType l = dist.non_centrality();
							 | 
						||
| 
								 | 
							
								         RealType r;
							 | 
						||
| 
								 | 
							
								         if(!detail::check_df(
							 | 
						||
| 
								 | 
							
								            function,
							 | 
						||
| 
								 | 
							
								            k, &r, Policy())
							 | 
						||
| 
								 | 
							
								            ||
							 | 
						||
| 
								 | 
							
								         !detail::check_non_centrality(
							 | 
						||
| 
								 | 
							
								            function,
							 | 
						||
| 
								 | 
							
								            l,
							 | 
						||
| 
								 | 
							
								            &r,
							 | 
						||
| 
								 | 
							
								            Policy()))
							 | 
						||
| 
								 | 
							
								               return r;
							 | 
						||
| 
								 | 
							
								         return 2 * (2 * l + k);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      // RealType standard_deviation(const non_central_chi_squared_distribution<RealType, Policy>& dist)
							 | 
						||
| 
								 | 
							
								      // standard_deviation provided by derived accessors.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								      inline RealType skewness(const non_central_chi_squared_distribution<RealType, Policy>& dist)
							 | 
						||
| 
								 | 
							
								      { // skewness = sqrt(l).
							 | 
						||
| 
								 | 
							
								         const char* function = "boost::math::non_central_chi_squared_distribution<%1%>::skewness()";
							 | 
						||
| 
								 | 
							
								         RealType k = dist.degrees_of_freedom();
							 | 
						||
| 
								 | 
							
								         RealType l = dist.non_centrality();
							 | 
						||
| 
								 | 
							
								         RealType r;
							 | 
						||
| 
								 | 
							
								         if(!detail::check_df(
							 | 
						||
| 
								 | 
							
								            function,
							 | 
						||
| 
								 | 
							
								            k, &r, Policy())
							 | 
						||
| 
								 | 
							
								            ||
							 | 
						||
| 
								 | 
							
								         !detail::check_non_centrality(
							 | 
						||
| 
								 | 
							
								            function,
							 | 
						||
| 
								 | 
							
								            l,
							 | 
						||
| 
								 | 
							
								            &r,
							 | 
						||
| 
								 | 
							
								            Policy()))
							 | 
						||
| 
								 | 
							
								               return r;
							 | 
						||
| 
								 | 
							
								         BOOST_MATH_STD_USING
							 | 
						||
| 
								 | 
							
								            return pow(2 / (k + 2 * l), RealType(3)/2) * (k + 3 * l);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								      inline RealType kurtosis_excess(const non_central_chi_squared_distribution<RealType, Policy>& dist)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								         const char* function = "boost::math::non_central_chi_squared_distribution<%1%>::kurtosis_excess()";
							 | 
						||
| 
								 | 
							
								         RealType k = dist.degrees_of_freedom();
							 | 
						||
| 
								 | 
							
								         RealType l = dist.non_centrality();
							 | 
						||
| 
								 | 
							
								         RealType r;
							 | 
						||
| 
								 | 
							
								         if(!detail::check_df(
							 | 
						||
| 
								 | 
							
								            function,
							 | 
						||
| 
								 | 
							
								            k, &r, Policy())
							 | 
						||
| 
								 | 
							
								            ||
							 | 
						||
| 
								 | 
							
								         !detail::check_non_centrality(
							 | 
						||
| 
								 | 
							
								            function,
							 | 
						||
| 
								 | 
							
								            l,
							 | 
						||
| 
								 | 
							
								            &r,
							 | 
						||
| 
								 | 
							
								            Policy()))
							 | 
						||
| 
								 | 
							
								               return r;
							 | 
						||
| 
								 | 
							
								         return 12 * (k + 4 * l) / ((k + 2 * l) * (k + 2 * l));
							 | 
						||
| 
								 | 
							
								      } // kurtosis_excess
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								      inline RealType kurtosis(const non_central_chi_squared_distribution<RealType, Policy>& dist)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								         return kurtosis_excess(dist) + 3;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								      inline RealType pdf(const non_central_chi_squared_distribution<RealType, Policy>& dist, const RealType& x)
							 | 
						||
| 
								 | 
							
								      { // Probability Density/Mass Function.
							 | 
						||
| 
								 | 
							
								         return detail::nccs_pdf(dist, x);
							 | 
						||
| 
								 | 
							
								      } // pdf
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								      RealType cdf(const non_central_chi_squared_distribution<RealType, Policy>& dist, const RealType& x)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								         const char* function = "boost::math::non_central_chi_squared_distribution<%1%>::cdf(%1%)";
							 | 
						||
| 
								 | 
							
								         RealType k = dist.degrees_of_freedom();
							 | 
						||
| 
								 | 
							
								         RealType l = dist.non_centrality();
							 | 
						||
| 
								 | 
							
								         RealType r;
							 | 
						||
| 
								 | 
							
								         if(!detail::check_df(
							 | 
						||
| 
								 | 
							
								            function,
							 | 
						||
| 
								 | 
							
								            k, &r, Policy())
							 | 
						||
| 
								 | 
							
								            ||
							 | 
						||
| 
								 | 
							
								         !detail::check_non_centrality(
							 | 
						||
| 
								 | 
							
								            function,
							 | 
						||
| 
								 | 
							
								            l,
							 | 
						||
| 
								 | 
							
								            &r,
							 | 
						||
| 
								 | 
							
								            Policy())
							 | 
						||
| 
								 | 
							
								            ||
							 | 
						||
| 
								 | 
							
								         !detail::check_positive_x(
							 | 
						||
| 
								 | 
							
								            function,
							 | 
						||
| 
								 | 
							
								            x,
							 | 
						||
| 
								 | 
							
								            &r,
							 | 
						||
| 
								 | 
							
								            Policy()))
							 | 
						||
| 
								 | 
							
								               return r;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         return detail::non_central_chi_squared_cdf(x, k, l, false, Policy());
							 | 
						||
| 
								 | 
							
								      } // cdf
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								      RealType cdf(const complemented2_type<non_central_chi_squared_distribution<RealType, Policy>, RealType>& c)
							 | 
						||
| 
								 | 
							
								      { // Complemented Cumulative Distribution Function
							 | 
						||
| 
								 | 
							
								         const char* function = "boost::math::non_central_chi_squared_distribution<%1%>::cdf(%1%)";
							 | 
						||
| 
								 | 
							
								         non_central_chi_squared_distribution<RealType, Policy> const& dist = c.dist;
							 | 
						||
| 
								 | 
							
								         RealType x = c.param;
							 | 
						||
| 
								 | 
							
								         RealType k = dist.degrees_of_freedom();
							 | 
						||
| 
								 | 
							
								         RealType l = dist.non_centrality();
							 | 
						||
| 
								 | 
							
								         RealType r;
							 | 
						||
| 
								 | 
							
								         if(!detail::check_df(
							 | 
						||
| 
								 | 
							
								            function,
							 | 
						||
| 
								 | 
							
								            k, &r, Policy())
							 | 
						||
| 
								 | 
							
								            ||
							 | 
						||
| 
								 | 
							
								         !detail::check_non_centrality(
							 | 
						||
| 
								 | 
							
								            function,
							 | 
						||
| 
								 | 
							
								            l,
							 | 
						||
| 
								 | 
							
								            &r,
							 | 
						||
| 
								 | 
							
								            Policy())
							 | 
						||
| 
								 | 
							
								            ||
							 | 
						||
| 
								 | 
							
								         !detail::check_positive_x(
							 | 
						||
| 
								 | 
							
								            function,
							 | 
						||
| 
								 | 
							
								            x,
							 | 
						||
| 
								 | 
							
								            &r,
							 | 
						||
| 
								 | 
							
								            Policy()))
							 | 
						||
| 
								 | 
							
								               return r;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								         return detail::non_central_chi_squared_cdf(x, k, l, true, Policy());
							 | 
						||
| 
								 | 
							
								      } // ccdf
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								      inline RealType quantile(const non_central_chi_squared_distribution<RealType, Policy>& dist, const RealType& p)
							 | 
						||
| 
								 | 
							
								      { // Quantile (or Percent Point) function.
							 | 
						||
| 
								 | 
							
								         return detail::nccs_quantile(dist, p, false);
							 | 
						||
| 
								 | 
							
								      } // quantile
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      template <class RealType, class Policy>
							 | 
						||
| 
								 | 
							
								      inline RealType quantile(const complemented2_type<non_central_chi_squared_distribution<RealType, Policy>, RealType>& c)
							 | 
						||
| 
								 | 
							
								      { // Quantile (or Percent Point) function.
							 | 
						||
| 
								 | 
							
								         return detail::nccs_quantile(c.dist, c.param, true);
							 | 
						||
| 
								 | 
							
								      } // quantile complement.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   } // namespace math
							 | 
						||
| 
								 | 
							
								} // namespace boost
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// This include must be at the end, *after* the accessors
							 | 
						||
| 
								 | 
							
								// for this distribution have been defined, in order to
							 | 
						||
| 
								 | 
							
								// keep compilers that support two-phase lookup happy.
							 | 
						||
| 
								 | 
							
								#include <boost/math/distributions/detail/derived_accessors.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif // BOOST_MATH_SPECIAL_NON_CENTRAL_CHI_SQUARE_HPP
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 |