Message Boards Message Boards

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

GROUPS:

Taylor approximations to a Bessel function

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.)

POSTED BY: Clayton Shonkwiler
Answer
8 months ago

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!)

POSTED BY: Christopher Wolfram
Answer
8 months ago

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}]]
POSTED BY: Clayton Shonkwiler
Answer
8 months ago

Just a note that a general term can be obtained as

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

enter image description here

and simplified further

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

enter image description here

POSTED BY: Vitaliy Kaurov
Answer
8 months ago

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]] 

Approximation

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.

POSTED BY: Brad Klee
Answer
8 months ago

enter image description here - Congratulations! This post is now a Staff Pick! Thank you for your wonderful contributions. Please, keep them coming!

POSTED BY: Moderation Team
Answer
8 months ago

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}]]

Padé approximants of zero-order Bessel function

POSTED BY: J. M.
Answer
7 months ago

Group Abstract Group Abstract