我們再回顧所謂的「牛頓法」。這是以數值計算估計 f(x) = 0 之一個根的方法。
假設 f(x) 可微,且在某個數 x0 的「附近」有一個根,
則根據以下迭代公式
問題是,用電腦做計算總是無法真的計算無窮多項,因此不能真的算出極限。
我們再度以 f(x) = x2 - 2 為例,用牛頓法計算正根
。
則迭代公式為
以上程式可以直接寫在 Matlab 介面內, 但是最好寫成一個腳本程式。 在以上程式內,紅色的數目代表列號,稍後再說,它們並不是程式的一部分。 而我們假設 x0 = 1,並且採用「變數置換」的技巧, 不必使用三個變數 x1, x2, x3, 而是重複使用一個變數 x。這應該是我們起碼已經熟悉的技巧。1 x = 1; 2 for n = 1:3, 3 x = x/2 + 1/x; 4 end
當 Matlab 執行上述四列指令時,變數 n 和 x 的變化如下:
列號 | n | x |
---|---|---|
1 | 未使用 | x0 |
2 | 1 | x0 |
3 | 1 | x1 |
4 | 迴圈結束,返回 2 | |
2 | 2 | x1 |
3 | 2 | x2 |
4 | 迴圈結束,返回 2 | |
2 | 3 | x2 |
3 | 3 | x3 |
4 | 迴圈結束,返回 2, 但是發現沒有下一個數要 代入 n,所以完成迴圈 | |
5 | 輸入下一步指令 |
從上述表格中觀察,得知每當迴圈結束,x 的值就是 xn, 而 n 就是當時代入的值。所以
完成之後,就計算出來 x10。讀者注意不要忘記, 每次重新開始迭代之前,要記得把 x 指派成初始值。x = 1; for n = 1:10, x = x/2 + 1/x; end
以上的說明,告訴我們如何計算 xn,但是沒有說明如何讓 Matlab
自動檢查 xn 是否已經足夠靠近 p。
一般而言,我們並不知道 p,所以不可能計算 |xn - p|。
因此在計算的技巧上,我們通常要預設一個「容忍誤差」err,如果
1 x = 1; 2 for n = 1:10 3 xold = x; 4 x = x/2 + 1/x; 5 if ( abs(xold - x) <= err ) 6 break; 7 end 8 end
我們再一步步地審視 Matlab 的執行狀況:
列號 | n | x | xold |
---|---|---|---|
1 | 未使用 | x0 | 未使用 |
2 | 1 | x0 | 未使用 |
3 | 1 | x0 | x0 |
4 | 1 | x1 | x0 |
5 | 變數都沒被更動,只是檢查條件。假如 False,則 6 沒執行 | ||
7 | if 結束,變數都沒被更動 | ||
8 | 迴圈結束,返回 2 | ||
2 | 2 | x1 | x0 |
3 | 2 | x1 | x1 |
4 | 2 | x2 | x1 |
5 | 變數都沒被更動,只是檢查條件。假如 False,則 6 沒執行 | ||
7 | if 結束,變數都沒被更動 | ||
8 | 迴圈結束,返回 2 | ||
... | |||
2 | 6 | x5 | x4 |
3 | 6 | x5 | x5 |
4 | 6 | x6 | x5 |
5 | 變數都沒被更動,只是檢查條件。假如 True | ||
6 | 提早完成迴圈,跳到 8 的下一個指令 | ||
9 | 輸入下一步指令 |
可見得,當上述迭代結束的時候,要不是 n 達到了 10, 就是 |xn - xn-1| <= err。 我們可以檢查 n 的值。如果它是 10,則有可能 |xn - xn-1| 沒有達到容忍誤差,否則就代表 |xn - xn-1| 達到了容忍誤差, 而我們可以將 xn 視為極限 p。
假設 err = 5e-15 也就是 5 * 10-15,則上述程式結束時, n 的值是 6 而 abs(x - sqrt(2)) 是 2.2204e-16。
採用另一個變數來紀錄「前一次迭代結果」的技巧非常基本且重要,要能夠流利使用。
習題