618 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			618 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								//  Copyright (c) 2013 Christopher Kormanyos
							 | 
						||
| 
								 | 
							
								//  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)
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// This work is based on an earlier work:
							 | 
						||
| 
								 | 
							
								// "Algorithm 910: A Portable C++ Multiple-Precision System for Special-Function Calculations",
							 | 
						||
| 
								 | 
							
								// in ACM TOMS, {VOL 37, ISSUE 4, (February 2011)} (C) ACM, 2011. http://doi.acm.org/10.1145/1916461.1916469
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// This header contains implementation details for estimating the zeros
							 | 
						||
| 
								 | 
							
								// of cylindrical Bessel and Neumann functions on the positive real axis.
							 | 
						||
| 
								 | 
							
								// Support is included for both positive as well as negative order.
							 | 
						||
| 
								 | 
							
								// Various methods are used to estimate the roots. These include
							 | 
						||
| 
								 | 
							
								// empirical curve fitting and McMahon's asymptotic approximation
							 | 
						||
| 
								 | 
							
								// for small order, uniform asymptotic expansion for large order,
							 | 
						||
| 
								 | 
							
								// and iteration and root interlacing for negative order.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								#ifndef _BESSEL_JY_ZERO_2013_01_18_HPP_
							 | 
						||
| 
								 | 
							
								  #define _BESSEL_JY_ZERO_2013_01_18_HPP_
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  #include <algorithm>
							 | 
						||
| 
								 | 
							
								  #include <boost/math/constants/constants.hpp>
							 | 
						||
| 
								 | 
							
								  #include <boost/math/special_functions/math_fwd.hpp>
							 | 
						||
| 
								 | 
							
								  #include <boost/math/special_functions/cbrt.hpp>
							 | 
						||
| 
								 | 
							
								  #include <boost/math/special_functions/detail/airy_ai_bi_zero.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  namespace boost { namespace math {
							 | 
						||
| 
								 | 
							
								  namespace detail
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    namespace bessel_zero
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      template<class T>
							 | 
						||
| 
								 | 
							
								      T equation_nist_10_21_19(const T& v, const T& a)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        // Get the initial estimate of the m'th root of Jv or Yv.
							 | 
						||
| 
								 | 
							
								        // This subroutine is used for the order m with m > 1.
							 | 
						||
| 
								 | 
							
								        // The order m has been used to create the input parameter a.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // This is Eq. 10.21.19 in the NIST Handbook.
							 | 
						||
| 
								 | 
							
								        const T mu                  = (v * v) * 4U;
							 | 
						||
| 
								 | 
							
								        const T mu_minus_one        = mu - T(1);
							 | 
						||
| 
								 | 
							
								        const T eight_a_inv         = T(1) / (a * 8U);
							 | 
						||
| 
								 | 
							
								        const T eight_a_inv_squared = eight_a_inv * eight_a_inv;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        const T term3 = ((mu_minus_one *  4U) *     ((mu *    7U) -     T(31U) )) / 3U;
							 | 
						||
| 
								 | 
							
								        const T term5 = ((mu_minus_one * 32U) *   ((((mu *   83U) -    T(982U) ) * mu) +    T(3779U) )) / 15U;
							 | 
						||
| 
								 | 
							
								        const T term7 = ((mu_minus_one * 64U) * ((((((mu * 6949U) - T(153855UL)) * mu) + T(1585743UL)) * mu) - T(6277237UL))) / 105U;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return a + ((((                      - term7
							 | 
						||
| 
								 | 
							
								                       * eight_a_inv_squared - term5)
							 | 
						||
| 
								 | 
							
								                       * eight_a_inv_squared - term3)
							 | 
						||
| 
								 | 
							
								                       * eight_a_inv_squared - mu_minus_one)
							 | 
						||
| 
								 | 
							
								                       * eight_a_inv);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      template<typename T>
							 | 
						||
| 
								 | 
							
								      class equation_as_9_3_39_and_its_derivative
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								      public:
							 | 
						||
| 
								 | 
							
								        equation_as_9_3_39_and_its_derivative(const T& zt) : zeta(zt) { }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        boost::math::tuple<T, T> operator()(const T& z) const
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								          BOOST_MATH_STD_USING // ADL of std names, needed for acos, sqrt.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          // Return the function of zeta that is implicitly defined
							 | 
						||
| 
								 | 
							
								          // in A&S Eq. 9.3.39 as a function of z. The function is
							 | 
						||
