小時候,我們可能都做過「從一加到一百」這種問題,也就是
1 + 2 + 3 + ... + 100許多讀者可能聽說過,數學王子高斯 (Carl Gauss) 在幼童時代, 就自己發明了計算上述問題的公式。不論如何,大家都應該知道,答案是 5050。 如果要寫個程式來計算呢?如果讀者以前學過類似 C, FORTRAN, Pascal, BASIC 這些程式語言,可能立刻就想到:使用迴圈。 但是,應用 Matlab 的訣竅,就在於將問題以矩陣(包括向量、序列)形式來思考, 一次處理一個矩陣,而不是將矩陣中的元素拿出來一一處理。 這就是基本的 物件導向 的思惟方式。 以後,讀者或許會逐漸體會,所謂「物件導向」這個時髦的名詞, 也不過就是要我們以「數學的函數觀念來思考」。
如何應用 Matlab 執行上述計算呢? 在想法上,我們可以先產生一個元素為 1, 2, 3, ..., 100 的向量(或序列), 然後代入 sum( ) 函式求此向量的元素和。 利用冒號指令,便可以輕易產生上述向量。因此,以下是一種做法:
v = 1:100;其實,何必經過一個變數 v 來計算呢?何不說
sum(v);
sum(1:100)
因此,<= 100 的偶數和就是
sum(2:2:100)讀者當然知道,這個答案和
2 * sum(1:50)是一樣的。
利用點運算,我們還可以輕易計算從一到一百的立方和:
v = (1:100).^3;或者,將兩句話合成一句:
sum(v)
sum((1:100).^3)
同理,我們還可以計算從一到一百的倒數和:
sum(1 ./ (1:100))
再考慮一個簡單的問題:
pm = (-1) .^ (0:99);它的效果就是產生
v = (1:100) .* pm;就好了。注意,前面我們說 (-ones(1,100)) 這是因為如果不把負號刮起來, Matlab 會先算 .^ 然後才取負號。那不是我們想要的結果。
sum(v)
其實,上述操作純粹只是技術上的示範。 對於解決問題,根本不必這麼麻煩,何不說
sum(1:2:100) - sum(2:2: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/(2^2) + 1/(3^2) + ... + 1/(100^2)
1 + 1/(2^2) + 1/(3^2) + ... + 1/(100^2)但是,請不要用 .* 或 .^ 指令,改用內積函式 dot( ) 來完成任務。
1 - 1/3 + 1/5 - 1/7 + ... + 1/97 - 1/99
4 * (1 - 1/3 + 1/5 - 1/7 + ... - 1/(4*n-1))