Matlab編輯器(editor)功能在於產生可執行之M-檔案,該檔案之執行過程也可以利用這個編輯器偵錯。呼叫編輯器時只要在Matlab主程式之file下,選擇New-->M-file,或選open-->edit即可。其視窗外觀如下圖。
此編輯器之優點是它會自動產生行號,並且以不同顏色顯示關鍵字,最重要的功能是它有一邊執行一邊偵錯的功能。在執行過程中,只要在任何行號上設立中斷點,或將滑鼠指向行號之頭部按下,即會在該行頭部顯示紅點;或者,也可將滑鼠指向該行,然後按下中斷設定指令(具有紅點之圖示)。當程式執行時,碰到行頭之紅點位置,即會暫停。此時可以用滑鼠指向任何變數位置,即會顯示該變數之現值,以確定執行過程是否正確。若要取消中斷點,可按紅色打X的圖示解除;亦可直接在行頭上之紅點上重按一次解除之。
中斷點可以設置無數處。當程式執行到某一紅點,即會在該處出現綠色箭頭(如圖之第二個紅點)。此時亦可使用步進指令(位於紅X之右,具有曲形箭頭之圖示)偵錯,每按一次會執行一行,如此可以瞭解程式執行過程中之跳躍過程。另有一直線往下之箭頭圖示(曲形箭頭之右側),表示按時可以直接執行程式完畢或停在下一個紅色中斷點上。在任何中斷點處除使用滑鼠指向變數可以顯示該變數之對應值外,亦可在指令窗下,直接打入變數名稱,以顯示整個變數之內容,或更改某特定之變數值,以比較執行的結果。
同一個編輯窗中可以同時顯現許多M-檔案,各檔案的名稱均顯示在視窗之左下方,只要按下所需的檔案,即可觀察個別檔案之內容與進行情形。亦可一個檔案分別各有一個視窗,但必須自行設定。
新版的編輯器已加入M-Lint Code 的功能,可以分段執行檔案中之程式,亦可將執行與文字合併成為瀏覽窗下可以觀看的文件。此外,新版亦另外加上一項檢查報告的功能。可以檢查程式之執行效率,挑出那些指令所使用之CPU時間,以便程式設計師作有效率的設計。有關這一部份,有興趣的讀者可以參考線上輔助或其他書籍。
如何使用notebook指令?
notebook這個指令是matlab特有的指令,其功能係將執行matlab指令的功能直接合併置於微軟的文書軟體(Word)中。因此指令與執行結果可以整合於一報告之中,實際應用上有其方便性。
在初次執行此指令時,matlab會先在WORD設定一個notebook的巨集,並且在WORD之指令行上設有該項下拉式清單。其各項指令指下:
1. Define Input Cell
2. Define AutoInit Cell
3. Define Calc Zone
4. Undefine Cells
5. Purge Selected Output Cells
----------------------------
6. Group Cells
7. Ungroup Cells
8. Hide Cell Markers
9. Toggle Graph Output for Cell
----------------------------
10. Evaluate Cell
11. Evaluate M-book
12. Evaluate Loop
----------------------------
13. Bring MATLAB to Front
14. Notebook Options
在文書處理本身,其原先之功能均存在。只是文中屬於matlab之指令敘述,可以利用上述下拉式清單中之指令處理。其中第1項與第10項較為常用。通常是利用第1項指令定義文中之指令位置,然後用第10項加以執行,其所得之結果將出現在該指令之後。例如要計算十的三次方:
a=10^3
首先將要當為指令的部份全反白,然後要選第1項將其定義為matlab指令,其次再使用第10項加以執行,其結果如下:
a=10^3
a =
1000
另一種快速的方式是將指令部份反白後,按滑鼠右鍵,選第10項之evaluate cells指令即可得到相同的答案。此時這些屬於matlab之指令與結果均會用中括號括起,這部份在印出時並不顯示。屬於指令部份用綠色,屬於結果部份用藍色。
第2項指令之功能與第一項相同,只是第2項執行後,每一次將此一文件開啟時,其指令均會自動計算一次,利用第1項計算的則維持原樣。所以每次內文開啟時會改變的數值,例如日期date指令在文件開啟時,會自動更新。
若有許多指令合併使用,則可使用第6項的群組指令,這有點像寫一個小程式一樣。例如:
t=0:pi/100:2*pi;
y=cos(t);
plot(t,y)
結果連圖都會畫在word上。實際上這個群組令只要將要執行的指令全部反白後,使用第一項指今令也可以執行。其餘相關功能請打如下指令進行參考:
>>doc notebook
第二章 矩陣製作
MATLAB所處理之資料型態主要為長方矩陣,矩陣中之各小項可能為複雜的資料型式。所有變數均以矩陣的型態出現,是為MATLAB的最大賣點。在某些情況,即使一個常數也可視為1x1之矩陣,而向量則視為行矩陣或列矩陣。 陣列與矩陣之差別在於前者是採用逐元處理的方式,而後者除逐元處理外,亦有傳統矩陣之處理功能。
下面為操作矩陣之各項指令 :
- B=abs(A) 將各元素取其絕對值。
- L=length(A) 列向量之元素數目。若A為行向量或列向量,則直接得到其元素數。若為矩陣,則僅得列數。
- find(A) 將非零元素的位置依行向量輸出。
- max(A) 尋求矩陣A之最大元素值,若A為矩陣,則為各行(或列)中之最大值,其結果為列(或行)向量。
- min(A) 尋求矩陣A之最小元素值,若A為矩陣,則為各行(或列)中之最小值,其結果為列(或行)向量。
- mean(A) 尋求矩陣A諸元素之平均值,若A為矩陣,則為各行(或列)中之平均值,其結果為列(或行)向量。
- sum(A) 尋求矩陣A諸元素之總和,若A為矩陣,則為各行(或列)中之總和,其結果為列(或行)向量。
- size(A) 矩陣之大小,其結果為二元素列向量,第一項為列數,第二項為行數。
- linspace(a, b, n) 製作一個包括a, b 兩點以n等矩劃分之向量。
- logspace(a, b, n) 製作一個包括a, b 兩點以對數等矩劃分之向量。
- sort(A) 將矩陣A內之元素進行排序,分為行向或列向排序。
- sortrows(A) 將矩陣A之元素依特定行排序,僅能依行向排序。
- cat(3,A,B) 將A、B兩矩陣依設定維度串接 。
2.1矩陣元素之形成
矩陣可說是MATLAB各項變數之基本型式,而向量則是一種單維的矩陣,也是矩陣之特殊型式。單維向量可分為行向量(Colum vector)與列向量(Row vector),或稱為行矩陣與列矩陣。無論如何,這些僅是一般矩陣的特殊例子而已。一般矩陣產生之方式有下列幾種:
- 以一系列單元輸入。
- 利用預設之函數產生。
- 在M檔案中產生。
- 由外面資料檔中直接輸入。
今以一個簡單的列向量變數a為例,令其包含五項元素。首先,可在指令窗中打入如下指令,注意輸入之元素群前後都有中括號,元素間則以空隔或逗號","分開:
>>a = [8 4 2 7 9]
a = 8 4 2 7 9
結果,這個參數a之內容立即可以顯出來(注意變數之大小寫所指是不同的變數)。若不想立即顯示出結果,只保留其內容在記憶體中供其他指令使用時,可以在指令後面加上";"分號如:
>>a = [8 4 2 7 9];
執行後,並沒有如上述之結果出現。但這並不是說變數a的內容沒有改變,實際上是記在記憶體中,不顯現而已,你只要再打上a,即可立即顯示剛才輸入之資料:
>>a
a =
8 4 2 7 9
現在,再令向量a中之各元素均加2,並將其結果存於一個新變數b:
>>b = a + 2
b =
10 6 4 9 11
注意 MATLAB 並不需要任何特別處理,即可完成矩陣的操作。
若要將上述列向量b改為行向量,並存於c時,則只要在b的後面加上一撇之移置符號"'"即可,此方法稱為移置(Transpose),相當有用,可以在陣列中活用:
>>c=b'
c =
10
6
4
9
11
在列向量a之表示式中,元素間係以空格分開。實際上亦可用逗號","分開,其意義相同。以列向量d為例:
>>d=[2,4,3,6,7]
d =
2 4 3 6 7
在輸入行向量時,由於其所佔的直行空格多,故常先以列向量輸入,然後再進行移置,如前例之行向量c。另一個方法是在各元素間加上分號";",表示其輸入元素置於下一行的意思,如行向量c:
>>c=[10;6;4;9;11]
c =
10
6
4
9
11
結果相同。所以在距陣之操作中,記得逗號及空隔是分開元素,分號則是移至下一列。如此即使輸入僅為一列,亦可處理多列的矩陣資料。
利用函數產生
矩陣亦可利用內建函數產生,例如魔術矩陣函數magic(n),其括號中之n為表示產生一個nxn大小之方矩陣,其特性是無論行向、列向或對角方向之元素總和均相等。
>> M=magic(4)
M =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
其他特殊函數產生之矩陣將在特殊函數項下討論。
自檔案輸入
此外,正如指令窗之輸入方式一樣,矩陣亦可由M檔案中輸入,亦可利用資料檔輸入。前文已討論利用load指令可以輸入工作間之變數值。若僅有一參數之內容,則可作成以該參數名稱為檔名,而以.dat為副檔名之資料檔 ,這是由文字編輯器產生之文字檔。設此文字檔名為fon.dat,其內容為:
100 200 300
250 350 450
460 370 670
則經下面之load指令後,可以產生fon之矩陣。
>>load fon.dat
>>fon
100 200 300
250 350 450
460 370 670
同樣,亦可利用m檔案輸入,不過其變數名稱必須在檔案中指明,實際上等於在指令窗下同等指令一樣:
例如,令fon.m檔案(敘述檔)中含有下列數據:
A=[22 33 44; 55 66 77; 88 99 11];
執行fon函數後,即可得變數A之資料如下:
>>fon
>>A
22 33 44
55 66 77
88 99 11
指令之長度
在指令檔案中,有些指令使用一行仍然不足,必須延長到下一行時,可以在斷行處加三個連續點即"...",指令會視其連續到下一行。如此,再長的指令也可以一併執行。
>> Age=input('How old are you?');...
Age
How old are you?16
Age =
16
2.2 等距元素之輸入
不規則的向量,若元素增多,個別輸入較麻煩。有些則可由資料庫或檔案中直接讀取;但有些向量比較特殊,例如具有等距值之向量,則可利用下面的方式輸入,甚為方便:
>>x=0:2:10 %initial value: increment: final value
x =
0 2 4 6 8 10
此列向量係以冒號為間隔,最左為初值,中間為等距增量,右邊為最終值。若中間值是1時,則中間項可以省略,只取前後兩項。若單獨使用,有無使用中括號並不影響結果,且這三個參數也可使用負值。例如:
>>x1=-5:2:10
x1 =
-5 -3 -1 1 3 5 7 9
注意x1之項目僅到9,無法到其設定的最終值10。所以最終值並不能保證為此列矩陣之最後一項。
除列向量外,亦可利用這種方式製造矩陣:
>> A=[4:30:100;8:2:14]
A =
4 34 64 94
8 10 12 14
有些矩陣若係重覆第一列之值時,除直接重覆輸入或以程式安排外,亦可利用向量為1之陣列產生,例如:要輸入a=[ 1 2 3 4 5;1 2 3 4 5; 1 2 3 4 5]這樣的矩陣,則用先界定一列之值,再利用該式加入下面之方式為之:
>> a=1:5
a =
1 2 3 4 5
>> a([1 1 1],:)
ans =
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
若需要重覆無數次,則可利用ones()函數為之,例如:
>> c=b(ones(20,1),:)
c =
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
2.3 指令LINSPACE之使用
上述例子中,最後一項無法列入之遺憾可以用linspace這個指令來補償。這個指令也是同時產生許多等距的元素,其前後項必定包括在內,但以要切成多少等份決定等距值。例如:
>>x=linspace(0,pi,8) % initial value, final value, n=no. of points
x =
0 0.4488 0.8976 1.3464 1.7952 2.2440 2.6928 3.1416
上述例子是將0至π間分成八個點值。注意其前後之數值均包括在內的八個點,若以切成的等份而言,應為七等份才對。例子中用pi表示,在中pi是代表π之固定常數,到處都可使用。所以注意你的自訂變數名稱不要用pi,以免混淆。
linspace指令之第三個參數可以省略。但若省略,函數會自定為100,所以務必小心使用。
與linspace相同的用法,但應用於對數運算的為logspace。例如:
>>xlog=logspace(0,1,8)
xlog =
1.0000 1.3895 1.9307 2.6827 3.7276 5.1795 7.1969 10.0000
其值落於10^0(=1)與10^1(=10)之間,其對數值係以10為底。若點數8不指明時,函數自動設定為50,因此會有五十點資料。
2.4二維矩陣與陣列
二維矩陣是MATLAB最常用的型式,其應用也符合數學運算的原則。但是,在MATLAB中也獨自創出其特有的運算法,使矩陣的運算更為靈活。矩陣的大小通常列數乘行數表示,如[2x3]即為二列三行之矩陣,以A為例:
>>A=[1 2 3;4 5 6]
A =
1 2 3
4 5 6
上述變數A可利用鍵盤輸入矩陣,但要記得利用分號隔出另一列,各列中之元素則仍以空格或分號區隔,其方式與前面所述之行、列向量之使用相同。上面所得之矩陣A是為2x3的矩陣。在MATLAB中也有一個指令size可以檢查其大小,例如:
>>m=size(A)
m =
2 3
這時候m本身也是一個列矩陣,其第一元素2代表二列,第二元素3代表三行。
矩陣與矩陣之間,可以作線性代數之運算。以M=magic(4)為例:
>>M=magic(4)
M=
16 3 2 13
5 10 11 8
9 6 7 12
4 15 14 1
將M作移置後,再相加,得:
>>M+M'
ans =
32 8 11 17
8 20 17 23
11 17 14 26
17 23 26 2
兩矩陣亦可相乘,可以產生另一矩陣:
>>M'*M
ans =
378 212 206 360
212 370 368 206
206 368 370 212
360 206 212 378
矩陣M之判定式為零,可以利用以下指令計算:
>>m=det(M)
m=
0
陣列(array)為矩陣之特殊型式,其外觀型式與矩陣相同,只是陣列之意義在於元素與元素間的一對一的關係,故常以行矩陣為主。陣列之操作,除加法與減法與矩陣相同外,其餘乘、除、倒除、次方、移置等均需在其對應符號(*、/、/、^、')之前加點(.)號,以表示是元素與元素間一對一的操作。例如,前面之M矩陣,以陣列相乘考慮時為:
>>M.*M
ans =
256 9 4 169
25 100 121 64
81 36 49 144
16 225 196 1
如何建立一般表格
利用陣列之觀念,亦可創造不同意義之矩陣,或以矩陣型式表示之對照表格,這可以將不同行矩陣以中括號組合而成之新矩陣表示之,例如:
>> m=(0:9)';
>> table=[m m.^2 2.^n]
??? Undefined function or variable 'n'.
>> table=[m m.^2 2.^m]
table =
0 0 1
1 1 2
2 4 4
3 9 8
4 16 16
5 25 32
6 36 64
7 49 128
8 64 256
9 81 512
同理,亦可作一個以10為底的對數函數表:
>> format short g
>> x = (1:0.1:2)';
>> logs = [x log10(x)]
logs =
1 0
1.1 0.041393
1.2 0.079181
1.3 0.11394
1.4 0.14613
1.5 0.17609
1.6 0.20412
1.7 0.23045
1.8 0.25527
1.9 0.27875
2 0.30103
2.5 矩陣的分合與定址
矩陣疊加
此外利用幾個行向量或列向量相搭配,也可以湊出另一個新的矩陣。以A矩陣為例,可以自我疊加,或與其他同大小的矩陣疊加:
>>A=[1 2 3;4 5 6];
>>B=[A;A]
B =
1 2 3
4 5 6
1 2 3
4 5 6
>> C=[A' A']
C =
1 4 1 4
2 5 2 5
3 6 3 6
>> D=[A' A';B']
D =
1 4 1 4
2 5 2 5
3 6 3 6
1 4 1 4
2 5 2 5
3 6 3 6
結果,B為4x3大小之矩陣;C為3x4大小之矩陣。後者之A必須先行轉置,才能進行合併。
矩陣次標
要指出某矩陣中之元素,或取出運用必須有一套方法,通常就其位置在第幾列第幾行呼之,如:
>>A(2,3)
ans = 6
>>[A(1,3) A(2,2) A(1,2)]
ans = 3 5 2
所以利用這種直接呼叫的方式,也可以另組一個新的矩陣,但仍必須加中括號規範之。若所要取出的元素是鄰近的位置,則可用n1:n2之表示法,以上述之C矩陣為例:
>>C(3,2:4)
ans = 6 3 6
所取到的是C矩陣第三列第二、三、四行的元素。若要取得其中之全行,則僅使用冒號(:),前後不加數字即可,如取A之第一列轉置再與C之第二、三行合併成D矩陣:
>>D=[A(1,:)' C(:,2:3)]
D =
1 4 1
2 5 2
3 6 3
如此形成另一個3x3的矩陣。如果所選取的行或列並不相鄰,則可以用中括號將所要的行或列直接列舉,如將C矩陣中之第一、三、五行抽出成立E矩陣:
>> E=C(:,[1,3,4])
E =
1 1 4
2 2 5
3 3 6
此外,空矩陣也是一個常用的矩陣,實際上其內並不含任何元素,它常以[ ]表示。如果矩陣中某一行或列被此空矩陣取代,表示將該行或該列將被刪除。
>>E(2:3,:)=[]
E = 1 1 4
此時之E矩陣由於二及三列被取代為空矩陣,故只剩下孤單單的一個列矩陣了。
在矩陣之排序中,即使為二維矩陣,它仍有一定的排序順序。實際上其計數是以行為順序進行計數,以一個矩陣AA=[1 2 3;4 5 6;7 8 9] 為例,其AA(3,2)與AA(5)所指的位置是相同的,這點也可以由AA(1:9)得到印證:
>>AA =
1 2 3
4 5 6
7 8 9
>>AA(3,2)
ans = 8
>>AA(6)
ans = 8
>>AA(1:9)
ans =
1 4 7 2 5 8 3 6 9
因此,從這個表示法可以找到一個共通點,即使用二維向量也可用一維表示。通常可以用AA(:)代表其全部的元素位置。但AA(:)執行之結果會是行向量,經轉置後,結果如下:
>>AA(:)'
ans =
1 4 7 2 5 8 3 6 9
不過要記得,由二維矩陣轉為一維矩陣,其順序並非列向量的排法,而是先排行向量,將來在應用時必須注意。一個矩陣亦可由不同的區塊矩陣組成,例如:上述之A為[3 x 3]矩陣,加上其他可以組成另一個 [6x4] 之B矩陣:
>> A=[1 2 3;4 5 6;7 8 9]
A =
1 2 3 4 5 6 7 8 9
>> B = [A, zeros(3,1); 4*ones(3,3), [1;2;3]]
B =
1 2 3 0
4 5 6 0
7 8 9 0
4 4 4 1
4 4 4 2
4 4 4 3
再次請特別注意,矩陣中之”;”表示置於下一列,而”,”表示接續於下一行之意。
矩陣之重組
若要重排原來矩陣之型式,可以利用reshape函數,其第二及三個參數即為要改變之大小:
>> d=reshape(B,3,8)
d =
1 4 2 4 3 4 0 1
4 4 5 4 6 4 0 2
7 4 8 4 9 4 0 3
>> d=reshape(B,8,3)
d =
1 8 4
4 4 4
7 4 0
4 4 0
4 3 0
4 6 1
2 9 2
5 4 3
>> d=reshape(B,4,6)
d =
1 4 8 3 4 0
4 4 4 6 4 1
7 2 4 9 0 2
4 5 4 4 0 3
無論如何改變,注意其順序係先取行向,逐行取盡。若非此種取向,則B矩陣需先行轉置。
下面的例子為利用reshape之函數組成新矩陣AA之例子:
>> AA =reshape(1:9,3,3)
AA =
1 4 7
2 5 8
3 6 9
若將其中對角線之元素累加,則得:
>> AA(1,1)+AA(2,2)+AA(3,3)
ans = 15
若相取出某一項超出矩陣範圍的元素時,程式會發出錯誤的信息:
>> AA(2,4)??? Index exceeds matrix dimensions.
但是也將矩陣之特定元素更換其值,例如:
>> AA(1,1)=10
AA =
10 4 7
2 5 8
3 6 9
第一項之值即單獨改變。但若將某值給予超出矩陣的位置時,矩陣倒可以隨機應變,增加其大小,其餘未有給值的元素一律給零,例如:
>> AA(2,4)=10
AA =
10 4 7 0
2 5 8 10
3 6 9 0
這個特性有時可以多加利用,但如果在程式中,一再利用這種擴充方式,可能會增加電腦之計算時間。實際上應用時,應加以考慮。
2.6 特殊矩陣
輸入特定矩陣,有時比較煩瑣,其輸入問題與前述之向量相同。由鍵盤輸入是一般性的作法,但數量一多,就需耗費甚大的功夫。有些資料可來自其他資料檔,或excel之檔案內容,或特殊函數執行後之結果。由資料檔輸出入將另章作討論,而特函矩陣例如,magic(N):
>>M=magic(3)
M =
8 1 6
3 5 7
4 9 2
這個特殊函數會產生以括號內之參數值為維度之方矩陣,其元素為由1至N^2(此例中N=3)之連續正整數,其各行各列及對角線元素之和均相等。在應用時,常以此函數為例,立即製作一個方矩陣,其大小為NxN。
隨機函數rand也是一個常用的函數,它可以利用亂數產生矩陣,其值介於0與1之間,要使用時可以自行乘以所需之倍數。
>>R=rand(3,4)*10
R =
0.1527 9.3181 8.4622 6.7214
7.4679 4.6599 5.2515 8.3812
4.4510 4.1865 2.0265 0.1964
要創造一個矩陣全為零或全為零的元素,在MATLAB中也有辦法,不必利用鍵盤輸入。其函數有zeros(N1,N2)、ones(N1,N2)及eye(N1,N2)等,執行後會產生一個N1xN2的矩陣,其內含元素均為0或均為1(zeros);後者則是其對角元素為1,其餘元素為0。參數中N1, N2分別為其列與行的維數,若僅輸入一項,則其結果為方矩陣。下面為幾個應用的例子:
>>I=ones(2,5)
I =
1 1 1 1 1
1 1 1 1 1
>>O=zeros(3)
O =
0 0 0
0 0 0
0 0 0
>>U=eye(5)
U =
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
上述函數可以在設定初值或預設矩陣大小時使用。
對角線矩陣函數(diag)之功能則可由下列例子加以說明。若A為方矩陣,則diag(A)會產生一個行向量包括A對角項目。若某一向量 x 則 diag(x) 後會產生以此向量之項目為對角線項目而其餘為零之方矩陣,下面為x為ans之例子:
>>A = [1 2 3;4 5 6; 7 8 9]
A =
1 2 3
4 5 6
7 8 9
>>D=diag(A)
D =
1
5
9
>>diag(D) %put elements in D as the diagonal elements in a square matrix
ans =
1 0 0
0 5 0
0 0 9
表4.4特殊矩陣一覽表
特殊函數 說明
- eye(n) 特性矩陣(identity matrix),產生一個nxn單位方矩陣。
- zeros(n1,n2) 值零n1xn2矩陣,元素值為零
- ones(n1,n2) 值一n1xn2矩陣,元素值為一
- diag 對角線矩陣(diagonal matrix),僅對角線項有值。
- triu 上三角矩陣
- tril 下三角矩陣
- rand 隨機矩陣
- hilb 希伯特矩陣
- magic(n) 魔術方塊nxn矩陣
- toeplitz 參見help toeplitz之解說
2.7尋找非零元素
另外一個指令find則是專門找尋矩陣中元素非為零的值及行列位置。以下面之bb矩陣為例,利用find函數查尋非零元素之序號:
>> bb=[1 0 3;0 2 5;3 7 0]
bb =
1 0 3
0 2 5
3 7 0
>> find(bb)' % find the nonzero element
ans =
1 3 5 6 7 8
即表示bb矩陣中,其總序號第1、3、5、6、7、8個元素均為非零元素。若第二個參數加入,則表示該參數值為前面個數。例如:
>>find(bb,3)' % find the first 3 nonzero elements
ans =
1 3 5
表示前三項非零元素為第1、3、5項。但這種以項序指示有時不容易分辨,最好以列數與行數作為座標型態的認定。其語法則必須在指令前加三個參數,如下例:
>>x y z]=find(bb,3); % find the corespondent row & column of
>>[x y z] % the nonzero elements, z is its value
ans =
1 1 1
3 1 3
2 2 2
在find函數前置三個未知行向量[x,y,z],其內所存的x為該非零元素所在之列,y為其對應行,z為其元素值。例如第一個應在第一列第一行,其值為1。利用此一指令可以依需要各取所需。
但是有時所要找的並非僅屬於非零元素,那要怎麼辦好呢?下面例子可以解決這方面的問題:
>>find(bb>5) %find matrix elements exceeding 5
ans = 6
利用邏輯語法,可以獲得其他條件的結果。例如:要求等於零的元素項:
>>[u, v]=find(bb==0); % find elements equals to zero
[u, v]
ans =
2 1
1 2
3 3
亦即等於零的元素有三項,分別在(2,1)、(1,2)、(3,3)處,有誰能解釋為什麼上述的例子不讓它直接顯示,而另加一個矩陣表示嗎?
2.8 尋找特殊元素
要在矩陣中尋找元素中之最大值、最小值及其平均值,可分別使用max、min、mean、sum等四函數。在這些函數因應用於二維與一維而功能上有些不同。以一矩陣AA=[-5 -4 3; 3 -3 1; 6 3 1] 為例,其對應值可計算如下:
>>AA =
-5 -4 3
3 -3 1
6 3 1
>>ax_aa=max(AA)
ax_aa =
6 3 3
兩相對照之下,所得之最大值是針對AA所含之行向量取得最大值,故其結果為一列矩陣。若左邊給兩項參數,則:
>>[vmax, va]=max(AA)
vmax =
6 3 3
va =
3 3 1
va所顯示的數值顯然是指該行之最大值發生在那一列。若要求得整個矩陣之最大值,則可就vmax之列向量再作一次極大值求證,或者對原矩陣AA連續施用max函數:
>>max(vmax)
ans = 6
或
>>max(max(AA))
ans = 6
兩者結果一致。不過亦可利用下式指令直接求得:
>>max(AA(:))
ans = 6
為何如此?請讀者自行印證。
極小值函數min之應用與max函數完全一樣,讀者也不妨按上述的過程自行測試。
要求得一陣列之平均值或總和函數分別為mean與sum兩函數。仍以上述之矩陣AA為例:
>>AVG=mean(AA)
AVG =
1.3333 -1.3333 1.6667
>>TOT=sum(AA)
TOT = 4 -4 5
上面介紹的四種函數中,基本之運算方式是一致的,其處理過程均先以矩陣之行方向演算。實際上若矩陣AA本身即屬行向量或列向量,其運算結果即為所需之答案。這也為什麼我們若先把AA矩陣變為AA(:),使其成為行向量矩陣,即可求出整體之最大值。實際上,上述這些函數也可以列方向作處理,其方式是在輸入參數另加一項,設為dim,其型式為max(AA,dim)。當dim設為2時,表示以列方向操作,其結果為行矩陣;當dim設為1時則表示行向操作,即為預設值。這一部份讀者可以自行實驗。
2.9 矩陣之排序
矩陣中各元素之大小之排列與排序也是重要的操作。部份依需求而不同,有時需升冪排例(ascend),有時要降冪排列(descend),有時則只依其中某些行或某些列進行排列。排序之基本型式如下:
B = sort(A,dim)
B = sort(A,dim,mode)
[B,IX] = sort(A)
其中參數dim代表的意義與前面相同。dim=1時,是依行向排序;dim=2時,則是是依列向排序。前者為預設值,故不輸入亦可。參數mode則代表排列的方式,若mode='ascend'時為升冪排列;mode='decend'時為降冪排列,前者為預設值。設A之內容可利用亂數產生如下,先各乘以100再進行四捨五入:
>>A=round(rand(3,4)*100) %using random function to find a 3X4 matrix
A =
95 49 46 44
23 89 2 62
61 76 82 79
因此,A是一個3x4的矩陣。首先進行任意升幂排序:
>>sort(A) % Sorting A in a columnwise and acending order
ans =
23 49 2 44
61 76 46 62
95 89 82 79
由其結果可以看出每一行都進行升冪排列,故所有的順序都改變了。現在以列向排序,並且採降冪排列:
>>sort(A,2,'descend') % Sorting A rowwise and in a decending order
ans =
95 49 46 44
89 62 23 2
82 79 76 61
審視其結果,與原矩陣A相較,應符合原先的設定與應用。
此外,若還要知道原來元素移動之前的位置時,則可在函數左邊設定兩個輸出參數,前一項代表排序後的內容,後一項則為該元素在排序前所在的位置(行或列)。
>> [B,ix]=sort(A)
B =
23 49 2 44
61 76 46 62
95 89 82 79
ix =
2 1 2 1
3 3 1 2
1 2 3 3
如果要矩陣依某一行或某一列排序,其餘之行列元素則隨同移動,則可使用另一函數指令sortrows(A),其呼叫格式如下:
B = sortrows(A,column)
>>[B,IX] = sortrows(A)
這個排序函數僅能依行,若要依列排序可先將A倒置。column代表所要排的那一行,如果不說明,則預設為第一行。其中B與IX之定義與sort函數相同,惟此處僅代表指定排序的那一行元素原先之位置。
>>[B,IX]=sortrows(A)
B =
23 89 2 62
61 76 82 79
95 49 46 44
IX =
2
3
1
讀者可就其結果與先前之矩陣A相印證。
2.10 陣列運算
矩陣為一組二維向量之實數或複數之陣列,其加減乘除之運算與一般的數學運算法略有不同,陣列通常以行向量為主,但一般運算仍可混用。即使如此,在線性代數中所定義的矩陣操作大體上
Matlab均能支援。其中諸如一般運算、線性方程、特徵值及單一值與階乘運算等均包括在內。
由於陣列所代表的是一堆有系統的數字,與另一個陣列相運算時,必須依據不同的規則才能獲得
================================
操作名稱 應用情形
---------------------------------
C= A◎B-- ◎處可為加法(+)、減法(-)、乘法(*)、左除(/)、右除(/)
C= A.◎B-- ◎處可為乘法(*)、乘幂(^)、左除(/)、右除(/)
C= A◎c-- ◎處可為加法(+)、減法(-)、乘法(*)、乘幂(^)、右除(/)
C= c◎B-- ◎處可為加法(+)、減法(-)、乘法(*)、乘幂(^)、左除(/)、右除(./)
由表中可知,一個操作元前有一點與沒有一點其意義是不同的。在操作元前加一點表示是項目與項目間之操作,即為所謂之對映運算方式,此時兩矩陣之大小要相同。這與一般矩陣之加法及減法相同,其運算僅針對元素間之運算。偏置功能則僅適用於矩陣間,不適用於項目間之操作。這些操作元亦可應用於矩陣與一般常數,後者之大小為[1x1]。
2.10.1矩陣之加減
設C、D分別為3x3之方矩陣,且設C為魔術方塊,D為[1 2 3;4 5 6;7 8 9],即:
>>C=magic(3)
C =
8 1 6
3 5 7
4 9 2
>>D=[1 2 3;4 5 6;7 8 9]
D =
1 2 3
4 5 6
7 8 9
則C+D與C-D之結果分別為各對應元素間之相互運算:
>>C+D %對應元素相加
ans=
9 3 9
7 10 13
11 17 11
>>C-D %對應元素相減
ans=
7 -1 3
-1 0 1
-3 1 -7
2.10.2矩陣之乘法
下面是C.*D與C*D兩種之運算結果,前者為對應元素相乘;後者為兩個矩陣進行數學相乘:
>>C.*D %對應元素相乘
ans =
8 2 18
12 25 42
28 72 18
>>C*D %矩陣乘法
ans =
54 69 84
72 87 102
54 69 84
數學矩陣相乘所代表的意義因實際的問題而定。例如有一化妝品系列,均由三種原料調配而成,因原料之分量會產生不同產品系列。今設有四種產品,其基本原料分別如有下份量:
>>A=[ 2 4 3; 5 2 1; 7 3 5; 4 5 6]
ans=
2 4 3 %產品1之成分
5 2 1 %產品2之成分
7 3 5 %產品3之成分
4 5 6 %產品4之成分
此時矩陣A代表四種產品(四列)之三種成份量。現設三種成分均有不同的價格,其價格設以一行向量表示,即:
>>P=[120 50 100]'
P =
120
50
100
若用向量的表示法,第一種產品之成分代表A(1,:),即:
>>A(1,:)
ans =
2 4 3
即為A矩陣之第一列,其成本只要將A(1,:)與P相乘,即A(1,:)*P,其結果為:
>>A(1,:)*P
ans = 740
亦即代表產品1的成本,若直接計算應為
2 x (120) + 4x(50) +3x(100) = 740
結果與上面之A(1,:)*P相同。
故上面四種產品,若以成分矩陣A與價格矩陣P,即可得四種產品之成本:
>>A*P
ans =
740
800
1490
1330
不過上述這種乘法必須意到其矩陣大小之配合。由前述可知:A之大小為(4x3),P之大小為(3x1),得到的結果為(3x1)。換言之,兩矩陣相乘,第一矩陣之行與第二矩陣之列,其大小應一致。而結果之大小應為第一矩陣之列與第二矩陣之行,或(4x3)(3x1)=(4x1)。以通式表示之:
A[m,n] * B[n,p] = C[m,p]
若以其元素間之關係而言,可表示如下:
c(ij)=Σ a(ik)b(kj)
其中,i=1,2,…,m;j=1,2,..p,k=1,2...n。其結果即為C[m,p]。由於矩陣大小須配合的關係,顯然B*A並不一定存在,除非其除非其大小均為方矩陣(如前面C*D之例子),但即使如此,其結果也並不一定相同。如:
>>D*C
ans =
26 38 26
71 83 71
116 128 116
足見D*C與C*D的結果並不同。但只要矩陣之大小相搭配,其分解及分配之特性則仍然存在,如:
A*(B+C)=A*B + A*C
或
(A*B)*C=A*(B*C)
矩陣相乘,還有許多有趣的例子。既然大小要相符合,那兩個大小相同之方矩陣之相乘應不會有差錯,至少大小之搭配上不會有問題。如某矩陣AA,設其為(3x3)的魔術方陣:
>>AA=magic(3)
AA =
8 1 6
3 5 7
4 9 2
則
>>AA*AA
ans =
91 67 67
67 91 67
67 67 91
>>AA*AA*AA
ans =
1197 1029 1149
1077 1125 1173
1101 1221 1053
>>AA^3
ans =
1197 1029 1149
1077 1125 1173
1101 1221 1053
顯然矩陣AA之三次方與AA*AA*AA之結果相同。若用eye(3)函數產生單位矩陣,則其無論先乘與後乘,結果都會一樣。
>>I=eye(3)
I =
1 0 0
0 1 0
0 0 1
>>AA*I
ans =
8 1 6
3 5 7
4 9 2
>>I*AA
ans =
8 1 6
3 5 7
4 9 2
結論是若I為單位矩陣,則I*A=A*I=A,顯示交換律在此情形下仍可成立。
2.10.3 陣列之除法
陣列除法屬逐元除法,因此兩陣列相除時必須同樣大小。例如:
>> a=[2 3 4]
a =
2 3 4
>> b=[5 6 7]
b =
5 6 7
>> a./b
ans =
0.4000 0.5000 0.5714
>> c=[1 2;3 4]
c =
1 2
3 4
>> d=[3 5; 8 7]
d =
3 5
8 7
>> c./d
ans =
0.3333 0.4000
0.3750 0.5714
這是兩陣列經過右除(./)運算之結果。
2.10.4 陣列之次方
陣列之逐元運算亦可應用於次方,但其次方數必須為常數,以pascal函數產生之對稱矩陣為例:
>> A=pascal(3)
A =
1 1 1
1 2 3
1 3 6
>> A.^3
ans =
1 1 1
1 8 27
1 27 216