| 
								 | 
							
								          // returned along with its derivative with respect to z.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          const T zsq_minus_one_sqrt = sqrt((z * z) - T(1));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          const T the_function(
							 | 
						||
| 
								 | 
							
								              zsq_minus_one_sqrt
							 | 
						||
| 
								 | 
							
								            - (  acos(T(1) / z) + ((T(2) / 3U) * (zeta * sqrt(zeta)))));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          const T its_derivative(zsq_minus_one_sqrt / z);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          return boost::math::tuple<T, T>(the_function, its_derivative);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      private:
							 | 
						||
| 
								 | 
							
								        const equation_as_9_3_39_and_its_derivative& operator=(const equation_as_9_3_39_and_its_derivative&);
							 | 
						||
| 
								 | 
							
								        const T zeta;
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      template<class T>
							 | 
						||
| 
								 | 
							
								      static T equation_as_9_5_26(const T& v, const T& ai_bi_root)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        BOOST_MATH_STD_USING // ADL of std names, needed for log, sqrt.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Obtain the estimate of the m'th zero of Jv or Yv.
							 | 
						||
| 
								 | 
							
								        // The order m has been used to create the input parameter ai_bi_root.
							 | 
						||
| 
								 | 
							
								        // Here, v is larger than about 2.2. The estimate is computed
							 | 
						||
| 
								 | 
							
								        // from Abramowitz and Stegun Eqs. 9.5.22 and 9.5.26, page 371.
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        // The inversion of z as a function of zeta is mentioned in the text
							 | 
						||
| 
								 | 
							
								        // following A&S Eq. 9.5.26. Here, we accomplish the inversion by
							 | 
						||
| 
								 | 
							
								        // performing a Taylor expansion of Eq. 9.3.39 for large z to order 2
							 | 
						||
| 
								 | 
							
								        // and solving the resulting quadratic equation, thereby taking
							 | 
						||
| 
								 | 
							
								        // the positive root of the quadratic.
							 | 
						||
| 
								 | 
							
								        // In other words: (2/3)(-zeta)^(3/2) approx = z + 1/(2z) - pi/2.
							 | 
						||
| 
								 | 
							
								        // This leads to: z^2 - [(2/3)(-zeta)^(3/2) + pi/2]z + 1/2 = 0.
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        // With this initial estimate, Newton-Raphson iteration is used
							 | 
						||
| 
								 | 
							
								        // to refine the value of the estimate of the root of z
							 | 
						||
| 
								 | 
							
								        // as a function of zeta.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        const T v_pow_third(boost::math::cbrt(v));
							 | 
						||
| 
								 | 
							
								        const T v_pow_minus_two_thirds(T(1) / (v_pow_third * v_pow_third));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Obtain zeta using the order v combined with the m'th root of
							 | 
						||
| 
								 | 
							
								        // an airy function, as shown in  A&S Eq. 9.5.22.
							 | 
						||
| 
								 | 
							
								        const T zeta = v_pow_minus_two_thirds * (-ai_bi_root);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        const T zeta_sqrt = sqrt(zeta);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Set up a quadratic equation based on the Taylor series
							 | 
						||
| 
								 | 
							
								        // expansion mentioned above.
							 | 
						||
| 
								 | 
							
								        const T b = -((((zeta * zeta_sqrt) * 2U) / 3U) + boost::math::constants::half_pi<T>());
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Solve the quadratic equation, taking the positive root.
							 | 
						||
| 
								 | 
							
								        const T z_estimate = (-b + sqrt((b * b) - T(2))) / 2U;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Establish the range, the digits, and the iteration limit
							 | 
						||
| 
								 | 
							
								        // for the upcoming root-finding.
							 | 
						||
| 
								 | 
							
								        const T range_zmin = (std::max<T>)(z_estimate - T(1), T(1));
							 | 
						||
| 
								 | 
							
								        const T range_zmax = z_estimate + T(1);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        const int my_digits10 = static_cast<int>(static_cast<float>(boost::math::tools::digits<T>() * 0.301F));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Select the maximum allowed iterations based on the number
							 | 
						||
| 
								 | 
							
								        // of decimal digits in the numeric type T, being at least 12.
							 | 
						||
| 
								 | 
							
								        const boost::uintmax_t iterations_allowed = static_cast<boost::uintmax_t>((std::max)(12, my_digits10 * 2));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        boost::uintmax_t iterations_used = iterations_allowed;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Calculate the root of z as a function of zeta.
							 | 
						||
