mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-31 13:10:19 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			385 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			385 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| [/
 | |
| Copyright (c) 2012 John Maddock
 | |
| 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)
 | |
| ]
 | |
| 
 | |
| [section:airy Airy Functions]
 | |
| 
 | |
| [section:ai Airy Ai Function]
 | |
| 
 | |
| [heading Synopsis]
 | |
| 
 | |
| ``
 | |
|   #include <boost/math/special_functions/airy.hpp>
 | |
| ``
 | |
| 
 | |
|   namespace boost { namespace math {
 | |
| 
 | |
|    template <class T>
 | |
|    ``__sf_result`` airy_ai(T x);
 | |
| 
 | |
|    template <class T, class Policy>
 | |
|    ``__sf_result`` airy_ai(T x, const Policy&);
 | |
| 
 | |
|   }} // namespaces
 | |
|   
 | |
| [heading Description]
 | |
| 
 | |
| The function __airy_ai calculates the Airy function Ai which is the first solution
 | |
| to the differential equation:
 | |
| 
 | |
| [equation airy]
 | |
| 
 | |
| See Weisstein, Eric W. "Airy Functions." From MathWorld--A Wolfram Web Resource.
 | |
| [@http://mathworld.wolfram.com/AiryFunctions.html];
 | |
| 
 | |
| 
 | |
| [optional_policy]
 | |
| 
 | |
| The following graph illustrates how this function changes as /x/ changes: for negative /x/
 | |
| the function is cyclic, while for positive /x/ the value tends to zero:
 | |
| 
 | |
| [graph airy_ai]
 | |
| 
 | |
| [heading Accuracy]
 | |
| 
 | |
| This function is implemented entirely in terms of the Bessel functions 
 | |
| __cyl_bessel_j and __cyl_bessel_k - refer to those functions for detailed accuracy information.
 | |
| 
 | |
| In general though, the relative error is low (less than 100 [epsilon]) for /x > 0/ while
 | |
| only the absolute error is low for /x < 0/.
 | |
| 
 | |
| [heading Testing]
 | |
| 
 | |
| Since this function is implemented in terms of other special functions, there are only a few 
 | |
| basic sanity checks, using test values from [@http://functions.wolfram.com/ Wolfram Airy Functions].
 | |
| 
 | |
| [heading Implementation]
 | |
| 
 | |
| This function is implemented in terms of the Bessel functions using the relations:
 | |
| 
 | |
| [equation airy_ai]
 | |
| 
 | |
| [endsect]
 | |
| 
 | |
| [section:bi Airy Bi Function]
 | |
| 
 | |
| [heading Synopsis]
 | |
| 
 | |
| ``
 | |
|   #include <boost/math/special_functions/airy.hpp>
 | |
| ``
 | |
| 
 | |
|   namespace boost { namespace math {
 | |
| 
 | |
|    template <class T>
 | |
|    ``__sf_result`` airy_bi(T x);
 | |
| 
 | |
|    template <class T, class Policy>
 | |
|    ``__sf_result`` airy_bi(T x, const Policy&);
 | |
| 
 | |
|   }} // namespaces
 | |
|   
 | |
| [heading Description]
 | |
| 
 | |
| The function __airy_bi calculates the Airy function Bi which is the second solution to the differential equation:
 | |
| 
 | |
| [equation airy]
 | |
| 
 | |
| [optional_policy]
 | |
| 
 | |
| The following graph illustrates how this function changes as /x/ changes: for negative /x/
 | |
| the function is cyclic, while for positive /x/ the value tends to infinity:
 | |
| 
 | |
| [graph airy_bi]
 | |
| 
 | |
| [heading Accuracy]
 | |
| 
 | |
| This function is implemented entirely in terms of the Bessel functions 
 | |
| __cyl_bessel_i and __cyl_bessel_j - refer to those functions for detailed accuracy information.
 | |
| 
 | |
| In general though, the relative error is low (less than 100 [epsilon]) for /x > 0/ while
 | |
| only the absolute error is low for /x < 0/.
 | |
| 
 | |
| [heading Testing]
 | |
| 
 | |
| Since this function is implemented in terms of other special functions, there are only a few 
 | |
| basic sanity checks, using test values from [@http://functions.wolfram.com functions.wolfram.com].
 | |
| 
 | |
| [heading Implementation]
 | |
| 
 | |
| This function is implemented in terms of the Bessel functions using the relations:
 | |
| 
 | |
| [equation airy_bi]
 | |
| 
 | |
| [endsect]
 | |
| 
 | |
| [section:aip Airy Ai' Function]
 | |
| 
 | |
| [heading Synopsis]
 | |
| 
 | |
| ``
 | |
|   #include <boost/math/special_functions/airy.hpp>
 | |
| ``
 | |
| 
 | |
|   namespace boost { namespace math {
 | |
| 
 | |
|    template <class T>
 | |
|    ``__sf_result`` airy_ai_prime(T x);
 | |
| 
 | |
|    template <class T, class Policy>
 | |
|    ``__sf_result`` airy_ai_prime(T x, const Policy&);
 | |
| 
 | |
|   }} // namespaces
 | |
|   
 | |
| [heading Description]
 | |
| 
 | |
| The function __airy_ai_prime calculates the Airy function Ai' which is the derivative of the first solution to the differential equation:
 | |
| 
 | |
| [equation airy]
 | |
| 
 | |
| [optional_policy]
 | |
| 
 | |
| The following graph illustrates how this function changes as /x/ changes: for negative /x/
 | |
| the function is cyclic, while for positive /x/ the value tends to zero:
 | |
| 
 | |
| [graph airy_aip]
 | |
| 
 | |
| [heading Accuracy]
 | |
| 
 | |
| This function is implemented entirely in terms of the Bessel functions 
 | |
| __cyl_bessel_j and __cyl_bessel_k - refer to those functions for detailed accuracy information.
 | |
| 
 | |
| In general though, the relative error is low (less than 100 [epsilon]) for /x > 0/ while
 | |
| only the absolute error is low for /x < 0/.
 | |
| 
 | |
| [heading Testing]
 | |
| 
 | |
| Since this function is implemented in terms of other special functions, there are only a few 
 | |
| basic sanity checks, using test values from [@http://functions.wolfram.com functions.wolfram.com].
 | |
| 
 | |
| [heading Implementation]
 | |
| 
 | |
| This function is implemented in terms of the Bessel functions using the relations:
 | |
| 
 | |
| [equation airy_aip]
 | |
| 
 | |
| [endsect]
 | |
| 
 | |
| [section:bip Airy Bi' Function]
 | |
| 
 | |
| [heading Synopsis]
 | |
| 
 | |
| ``
 | |
|   #include <boost/math/special_functions/airy.hpp>
 | |
| ``
 | |
| 
 | |
|   namespace boost { namespace math {
 | |
| 
 | |
|    template <class T>
 | |
|    ``__sf_result`` airy_bi_prime(T x);
 | |
| 
 | |
|    template <class T, class Policy>
 | |
|    ``__sf_result`` airy_bi_prime(T x, const Policy&);
 | |
| 
 | |
|   }} // namespaces
 | |
|   
 | |
| [heading Description]
 | |
| 
 | |
| The function __airy_bi_prime calculates the Airy function Bi' which is the derivative of the second solution to the differential equation:
 | |
| 
 | |
| [equation airy]
 | |
| 
 | |
| [optional_policy]
 | |
| 
 | |
| The following graph illustrates how this function changes as /x/ changes: for negative /x/
 | |
| the function is cyclic, while for positive /x/ the value tends to infinity:
 | |
| 
 | |
| [graph airy_bi]
 | |
| 
 | |
| [heading Accuracy]
 | |
| 
 | |
| This function is implemented entirely in terms of the Bessel functions 
 | |
| __cyl_bessel_i and __cyl_bessel_j - refer to those functions for detailed accuracy information.
 | |
| 
 | |
| In general though, the relative error is low (less than 100 [epsilon]) for /x > 0/ while
 | |
| only the absolute error is low for /x < 0/.
 | |
| 
 | |
| [heading Testing]
 | |
| 
 | |
| Since this function is implemented in terms of other special functions, there are only a few 
 | |
| basic sanity checks, using test values from [@http://functions.wolfram.com functions.wolfram.com].
 | |
| 
 | |
| [heading Implementation]
 | |
| 
 | |
| This function is implemented in terms of the Bessel functions using the relations:
 | |
| 
 | |
| [equation airy_bip]
 | |
| 
 | |
| [endsect]
 | |
| 
 | |
| [section:airy_root Finding Zeros of Airy Functions]
 | |
| 
 | |
| [h4 Synopsis]
 | |
| 
 | |
| `#include <boost/math/special_functions/airy.hpp>`
 | |
| 
 | |
| Functions for obtaining both a single zero or root of the Airy functions,
 | |
| and placing multiple zeros into a container like `std::vector`
 | |
| by providing an output iterator.
 | |
| 
 | |
| The signature of the single value functions are:
 | |
| 
 | |
|   template <class T>
 | |
|   T airy_ai_zero(
 | |
|            int m);         // 1-based index of zero.
 | |
| 
 | |
|   template <class T>
 | |
|   T airy_bi_zero(
 | |
|            int m);         // 1-based index of zero.
 | |
| 
 | |
| and for multiple zeros:
 | |
| 
 | |
|  template <class T, class OutputIterator>
 | |
|  OutputIterator airy_ai_zero(
 | |
|                       int start_index,           // 1-based index of first zero.
 | |
|                       unsigned number_of_zeros,  // How many zeros to generate.
 | |
|                       OutputIterator out_it);    // Destination for zeros.
 | |
| 
 | |
|  template <class T, class OutputIterator>
 | |
|  OutputIterator airy_bi_zero(
 | |
|                       int start_index,           // 1-based index of zero.
 | |
|                       unsigned number_of_zeros,  // How many zeros to generate
 | |
|                       OutputIterator out_it);    // Destination for zeros.
 | |
| 
 | |
| There are also versions which allow control of the __policy_section for error handling and precision.
 | |
| 
 | |
|   template <class T>
 | |
|   T airy_ai_zero(
 | |
|            int m,          // 1-based index of zero.
 | |
|            const Policy&); // Policy to use.
 | |
| 
 | |
|   template <class T>
 | |
|   T airy_bi_zero(
 | |
|            int m,          // 1-based index of zero.
 | |
|            const Policy&); // Policy to use.
 | |
| 
 | |
| 
 | |
|  template <class T, class OutputIterator>
 | |
|  OutputIterator airy_ai_zero(
 | |
|                       int start_index,           // 1-based index of first zero.
 | |
|                       unsigned number_of_zeros,  // How many zeros to generate.
 | |
|                       OutputIterator out_it,     // Destination for zeros.
 | |
|                       const Policy& pol);        // Policy to use.
 | |
| 
 | |
|  template <class T, class OutputIterator>
 | |
|  OutputIterator airy_bi_zero(
 | |
|                       int start_index,           // 1-based index of zero.
 | |
|                       unsigned number_of_zeros,  // How many zeros to generate.
 | |
|                       OutputIterator out_it,     // Destination for zeros.
 | |
|                       const Policy& pol);        // Policy to use.
 | |
| 
 | |
| [h4 Description]
 | |
| 
 | |
| The Airy Ai and Bi functions have an infinite
 | |
| number of zeros on the negative real axis. The real zeros on the negative real
 | |
| axis can be found by solving for the roots of
 | |
| 
 | |
| [emquad] ['Ai(x[sub m]) = 0]
 | |
| 
 | |
| [emquad] ['Bi(y[sub m]) = 0]
 | |
| 
 | |
| Here, ['x[sub m]] represents the ['m[super th]]
 | |
| root of the Airy Ai function,
 | |
| and ['y[sub m]] represents the ['m[super th]]
 | |
| root of the Airy Bi function.
 | |
| 
 | |
| The zeros or roots (values of `x` where the function crosses the horizontal `y = 0` axis)
 | |
| of the Airy Ai and Bi functions are computed by two functions,
 | |
| `airy_ai_zero` and `airy_bi_zero`.
 | |
| 
 | |
| In each case the index or rank of the zero
 | |
| returned is 1-based, which is to say:
 | |
| 
 | |
|    airy_ai_zero(1);
 | |
| 
 | |
| returns the first zero of Ai.
 | |
| 
 | |
| Passing an `start_index <= 0` results in a __domain_error being raised.
 | |
| 
 | |
| The first few zeros returned by these functions have approximate values as follows:
 | |
| 
 | |
| [table
 | |
| [[m][Ai][Bi]]
 | |
| [[1][-2.33811...][-1.17371...]]
 | |
| [[2][-4.08795...][-3.27109...]]
 | |
| [[3][-5.52056...][-4.83074...]]
 | |
| [[4][-6.78671...][-6.16985...]]
 | |
| [[5][-7.94413...][-7.37676...]]
 | |
| [[6][-9.02265...][-8.49195...]]
 | |
| ]
 | |
| 
 | |
| [graph airy_zeros]
 | |
| 
 | |
| 
 | |
| [h4 Examples of finding Airy Zeros]
 | |
| 
 | |
| [import ../../example/airy_zeros_example.cpp]
 | |
| 
 | |
| [airy_zeros_example_1]
 | |
| [airy_zeros_example_2]
 | |
| 
 | |
| Produces the program output:
 | |
| [pre
 | |
| boost::math::airy_ai_zero<double>(1) = -2.33811
 | |
| boost::math::airy_ai_zero<double>(2) = -4.08795
 | |
| boost::math::airy_bi_zero<double>(3) = -4.83074
 | |
| airy_ai_zeros:
 | |
| -2.33811
 | |
| -4.08795
 | |
| -5.52056
 | |
| -6.78671
 | |
| -7.94413
 | |
| 
 | |
| boost::math::airy_bi_zero<float_type>(1)  = -2.3381074104597670384891972524467354406385401456711
 | |
| boost::math::airy_bi_zero<float_type>(2)  = -4.0879494441309706166369887014573910602247646991085
 | |
| boost::math::airy_bi_zero<float_type>(7)  = -9.5381943793462388866329885451560196208390720763825
 | |
| airy_ai_zeros:
 | |
| -2.3381074104597670384891972524467354406385401456711
 | |
| -4.0879494441309706166369887014573910602247646991085
 | |
| -5.5205598280955510591298555129312935737972142806175
 | |
| ]
 | |
| 
 | |
| The full code (and output) for this example is at
 | |
| [@../../example/airy_zeros_example.cpp airy_zeros_example.cpp],
 | |
| 
 | |
| [h3 Implementation]
 | |
| 
 | |
| Given the following function (A&S 10.4.105):
 | |
| 
 | |
| [equation airy_zero_1]
 | |
| 
 | |
| Then an initial estimate for the n[super th] zero a[sub n] of Ai is given by (A&S 10.4.94):
 | |
| 
 | |
| [equation airy_zero_2]
 | |
| 
 | |
| and an initial estimate for the n[super th] zero b[sub n] of Bi is given by (A&S 10.4.98):
 | |
| 
 | |
| [equation airy_zero_3]
 | |
| 
 | |
| Thereafter the roots are refined using Newton iteration.
 | |
| 
 | |
| 
 | |
| [h3 Testing]
 | |
| 
 | |
| The precision of evaluation of zeros was tested at 50 decimal digits using `cpp_dec_float_50`
 | |
| and found identical with spot values computed by __WolframAlpha.
 | |
| 
 | |
| [endsect]  [/section:bessel Finding Zeros of Bessel Functions of the First and Second Kinds]
 | |
| 
 | |
| 
 | |
| [endsect]
 | |
| 
 |