跳轉到

7.3 泰勒展開與級數加速#

概念說明#

電腦怎麼算出 sin(1)、e²、π?答案是無窮級數的有限截斷。任何標準函數庫的底層,都是把函數展開成收斂級數,取前有限項求值。泰勒定理是這件事的理論基礎:

f(x) = Σ_{k=0}^{N} f⁽ᵏ⁾(a)(x−a)ᵏ/k! + Rₙ(x)

例如 eˣ = 1 + x + x²/2! + x³/3! + …、sin x = x − x³/3! + x⁵/5! − …。截斷誤差(餘項)對 eˣ 在 |x| < 1 時 ≤ e·|x|^(N+1)/(N+1)!,階乘分母使收斂快得驚人——這就是為什麼 math.exp 只需十幾項就達到機器精度。

但並非所有級數都這麼乖。著名的 Leibniz 級數 π/4 = 1 − 1/3 + 1/5 − … 收斂慢得令人髮指:要 10¹⁰ 項才對 10 位數。級數加速(series acceleration)是一組技術,用「誤差自身的規律」去抵銷誤差:

  • Aitken Δ² 法:若誤差近似幾何衰減 eₙ ≈ C·qⁿ,則由三個相鄰近似值可外推 eₙ ≈ 0 的位置。
  • Richardson 外推:若誤差有已知形式 eₙ = C·hᵖ,用兩個不同步長的結果線性組合消掉主誤差項,階數躍升(6.2 節的 Romberg 積分就是它的應用)。
  • Euler 變換與收斂加速公式:對交錯級數特別有效,可把 Leibniz 級數變成快速收斂版本。

更務實的心法是:換一個收斂快的級數勝過苦練加速術——算 π 時用 Machin 公式或 Ramanujan 級數,比加速 Leibniz 級數快上百萬倍。

演算法步驟#

Aitken Δ² 加速:

  1. 取級數的三個連續部分和 Sₙ, Sₙ₊₁, Sₙ₊₂。
  2. 計算 Tₙ = Sₙ − (ΔSₙ)²/Δ²Sₙ,其中 ΔSₙ = Sₙ₊₁ − Sₙ、Δ²Sₙ = Sₙ₊₂ − 2Sₙ₊₁ + Sₙ。
  3. Tₙ 的誤差通常遠小於 Sₙ(若誤差恰為幾何,Tₙ 一次到位)。

Richardson 外推(已知誤差階 p):

  1. 以步長 h 與 h/2 各算一次:A(h), A(h/2)。
  2. 外推值 = A(h/2) + [A(h/2) − A(h)]/(2ᵖ − 1)。

Python 程式碼範例#

import math

# --- 泰勒級數求 e^x ---
def exp_taylor(x, tol=1e-16):
    term, s, k = 1.0, 1.0, 0
    while abs(term) > tol * abs(s) and k < 200:
        k += 1
        term *= x / k                 # 每項 = 前項 * x/k
        s += term
    return s, k

for x in [1.0, 5.0, 20.0]:
    val, k = exp_taylor(x)
    print(f"e^{x}: 泰勒 {val:.15f}({k} 項), math.exp 誤差 {abs(val - math.exp(x)):.1e}")

# --- Leibniz 級數與 Aitken 加速 ---
def leibniz_partial(N):
    return sum((-1)**k / (2*k + 1) for k in range(N))

pi4 = math.pi / 4
print("\nLeibniz 直接收斂(部分和誤差):")
for N in [10, 100, 1000, 10000]:
    print(f"  N={N:>6}: 誤差 {abs(leibniz_partial(N) - pi4):.3e}")

S = [leibniz_partial(n) for n in range(1, 31)]
T = [S[i] - (S[i+1]-S[i])**2 / (S[i+2] - 2*S[i+1] + S[i])
     for i in range(len(S) - 2)]
print(f"Aitken 加速後(n≈28)誤差: {abs(T[-1] - pi4):.3e}")

# --- Richardson 外推:中點差分的導數 ---
def midpoint_diff(f, x, h):
    return (f(x + h) - f(x - h)) / (2 * h)

f = math.sin
x, exact = 1.0, math.cos(1.0)
A1 = midpoint_diff(f, x, 0.1)          # 誤差階 p = 2
A2 = midpoint_diff(f, x, 0.05)
rich = A2 + (A2 - A1) / (2**2 - 1)
print(f"\n中點差分 h=0.05 誤差: {abs(A2 - exact):.3e}")
print(f"Richardson 外推後誤差: {abs(rich - exact):.3e}")

誤差分析#

泰勒餘項有兩種有用形式:Lagrange 型 Rₙ = f⁽ⁿ⁺¹⁾(ξ)(x−a)^(n+1)/(n+1)!(可估界)與積分型(可推遞迴)。工程要點:截斷誤差 O(h^(N+1)),但要注意 (1) x 離展開中心太遠時收斂半徑問題(eˣ 全域收斂、arctan 只有 |x| ≤ 1),實作上用參數規約(range reduction):先縮小自變數到收斂快的小區間再展開;(2) 項與項之間用遞迴(term × x/k)而非每項重算階乘,兼顧速度與捨入誤差;(3) 交錯級數的截斷誤差小於第一個丟棄項的絕對值,這給了免費的誤差證書。加速技術的理論:Aitken Δ² 把誤差階從 q 提到 q²(對幾何誤差),反覆套用構成 Shanks 變換;Richardson 外推每套用一次,誤差階 p → p + 下一段的 p 值,Romberg 積分疊出 O(h²ⁿ) 就是這麼來的。而誤差呈 O(1/n) 衰減的調和型級數(如 π/4 = Σ(−1)ᵏ/(2k+1))對 Aitken 不敏感,正解是換公式——例如 Machin 公式 π = 16 arctan(1/5) − 4 arctan(1/239),arctan 的冪級數在 x = 1/5 每項縮小 25 倍,只需約 15 項就達 20 位精度。

練習#

  1. 寫函數 sin_taylor(x, tol)(用遞迴項且先做 x ← x mod 2π 的參數規約),對 x = 1, 10, 100 比較項數需求,驗證規約的重要性。
  2. 用 Aitken Δ² 加速 Σ 1/k²(收斂到 π²/6),畫出加速前後誤差對 n 的曲線;解釋為什麼加速有效(誤差近似 C/n,非幾何但單調可外推)。
  3. 實作 Machin 公式求 π 到 50 位(搭配 1.3 節的 decimal 模組),與 Leibniz 級數比較達到同精度所需的項數。