Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

This notebook explores Taylor polynomial approximations and their error behavior.

import numpy as np
import matplotlib.pyplot as plt
from math import factorial

Taylor Polynomials of exe^x

The Taylor series for exe^x centered at x0=0x_0 = 0 is:

ex=k=0xkk!=1+x+x22!+x33!+e^x = \sum_{k=0}^{\infty} \frac{x^k}{k!} = 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} + \cdots

The nn-th degree Taylor polynomial Pn(x)P_n(x) truncates this series.

def taylor_exp(x, n):
    """Compute n-th degree Taylor polynomial of e^x at x=0."""
    return sum(x**k / factorial(k) for k in range(n + 1))

# Vectorize for array input
taylor_exp_vec = np.vectorize(taylor_exp, excluded=['n'])

x = np.linspace(-2, 3, 200)

fig, ax = plt.subplots(figsize=(10, 6))

# Plot exact function
ax.plot(x, np.exp(x), 'k--', linewidth=2, label=r'$e^x$ (exact)')

# Plot Taylor polynomials
colors = plt.cm.viridis(np.linspace(0.2, 0.8, 4))
for i, n in enumerate([1, 2, 3, 4]):
    y_approx = taylor_exp_vec(x, n)
    error_at_1 = abs(taylor_exp(1, n) - np.e)
    ax.plot(x, y_approx, color=colors[i], linewidth=1.5,
            label=f'$P_{n}(x)$, error at $x=1$: {error_at_1:.2e}')

ax.set_xlim(-2, 3)
ax.set_ylim(-1, 10)
ax.set_xlabel('$x$', fontsize=12)
ax.set_ylabel('$y$', fontsize=12)
ax.set_title('Taylor Polynomial Approximations of $e^x$', fontsize=14)
ax.legend(loc='upper left', fontsize=10)
ax.grid(True, alpha=0.3)
ax.axhline(y=0, color='k', linewidth=0.5)
ax.axvline(x=0, color='k', linewidth=0.5)

plt.tight_layout()
plt.show()

Taylor Polynomials of tan(x)\tan(x)

Let’s approximate tan(x)\tan(x) near x0=0x_0 = 0. The Taylor series is:

tan(x)=x+x33+2x515+\tan(x) = x + \frac{x^3}{3} + \frac{2x^5}{15} + \cdots

We’ll examine how the remainder term bounds the true error.

def taylor_tan(x, n):
    """Taylor polynomial of tan(x) at x=0.
    
    Only odd terms are nonzero. We compute coefficients numerically.
    """
    # Coefficients for tan(x): 1, 0, 1/3, 0, 2/15, 0, 17/315, ...
    coeffs = [0, 1, 0, 1/3, 0, 2/15, 0, 17/315, 0, 62/2835]
    result = 0
    for k in range(min(n + 1, len(coeffs))):
        result += coeffs[k] * x**k
    return result

taylor_tan_vec = np.vectorize(taylor_tan, excluded=['n'])

x = np.linspace(0, 0.5, 100)

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))

# Left: Function and approximations
ax1.plot(x, np.tan(x), 'k-', linewidth=2, label=r'$\tan(x)$ (exact)')
for n, color in [(1, 'C0'), (3, 'C1'), (5, 'C2')]:
    ax1.plot(x, taylor_tan_vec(x, n), '--', color=color, linewidth=1.5, label=f'$P_{n}(x)$')

ax1.set_xlabel('$x$', fontsize=12)
ax1.set_ylabel('$y$', fontsize=12)
ax1.set_title(r'Taylor Approximations of $\tan(x)$', fontsize=14)
ax1.legend(fontsize=10)
ax1.grid(True, alpha=0.3)

# Right: Absolute errors
for n, color in [(1, 'C0'), (3, 'C1'), (5, 'C2')]:
    error = np.abs(np.tan(x) - taylor_tan_vec(x, n))
    ax2.semilogy(x, error + 1e-16, '-', color=color, linewidth=1.5, label=f'$|\\tan(x) - P_{n}(x)|$')

ax2.set_xlabel('$x$', fontsize=12)
ax2.set_ylabel('Absolute Error', fontsize=12)
ax2.set_title('Approximation Error', fontsize=14)
ax2.legend(fontsize=10)
ax2.grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

The Remainder Term

Taylor’s theorem tells us that for Pn(x)P_n(x) centered at x0x_0:

f(x)=Pn(x)+Rn(x)f(x) = P_n(x) + R_n(x)

where the remainder is:

Rn(x)=f(n+1)(ξ)(n+1)!(xx0)n+1R_n(x) = \frac{f^{(n+1)}(\xi)}{(n+1)!}(x - x_0)^{n+1}

for some ξ\xi between x0x_0 and xx. This gives us an error bound.

# For e^x, all derivatives are e^x, so |R_n(x)| <= e^|x| * |x|^(n+1) / (n+1)!

x_val = 0.5

print(f"Approximating e^{x_val} = {np.exp(x_val):.10f}")
print()
print(f"{'n':>3} | {'P_n(x)':>14} | {'True Error':>12} | {'Bound |R_n|':>12} | {'Bound ok?':>10}")
print("-" * 65)

for n in range(1, 8):
    approx = taylor_exp(x_val, n)
    true_error = abs(np.exp(x_val) - approx)
    # Upper bound: max of e^x on [0, 0.5] is e^0.5
    bound = np.exp(x_val) * x_val**(n+1) / factorial(n+1)
    ok = "Yes" if true_error <= bound else "No"
    print(f"{n:3d} | {approx:14.10f} | {true_error:12.2e} | {bound:12.2e} | {ok:>10}")

Key Observations

  1. Taylor polynomials provide increasingly accurate approximations near the expansion point

  2. The remainder term gives a rigorous error bound that always overestimates the true error

  3. Convergence is local: Taylor polynomials work best near x0x_0; accuracy degrades as you move away

  4. Higher degree = higher accuracy near x0x_0, but may oscillate wildly far from x0x_0