5.4 泰勒展開#
本節目標#
- 理解泰勒級數的核心思想:用多項式逼近任意光滑函數
- 會用
series()展開 \(\sin x\) 、 \(e^x\) 、 \(\ln(1+x)\) ,並用removeO()取出多項式 - 做截斷誤差實驗:疊圖觀察各階泰勒多項式的「貼合範圍」
- 用泰勒展開優雅地重解 5.1 節的 \(\lim \frac{\sin x}{x}\)
核心思想:用多項式當替身#
多項式是最好計算的函數——加減乘就能算。如果一個複雜函數(如 \(\sin\) 、 \(e^x\) )在某一點附近能被一個多項式「冒充」,所有難算的問題都變簡單。
泰勒的想法:在 \(x = 0\) (即 Maclaurin 情形)附近,要求這個多項式 \(p(x)\) 與原函數 \(f(x)\) 的值、一階導數、二階導數、…… 全部相同:
滿足這些條件的 \(n\) 次多項式是唯一的:
係數模式 \(\dfrac{f^{(k)}(0)}{k!}\) 的由來:對 \(x^k\) 連微 \(k\) 次會掉下 \(k!\) ,剛好把分母抵掉。
series():SymPy 的一行展開#
from sympy import symbols, series, sin, cos, exp, log, limit
x = symbols('x')
series(sin(x), x, 0, 8)
# x - x**3/6 + x**5/120 - x**7/5040 + O(x**8)
series(exp(x), x, 0, 6)
# 1 + x + x**2/2 + x**3/6 + x**4/24 + x**5/120 + O(x**6)
series(log(1 + x), x, 0, 6)
# x - x**2/2 + x**3/3 - x**4/4 + x**5/5 + O(x**6)
series(expr, x, 0, n):在 \(x = 0\) 附近展開到 \(x^{n-1}\) 階。- 結尾的
O(x**8)是皮亞諾餘項,表示「 \(8\) 次以上的項被截斷了」。 - 三個展開式都與 5.2 節的觀察吻合: \(\sin\) 的導數四階循環,所以只有奇數次項; \(e^x\) 各階導數在 \(0\) 都是 \(1\) ,係數是 \(\frac{1}{k!}\) 。
removeO():把餘項剝掉,得到乾淨的多項式(可直接代入、畫圖):
p = series(sin(x), x, 0, 8).removeO()
print(p) # x - x**3/6 + x**5/120 - x**7/5040
p.subs(x, 0.1) # 0.0998334166468254
動手實驗:截斷誤差與疊圖#
泰勒多項式只在展開點附近可靠。各階多項式到底貼得多近、多遠就失效?畫圖最清楚:
import numpy as np
import matplotlib.pyplot as plt
from sympy import lambdify
f = sin(x)
xs = np.linspace(-2* np.pi, 2*np.pi, 400)
plt.plot(xs, np.sin(xs), 'k', lw=2, label='$\\sin x$')
for n in [1, 3, 5, 9]:
p = series(f, x, 0, n + 1).removeO()
pf = lambdify(x, p, 'numpy')
plt.plot(xs, pf(xs), '--', label=f'Taylor n={n}')
plt.ylim(-2, 2)
plt.axhline(0, color='gray', lw=0.5)
plt.axvline(0, color='gray', lw=0.5)
plt.legend()
plt.title('$\\sin x$ 與各階泰勒多項式')
plt.show()
觀察重點:
- 階數越高,多項式與 \(\sin x\) 的「貼合區間」越寬。
- 貼合區間之外,多項式會爆炸性偏離( \(n=9\) 的多項式在 \(\pm 2\pi\) 外早已衝天)——泰勒逼近是局部的。
- \(\sin\) 是奇函數,展開式只有奇次項——偶數階的圖與低一階的完全重合。
再做定量實驗:固定 \(x = 0.5\) ,看誤差隨階數下降:
from sympy import Abs
x0 = 0.5
true_val = f.subs(x, x0).evalf()
for n in [1, 3, 5, 7, 9, 11]:
p = series(f, x, 0, n + 1).removeO()
err = Abs(p.subs(x, x0) - true_val).evalf()
print(f"n={n:>2} 誤差 = {err:.3e}")
誤差以驚人的速度墜落( \(\sin\) 的泰勒餘項約為 \(\frac{|x|^{n+1}}{(n+1)!}\) ,階乘衰減極快)。
用泰勒展開重解 \(\lim_{x \to 0} \dfrac{\sin x}{x}\)#
5.1 節我們用 limit() 得到答案 \(1\) ,但那是「CAS 說了算」。泰勒展開讓你親手看清原因:
當 \(x \to 0\) , \(\frac{x^2}{6}\) 之後的項統統消失,極限就是多項式首項 \(1\) 。
from sympy import simplify
ratio = series(sin(x), x, 0, 5).removeO() / x
print(ratio) # x**4/24 - x**2/6 + 1
limit(ratio, x, 0) # 1
同樣手法處理 5.1 節那題 \(\frac{e^x - 1 - x}{x^2}\) :
num = series(exp(x), x, 0, 4).removeO() # x**3/6 + x**2/2 + x + 1
simplify((num - 1 - x) / x**2) # x/6 + 1/2 → 極限 = 1/2
一次展開,分子中 \(1 + x\) 被抵消、剩下 \(\frac{x^2}{2}\) 主項——「 \(0/0\) 型極限」的迷霧徹底撥開。這正是泰勒展開在求極限上的威力:把比較誰衰減得快,變成比較多項式的最低次項。
動手實驗:算 \(\sin(0.1)\) 用幾階夠準?#
真實場景:計算機與數學函式庫算 \(\sin\) 時,就是用多項式(泰勒變體)。用幾階才夠?
import math
x0 = 0.1
target = math.sin(x0)
print(f"真值(Python 內建): {target:.16f}\n")
for n in range(1, 10, 2):
p = series(sin(x), x, 0, n + 1).removeO()
val = float(p.subs(x, x0))
print(f"n={n:>2} 近似 = {val:.16f} 誤差 = {abs(val - target):.2e}")
典型輸出:
n= 1 近似 = 0.1000000000000000 誤差 = 1.67e-04
n= 3 近似 = 0.0998333333333333 誤差 = 8.33e-08
n= 5 近似 = 0.0998334166666667 誤差 = 8.33e-12
n= 7 近似 = 0.0998334166666667 誤差 = 1.39e-16 ← 已達雙精度極限
結論: \(x = 0.1\) 很小,三階( \(n=3\) )就有 \(10^{-8}\) 精度,五階達 \(10^{-12}\) ,七階已經到達 float 的極限(約 \(10^{-16}\) )——再高階毫無意義。若把 \(x_0\) 改成 \(1.0\) 重跑,需要的階數明顯增加——越遠離展開點,需要越高階,與疊圖實驗的結論一致。
把實驗延伸一下:對固定的目標精度(如 \(10^{-10}\) ),畫出「所需最低階數 vs \(x_0\) 」的關係圖,體會收斂半徑的概念。
小結與練習#
- 泰勒多項式在展開點附近與原函數的值與各階導數完全吻合。
series(expr, x, 0, n)展開,removeO()剝掉餘項取多項式。- 逼近是局部的:階數越高貼合區間越寬,但區間外會爆炸偏離。
- 泰勒展開是求 \(\frac{0}{0}\) 型極限的利器:展開、抵消、讀出首項。
練習
- 展開 \(\cos x\) 到 \(x^8\) ,驗證只有偶次項,並畫疊圖。
- 用泰勒展開手推 \(\lim_{x \to 0} \dfrac{1 - \cos x}{x^2}\) ,再用 SymPy 驗證。
- 展開 \(\ln(1+x)\) 到 10 階,代入 \(x = 1\) 得到 \(\ln 2\) 的級數近似;需要幾項才能達到 \(10^{-4}\) 精度?
- 對 \(f(x) = e^x\) 在 \(x = 1\) 附近展開(
series(exp(x), x, 1, n)),與在 \(0\) 附近展開比較:哪個在 \(x = 2\) 處更準?為什麼?