採用另一個變數來紀錄「前一次迭代結果」的技巧非常基本且重要, 現在我們用常見的「梯形積分法」再示範一遍。
假設 f(x) 是一個在 [a,b] 閉區間內的連續函數, 則 f(x) 在 [a,b] 閉區間內的積分 (quadrature), 可以用解析方法求得,也可以用數值方法估計。 所謂解析方法,就是我們在微積分課程中學習的: 先找到 f(x) 的反導函數 F(x),然後計算 F(b) - F(a)。 但是許多 f(x) 是找不到 (基本函數型式的) F(x), 因此解析方法就使不上力。 這時候只能用數值方法來估計積分值,這些方法通稱為 數值積分法 (numerical quadrature rules)。
現在我們要介紹一種常見的數值積分法:梯形積分法
(Trapezoidal quadrature rule)。
請參照下圖:先把 [a,b] 區間等分成 n 段 (n 是一個正整數),
每一小段的兩端點形成一組節點 (nodal points),
將這些節點編號、命名為 x0、x1、x2、...、
xn,很明顯地 x0 = a 而 xn = b。
第一段是 [x0, x1]、
第二段是 [x1, x2]、
第三段是 [x2, x3]、...、
第 n 段是 [xn-1, xn]。
每一段的寬度都一樣,就是 (b-a)/n,記做
。
參照上面右側的圖,在第一段上有一個「高」為
而兩「底」之寬度分別為 f(x0) 和 f(x1) 的梯形,
它的面積是
同理,在第二段上的梯形面積就是
在第三段上的梯形面積就是
... 在第 n 段上的梯形面積就是
把這些小段上的面積加在一起,就是
即使 f(x) 不是正值的函數,我們還是用一樣的公式來計算 n 段梯形積分估計值。
舉例來說,
就找不到基本函數型式的反導函數,
所以必須用數值積分法來估計它在 [0,1] 閉區間內的積分值:
x = linspace(0,1,101);以下解釋上述四句指令的用處:
y = sqrt(1+x.^3);
h = 1/100;
T = h * (y(1)/2 + sum(y(2:100)) + y(101)/2)
T = h * (sum(y) - y(1)/2 - y(101)/2)
上面示範了如何計算特定段數的梯形積分估計值。
但是特定的段數並無意義,因為我們不知道那個估計值究竟有多準確?
為了敘述的方便,我們把 n 段梯形積分估計值寫成以下記號:
以下就是一批實現上述想法的 Matlab 指令,我們假設最多分成 220 段。
以上程式可以直接寫在 Matlab 介面內,但是最好寫成一個腳本程式。 其中第一條指令就是計算 T1(f,0,1),請讀者自己驗證。T = (1+sqrt(2))/2; for k = 1:20 Told = T; n = 2^k; x = linspace(0,1,n+1); y = sqrt(1+x.^3); h = 1/n; T = h * (sum(y) - y(1)/2 - y(n+1)/2); if ( abs(Told - T) <= err ) break; end end
可見得,當上述迭代結束的時候,要不是 k 達到了 20, 就是相鄰兩次的梯形積分估計值的差異,已經落在容忍誤差之內。 假設 err = 1e-8 也就是 10-8,則上述程式結束時, k 的值是 13 而 T 是 1.11144797184967, 我們應該可以相信這個 T 和積分的解析值相差在 10-7 以下, 所以 1.1114480 應該是一個正確的估計值。
習題