2 Copyright (c) 2012 John Maddock
3 Use, modification and distribution are subject to the
4 Boost Software License, Version 1.0. (See accompanying file
5 LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 [section:airy Airy Functions]
10 [section:ai Airy Ai Function]
15 #include <boost/math/special_functions/airy.hpp>
18 namespace boost { namespace math {
21 ``__sf_result`` airy_ai(T x);
23 template <class T, class Policy>
24 ``__sf_result`` airy_ai(T x, const Policy&);
30 The function __airy_ai calculates the Airy function Ai which is the first solution
31 to the differential equation:
35 See Weisstein, Eric W. "Airy Functions." From MathWorld--A Wolfram Web Resource.
36 [@http://mathworld.wolfram.com/AiryFunctions.html];
41 The following graph illustrates how this function changes as /x/ changes: for negative /x/
42 the function is cyclic, while for positive /x/ the value tends to zero:
48 This function is implemented entirely in terms of the Bessel functions
49 __cyl_bessel_j and __cyl_bessel_k - refer to those functions for detailed accuracy information.
51 In general though, the relative error is low (less than 100 [epsilon]) for /x > 0/ while
52 only the absolute error is low for /x < 0/.
56 Since this function is implemented in terms of other special functions, there are only a few
57 basic sanity checks, using test values from [@http://functions.wolfram.com/ Wolfram Airy Functions].
59 [heading Implementation]
61 This function is implemented in terms of the Bessel functions using the relations:
67 [section:bi Airy Bi Function]
72 #include <boost/math/special_functions/airy.hpp>
75 namespace boost { namespace math {
78 ``__sf_result`` airy_bi(T x);
80 template <class T, class Policy>
81 ``__sf_result`` airy_bi(T x, const Policy&);
87 The function __airy_bi calculates the Airy function Bi which is the second solution to the differential equation:
93 The following graph illustrates how this function changes as /x/ changes: for negative /x/
94 the function is cyclic, while for positive /x/ the value tends to infinity:
100 This function is implemented entirely in terms of the Bessel functions
101 __cyl_bessel_i and __cyl_bessel_j - refer to those functions for detailed accuracy information.
103 In general though, the relative error is low (less than 100 [epsilon]) for /x > 0/ while
104 only the absolute error is low for /x < 0/.
108 Since this function is implemented in terms of other special functions, there are only a few
109 basic sanity checks, using test values from [@http://functions.wolfram.com functions.wolfram.com].
111 [heading Implementation]
113 This function is implemented in terms of the Bessel functions using the relations:
119 [section:aip Airy Ai' Function]
124 #include <boost/math/special_functions/airy.hpp>
127 namespace boost { namespace math {
130 ``__sf_result`` airy_ai_prime(T x);
132 template <class T, class Policy>
133 ``__sf_result`` airy_ai_prime(T x, const Policy&);
137 [heading Description]
139 The function __airy_ai_prime calculates the Airy function Ai' which is the derivative of the first solution to the differential equation:
145 The following graph illustrates how this function changes as /x/ changes: for negative /x/
146 the function is cyclic, while for positive /x/ the value tends to zero:
152 This function is implemented entirely in terms of the Bessel functions
153 __cyl_bessel_j and __cyl_bessel_k - refer to those functions for detailed accuracy information.
155 In general though, the relative error is low (less than 100 [epsilon]) for /x > 0/ while
156 only the absolute error is low for /x < 0/.
160 Since this function is implemented in terms of other special functions, there are only a few
161 basic sanity checks, using test values from [@http://functions.wolfram.com functions.wolfram.com].
163 [heading Implementation]
165 This function is implemented in terms of the Bessel functions using the relations:
171 [section:bip Airy Bi' Function]
176 #include <boost/math/special_functions/airy.hpp>
179 namespace boost { namespace math {
182 ``__sf_result`` airy_bi_prime(T x);
184 template <class T, class Policy>
185 ``__sf_result`` airy_bi_prime(T x, const Policy&);
189 [heading Description]
191 The function __airy_bi_prime calculates the Airy function Bi' which is the derivative of the second solution to the differential equation:
197 The following graph illustrates how this function changes as /x/ changes: for negative /x/
198 the function is cyclic, while for positive /x/ the value tends to infinity:
204 This function is implemented entirely in terms of the Bessel functions
205 __cyl_bessel_i and __cyl_bessel_j - refer to those functions for detailed accuracy information.
207 In general though, the relative error is low (less than 100 [epsilon]) for /x > 0/ while
208 only the absolute error is low for /x < 0/.
212 Since this function is implemented in terms of other special functions, there are only a few
213 basic sanity checks, using test values from [@http://functions.wolfram.com functions.wolfram.com].
215 [heading Implementation]
217 This function is implemented in terms of the Bessel functions using the relations:
223 [section:airy_root Finding Zeros of Airy Functions]
227 `#include <boost/math/special_functions/airy.hpp>`
229 Functions for obtaining both a single zero or root of the Airy functions,
230 and placing multiple zeros into a container like `std::vector`
231 by providing an output iterator.
233 The signature of the single value functions are:
237 int m); // 1-based index of zero.
241 int m); // 1-based index of zero.
243 and for multiple zeros:
245 template <class T, class OutputIterator>
246 OutputIterator airy_ai_zero(
247 int start_index, // 1-based index of first zero.
248 unsigned number_of_zeros, // How many zeros to generate.
249 OutputIterator out_it); // Destination for zeros.
251 template <class T, class OutputIterator>
252 OutputIterator airy_bi_zero(
253 int start_index, // 1-based index of zero.
254 unsigned number_of_zeros, // How many zeros to generate
255 OutputIterator out_it); // Destination for zeros.
257 There are also versions which allow control of the __policy_section for error handling and precision.
261 int m, // 1-based index of zero.
262 const Policy&); // Policy to use.
266 int m, // 1-based index of zero.
267 const Policy&); // Policy to use.
270 template <class T, class OutputIterator>
271 OutputIterator airy_ai_zero(
272 int start_index, // 1-based index of first zero.
273 unsigned number_of_zeros, // How many zeros to generate.
274 OutputIterator out_it, // Destination for zeros.
275 const Policy& pol); // Policy to use.
277 template <class T, class OutputIterator>
278 OutputIterator airy_bi_zero(
279 int start_index, // 1-based index of zero.
280 unsigned number_of_zeros, // How many zeros to generate.
281 OutputIterator out_it, // Destination for zeros.
282 const Policy& pol); // Policy to use.
286 The Airy Ai and Bi functions have an infinite
287 number of zeros on the negative real axis. The real zeros on the negative real
288 axis can be found by solving for the roots of
290 [emquad] ['Ai(x[sub m]) = 0]
292 [emquad] ['Bi(y[sub m]) = 0]
294 Here, ['x[sub m]] represents the ['m[super th]]
295 root of the Airy Ai function,
296 and ['y[sub m]] represents the ['m[super th]]
297 root of the Airy Bi function.
299 The zeros or roots (values of `x` where the function crosses the horizontal `y = 0` axis)
300 of the Airy Ai and Bi functions are computed by two functions,
301 `airy_ai_zero` and `airy_bi_zero`.
303 In each case the index or rank of the zero
304 returned is 1-based, which is to say:
308 returns the first zero of Ai.
310 Passing an `start_index <= 0` results in a __domain_error being raised.
312 The first few zeros returned by these functions have approximate values as follows:
316 [[1][-2.33811...][-1.17371...]]
317 [[2][-4.08795...][-3.27109...]]
318 [[3][-5.52056...][-4.83074...]]
319 [[4][-6.78671...][-6.16985...]]
320 [[5][-7.94413...][-7.37676...]]
321 [[6][-9.02265...][-8.49195...]]
327 [h4 Examples of finding Airy Zeros]
329 [import ../../example/airy_zeros_example.cpp]
331 [airy_zeros_example_1]
332 [airy_zeros_example_2]
334 Produces the program output:
336 boost::math::airy_ai_zero<double>(1) = -2.33811
337 boost::math::airy_ai_zero<double>(2) = -4.08795
338 boost::math::airy_bi_zero<double>(3) = -4.83074
346 boost::math::airy_bi_zero<float_type>(1) = -2.3381074104597670384891972524467354406385401456711
347 boost::math::airy_bi_zero<float_type>(2) = -4.0879494441309706166369887014573910602247646991085
348 boost::math::airy_bi_zero<float_type>(7) = -9.5381943793462388866329885451560196208390720763825
350 -2.3381074104597670384891972524467354406385401456711
351 -4.0879494441309706166369887014573910602247646991085
352 -5.5205598280955510591298555129312935737972142806175
355 The full code (and output) for this example is at
356 [@../../example/airy_zeros_example.cpp airy_zeros_example.cpp],
360 Given the following function (A&S 10.4.105):
362 [equation airy_zero_1]
364 Then an initial estimate for the n[super th] zero a[sub n] of Ai is given by (A&S 10.4.94):
366 [equation airy_zero_2]
368 and an initial estimate for the n[super th] zero b[sub n] of Bi is given by (A&S 10.4.98):
370 [equation airy_zero_3]
372 Thereafter the roots are refined using Newton iteration.
377 The precision of evaluation of zeros was tested at 50 decimal digits using `cpp_dec_float_50`
378 and found identical with spot values computed by __WolframAlpha.
380 [endsect] [/section:bessel Finding Zeros of Bessel Functions of the First and Second Kinds]