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]
38 and [@https://en.wikipedia.org/wiki/Airy_zeta_function Airy Zeta function].
42 The following graph illustrates how this function changes as /x/ changes: for negative /x/
43 the function is cyclic, while for positive /x/ the value tends to zero:
49 This function is implemented entirely in terms of the Bessel functions
50 __cyl_bessel_j and __cyl_bessel_k - refer to those functions for detailed accuracy information.
52 In general though, the relative error is low (less than 100 [epsilon]) for /x > 0/ while
53 only the absolute error is low for /x < 0/ as the following error plot illustrates:
59 Since this function is implemented in terms of other special functions, there are only a few
60 basic sanity checks, using test values from [@http://functions.wolfram.com/ Wolfram Airy Functions].
62 [heading Implementation]
64 This function is implemented in terms of the Bessel functions using the relations:
68 [endsect] [/section:ai Airy Ai Function]
70 [section:bi Airy Bi Function]
75 #include <boost/math/special_functions/airy.hpp>
78 namespace boost { namespace math {
81 ``__sf_result`` airy_bi(T x);
83 template <class T, class Policy>
84 ``__sf_result`` airy_bi(T x, const Policy&);
90 The function __airy_bi calculates the Airy function Bi which is the second solution to the differential equation:
96 The following graph illustrates how this function changes as /x/ changes: for negative /x/
97 the function is cyclic, while for positive /x/ the value tends to infinity:
103 This function is implemented entirely in terms of the Bessel functions
104 __cyl_bessel_i and __cyl_bessel_j - refer to those functions for detailed accuracy information.
106 In general though, the relative error is low (less than 100 [epsilon]) for /x > 0/ while
107 only the absolute error is low for /x < 0/ as the following error plot illustrate:
113 Since this function is implemented in terms of other special functions, there are only a few
114 basic sanity checks, using test values from [@http://functions.wolfram.com functions.wolfram.com].
116 [heading Implementation]
118 This function is implemented in terms of the Bessel functions using the relations:
122 [endsect] [/section:bi Airy Bi Function]
124 [section:aip Airy Ai' Function]
129 #include <boost/math/special_functions/airy.hpp>
132 namespace boost { namespace math {
135 ``__sf_result`` airy_ai_prime(T x);
137 template <class T, class Policy>
138 ``__sf_result`` airy_ai_prime(T x, const Policy&);
142 [heading Description]
144 The function __airy_ai_prime calculates the Airy function Ai' which is the derivative of the first solution to the differential equation:
150 The following graph illustrates how this function changes as /x/ changes: for negative /x/
151 the function is cyclic, while for positive /x/ the value tends to zero:
157 This function is implemented entirely in terms of the Bessel functions
158 __cyl_bessel_j and __cyl_bessel_k - refer to those functions for detailed accuracy information.
160 In general though, the relative error is low (less than 100 [epsilon]) for /x > 0/ while
161 only the absolute error is low for /x < 0/ as the following error plot illustrates:
163 [graph ai_prime__double]
167 Since this function is implemented in terms of other special functions, there are only a few
168 basic sanity checks, using test values from [@http://functions.wolfram.com functions.wolfram.com].
170 [heading Implementation]
172 This function is implemented in terms of the Bessel functions using the relations:
176 [endsect] [/section:aip Airy Ai' Function]
178 [section:bip Airy Bi' Function]
183 #include <boost/math/special_functions/airy.hpp>
186 namespace boost { namespace math {
189 ``__sf_result`` airy_bi_prime(T x);
191 template <class T, class Policy>
192 ``__sf_result`` airy_bi_prime(T x, const Policy&);
196 [heading Description]
198 The function __airy_bi_prime calculates the Airy function Bi' which is the derivative of the second solution to the differential equation:
204 The following graph illustrates how this function changes as /x/ changes: for negative /x/
205 the function is cyclic, while for positive /x/ the value tends to infinity:
211 This function is implemented entirely in terms of the Bessel functions
212 __cyl_bessel_i and __cyl_bessel_j - refer to those functions for detailed accuracy information.
214 In general though, the relative error is low (less than 100 [epsilon]) for /x > 0/ while
215 only the absolute error is low for /x < 0/ as the following error plot illustrates:
217 [graph bi_prime__double]
221 Since this function is implemented in terms of other special functions, there are only a few
222 basic sanity checks, using test values from [@http://functions.wolfram.com functions.wolfram.com].
224 [heading Implementation]
226 This function is implemented in terms of the Bessel functions using the relations:
230 [endsect] [/section:bip Airy Bi' Function]
232 [section:airy_root Finding Zeros of Airy Functions]
236 `#include <boost/math/special_functions/airy.hpp>`
238 Functions for obtaining both a single zero or root of the Airy functions,
239 and placing multiple zeros into a container like `std::vector`
240 by providing an output iterator.
242 The signature of the single value functions are:
246 int m); // 1-based index of zero.
250 int m); // 1-based index of zero.
252 and for multiple zeros:
254 template <class T, class OutputIterator>
255 OutputIterator airy_ai_zero(
256 int start_index, // 1-based index of first zero.
257 unsigned number_of_zeros, // How many zeros to generate.
258 OutputIterator out_it); // Destination for zeros.
260 template <class T, class OutputIterator>
261 OutputIterator airy_bi_zero(
262 int start_index, // 1-based index of zero.
263 unsigned number_of_zeros, // How many zeros to generate
264 OutputIterator out_it); // Destination for zeros.
266 There are also versions which allow control of the __policy_section for error handling and precision.
270 int m, // 1-based index of zero.
271 const Policy&); // Policy to use.
275 int m, // 1-based index of zero.
276 const Policy&); // Policy to use.
279 template <class T, class OutputIterator>
280 OutputIterator airy_ai_zero(
281 int start_index, // 1-based index of first zero.
282 unsigned number_of_zeros, // How many zeros to generate.
283 OutputIterator out_it, // Destination for zeros.
284 const Policy& pol); // Policy to use.
286 template <class T, class OutputIterator>
287 OutputIterator airy_bi_zero(
288 int start_index, // 1-based index of zero.
289 unsigned number_of_zeros, // How many zeros to generate.
290 OutputIterator out_it, // Destination for zeros.
291 const Policy& pol); // Policy to use.
295 The Airy Ai and Bi functions have an infinite
296 number of zeros on the negative real axis. The real zeros on the negative real
297 axis can be found by solving for the roots of
299 [:['Ai(x[sub m]) = 0]]
301 [:['Bi(y[sub m]) = 0]]
303 Here, ['x[sub m]] represents the ['m[super th]]
304 root of the Airy Ai function,
305 and ['y[sub m]] represents the ['m[super th]]
306 root of the Airy Bi function.
308 The zeros or roots (values of `x` where the function crosses the horizontal `y = 0` axis)
309 of the Airy Ai and Bi functions are computed by two functions,
310 `airy_ai_zero` and `airy_bi_zero`.
312 In each case the index or rank of the zero
313 returned is 1-based, which is to say:
317 returns the first zero of Ai.
319 Passing an `start_index <= 0` results in a __domain_error being raised.
321 The first few zeros returned by these functions have approximate values as follows:
325 [[1][-2.33811...][-1.17371...]]
326 [[2][-4.08795...][-3.27109...]]
327 [[3][-5.52056...][-4.83074...]]
328 [[4][-6.78671...][-6.16985...]]
329 [[5][-7.94413...][-7.37676...]]
330 [[6][-9.02265...][-8.49195...]]
335 [h4 Examples of finding Airy Zeros]
337 [import ../../example/airy_zeros_example.cpp]
339 [airy_zeros_example_1]
340 [airy_zeros_example_2]
342 Produces the program output:
344 boost::math::airy_ai_zero<double>(1) = -2.33811
345 boost::math::airy_ai_zero<double>(2) = -4.08795
346 boost::math::airy_bi_zero<double>(3) = -4.83074
354 boost::math::airy_bi_zero<float_type>(1) = -2.3381074104597670384891972524467354406385401456711
355 boost::math::airy_bi_zero<float_type>(2) = -4.0879494441309706166369887014573910602247646991085
356 boost::math::airy_bi_zero<float_type>(7) = -9.5381943793462388866329885451560196208390720763825
358 -2.3381074104597670384891972524467354406385401456711
359 -4.0879494441309706166369887014573910602247646991085
360 -5.5205598280955510591298555129312935737972142806175
363 The full code (and output) for this example is at
364 [@../../example/airy_zeros_example.cpp airy_zeros_example.cpp],
368 Given the following function (A&S 10.4.105):
370 [equation airy_zero_1]
372 Then an initial estimate for the n[super th] zero a[sub n] of Ai is given by (A&S 10.4.94):
374 [equation airy_zero_2]
376 and an initial estimate for the n[super th] zero b[sub n] of Bi is given by (A&S 10.4.98):
378 [equation airy_zero_3]
380 Thereafter the roots are refined using Newton iteration.
384 The precision of evaluation of zeros was tested at 50 decimal digits using `cpp_dec_float_50`
385 and found identical with spot values computed by __WolframAlpha.
387 [endsect] [/section:airy_root Finding Zeros of Airy Functions]
389 [endsect] [/section:airy Airy Functions]