3 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
4 <title>Bessel Functions of the First and Second Kinds</title>
5 <link rel="stylesheet" href="../../../../../../../../doc/src/boostbook.css" type="text/css">
6 <meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
7 <link rel="home" href="../../../index.html" title="Math Toolkit">
8 <link rel="up" href="../bessel.html" title="Bessel Functions">
9 <link rel="prev" href="bessel_over.html" title="Bessel Function Overview">
10 <link rel="next" href="mbessel.html" title="Modified Bessel Functions of the First and Second Kinds">
12 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13 <table cellpadding="2" width="100%"><tr>
14 <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../../boost.png"></td>
15 <td align="center"><a href="../../../../../../../../index.html">Home</a></td>
16 <td align="center"><a href="../../../../../../../../libs/libraries.htm">Libraries</a></td>
17 <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
18 <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
19 <td align="center"><a href="../../../../../../../../more/index.htm">More</a></td>
22 <div class="spirit-nav">
23 <a accesskey="p" href="bessel_over.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../bessel.html"><img src="../../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="mbessel.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a>
25 <div class="section math_toolkit_special_bessel_bessel">
26 <div class="titlepage"><div><div><h4 class="title">
27 <a name="math_toolkit.special.bessel.bessel"></a><a class="link" href="bessel.html" title="Bessel Functions of the First and Second Kinds">Bessel Functions
28 of the First and Second Kinds</a>
29 </h4></div></div></div>
31 <a name="math_toolkit.special.bessel.bessel.h0"></a>
32 <span><a name="math_toolkit.special.bessel.bessel.synopsis"></a></span><a class="link" href="bessel.html#math_toolkit.special.bessel.bessel.synopsis">Synopsis</a>
34 <pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T2</span><span class="special">></span>
35 <a class="link" href="../../main_overview/result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">cyl_bessel_j</span><span class="special">(</span><span class="identifier">T1</span> <span class="identifier">v</span><span class="special">,</span> <span class="identifier">T2</span> <span class="identifier">x</span><span class="special">);</span>
37 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T2</span><span class="special">,</span> <span class="keyword">class</span> <a class="link" href="../../policy.html" title="Policies">Policy</a><span class="special">></span>
38 <a class="link" href="../../main_overview/result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">cyl_bessel_j</span><span class="special">(</span><span class="identifier">T1</span> <span class="identifier">v</span><span class="special">,</span> <span class="identifier">T2</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">const</span> <a class="link" href="../../policy.html" title="Policies">Policy</a><span class="special">&);</span>
40 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T2</span><span class="special">></span>
41 <a class="link" href="../../main_overview/result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">cyl_neumann</span><span class="special">(</span><span class="identifier">T1</span> <span class="identifier">v</span><span class="special">,</span> <span class="identifier">T2</span> <span class="identifier">x</span><span class="special">);</span>
43 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T2</span><span class="special">,</span> <span class="keyword">class</span> <a class="link" href="../../policy.html" title="Policies">Policy</a><span class="special">></span>
44 <a class="link" href="../../main_overview/result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">cyl_neumann</span><span class="special">(</span><span class="identifier">T1</span> <span class="identifier">v</span><span class="special">,</span> <span class="identifier">T2</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">const</span> <a class="link" href="../../policy.html" title="Policies">Policy</a><span class="special">&);</span>
47 <a name="math_toolkit.special.bessel.bessel.h1"></a>
48 <span><a name="math_toolkit.special.bessel.bessel.description"></a></span><a class="link" href="bessel.html#math_toolkit.special.bessel.bessel.description">Description</a>
51 The functions <a class="link" href="bessel.html" title="Bessel Functions of the First and Second Kinds">cyl_bessel_j</a>
52 and <a class="link" href="bessel.html" title="Bessel Functions of the First and Second Kinds">cyl_neumann</a>
53 return the result of the Bessel functions of the first and second kinds
57 cyl_bessel_j(v, x) = J<sub>v</sub>(x)
60 cyl_neumann(v, x) = Y<sub>v</sub>(x) = N<sub>v</sub>(x)
66 <span class="inlinemediaobject"><img src="../../../../equations/bessel2.png"></span>
69 <span class="inlinemediaobject"><img src="../../../../equations/bessel3.png"></span>
72 The return type of these functions is computed using the <a class="link" href="../../main_overview/result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>result
73 type calculation rules</em></span></a> when T1 and T2 are different types.
74 The functions are also optimised for the relatively common case that T1
78 The final <a class="link" href="../../policy.html" title="Policies">Policy</a> argument is
79 optional and can be used to control the behaviour of the function: how
80 it handles errors, what level of precision to use etc. Refer to the <a class="link" href="../../policy.html" title="Policies">policy documentation for more details</a>.
83 The functions return the result of <a class="link" href="../../main_overview/error_handling.html#domain_error">domain_error</a>
84 whenever the result is undefined or complex. For <a class="link" href="bessel.html" title="Bessel Functions of the First and Second Kinds">cyl_bessel_j</a>
85 this occurs when <code class="computeroutput"><span class="identifier">x</span> <span class="special"><</span>
86 <span class="number">0</span></code> and v is not an integer, or when
87 <code class="computeroutput"><span class="identifier">x</span> <span class="special">==</span>
88 <span class="number">0</span></code> and <code class="computeroutput"><span class="identifier">v</span>
89 <span class="special">!=</span> <span class="number">0</span></code>.
90 For <a class="link" href="bessel.html" title="Bessel Functions of the First and Second Kinds">cyl_neumann</a>
91 this occurs when <code class="computeroutput"><span class="identifier">x</span> <span class="special"><=</span>
92 <span class="number">0</span></code>.
95 The following graph illustrates the cyclic nature of J<sub>v</sub>:
98 <span class="inlinemediaobject"><img src="../../../../graphs/cyl_bessel_j.png" align="middle"></span>
101 The following graph shows the behaviour of Y<sub>v</sub>: this is also cyclic for
102 large <span class="emphasis"><em>x</em></span>, but tends to -∞   for small <span class="emphasis"><em>x</em></span>:
105 <span class="inlinemediaobject"><img src="../../../../graphs/cyl_neumann.png" align="middle"></span>
108 <a name="math_toolkit.special.bessel.bessel.h2"></a>
109 <span><a name="math_toolkit.special.bessel.bessel.testing"></a></span><a class="link" href="bessel.html#math_toolkit.special.bessel.bessel.testing">Testing</a>
112 There are two sets of test values: spot values calculated using <a href="http://functions.wolfram.com" target="_top">functions.wolfram.com</a>, and a
113 much larger set of tests computed using a simplified version of this implementation
114 (with all the special case handling removed).
117 <a name="math_toolkit.special.bessel.bessel.h3"></a>
118 <span><a name="math_toolkit.special.bessel.bessel.accuracy"></a></span><a class="link" href="bessel.html#math_toolkit.special.bessel.bessel.accuracy">Accuracy</a>
121 The following tables show how the accuracy of these functions varies on
122 various platforms, along with comparisons to the <a href="http://www.gnu.org/software/gsl/" target="_top">GSL-1.9</a>
123 and <a href="http://www.netlib.org/cephes/" target="_top">Cephes</a> libraries.
124 Note that the cyclic nature of these functions means that they have an
125 infinite number of irrational roots: in general these functions have arbitrarily
126 large <span class="emphasis"><em>relative</em></span> errors when the arguments are sufficiently
127 close to a root. Of course the absolute error in such cases is always small.
128 Note that only results for the widest floating-point type on the system
129 are given as narrower types have <a class="link" href="../../backgrounders/relative_error.html#zero_error">effectively
130 zero error</a>. All values are relative errors in units of epsilon.
133 <a name="math_toolkit.special.bessel.bessel.errors_rates_in_cyl_bessel_j"></a><p class="title"><b>Table 39. Errors Rates in cyl_bessel_j</b></p>
134 <div class="table-contents"><table class="table" summary="Errors Rates in cyl_bessel_j">
150 Platform and Compiler
155 J<sub>0</sub>   and J<sub>1</sub>
165 J<sub>v</sub>   (large values of x > 1000)
178 Win32 / Visual C++ 8.0
189 <a href="http://www.netlib.org/cephes/" target="_top">Cephes</a> Peak=2.5
201 <a href="http://www.netlib.org/cephes/" target="_top">Cephes</a> Peak=17
210 GSL Peak=6x10<sup>11</sup>
213 <a href="http://www.netlib.org/cephes/" target="_top">Cephes</a> Peak=2x10<sup>5</sup>
225 Red Hat Linux IA64 / G++ 3.4
240 Peak=2x10<sup>4</sup>   Mean=6x10<sup>3</sup>
252 SUSE Linux AMD64 / G++ 4.1
267 Peak=2x10<sup>4</sup>   Mean=1x10<sup>4</sup>
301 <br class="table-break"><div class="table">
302 <a name="math_toolkit.special.bessel.bessel.errors_rates_in_cyl_neumann"></a><p class="title"><b>Table 40. Errors Rates in cyl_neumann</b></p>
303 <div class="table-contents"><table class="table" summary="Errors Rates in cyl_neumann">
319 Platform and Compiler
324 J<sub>0</sub>   and J<sub>1</sub>
329 J<sub>n</sub> (integer orders)
334 J<sub>v</sub> (fractional orders)
347 Win32 / Visual C++ 8.0
358 <a href="http://www.netlib.org/cephes/" target="_top">Cephes</a> Peak=330
370 <a href="http://www.netlib.org/cephes/" target="_top">Cephes</a> Peak=923
379 GSL Peak=1.4x10<sup>6</sup>   Mean=7x10<sup>4</sup>  
382 <a href="http://www.netlib.org/cephes/" target="_top">Cephes</a> Peak=+INF
394 Red Hat Linux IA64 / G++ 3.4
421 SUSE Linux AMD64 / G++ 4.1
431 Peak=2x10<sup>4</sup>   Mean=8x10<sup>3</sup>
436 Peak=1x10<sup>5</sup>   Mean=6x10<sup>3</sup>
463 Peak=2x10<sup>4</sup>   Mean=1200
470 <br class="table-break"><p>
471 Note that for large <span class="emphasis"><em>x</em></span> these functions are largely
472 dependent on the accuracy of the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">sin</span></code>
473 and <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cos</span></code> functions.
476 Comparison to GSL and <a href="http://www.netlib.org/cephes/" target="_top">Cephes</a>
477 is interesting: both <a href="http://www.netlib.org/cephes/" target="_top">Cephes</a>
478 and this library optimise the integer order case - leading to identical
479 results - simply using the general case is for the most part slightly more
480 accurate though, as noted by the better accuracy of GSL in the integer
481 argument cases. This implementation tends to perform much better when the
482 arguments become large, <a href="http://www.netlib.org/cephes/" target="_top">Cephes</a>
483 in particular produces some remarkably inaccurate results with some of
484 the test data (no significant figures correct), and even GSL performs badly
485 with some inputs to J<sub>v</sub>. Note that by way of double-checking these results,
486 the worst performing <a href="http://www.netlib.org/cephes/" target="_top">Cephes</a>
487 and GSL cases were recomputed using <a href="http://functions.wolfram.com" target="_top">functions.wolfram.com</a>,
488 and the result checked against our test data: no errors in the test data
492 <a name="math_toolkit.special.bessel.bessel.h4"></a>
493 <span><a name="math_toolkit.special.bessel.bessel.implementation"></a></span><a class="link" href="bessel.html#math_toolkit.special.bessel.bessel.implementation">Implementation</a>
496 The implementation is mostly about filtering off various special cases:
499 When <span class="emphasis"><em>x</em></span> is negative, then the order <span class="emphasis"><em>v</em></span>
500 must be an integer or the result is a domain error. If the order is an
501 integer then the function is odd for odd orders and even for even orders,
502 so we reflect to <span class="emphasis"><em>x > 0</em></span>.
505 When the order <span class="emphasis"><em>v</em></span> is negative then the reflection formulae
506 can be used to move to <span class="emphasis"><em>v > 0</em></span>:
509 <span class="inlinemediaobject"><img src="../../../../equations/bessel9.png"></span>
512 <span class="inlinemediaobject"><img src="../../../../equations/bessel10.png"></span>
515 Note that if the order is an integer, then these formulae reduce to:
518 J<sub>-n</sub> = (-1)<sup>n</sup>J<sub>n</sub>
521 Y<sub>-n</sub> = (-1)<sup>n</sup>Y<sub>n</sub>
524 However, in general, a negative order implies that we will need to compute
528 When <span class="emphasis"><em>x</em></span> is large compared to the order <span class="emphasis"><em>v</em></span>
529 then the asymptotic expansions for large <span class="emphasis"><em>x</em></span> in M. Abramowitz
530 and I.A. Stegun, <span class="emphasis"><em>Handbook of Mathematical Functions</em></span>
531 9.2.19 are used (these were found to be more reliable than those in A&S
535 When the order <span class="emphasis"><em>v</em></span> is an integer the method first relates
536 the result to J<sub>0</sub>, J<sub>1</sub>, Y<sub>0</sub>   and Y<sub>1</sub>   using either forwards or backwards recurrence
537 (Miller's algorithm) depending upon which is stable. The values for J<sub>0</sub>,
538 J<sub>1</sub>, Y<sub>0</sub>   and Y<sub>1</sub>   are calculated using the rational minimax approximations on
539 root-bracketing intervals for small <span class="emphasis"><em>|x|</em></span> and Hankel
540 asymptotic expansion for large <span class="emphasis"><em>|x|</em></span>. The coefficients
544 W.J. Cody, <span class="emphasis"><em>ALGORITHM 715: SPECFUN - A Portable FORTRAN Package
545 of Special Function Routines and Test Drivers</em></span>, ACM Transactions
546 on Mathematical Software, vol 19, 22 (1993).
552 J.F. Hart et al, <span class="emphasis"><em>Computer Approximations</em></span>, John Wiley
553 & Sons, New York, 1968.
556 These approximations are accurate to around 19 decimal digits: therefore
557 these methods are not used when type T has more than 64 binary digits.
560 When <span class="emphasis"><em>x</em></span> is smaller than machine epsilon then the following
561 approximations for Y<sub>0</sub>(x), Y<sub>1</sub>(x), Y<sub>2</sub>(x) and Y<sub>n</sub>(x) can be used (see: <a href="http://functions.wolfram.com/03.03.06.0037.01" target="_top">http://functions.wolfram.com/03.03.06.0037.01</a>,
562 <a href="http://functions.wolfram.com/03.03.06.0038.01" target="_top">http://functions.wolfram.com/03.03.06.0038.01</a>,
563 <a href="http://functions.wolfram.com/03.03.06.0039.01" target="_top">http://functions.wolfram.com/03.03.06.0039.01</a>
564 and <a href="http://functions.wolfram.com/03.03.06.0040.01" target="_top">http://functions.wolfram.com/03.03.06.0040.01</a>):
567 <span class="inlinemediaobject"><img src="../../../../equations/bessel_y0_small_z.png"></span>
570 <span class="inlinemediaobject"><img src="../../../../equations/bessel_y1_small_z.png"></span>
573 <span class="inlinemediaobject"><img src="../../../../equations/bessel_y2_small_z.png"></span>
576 <span class="inlinemediaobject"><img src="../../../../equations/bessel_yn_small_z.png"></span>
579 When <span class="emphasis"><em>x</em></span> is small compared to <span class="emphasis"><em>v</em></span>
580 and <span class="emphasis"><em>v</em></span> is not an integer, then the following series
581 approximation can be used for Y<sub>v</sub>(x), this is also an area where other approximations
582 are often too slow to converge to be used (see <a href="http://functions.wolfram.com/03.03.06.0034.01" target="_top">http://functions.wolfram.com/03.03.06.0034.01</a>):
585 <span class="inlinemediaobject"><img src="../../../../equations/bessel_yv_small_z.png"></span>
588 When <span class="emphasis"><em>x</em></span> is small compared to <span class="emphasis"><em>v</em></span>,
589 J<sub>v</sub>x   is best computed directly from the series:
592 <span class="inlinemediaobject"><img src="../../../../equations/bessel2.png"></span>
595 In the general case we compute J<sub>v</sub>   and Y<sub>v</sub>   simultaneously.
598 To get the initial values, let μ   = ν - floor(ν + 1/2), then μ   is the fractional
599 part of ν   such that |μ| <= 1/2 (we need this for convergence later). The
600 idea is to calculate J<sub>μ</sub>(x), J<sub>μ+1</sub>(x), Y<sub>μ</sub>(x), Y<sub>μ+1</sub>(x) and use them to obtain
601 J<sub>ν</sub>(x), Y<sub>ν</sub>(x).
604 The algorithm is called Steed's method, which needs two continued fractions
605 as well as the Wronskian:
608 <span class="inlinemediaobject"><img src="../../../../equations/bessel8.png"></span>
611 <span class="inlinemediaobject"><img src="../../../../equations/bessel11.png"></span>
614 <span class="inlinemediaobject"><img src="../../../../equations/bessel12.png"></span>
617 See: F.S. Acton, <span class="emphasis"><em>Numerical Methods that Work</em></span>, The
618 Mathematical Association of America, Washington, 1997.
621 The continued fractions are computed using the modified Lentz's method
622 (W.J. Lentz, <span class="emphasis"><em>Generating Bessel functions in Mie scattering calculations
623 using continued fractions</em></span>, Applied Optics, vol 15, 668 (1976)).
624 Their convergence rates depend on <span class="emphasis"><em>x</em></span>, therefore we
625 need different strategies for large <span class="emphasis"><em>x</em></span> and small <span class="emphasis"><em>x</em></span>.
628 <span class="emphasis"><em>x > v</em></span>, CF1 needs O(<span class="emphasis"><em>x</em></span>) iterations
629 to converge, CF2 converges rapidly
632 <span class="emphasis"><em>x <= v</em></span>, CF1 converges rapidly, CF2 fails to converge
633 when <span class="emphasis"><em>x</em></span> <code class="literal">-></code> 0
636 When <span class="emphasis"><em>x</em></span> is large (<span class="emphasis"><em>x</em></span> > 2), both
637 continued fractions converge (CF1 may be slow for really large <span class="emphasis"><em>x</em></span>).
638 J<sub>μ</sub>, J<sub>μ+1</sub>, Y<sub>μ</sub>, Y<sub>μ+1</sub> can be calculated by
641 <span class="inlinemediaobject"><img src="../../../../equations/bessel13.png"></span>
647 <span class="inlinemediaobject"><img src="../../../../equations/bessel14.png"></span>
650 J<sub>ν</sub> and Y<sub>μ</sub> are then calculated using backward (Miller's algorithm) and forward
651 recurrence respectively.
654 When <span class="emphasis"><em>x</em></span> is small (<span class="emphasis"><em>x</em></span> <= 2),
655 CF2 convergence may fail (but CF1 works very well). The solution here is
659 <span class="inlinemediaobject"><img src="../../../../equations/bessel15.png"></span>
665 <span class="inlinemediaobject"><img src="../../../../equations/bessel16.png"></span>
668 g<sub>k</sub>   and h<sub>k</sub>  
669 are also computed by recursions (involving gamma functions), but
670 the formulas are a little complicated, readers are refered to N.M. Temme,
671 <span class="emphasis"><em>On the numerical evaluation of the ordinary Bessel function of
672 the second kind</em></span>, Journal of Computational Physics, vol 21, 343
673 (1976). Note Temme's series converge only for |μ| <= 1/2.
676 As the previous case, Y<sub>ν</sub>   is calculated from the forward recurrence, so is
677 Y<sub>ν+1</sub>. With these two values and f<sub>ν</sub>, the Wronskian yields J<sub>ν</sub>(x) directly without
681 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
682 <td align="left"></td>
683 <td align="right"><div class="copyright-footer">Copyright © 2006-2010 John Maddock, Paul A. Bristow, Hubert Holin, Xiaogang Zhang, Bruno
684 Lalande, Johan Råde, Gautam Sewani, Thijs van den Berg and Benjamin Sobotta<p>
685 Distributed under the Boost Software License, Version 1.0. (See accompanying
686 file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
691 <div class="spirit-nav">
692 <a accesskey="p" href="bessel_over.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../bessel.html"><img src="../../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="mbessel.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a>