| 
								 | 
							
								        const T z = boost::math::tools::newton_raphson_iterate(
							 | 
						||
| 
								 | 
							
								          boost::math::detail::bessel_zero::equation_as_9_3_39_and_its_derivative<T>(zeta),
							 | 
						||
| 
								 | 
							
								          z_estimate,
							 | 
						||
| 
								 | 
							
								          range_zmin,
							 | 
						||
| 
								 | 
							
								          range_zmax,
							 | 
						||
| 
								 | 
							
								          (std::min)(boost::math::tools::digits<T>(), boost::math::tools::digits<float>()),
							 | 
						||
| 
								 | 
							
								          iterations_used);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        static_cast<void>(iterations_used);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Continue with the implementation of A&S Eq. 9.3.39.
							 | 
						||
| 
								 | 
							
								        const T zsq_minus_one      = (z * z) - T(1);
							 | 
						||
| 
								 | 
							
								        const T zsq_minus_one_sqrt = sqrt(zsq_minus_one);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // This is A&S Eq. 9.3.42.
							 | 
						||
| 
								 | 
							
								        const T b0_term_5_24 = T(5) / ((zsq_minus_one * zsq_minus_one_sqrt) * 24U);
							 | 
						||
| 
								 | 
							
								        const T b0_term_1_8  = T(1) / ( zsq_minus_one_sqrt * 8U);
							 | 
						||
| 
								 | 
							
								        const T b0_term_5_48 = T(5) / ((zeta * zeta) * 48U);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        const T b0 = -b0_term_5_48 + ((b0_term_5_24 + b0_term_1_8) / zeta_sqrt);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // This is the second line of A&S Eq. 9.5.26 for f_k with k = 1.
							 | 
						||
| 
								 | 
							
								        const T f1 = ((z * zeta_sqrt) * b0) / zsq_minus_one_sqrt;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // This is A&S Eq. 9.5.22 expanded to k = 1 (i.e., one term in the series).
							 | 
						||
| 
								 | 
							
								        return (v * z) + (f1 / v);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      namespace cyl_bessel_j_zero_detail
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        template<class T>
							 | 
						||
| 
								 | 
							
								        T equation_nist_10_21_40_a(const T& v)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								          const T v_pow_third(boost::math::cbrt(v));
							 | 
						||
| 
								 | 
							
								          const T v_pow_minus_two_thirds(T(1) / (v_pow_third * v_pow_third));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          return v * (((((                         + T(0.043)
							 | 
						||
| 
								 | 
							
								                          * v_pow_minus_two_thirds - T(0.0908))
							 | 
						||
| 
								 | 
							
								                          * v_pow_minus_two_thirds - T(0.00397))
							 | 
						||
| 
								 | 
							
								                          * v_pow_minus_two_thirds + T(1.033150))
							 | 
						||
| 
								 | 
							
								                          * v_pow_minus_two_thirds + T(1.8557571))
							 | 
						||
| 
								 | 
							
								                          * v_pow_minus_two_thirds + T(1));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        template<class T, class Policy>
							 | 
						||
| 
								 | 
							
								        class function_object_jv
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								        public:
							 | 
						||
| 
								 | 
							
								          function_object_jv(const T& v,
							 | 
						||
| 
								 | 
							
								                             const Policy& pol) : my_v(v),
							 | 
						||
| 
								 | 
							
								                                                  my_pol(pol) { }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          T operator()(const T& x) const
							 | 
						||
