JOVANA
Explore Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

局部誤差、全域誤差,以及階數

你用尤拉法沿著斜率前進——但答案到底錯多少?把步長減半又能換來什麼?來認識每個 ODE 方法都會犯的兩種誤差,以及那個告訴你它們縮小得多快的單一數字:階數。

兩種不同的錯法

在上一篇指南裡,你用前向尤拉法把一個初值問題往前推進,一步接一步,每步大小為 h。每一步你都相信當前點的斜率,沿一小段直線走過去。自然的問題是:你最後落腳的那個點錯了多少?結果有兩個答案,而把它們分清楚,是這整個階段裡最有用的單一觀念。一種誤差是單獨一步所犯的小錯;另一種是當你抵達終點時,累積起來的總錯。

單步的錯誤是局部截斷誤差。想像你此刻正好坐在時間 t_n 的真實解曲線上——到目前為止沒有任何誤差——然後你只走一步尤拉,到 t_{n+1}。真實解在這一步裡會稍微彎曲,但你的直線不會。在這一步老實走完之後,你落腳的位置與真實曲線實際所在之間的差距,就是局部誤差。它只衡量最新這一步剛犯下的罪,假設它之前的一切都完美無瑕。

累積的錯誤是全域誤差:在你真正走完所有步之後,你的數值 y_n 與 t_n 處真實解之間的實際差距,而每一步都是從前一步交給你的那個不完美的點出發的。這才是你真正在乎的誤差——它決定你模擬的行星最後會不會落在正確的軌道上。接下來幾篇指南的全部功夫,就在於理解那些微小的局部誤差如何串通成全域誤差。

尤拉法的局部誤差從何而來

微積分階段學過的泰勒定理把活全幹了。從 t_n 處真實曲線 y 出發。把精確解往前展開一步得到 y(t_{n+1}) = y(t_n) + h·y'(t_n) + (h^2/2)·y''(xi),其中 xi 是這一步裡的某個點。但前向尤拉只算出 y(t_n) + h·y'(t_n)——它保留前兩項,悄悄丟掉從 h^2 那一項起的所有東西。剩下的 (h^2/2)·y''(xi) 正好就是局部截斷誤差。它是真實運動中,那條直線看不見的部分。

true step:   y(t_{n+1}) = y_n + h y'(t_n) + (h^2/2) y''(xi)
Euler step:  y_{n+1}    = y_n + h y'(t_n)
--------------------------------------------------------
local error per step  =  (h^2/2) y''(xi)   =  O(h^2)

halve h  ->  local error per step drops by  4x  (2^2)
前向尤拉保留泰勒級數到 h 那一項;被丟掉的 h^2 項就是每步的局部誤差。

所以尤拉法每步的局部誤差正比於 h^2——我們寫成 O(h^2)。把它讀成關於縮放的承諾,而非精確值:把步長減半,每一單步就大約準確四倍,因為 (h/2)^2 就是 h^2/4。當 h 很小時這個 h^2 確實很小——若 h 是 0.01,h^2 就是 0.0001。下一節要揭穿的陷阱是:你並不是只走一步。

為什麼全域誤差會掉一個 h 的次方

這裡有個第一次見到都會嚇一跳的算帳方式。要跨越從 t_0 到 T 的固定區間,你會走 N = (T - t_0)/h 步。每一步新增大約 (h^2/2)·y'' 的局部誤差。一個粗略的初步猜測就是把它們加起來:N 步,每步 O(h^2)。但 N 正比於 1/h,所以 N · h^2 正比於 (1/h) · h^2 = h。h^2 的因子與計數 1/h 部分抵消,從局部到全域的過程中,掉了一個 h 的次方

所以前向尤拉的局部誤差是 O(h^2),但全域誤差是 O(h)。誠實的陳述比單純相加更微妙,因為較早的誤差會被帶往後面,並被方程本身的動態拉伸或衰減——嚴謹的證明會用右手端的利普希茲常數來界定這種放大。但結論在嚴謹證明後依然成立:全域誤差是 O(h),比局部誤差低一階。這是幾乎每一個性質良好的單步方法的通則,也是為什麼我們從不單獨引用局部誤差。

階數就是價格標籤

一個方法的階數 p,是它全域誤差 O(h^p) 裡的指數,也是你在執行之前所能知道、關於這個方法最重要的數字。它回答了那個真正要緊的問題:如果我多做一倍的功——把 h 減半、步數加倍——我能買到多少精度?對一個 p 階方法,把 h 減半會讓全域誤差乘上 (1/2)^p。一階把誤差砍半;二階砍成四分之一;四階——就像下一篇指南等著的 RK4 方法——把它除以十六。階數愈高,每多做一份功就能買到遠多得多的精度。

階數與你在求根時見過的收斂階數密切相關,但有個重要差別。在那裡,牛頓法的二次收斂意味著每一步大致把正確位數平方——error_{n+1} ≈ C·error_n^2,飛快地暴衝。在這裡,階數 p 講的是最終誤差如何隨步長 h 縮放,而不是一次迭代對下一次。兩者都是支配誤差下降快慢的指數,但一個是衝向一個根,另一個是衡量加密網格的回報。別讓這個共用的詞騙了你。

有個誘人的謬誤值得現在就殺掉:高階並非免費。高階方法每步要做更多功(RK4 每步要算四次斜率),而它 O(h^p) 的優勢,只有在 h 小到你穩穩進入漸近區之後才會發揮。在一個崎嶇、鋸齒狀或剛性的問題上,給你那個 h^p 的平滑泰勒圖像可能崩潰,於是花俏的高階方法可能不比樸素的尤拉法好。階數是一個關於「小 h 極限、平滑問題」的承諾——一個真實的承諾,但是有條件的。

親手量出階數

你不必聽教科書說一個方法是幾階——你可以親手量,而且你應該量,因為一個程式碼錯誤很常見的第一個症狀,就是某個方法達不到它號稱的階數。訣竅是做收斂研究:用一連串減半的步長解同一個問題,把每個數值答案與已知真解比較,看誤差如何縮小。如果把 h 減半大致把誤差砍半,那就是一階;若砍成四分之一,二階;若砍成十六分之一,四階。

  1. 挑一個你知道精確解的測試問題——例如 y' = y、y(0) = 1,其真解是 e^t——這樣你就能算出在終點時間 T 的真實誤差。
  2. 用步長 h 解它,再用 h/2、h/4、h/8 各解一次,每次記下全域誤差 E(h) = |y_N - y(T)|。
  3. 計算比值 E(h) / E(h/2)。對一個 p 階方法,當 h 縮小時這個比值會趨近 2^p:尤拉約為 2,二階方法約為 4,RK4 約為 16。
  4. 更好的做法是把 log E 對 log h 作圖:這條線的斜率正好是階數 p。一條斜率符合預期的乾淨直線,是你程式碼正確的有力證據。