## Taylor expansions

We first import some prerequisite modules, most importantly Sympy and Matplotlib. 


```python
def uniq(seq): 
    # order preserving
    seen = {}
    result = []
    for item in seq:
        if item in seen: 
            continue
        seen[item] = 1
        result.append(item)
    return result
```


```python
import sympy as sm
from sympy.abc import x
from matplotlib.colors import cnames
```


```python
import matplotlib
from matplotlib.colors import rgb2hex

from numpy import arange
```


```python
from sympy import Symbol,plot
import matplotlib.pyplot as plt

def move_sympyplot_to_axes(p, ax):
    backend = p.backend(p)
    backend.ax = ax
    backend.process_series()
    backend.ax.spines['right'].set_color('none')
    backend.ax.spines['bottom'].set_position('zero')
    backend.ax.spines['top'].set_color('none')
    plt.close(backend.fig)
```

The following routine will plot the function `f` together with its Taylor polynomials up to the degree `degree`, in the square box with sides `[-A,A]`. We will use it several times for different functions `f`.


```python
def taylorplot(f, degree, A):
    L = [f.series(n=i).removeO() for i in range (1, degree+2)] # +1 for the offset of `range`, another +1 for the offset of `.series`
    L = uniq(L)
    L.insert(0,f)
    # Pick colors from the Blues colorscheme
    a = arange(0,1,1/len(L))
    c = matplotlib.cm.Blues(a)[:,:3]
    
    # Plot the original function in red, then add the graphs of Taylor polynomials in different shades of blue
    p1 = sm.plot(L[0], xlim=[-A,A], ylim=[-A,A], line_color = 'r',  show=False)
    for i in range(1,len(L)):
        p1.extend(sm.plot(L[i], xlim=[-A,A], ylim=[-A,A], line_color = rgb2hex(c[i,:]), show=False))
    p1.legend = False
    # p1.show()
    
    # Plot the original function alone
    p2 = sm.plot(L[0], xlim=[-A,A], ylim=[-A,A], line_color = 'r', show=False)
    p2.legend = False
    p2.grid = True
    # p2.show()

    # Generate the legend by LaTeXing the expressions for the functions involved.
    l =[]
    for i in range(len(L)):
        l.append(sm.latex(L[i], mode='inline'))

    # %matplotlib gtk3 # uncomment to use the external plot window
    # Combine the two resulting plots, add legend
    fig, (ax1,ax2) = plt.subplots(ncols=2,figsize=(20,10))
    move_sympyplot_to_axes(p1, ax1)
    move_sympyplot_to_axes(p2, ax2)
    fig.legend(l,loc='lower center', bbox_to_anchor=(0.5, 0.0),
              ncol=3, fancybox=True, shadow=True)
    plt.show()
```

----

Let us first plot the partial sums of the Maclaurin series of the Bessel function $J_0$, up to the degree 14. We will restrict the graphs to the box `[-10,10]` by `[-10,10]`:


```python
B = sm.besselj(0,x)
taylorplot(B, 14, 10)
```

In these graphs we show the Taylor polynomials (centered at $a=0$ here), using the darker shade to denote to the higher degree polynomial $T_n(x)$. The plot on the right shows $J_0(x)$ itself.

----

Next, let us do the same with $\sin(x)$. We plot its Taylor polynomials at 0 up to degree 13 in the box `[-10,10]` by `[-10,10]`.


```python
S = sm.sin(x)
taylorplot(S, 13,10)
```

---

Finally, let us look at two examples in which the Maclaurin series of a function does not converge for all `x`. The first example is $ 1/(1-x) $; we will plot its Taylor polynomials up to degree 10 in the square box `[-6,6]` by `[-6,6]`.


```python
f1 = 1/(1-x)
taylorplot(f1,10,6)
```

Observe how the polynomials $ T_n $ diverge away from the graph of the function `f1` when $x=-1$, even though the function does not have a singularity there. This is of course because the radius of convergence of the geometric series $$ \sum_{n=0}^\infty x^n $$ is $1$. Since the interval of convergence of a series must be symmetric, divergence of the series at $ x = 1 $, where the function `f1` has a singularity, means that the series must also diverge at $x = -1$.

---

The following example is even more subtle. The function we look at here, `f2`$= 1/(1+x^2) $, does not exhibit any singularities at all! On the other hand, its Maclaurin series  $$ \sum_{n=0}^\infty\, (-1)^n x^{2n} $$ diverges as soon as $|x|\geq 1 $. Let us plot the Taylor polynomials at $ a = 0 $ up to the degree  $ n = 20$.


```python
f2 = 1/(1+x**2)
taylorplot(f2,20,6)
```

**Outside of Calc2:** It turns out, to understand the reason for such behavior of this series, one has to extend the function `f2`$=1/(1+x^2)$ to *complex numbers*, where for $x = i$, our function `f2` has a singularity (the complex number $i$ is such that $i^2+1 = 0$, turning the denominator of `f2` into $0$). In the complex plane, series converge on *discs* instead of intervals, so because the function `f2` has a singularity at the point $0+i\,1$, its series centered at $a=0$ will have the radius of convergence equal to $1$. We show this relation in the following graph. In it, a point $(x,y)$ in the plane stands for the complex number $z = x+ iy$.


```python
    fig, ax = plt.subplots(figsize=(10,10))
    circle =  matplotlib.patches.Circle ((0, 0), 1, edgecolor='none',alpha=0.5)
    p = matplotlib.collections.PatchCollection([circle], alpha=0.4)
    ax.add_collection(p);
    ax.scatter([0.0],[1.0],marker='o',c='r',s=40)    
    ax.annotate('Singularity of f2 at $0+i$', xy=(0.1, 1.05), xytext=(1, 1.5),
            arrowprops=dict(arrowstyle="->")
            )
    ax.annotate('For complex $z= x + i\,y$\nthat lie inside this disc,\nthe series converges.', xy=(0.5, -0.5), xytext=(0.5, -1.5),
        arrowprops=dict(arrowstyle="->")
        )
    ax.annotate('The series will diverge at the\n points of the disc boundary', xy=(-1.02, -0.13), xytext=(-2, -1),
            arrowprops=dict(arrowstyle="->")
            )
    # This adjusts the position of the axes
    ax.spines['left'].set_position('center')
    ax.spines['bottom'].set_position('center')
    ax.spines['right'].set_color('none')
    ax.spines['top'].set_color('none')
    ax.xaxis.set_ticks_position('bottom')
    ax.yaxis.set_ticks_position('left')
    
    plt.ylim(-2,2)
    plt.xlim(-2,2)
    plt.show()
```

86ba68b4c905faee75caafef2f71823e3c84b49c
ipynb
Jupyter Notebook
assets/taylor.ipynb
OVlasiuk/ovlasiuk.github.io
ca3b6317fcc458945c6cfe3fd16a8b2622e836a2
MIT
assets/taylor.ipynb
OVlasiuk/ovlasiuk.github.io
ca3b6317fcc458945c6cfe3fd16a8b2622e836a2
MIT
assets/taylor.ipynb
OVlasiuk/ovlasiuk.github.io
ca3b6317fcc458945c6cfe3fd16a8b2622e836a2
MIT
Qwen/Qwen-72B
1. YES
2. YES