| 
								 | 
							
								          {
							 | 
						||
| 
								 | 
							
								            return boost::math::cyl_bessel_j(my_v, x, my_pol);
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        private:
							 | 
						||
| 
								 | 
							
								          const T my_v;
							 | 
						||
| 
								 | 
							
								          const Policy& my_pol;
							 | 
						||
| 
								 | 
							
								          const function_object_jv& operator=(const function_object_jv&);
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        template<class T, class Policy>
							 | 
						||
| 
								 | 
							
								        class function_object_jv_and_jv_prime
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								        public:
							 | 
						||
| 
								 | 
							
								          function_object_jv_and_jv_prime(const T& v,
							 | 
						||
| 
								 | 
							
								                                          const bool order_is_zero,
							 | 
						||
| 
								 | 
							
								                                          const Policy& pol) : my_v(v),
							 | 
						||
| 
								 | 
							
								                                                               my_order_is_zero(order_is_zero),
							 | 
						||
| 
								 | 
							
								                                                               my_pol(pol) { }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          boost::math::tuple<T, T> operator()(const T& x) const
							 | 
						||
| 
								 | 
							
								          {
							 | 
						||
| 
								 | 
							
								            // Obtain Jv(x) and Jv'(x).
							 | 
						||
| 
								 | 
							
								            // Chris's original code called the Bessel function implementation layer direct, 
							 | 
						||
| 
								 | 
							
								            // but that circumvented optimizations for integer-orders.  Call the documented
							 | 
						||
| 
								 | 
							
								            // top level functions instead, and let them sort out which implementation to use.
							 | 
						||
| 
								 | 
							
								            T j_v;
							 | 
						||
| 
								 | 
							
								            T j_v_prime;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if(my_order_is_zero)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              j_v       =  boost::math::cyl_bessel_j(0, x, my_pol);
							 | 
						||
| 
								 | 
							
								              j_v_prime = -boost::math::cyl_bessel_j(1, x, my_pol);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                      j_v       = boost::math::cyl_bessel_j(  my_v,      x, my_pol);
							 | 
						||
| 
								 | 
							
								              const T j_v_m1     (boost::math::cyl_bessel_j(T(my_v - 1), x, my_pol));
							 | 
						||
| 
								 | 
							
								                      j_v_prime = j_v_m1 - ((my_v * j_v) / x);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // Return a tuple containing both Jv(x) and Jv'(x).
							 | 
						||
| 
								 | 
							
								            return boost::math::make_tuple(j_v, j_v_prime);
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        private:
							 | 
						||
| 
								 | 
							
								          const T my_v;
							 | 
						||
| 
								 | 
							
								          const bool my_order_is_zero;
							 | 
						||
| 
								 | 
							
								          const Policy& my_pol;
							 | 
						||
| 
								 | 
							
								          const function_object_jv_and_jv_prime& operator=(const function_object_jv_and_jv_prime&);
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        template<class T> bool my_bisection_unreachable_tolerance(const T&, const T&) { return false; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        template<class T, class Policy>
							 | 
						||
| 
								 | 
							
								        T initial_guess(const T& v, const int m, const Policy& pol)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								          BOOST_MATH_STD_USING // ADL of std names, needed for floor.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          // Compute an estimate of the m'th root of cyl_bessel_j.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          T guess;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          // There is special handling for negative order.
							 | 
						||
| 
								 | 
							
								          if(v < 0)
							 | 
						||
| 
								 | 
							
								          {
							 | 
						||
| 
								 | 
							
								            if((m == 1) && (v > -0.5F))
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              // For small, negative v, use the results of empirical curve fitting.
							 | 
						||
| 
								 | 
							
								              // Mathematica(R) session for the coefficients:
							 | 
						||
| 
								 | 
							
								              //  Table[{n, BesselJZero[n, 1]}, {n, -(1/2), 0, 1/10}]
							 | 
						||
| 
								 | 
							
								              //  N[%, 20]
							 | 
						||
| 
								 | 
							
								              //  Fit[%, {n^0, n^1, n^2, n^3, n^4, n^5, n^6}, n]
							 | 
						||
| 
								 | 
							
								              guess = (((((    - T(0.2321156900729)
							 | 
						||
| 
								 | 
							
								                           * v - T(0.1493247777488))
							 | 
						||
| 
								 | 
							
								                           * v - T(0.15205419167239))
							 | 
						||
| 
								 | 
							
								                           * v + T(0.07814930561249))
							 | 
						||
| 
								 | 
							
								                           * v - T(0.17757573537688))
							 | 
						||
| 
								 | 
							
								                           * v + T(1.542805677045663))
							 | 
						||
| 
								 | 
							
								                           * v + T(2.40482555769577277);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								              return guess;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // Create the positive order and extract its positive floor integer part.
							 | 
						||
| 
								 | 
							
								            const T vv(-v);
							 | 
						||
| 
								 | 
							
								            const T vv_floor(floor(vv));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // The to-be-found root is bracketed by the roots of the
							 | 
						||
| 
								 | 
							
								            // Bessel function whose reflected, positive integer order
							 | 
						||
| 
								 | 
							
								            // is less than, but nearest to vv.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            T root_hi = boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::initial_guess(vv_floor, m, pol);
							 | 
						||
| 
								 | 
							
								            T root_lo;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if(m == 1)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              // The estimate of the first root for negative order is found using
							 | 
						||
| 
								 | 
							
								              // an adaptive range-searching algorithm.
							 | 
						||
| 
								 | 
							
								              root_lo = T(root_hi - 0.1F);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								              const bool hi_end_of_bracket_is_negative = (boost::math::cyl_bessel_j(v, root_hi, pol) < 0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								              while((root_lo > boost::math::tools::epsilon<T>()))
							 | 
						||
| 
								 | 
							
								              {
							 | 
						||
| 
								 | 
							
								                const bool lo_end_of_bracket_is_negative = (boost::math::cyl_bessel_j(v, root_lo, pol) < 0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if(hi_end_of_bracket_is_negative != lo_end_of_bracket_is_negative)
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                  break;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                root_hi = root_lo;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                // Decrease the lower end of the bracket using an adaptive algorithm.
							 | 
						||
| 
								 | 
							
								                if(root_lo > 0.5F)
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                  root_lo -= 0.5F;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                else
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                  root_lo *= 0.75F;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								              }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              root_lo = boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::initial_guess(vv_floor, m - 1, pol);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // Perform several steps of bisection iteration to refine the guess.
							 | 
						||
| 
								 | 
							
								            boost::uintmax_t number_of_iterations(12U);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // Do the bisection iteration.
							 | 
						||
| 
								 | 
							
								            const boost::math::tuple<T, T> guess_pair =
							 | 
						||
| 
								 | 
							
								               boost::math::tools::bisect(
							 | 
						||
| 
								 | 
							
								                  boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::function_object_jv<T, Policy>(v, pol),
							 | 
						||
| 
								 | 
							
								                  root_lo,
							 | 
						||
| 
								 | 
							
								                  root_hi,
							 | 
						||
| 
								 | 
							
								                  boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::my_bisection_unreachable_tolerance<T>,
							 | 
						||
| 
								 | 
							
								                  number_of_iterations);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            return (boost::math::get<0>(guess_pair) + boost::math::get<1>(guess_pair)) / 2U;
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          if(m == 1U)
							 | 
						||
| 
								 | 
							
								          {
							 | 
						||
| 
								 | 
							
								            // Get the initial estimate of the first root.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if(v < 2.2F)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              // For small v, use the results of empirical curve fitting.
							 | 
						||
| 
								 | 
							
								              // Mathematica(R) session for the coefficients:
							 | 
						||
| 
								 | 
							
								              //  Table[{n, BesselJZero[n, 1]}, {n, 0, 22/10, 1/10}]
							 | 
						||
| 
								 | 
							
								              //  N[%, 20]
							 | 
						||
| 
								 | 
							
								              //  Fit[%, {n^0, n^1, n^2, n^3, n^4, n^5, n^6}, n]
							 | 
						||
| 
								 | 
							
								              guess = (((((    - T(0.0008342379046010)
							 | 
						||
| 
								 | 
							
								                           * v + T(0.007590035637410))
							 | 
						||
| 
								 | 
							
								                           * v - T(0.030640914772013))
							 | 
						||
| 
								 | 
							
								                           * v + T(0.078232088020106))
							 | 
						||
| 
								 | 
							
								                           * v - T(0.169668712590620))
							 | 
						||
| 
								 | 
							
								                           * v + T(1.542187960073750))
							 | 
						||
| 
								 | 
							
								                           * v + T(2.4048359915254634);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              // For larger v, use the first line of Eqs. 10.21.40 in the NIST Handbook.
							 | 
						||
| 
								 | 
							
								              guess = boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::equation_nist_10_21_40_a(v);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								          else
							 | 
						||
| 
								 | 
							
								          {
							 | 
						||
| 
								 | 
							
								            if(v < 2.2F)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              // Use Eq. 10.21.19 in the NIST Handbook.
							 | 
						||
| 
								 | 
							
								              const T a(((v + T(m * 2U)) - T(0.5)) * boost::math::constants::half_pi<T>());
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								              guess = boost::math::detail::bessel_zero::equation_nist_10_21_19(v, a);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              // Get an estimate of the m'th root of airy_ai.
							 | 
						||
| 
								 | 
							
								              const T airy_ai_root(boost::math::detail::airy_zero::airy_ai_zero_detail::initial_guess<T>(m));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								              // Use Eq. 9.5.26 in the A&S Handbook.
							 | 
						||
| 
								 | 
							
								              guess = boost::math::detail::bessel_zero::equation_as_9_5_26(v, airy_ai_root);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          return guess;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      } // namespace cyl_bessel_j_zero_detail
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      namespace cyl_neumann_zero_detail
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        template<class T>
							 | 
						||
| 
								 | 
							
								        T equation_nist_10_21_40_b(const T& v)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								          const T v_pow_third(boost::math::cbrt(v));
							 | 
						||
| 
								 | 
							
								          const T v_pow_minus_two_thirds(T(1) / (v_pow_third * v_pow_third));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          return v * (((((                         - T(0.001)
							 | 
						||
| 
								 | 
							
								                          * v_pow_minus_two_thirds - T(0.0060))
							 | 
						||
| 
								 | 
							
								                          * v_pow_minus_two_thirds + T(0.01198))
							 | 
						||
| 
								 | 
							
								                          * v_pow_minus_two_thirds + T(0.260351))
							 | 
						||
| 
								 | 
							
								                          * v_pow_minus_two_thirds + T(0.9315768))
							 | 
						||
| 
								 | 
							
								                          * v_pow_minus_two_thirds + T(1));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        template<class T, class Policy>
							 | 
						||
| 
								 | 
							
								        class function_object_yv
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								        public:
							 | 
						||
| 
								 | 
							
								          function_object_yv(const T& v,
							 | 
						||
| 
								 | 
							
								                             const Policy& pol) : my_v(v),
							 | 
						||
| 
								 | 
							
								                                                  my_pol(pol) { }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          T operator()(const T& x) const
							 | 
						||
| 
								 | 
							
								          {
							 | 
						||
| 
								 | 
							
								            return boost::math::cyl_neumann(my_v, x, my_pol);
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        private:
							 | 
						||
| 
								 | 
							
								          const T my_v;
							 | 
						||
| 
								 | 
							
								          const Policy& my_pol;
							 | 
						||
| 
								 | 
							
								          const function_object_yv& operator=(const function_object_yv&);
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        template<class T, class Policy>
							 | 
						||
| 
								 | 
							
								        class function_object_yv_and_yv_prime
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								        public:
							 | 
						||
| 
								 | 
							
								          function_object_yv_and_yv_prime(const T& v,
							 | 
						||
| 
								 | 
							
								                                          const Policy& pol) : my_v(v),
							 | 
						||
| 
								 | 
							
								                                                               my_pol(pol) { }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          boost::math::tuple<T, T> operator()(const T& x) const
							 | 
						||
| 
								 | 
							
								          {
							 | 
						||
| 
								 | 
							
								            const T half_epsilon(boost::math::tools::epsilon<T>() / 2U);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            const bool order_is_zero = ((my_v > -half_epsilon) && (my_v < +half_epsilon));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // Obtain Yv(x) and Yv'(x).
							 | 
						||
| 
								 | 
							
								            // Chris's original code called the Bessel function implementation layer direct, 
							 | 
						||
| 
								 | 
							
								            // but that circumvented optimizations for integer-orders.  Call the documented
							 | 
						||
| 
								 | 
							
								            // top level functions instead, and let them sort out which implementation to use.
							 | 
						||
| 
								 | 
							
								            T y_v;
							 | 
						||
| 
								 | 
							
								            T y_v_prime;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if(order_is_zero)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              y_v       =  boost::math::cyl_neumann(0, x, my_pol);
							 | 
						||
| 
								 | 
							
								              y_v_prime = -boost::math::cyl_neumann(1, x, my_pol);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                      y_v       = boost::math::cyl_neumann(  my_v,      x, my_pol);
							 | 
						||
| 
								 | 
							
								              const T y_v_m1     (boost::math::cyl_neumann(T(my_v - 1), x, my_pol));
							 | 
						||
| 
								 | 
							
								                      y_v_prime = y_v_m1 - ((my_v * y_v) / x);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // Return a tuple containing both Yv(x) and Yv'(x).
							 | 
						||
| 
								 | 
							
								            return boost::math::make_tuple(y_v, y_v_prime);
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        private:
							 | 
						||
| 
								 | 
							
								          const T my_v;
							 | 
						||
| 
								 | 
							
								          const Policy& my_pol;
							 | 
						||
| 
								 | 
							
								          const function_object_yv_and_yv_prime& operator=(const function_object_yv_and_yv_prime&);
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        template<class T> bool my_bisection_unreachable_tolerance(const T&, const T&) { return false; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        template<class T, class Policy>
							 | 
						||
| 
								 | 
							
								        T initial_guess(const T& v, const int m, const Policy& pol)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								          BOOST_MATH_STD_USING // ADL of std names, needed for floor.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          // Compute an estimate of the m'th root of cyl_neumann.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          T guess;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          // There is special handling for negative order.
							 | 
						||
| 
								 | 
							
								          if(v < 0)
							 | 
						||
| 
								 | 
							
								          {
							 | 
						||
| 
								 | 
							
								            // Create the positive order and extract its positive floor and ceiling integer parts.
							 | 
						||
| 
								 | 
							
								            const T vv(-v);
							 | 
						||
| 
								 | 
							
								            const T vv_floor(floor(vv));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // The to-be-found root is bracketed by the roots of the
							 | 
						||
| 
								 | 
							
								            // Bessel function whose reflected, positive integer order
							 | 
						||
| 
								 | 
							
								            // is less than, but nearest to vv.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // The special case of negative, half-integer order uses
							 | 
						||
| 
								 | 
							
								            // the relation between Yv and spherical Bessel functions
							 | 
						||
| 
								 | 
							
								            // in order to obtain the bracket for the root.
							 | 
						||
| 
								 | 
							
								            // In these special cases, cyl_neumann(-n/2, x) = sph_bessel_j(+n/2, x)
							 | 
						||
| 
								 | 
							
								            // for v = -n/2.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            T root_hi;
							 | 
						||
| 
								 | 
							
								            T root_lo;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if(m == 1)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              // The estimate of the first root for negative order is found using
							 | 
						||
| 
								 | 
							
								              // an adaptive range-searching algorithm.
							 | 
						||
| 
								 | 
							
								              // Take special precautions for the discontinuity at negative,
							 | 
						||
| 
								 | 
							
								              // half-integer orders and use different brackets above and below these.
							 | 
						||
| 
								 | 
							
								              if(T(vv - vv_floor) < 0.5F)
							 | 
						||
| 
								 | 
							
								              {
							 | 
						||
| 
								 | 
							
								                root_hi = boost::math::detail::bessel_zero::cyl_neumann_zero_detail::initial_guess(vv_floor, m, pol);
							 | 
						||
| 
								 | 
							
								              }
							 | 
						||
| 
								 | 
							
								              else
							 | 
						||
| 
								 | 
							
								              {
							 | 
						||
| 
								 | 
							
								                root_hi = boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::initial_guess(T(vv_floor + 0.5F), m, pol);
							 | 
						||
| 
								 | 
							
								              }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								              root_lo = T(root_hi - 0.1F);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								              const bool hi_end_of_bracket_is_negative = (boost::math::cyl_neumann(v, root_hi, pol) < 0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								              while((root_lo > boost::math::tools::epsilon<T>()))
							 | 
						||
| 
								 | 
							
								              {
							 | 
						||
| 
								 | 
							
								                const bool lo_end_of_bracket_is_negative = (boost::math::cyl_neumann(v, root_lo, pol) < 0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if(hi_end_of_bracket_is_negative != lo_end_of_bracket_is_negative)
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                  break;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                root_hi = root_lo;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                // Decrease the lower end of the bracket using an adaptive algorithm.
							 | 
						||
| 
								 | 
							
								                if(root_lo > 0.5F)
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                  root_lo -= 0.5F;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                else
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                  root_lo *= 0.75F;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								              }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              if(T(vv - vv_floor) < 0.5F)
							 | 
						||
| 
								 | 
							
								              {
							 | 
						||
| 
								 | 
							
								                root_lo  = boost::math::detail::bessel_zero::cyl_neumann_zero_detail::initial_guess(vv_floor, m - 1, pol);
							 | 
						||
| 
								 | 
							
								                root_hi = boost::math::detail::bessel_zero::cyl_neumann_zero_detail::initial_guess(vv_floor, m, pol);
							 | 
						||
| 
								 | 
							
								                root_lo += 0.01F;
							 | 
						||
| 
								 | 
							
								                root_hi += 0.01F;
							 | 
						||
| 
								 | 
							
								              }
							 | 
						||
| 
								 | 
							
								              else
							 | 
						||
| 
								 | 
							
								              {
							 | 
						||
| 
								 | 
							
								                root_lo = boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::initial_guess(T(vv_floor + 0.5F), m - 1, pol);
							 | 
						||
| 
								 | 
							
								                root_hi = boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::initial_guess(T(vv_floor + 0.5F), m, pol);
							 | 
						||
| 
								 | 
							
								                root_lo += 0.01F;
							 | 
						||
| 
								 | 
							
								                root_hi += 0.01F;
							 | 
						||
| 
								 | 
							
								              }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // Perform several steps of bisection iteration to refine the guess.
							 | 
						||
| 
								 | 
							
								            boost::uintmax_t number_of_iterations(12U);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // Do the bisection iteration.
							 | 
						||
| 
								 | 
							
								            const boost::math::tuple<T, T> guess_pair =
							 | 
						||
| 
								 | 
							
								               boost::math::tools::bisect(
							 | 
						||
| 
								 | 
							
								                  boost::math::detail::bessel_zero::cyl_neumann_zero_detail::function_object_yv<T, Policy>(v, pol),
							 | 
						||
| 
								 | 
							
								                  root_lo,
							 | 
						||
| 
								 | 
							
								                  root_hi,
							 | 
						||
| 
								 | 
							
								                  boost::math::detail::bessel_zero::cyl_neumann_zero_detail::my_bisection_unreachable_tolerance<T>,
							 | 
						||
| 
								 | 
							
								                  number_of_iterations);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            return (boost::math::get<0>(guess_pair) + boost::math::get<1>(guess_pair)) / 2U;
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          if(m == 1U)
							 | 
						||
| 
								 | 
							
								          {
							 | 
						||
| 
								 | 
							
								            // Get the initial estimate of the first root.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if(v < 2.2F)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              // For small v, use the results of empirical curve fitting.
							 | 
						||
| 
								 | 
							
								              // Mathematica(R) session for the coefficients:
							 | 
						||
| 
								 | 
							
								              //  Table[{n, BesselYZero[n, 1]}, {n, 0, 22/10, 1/10}]
							 | 
						||
| 
								 | 
							
								              //  N[%, 20]
							 | 
						||
| 
								 | 
							
								              //  Fit[%, {n^0, n^1, n^2, n^3, n^4, n^5, n^6}, n]
							 | 
						||
| 
								 | 
							
								              guess = (((((    - T(0.0025095909235652)
							 | 
						||
| 
								 | 
							
								                           * v + T(0.021291887049053))
							 | 
						||
| 
								 | 
							
								                           * v - T(0.076487785486526))
							 | 
						||
| 
								 | 
							
								                           * v + T(0.159110268115362))
							 | 
						||
| 
								 | 
							
								                           * v - T(0.241681668765196))
							 | 
						||
| 
								 | 
							
								                           * v + T(1.4437846310885244))
							 | 
						||
| 
								 | 
							
								                           * v + T(0.89362115190200490);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              // For larger v, use the second line of Eqs. 10.21.40 in the NIST Handbook.
							 | 
						||
| 
								 | 
							
								              guess = boost::math::detail::bessel_zero::cyl_neumann_zero_detail::equation_nist_10_21_40_b(v);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								          else
							 | 
						||
| 
								 | 
							
								          {
							 | 
						||
| 
								 | 
							
								            if(v < 2.2F)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              // Use Eq. 10.21.19 in the NIST Handbook.
							 | 
						||
| 
								 | 
							
								              const T a(((v + T(m * 2U)) - T(1.5)) * boost::math::constants::half_pi<T>());
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								              guess = boost::math::detail::bessel_zero::equation_nist_10_21_19(v, a);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              // Get an estimate of the m'th root of airy_bi.
							 | 
						||
| 
								 | 
							
								              const T airy_bi_root(boost::math::detail::airy_zero::airy_bi_zero_detail::initial_guess<T>(m));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								              // Use Eq. 9.5.26 in the A&S Handbook.
							 | 
						||
| 
								 | 
							
								              guess = boost::math::detail::bessel_zero::equation_as_9_5_26(v, airy_bi_root);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          return guess;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      } // namespace cyl_neumann_zero_detail
							 | 
						||
| 
								 | 
							
								    } // namespace bessel_zero
							 | 
						||
| 
								 | 
							
								  } } } // namespace boost::math::detail
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif // _BESSEL_JY_ZERO_2013_01_18_HPP_
							 |