[GIF] Bessel (Taylor approximations to a Bessel function)

bessel6r.gif

Bessel

This animation shows successive Taylor polynomial approximations to the Bessel function of the first kins J_0. Specifically, the Taylor series for J_0 is

J_0(x) = \sum_{n=0}^\infty \frac{(-1)^n}{4^n (n!)^2} x^{2n},

and this animations shows the first 51 partial sums.

Here’s the code:

With[{cols = RGBColor /@ {"#28CC9E", "#132F2B"}},
 Manipulate[
  Plot[
   Evaluate@Table[Sum[(-1)^n/(4^n (n!)^2) x^(2 n), {n, 0, k}], {k, 0,  m}], {x, -30, 30},
   PlotRange -> {{-29.9, 29.9}, {-1.2, 1.2}}, 
   Background -> cols[[-1]], 
   PlotStyle ->  Directive[CapForm[None], cols[[1]], Opacity[.35], Thickness[.003]],
   Axes -> False, ImageSize -> 600], 
   {m, -1, 50, 1}]
 ]

(Incidentally, the CapForm[None] bit in the code is due to what seems to be an implementation bug in Plot: the graph of a function in Plot seems to be built out of several concatenated curves using the default CapForm option, but when PlotStyle includes Opacity[a] for some a<1, the concatenated curves have an overlap which shows up as a bright spot unless you include CapForm[None] in PlotStyle.)

6 Likes

You can do something similar with Series, but it doesn’t run as fast.

With[{cols = RGBColor /@ {"#28CC9E", "#132F2B"}},
 Manipulate[
  Plot[
   Evaluate@Table[Normal@Series[BesselJ[0,x],{x,0,n}],{n,0,m}], {x, -30, 30},
   PlotRange -> {{-29.9, 29.9}, {-1.2, 1.2}}, 
   Background -> cols[[-1]], 
   PlotStyle ->  Directive[CapForm[None], cols[[1]], Opacity[.35], Thickness[.003]],
   Axes -> False, ImageSize -> 600], 
   {m, -1, 50, 1}]
 ]

(I like the plot styling a lot by the way!)

2 Likes

Indeed, although my preference would be to increase the order in Series by 2 to avoid repeats. Like so:

With[{cols = RGBColor /@ {"#28CC9E", "#132F2B"}}, 
 Manipulate[
  Plot[Evaluate@
    Table[Normal@Series[BesselJ[0, x], {x, 0, 2 n}], {n, 0, m}], {x, -30, 30},
   PlotRange -> {{-29.9, 29.9}, {-1.2, 1.2}}, Background -> cols[[-1]], 
   PlotStyle -> Directive[CapForm[None], cols[[1]], Opacity[.35], Thickness[.003]], 
   Axes -> False, ImageSize -> 600],
  {m, -1, 50, 1}]]
2 Likes

Just a note that a general term can be obtained as

SeriesCoefficient[BesselJ[0, z], {z, 0, n}]

asdf.png

and simplified further

FullSimplify[SeriesCoefficient[BesselJ[0, z], {z, 0, n}]]

fsartergfd.png

2 Likes

As far as series approximation and function values go, the Bessel function is a nightmare, but it does mean something physical, especially in relation to quantum mechanics. So yes, calculate!

In some sense it is like the cosine function, where series approximation is already made difficult by the fact that the range never exceeds \pm 1, while the domain goes between \pm \infty. At the outer limits all polynomials blow up, so it’s hopeless to translate to another function value via series expansion around some starting point.

Considering any function as a manifold, series expansion is a local technique, to combine with overall global structure. You can get a pretty good approximation of sine / cosine if you expand a few orders of magnitude around say, every minima and maxima at intervals of \pi.

This technique also applies to the Bessel function, another example where

\lim_{x\rightarrow\infty}\frac{y(x)}{x} \longrightarrow 0 .

Mathematica greatly simplifies the finding of zeroes,

ApproxBessel[nCut_] := Normal@Series[BesselJ[0, x], {x, BesselJZero[0, #], nCut}] & /@  Range[5]
FList = N[ApproxBessel[#]] & /@ Range[10];
gList = MapThread[   Plot[#1, {x, 0, 20}, PlotRange -> {-1.1, 1.1}, PlotStyle -> #2, 
     Axes -> False] &, {    FList, Blend[{Green, Blue}, #/11] & /@ Range[10] }];
Stacked = Show[gList[[1 ;; #]]] & /@ Range[10];
ListAnimate[ Join[Stacked, Reverse@Stacked]] 

8011Bessel.gif

We can also approach critical values from either the left or right,

In[42]:= x /. FindRoot[#, {x, 4}] & /@ D[FList[[-1, {1, 2}]], x]
Out[42]= {3.83171, 3.83168}

Then compare with the first entry of the last table on mathworld: Bessel Function Zeroes . Matching of left / right values essentially provides a convergence criteria that allows you to say if a digit in decimal is correct. Up to order ten, we have four digits correct on the first minima. Getting a few of these values, we could make another patch function by expanding in quadratic and higher.

2015-11-02_10-07-11.png

  • Congratulations! This post is now a Staff Pick! Thank you for your wonderful contributions. Please, keep them coming!

The Padé approximants are interesting to look at as well:

With[{cols = RGBColor /@ {"#28CC9E", "#132F2B"}}, 
     Manipulate[Plot[Evaluate @ Table[PadeApproximant[BesselJ[0, x], {x, 0, k}], {k, 0, m, 2}],
                     {x, -30, 30}, Axes -> False,  Background -> cols[[-1]], ImageSize -> 600,
                     PlotRange -> {{-29.9, 29.9}, {-1.2, 1.2}}, 
                     PlotStyle -> Directive[CapForm[None], cols[[1]], Opacity[.35], Thickness[.003]]],
                {m, 0, 50, 2}]]

3 Likes