Matlab 教材:善用 Matlab 函式

小時候,我們可能都做過「從一加到一百」這種問題,也就是

1 + 2 + 3 + ... + 100
許多讀者可能聽說過,數學王子高斯 (Carl Gauss) 在幼童時代, 就自己發明了計算上述問題的公式。不論如何,大家都應該知道,答案是 5050。 如果要寫個程式來計算呢?如果讀者以前學過類似 C, FORTRAN, Pascal, BASIC 這些程式語言,可能立刻就想到:使用迴圈。 但是,應用 Matlab 的訣竅,就在於將問題以矩陣(包括向量、序列)形式來思考, 一次處理一個矩陣,而不是將矩陣中的元素拿出來一一處理。 這就是基本的 物件導向 的思惟方式。 以後,讀者或許會逐漸體會,所謂「物件導向」這個時髦的名詞, 也不過就是要我們以「數學的函數觀念來思考」。

如何應用 Matlab 執行上述計算呢? 在想法上,我們可以先產生一個元素為 1, 2, 3, ..., 100 的向量(或序列), 然後代入 sum( ) 函式求此向量的元素和。 利用冒號指令,便可以輕易產生上述向量。因此,以下是一種做法:

v = 1:100;
sum(v);
其實,何必經過一個變數 v 來計算呢?何不說
sum(1:100)

因此,<= 100 的偶數和就是

sum(2:2:100)
讀者當然知道,這個答案和
2 * sum(1:50)
是一樣的。

利用點運算,我們還可以輕易計算從一到一百的立方和:

1 + 23 + 33 + ... + 1003
做法是
v = (1:100).^3;
sum(v)
或者,將兩句話合成一句:
sum((1:100).^3)

同理,我們還可以計算從一到一百的倒數和:

1 + 1/2 + 1/3 + ... + 1/100
做法是
sum(1 ./ (1:100))

再考慮一個簡單的問題:

1 - 2 + 3 - 4 + ... + 99 - 100
這個無聊的問題,答案明顯是 -50。 我們利用它來練習一個操作技巧:產生 1, -2, 3, -4, ..., 99, -100 這樣的向量。 首先,利用 .^ 指令,我們可以製造
pm = (-1) .^ (0:99);
它的效果就是產生
pm = [1   -1   1   -1   1   -1   ...   1   -1]
然後,只要說
v = (1:100) .* pm;
sum(v)
就好了。注意,前面我們說 (-ones(1,100)) 這是因為如果不把負號刮起來, Matlab 會先算 .^ 然後才取負號。那不是我們想要的結果。

其實,上述操作純粹只是技術上的示範。 對於解決問題,根本不必這麼麻煩,何不說

sum(1:2:100) - sum(2:2:100)
就好了?同理,計算
1 - 1/2 + 1/3 - 1/4 + ... + 1/99 - 1/100
也就可以說
sum(1 ./ (1:2:100)) - sum(1 ./ (2:2:100))

連加可以用 sum( ) 達成,那麼連乘也就可以用 prod( ) 達成。 例如 3! = 1*2*3 可以這樣算:

prod(1:3)
一般而言,若 n 是一個正整數,則 prod(1:n) 就計算了 n!。 但是,因為階乘是個增大很快的數, 而 Matlab 最多只能計算(十進制)16 位數的科學記號數字, 所以,它無法正確計算太大的階乘。例如
prod(1:12)
還可以得到完整的答案 479001600,但是
prod(1:13)
就沒辦法了,Matlab 自動改成科學記號輸出 6.2270e+09

習題

  1. 計算從一到一百的倒數平方和。亦即
    1 + 1/(2^2) + 1/(3^2) + ... + 1/(100^2)
  2. 計算從一到一百的倒數平方和。亦即
    1 + 1/(2^2) + 1/(3^2) + ... + 1/(100^2)
    但是,請不要用 .* 或 .^ 指令,改用內積函式 dot( ) 來完成任務。
  3. 計算以下連加:
    1 - 1/3 + 1/5 - 1/7 + ... + 1/97 - 1/99
  4. 令 n=10000,計算
    4 * (1 - 1/3 + 1/5 - 1/7 + ... - 1/(4*n-1))
單維彰 (2001/10/10) --- 03/04/10 (單) [Prev] [Next] [Up]