9/27/2006

如何使用編輯器editor

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

9/22/2006

1.1 MATLAB簡介

如何開始使用MATLAB[1]?實際上只要會在指令窗下鍵入指令即行,當然你先要知道如何將MATLAB安裝及使用。在指令窗之前,要下那些指令似乎也沒多大學問。由於是交談式的環境,任何你想到的指令均可以輸入,輸入錯了,MATLAB會有錯誤的訊息,重新輸入正確的指令就行。若一時不知如何下手,有幾個指令可以作為開場白,諸如demohelphelpwindocwhowhat等等指令均可以一試,甚至一直打why,你也可以得到許多意想不到的答案。若有想到什麼指令類似的,則可在其前面打入lookfor進行尋找。如果什麼都不知道,打一個help也可以找到MATLAB所收集的相關指令。

如果真的什麼都不知道,那就將MATLAB當做掌上型計算機吧!雖然把MATLAB當計算機有點殺雞用牛刀,不過如果電腦已開著,閒著也是閒著,就從最簡單的123開始吧,你會發覺MATLAB還是相當好用的計算機呢。例如1200的開三次方,sin(pi/4)等於多少?就只怕你敲鍵太慢而已,MATLAB會在一瞬間給你答案。

1200^(1/3 )

ans =

10.6266

sin(pi/4)

ans =

0.7071

當初APPLE II [1]盛行之時,APPLEBASIC的交談特性,造就蘋果電腦曾經不可一世(雖然這段歷史已如過境雲煙),也使個人電腦有如今的發展。所謂交談特性是,一個指令一個動作,使你立即知道結果,不必經翻譯器。進入MATLAB時,呈眼簾的就是指令窗,在這個窗口下,每下一個指令,就執行一個動作,並顯示其結果如果指令下錯了,MATLAB會告訴你錯在那裡,或只要按一下向上的箭號,即可返回上一指令進行修改,並再重來。在最新版的MATLAB中,有一個分割的視窗則可顯示打過的指令(或稱為歷史指令窗)只要在打過的指令上一點,執行之結果可以重來。如此反覆使用指令則更方便了。

 雖然凡事均由指令窗開始,但實際上它亦可以將一連串命令貯存在一個檔案中,利用這個檔案名稱就可以創造另一個新指令,只要到指令窗一輸入,所有檔案內之指令就集體依序執行。這種可執行的檔案稱為M-files,因為其檔案名稱之字尾均以 ".m"附屬,所以得名。例如, myfirst.m 即表示其檔案名稱為 " myfirst",檔案型式為 M-file開始時只要將目錄指向存放該檔案之檔案夾,就可在指令窗下打入" myfirst"開始執行該檔內之指令群。若你不知道檔案在那兒,則可利用以前dos系統所用的方法,打入dir,即可列出在目前檔案夾中之諸M-檔案。如果在此檔案夾中找不到,亦可使用cd這個指令改變目前的目錄位置,如:

cd mydir %將目錄指向mydir

cd .. 將目指向上一層

前者跳到mydir這個檔案夾內,可以繼續使用dir觀看其下諸M-檔案,mydir這個檔案夾名稱後面是沒有附".m"字尾的,可以立即與實際檔案名稱分辨出來;後者則跳回上一層之檔案夾。注意下指令時應在">>"之後下,但有些新版本好像把">>"忘掉了,唯其空位仍然留著,可以照常下指令。其他有關系統操作指令如表1.1

1.1 系統指令

指令型式

說明

cd [\dir/..]

改變目前的目錄,或往上移動一層

date

顯示日期格式。

diary[on/off/filename]

打開╱關閉或將交談內容存於一檔案

path

顯示MATLAB搜尋之路徑

pwd

顯示目前的目錄名稱

dir, ls

顯示目前目錄下之檔案名稱

demo

示範檔案

help

輔助檔案及指令使用說明

helpwin

指令集

doc

指令使用說明

who

工作空間之變數

what

工作空間之內容



[1] APPLE Apple Computer, Inc.註冊商標。其網址為http//:www.apple.com



[1] MATLABMATHWORKS, INC.之註冊商標,其網址http://www.mathworks.com

1.2 指令使用原則

如前所言,MATLAB 是一種陳述性之語言,亦就是說你輸入一段陳述之指令,MATLAB 就替你翻譯並執行、輸出結果,其基本語法與其他電腦語言相差不遠。最常用的語法是:

>>指令陳述(expression )

>>指令名稱(輸入參數 )

>>[輸出變數(variable)] = 函數名稱(輸入參數 )

指令陳述通常由操作元、函數名稱及變數名稱組成。指令陳述之後會將其輸出變數之結果存於變數中,或顯示在顯示在螢幕上或顯示在圖視窗中。若某些指令函數執行後,其輸出變數僅是中間值,不希望在視窗中顯示,則可在指令之結尾加一個分號";",則其運算結果將保留在記憶體中,暫不輸出,惟其變數值仍可供後續之用。若指定之輸出變數及等號均省略時(如第二種情況)MATLAB會自動提供一個變數 "ans" ("answer"之意) ,將其第一個參數之結果放在裡面。不過這個"ans"的變數只是暫時的,其內容隨著下指令的過程而改變。因此最好的方法是自已指定一個適當的變數名稱。

一個指令陳述通常均以"Enter"鍵結束,表示指令下達完成。但有些指令陳述也許會很長,若超過一行時,可以在適當位置後加上三個點(""),然後再將後續部份延續到下一行,此三點代表延續至下一行。若指令陳述很短,也可以多條指令陳述共置一行,此時每一陳述後面加一個逗點(",")或分號(";")分號表示抑制顯示變數內容;逗點則否

在指定變數、函數、指令名稱時,須注意大小寫,因為MATLAB 對它認定甚為嚴格,故myfirstMYFIRST是兩個完全不同的檔案名稱。

執行MATLAB時,每次均會提供一個工作(workspace),以記錄所指定的變數名稱及內容。所以有時使用MATLAB 過久可能會製造許多不需要的變數名稱。若你的RAM夠大,自無所謂,但若能養成習慣將不要的變數清除,會使MATLAB 的作業顯得更有效率。你可以下清除指令,將某一個變數清除,如:

>>clear myfirst

>>clear

此時在工作間之myfirst變數將會被刪除,若僅打clear,則所有變數均被清除。若要保留變數內容後用,則可將所有之變數內容儲存,只要打一個save 指令:

>>save

此時MATLAB會將所建立之變數存在一個叫MATLAB.mat的檔案,下次再進入時,只要利用load指令即可將其叫進來。其他與檔案操作有關之指令請參看表1.2

在運算或顯示過程中,若有運算無法停止,或想中輟運行時,可以按CTRL-C 停止,此時會仍停留在MATLAB 的模式內,可以接受下一步的指令。

MATLAB 本身也有內建的常數,例如eps (epsilon)是一個10-52次方之小數,可以作為反覆運算時比較之用;而inf表示很大的值另外pi之值等於圓周率π,但須用小寫。

1.2有關檔案之指令

指令型式

說明

delete

刪除檔案

load

讀取存於matlab.mat檔中之變數於工作空間

save

儲存工作空間之變數於matlab.mat檔中

type

顯示檔案內容

edit

編輯檔案內容