顯示具有 Matlab 標籤的文章。 顯示所有文章
顯示具有 Matlab 標籤的文章。 顯示所有文章

11/16/2006

如何畫圖

圓形是畫圖之重要項目之一,但是在MATLAB並無直接指令可進行畫圓。畫一個圓需要圓心及半徑,亦需要顏色的參數。問題是圓在繪製時,必須先清礎座標的比例,否則會造成楕圓或比例不對稱的圓,此點可以在畫圓前先作等軸的宣告,至於終端機本身之軸向若有不等比例,則必須由終端機之控制鈕調整。即:


>> axis equal;



>>axis image

後者之指令功能與前者大略相同,但它會將所繪的圖自動調整至中央部份,可以一覽全圖。無論如何,經由上述任一個宣告之後,兩軸之比例亦會相等,若不宣告,則必須自行調整視窗之長與寬,使其近似等比的情況。

基本上圓周之構成可用三角函數的關係式計算:
x=rcosθ
y=rsinθ
    1.1
其中角度θ則應自零至360度。而其區間應為θ/ Nb。

繪圓之指令(circle.m)則如下述,其輸入參數包括半徑、圓心位置及繪製之點數。本指令本身並不自行繪圖,主要提供圓周各點之座標,供其他座標操作用途,故必須配合一小程式執行繪圖之功能:


function [coords] = circle(r,x0,y0,nn)
% This function draws a circle in a radius r,
% at the center (x0,y0)
% The inputs:
% r = radius of circle
% x0, y0= coordinates of the circular center
% nn = number of drawing points
% coords(nn,1-2)= vectors to store the coordinates
% Example: circle(10,0,0,10)
jj=0:2*pi/nn:2*pi;
coords=[x0+r*cos(jj);y0+r*sin(jj)];
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


實例:繪一半徑為5,原點處之圓。

>> coord=circle(5,0,0,20)
coord =
Columns 1 through 8
5.0000 4.7553 4.0451 2.9389 1.5451 0.0000 -1.5451 -2.9389
0 1.5451 2.9389 4.0451 4.7553 5.0000 4.7553 4.0451
Columns 9 through 16
-4.0451 -4.7553 -5.0000 -4.7553 -4.0451-2.9389 -1.5451 -0.0000
2.9389 1.5451 0.0000 -1.5451 -2.9389-4.0451 -4.7553 -5.0000
Columns 17 through 21
1.5451 2.9389 4.0451 4.7553 5.0000
-4.7553 -4.0451 -2.9389 -1.5451 -0.0000
>> plot(coord(1,:),coord(2,:))
>> axis equal
>> grid on




上述指令中,plot()是常用的指令,但也可以用line()這個指令取代(讀者可以自行在MATLAB上測試)。兩個間之不同處是,可以同時繪多圖,亦可在其後面之參數添加顏色值,後則是僅能繪一組線資料,其顏色則必須利用set()之指令進行設定。一般認知上,應為圓滑之曲線,但就circle()指令之操作,實際上圓仍由線段組成。因此段數或點數nn愈多,所繪製之曲線會愈為平滑;而其平滑度仍然會與半徑大小有關。故nn值之設定在本例中也有其重要性。

上述circle()之繪圓指令,只是先獲得圓周點之資料,供其他程式計算之用途。指令若能直接繪圖,則其功能將更為強大。函數circle1()是另一種多功能的繪圓指令,其內容如下:

function h=circle1(r,x0,y0,Nb,C)
% function h=circle1(r,x0,y0,Nb,C)
% Adding circles to the current plot
% Variables:
% r:radi of circle, a scalar or row matrix.
% x0,y0: Centers of circles, a scalar or row matrix
% C:line colors, a string ('r','b'...),
% or RGB values in column
% Nb:No. of drawing points, a scalar or
% row matrix(default=300)
% the size of Nb must be one
% or equal to the size of r.
% h:handles to the circles
% Rules:
% 1. r=a matrix, (x0,y0)=a scalar:Multiple
% co-centered circles
% 2. r=a scalar, (x0,y0)=row matrix: circle with
% r at each center
% 3. r,(x0,y0)=same length row matrix: circle
% with coresponding r at cooresponding center
% 4. r,(x0,y0)=different-length row matrix: Mutiple
% circles with different r at each center.
% Examples: (execute the commands "clf;" first)
%% Example 0:> circle1
%% Example 1
% circle1([1 2 3],[2 3 5],[1 2 1],20);
%
%% Example 2
% the=linspace(0,pi,200);
% r=cos(5*the);
% circle1(0.1,r.*sin(the),r.*cos(the),20,hsv(40));
%
%% Example 3
% [x,y]=meshgrid(1:10,1:10);
% circle1([0.5,0.3,0.1],x,y,20,['r';'y']);
%
%% Example 4
% circle1(1:10,0,0,3:12,[]);
%
%% Example 5
% circle1((1:10),[0,0,20,20],[0,20,20,0]);
%
% rewritten by Din-sue Fon. BIME, NTU. Date:Nov 18,2004.
% Check the number of input arguments
axis equal;
if nargin <5,C=get(gca,'colororder');end
if nargin <4,Nb=300;end
if nargin <3,y0=0;end
if nargin <2,x0=0;end
if nargin <1,r=1;end
% Change matrices into row-wise ones
x0=x0(:);y0=y0(:);r=r(:);Nb=Nb(:);nx=length(x0);
if length(y0)>nx&nx==1,x0=ones(length(y0),1)*x0;end;
if nx>length(y0)&length(y0)==1,y0=ones(nx,1)*y0;end;
nr=length(r);nx=length(x0);nnb=length(Nb);

if length(y0)~=nx,
error('The lengths of x0 and y0 must be identical');
return;
end;
% plotting
for k=1:nx,
if nx==nr,
coords=circle(r(k),x0(k),y0(k),Nb(rem(k-1,nnb)+1)+1);
h(k)=line(coords(1,:),coords(2,:));
set(h(k),'color',C(rem(k-1,size(C,1))+1,:));
else
for m=1:nr
coords=circle(r(m),x0(k),y0(k),...
Nb(rem(m-1,nnb)+1)+1);
h(k,m)=line(coords(1,:),coords(2,:));
set(h(k,m),'color',C(rem(k*m-1,size(C,1))+1,:));
end
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [coords] = circle(r,x0,y0,nn)
% function [coords] = circle(r,x0,y0,nn)
% This function draws a circle in a radius r,
% at the center (x0,y0)
% The inputs:
% r = radius of circle
% x0, y0= coordinates of the circular center
% nn = number of drawing points
% coords(nn,1-2)= vectors to store the coordinates
% Example: circle(10,0,0,10)
jj=0:2*pi/nn:2*pi;
coords=[x0+r*cos(jj);y0+r*sin(jj)];
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

1.1.2畫圓程式之應用

在MATLAB中繪線,可用line的功能,這個繪線指令係根據座標點矩陣逐點連線繪製。但是連線時係以直線表示,因此必須在適當的點數下所繪製的圖才能近似圓形,故點數也相當重要。在circle之函數當中,其輸入之變數分別如下:

  •  r::圓之半徑,可為列矩陣,若為列矩陣時,代表可同時繪製許多圓。
  •  x0, y0: 圓心之座標,可為矩陣,若為矩陣時,代表可同時繪製許多不同圓心位置之圓。
  •  C:圓之顏色
  •  Nb: 繪圓時所用之點數,其預設值為300點。

函數circle1()除可繪圖外,可以繪製多種型式的圓,並附上顏色。程式內容看來較為複雜,實際執行僅是其中之下半部,其餘均在核對輸入參數之正確性,使程式更能處理不同的需求。這個程式即使僅打入circle1亦可運作,如:

>> circle1
ans =
152.0021




圖2所示即為其繪圖之結果,由於輸入參數均未設定,故程式僅採用預設值,即半徑為1,圓心為原點。指令窗中所顯示之ans=152.0021為此圖之握把值,該值可以作為程式中指定該圖之參考指標。 

實例:

>> circle1([1:10],0,0)
ans =
Columns 1 through 8
152.0050 156.0038 157.0037 158.0033 159.0033 160.0032 161.0032 162.0032
Columns 9 through 10
163.0032 164.0032



圖3為同心圓,只要半徑為列矩陣,即可繪出不同的同心圓,而其顏色則依預設之順序分配,若欲固定顏色,則可在最後一參數中輸入其RGB值。

同心圓之方式也可稍作改變,這是將半徑10分成1,2,3,…,10之同心圓。若將中心點之位置移動,而半徑值固定,其程式如下:

實例:

>> clf;circle1(20,1:2:10,1:2:10)
ans =
152.0054
156.0042
157.0040
158.0035
159.0035



在此實例中,開始下clf是先將前圖洗淨的意思,若不下此指令,則後圖會與前面的圖重疊,不然就要先以configure(h)設定另一個圖窗。若要不同半徑之圓處於不相干之位置,亦可利用下述之方法求得:

實例:

>clf;circle1([1 2 3],[2 3 5],[1 2 1],20);



在此指令下,可以看到半徑r=[1 2 3]的列向量,而圓心x,y也是同元素之列向量,故繪出其對應的圓。其顏色則依內定的排列方式自動顯出。在此每圖之點數均為20點。這種變化有時可以應用在其他有規則之圓心軌跡上,如下面之實例:
實例:

>> the=linspace(0,pi,200);
>> r=cos(5*the);
>> circle1(0.1,r.*sin(the),r.*cos(the),20,hsv(40));
>> circle1(0.1,r.*sin(the),r.*cos(the),20,hsv(40));




在第一行指令中,有一個新指令linspace(),它是分點的函數,亦即在一數列上自開始點至終點間分成若干線段點,其最後之參數即為段數。請注意它不是linespace()。

在這個例子中,另外加顏色碼,使其變化依繪圓的過程而轉變顏色。hsv(40)是一個色彩度之顏色值,分成40個點,但每點有3項RGB值,故其形成之資料大小應為40x3。顏色亦可用文字代表,即'r'(紅色);'y'(黃色); 'k'(黑色);'b'(藍色)等,但必須以行矩陣表示。

若半徑與圓心座標之元素個數不同,則會在不同的圓心上作同心圓,如下實例:

實例:

%test1
clf;
axis equal;
[x,y]=meshgrid(1:5,1:5);
circle1([0.5,0.3,0.1],x,y,['r';'b']);




網格之製作可利用meshgrid()函數,其參數包含X軸與Y軸部份,以方格進行切割,得到不同之座標位置。利用circle1()函數即可以網格點為圓心,繪製不同之同心圓。

除此以外,亦可利用圓周之點繪製多邊形,其實例如下:

實例:

>> circle1(1:10,0,0,3:12)
ans =
Columns 1 through 8
152.0056 156.0044 157.0043 158.0038 159.0038 160.0034 161.0034 162.0034
Columns 9 through 10
163.0034 164.0034



比較複雜之運用則是除點數外,可以運用參數之可變特性繪製特殊之圓形圖形。

實例:

%test2
%
clf;
x=zeros(1,200);
y=cos(linspace(0,1,200)*4*pi);
rad=linspace(1,0,200);
cmap=hot(50);
circle1(rad,x,y,300,[flipud(cmap);cmap]);




此程式中,所用之函數大部份均已用過,其中zeros()函數較為特殊,通常一個矩陣中各元素要令其為零時,可用此函數,其括號內為矩陣之大小。此函數亦可作為某一矩陣大小之宣告,事先預約空間,使電腦在執行時加快速度。其相對應之函數為ones(),其功能相同,只是此函數將所有元素均設定為一。

在顏色之參數中,有一flipud()函數,這是將矩陣上下鏡射交換,使色調成為對稱狀態。

1.2如何繪製橢圓

某一特定點離兩固定點間之距離和為一定時之軌跡為ellipse 圓。垂直之兩軸是由半長軸Ra與半短軸Rb,構成,其與橢圓周上任意點P之座標關係如下:

x²/Ra²+y²/Rb²=1
x = Racosθ, y=Rb sinθ      1.2



若橢圓之長軸旋轉一個角度φ,則,則其新座標將變為:

x'=x cosφ-y sinφ
y'=x sinφ+y cosφ    1.3

將公式1.2代入1.3則關係式變為:

x'=Racosθ cosφ-Rb sinθ sinφ
y'=Racosθ sinφ+Rb sinθcosφ        1.4

事實上圓的圖形亦可作為ellipse 圓之特殊形,因為只要ellipse 圖之長軸與短軸相等時,即可以作成圓。與前面作圓之情況相同,在執行此指令時,若要避免發生重疊,可以先清除圖窗(即clf;)。

橢圓繪圖程式之應用

依據公式1.4,橢圓之座標點可用ellipsexy()這項函數求得,其輸入參數包括半長短軸Ra、Rb,中心座標(x0,y0),迴轉角度ang及點數 nn等。其座標值則儲存在coords中,可以直接用來繪圖。其程式之內容如下:


function [coords] = ellipsexy(ra,rb,x0,y0,ang,nn)
% function [coords] = ellipsexy(ra,rb,x0,y0,ang,nn)
% This function draws a ellipse with a long radius ra,
% and short radius rb at the center (x0,y0)
% The inputs:
% ra, rb = long & short radii of the ellipse
% x0, y0= coordinates of the ellipse center
% nn = number of drawing points
% ang = angle of the long axis, in radians
% coords(nn,1-2)= vectors to store the coordinates
% Example: ellixy(10,0,0,10)
jj=0:2*pi/nn:2*pi;
coords=[ra*cos(ang)*cos(jj)-rb*sin(ang)*sin(jj)+x0;...
ra*sin(ang)*cos(jj)+rb*cos(ang)*sin(jj)+y0];

本程式ellipsexy()並未有繪線之功能,可以配合plot()或linke()等繪線函數為之。仍採用line 的功能,逐點連線繪製。由於連線係以直線表示,因此必須在適當的點數下才能繪出近似橢圓形,故點數也相當重要。下面之實例中,點數僅10點,故其橢圓未能成形,可以比較其所繪出之圖形。

實例:半長短軸分別為10、5,中心座標為原點,長軸迴轉30度,試繪出其外形。

>> coord=ellipsexy(10,5,0,0,pi/6,10)
coord =
Columns 1 through 8
8.6603 5.5368 0.2985 -5.0538 -8.4758 -8.6603 -5.5368 -0.2985
5.0000 6.5903 5.6633 2.5731 -1.4999 -5.0000 -6.5903 -5.6633
Columns 9 through 11
5.0538 8.4758 8.6603
-2.5731 1.4999 5.0000
>> plot(coord(1,:),coord(2,:))
>> axis equal;grid on



具有繪製橢圓功能之函數為ellipse0()。可以多重繪製各種橢圓。其程式內容如後,主程式並呼叫副程式ellipsexy(),後者可以另行建檔,或附於呼叫程式之後。其相關參數如後:

  • ra, rb:橢圓之半長短軸,可為列矩陣,若為列矩陣時,代表可同時繪製許多橢圓,原則上兩陣列之大小應相同,若其中一個為常數(即為1x1陣列),程式會自動調整與其他一項目同。
  • ang:長軸之傾斜角,以度度表示。可為列矩陣,若與ra或rb之大小相同,則會在各中心點處繪製對應之單一橢圓。
  • x0,y0:橢圓之中心座標,可為矩陣,若為矩陣時,代表可同時繪製許多不同圓心位置之橢圓。
  • C:橢圓線之顏色,可為RGB之三組數值,是為行矩陣。亦可用代碼表示。如['r';'b';'k'...]。注意為使其形成行矩陣,中間必須用分號隔開。
  • Nb: 繪ellipse 圓時所用之點數。預設值為300。

其他參數配合使用原則:

  • 若ra 為單一項,x0,y0 為向量矩陣,則會繪製向量矩陣數之橢 圓。若x0,y0 為單一項,則會繪製同心橢圓。
  • ra 為向量矩陣,則會繪製同一橢圓心之不同半徑向量矩陣數之橢圓。
  • ra 均為同大小之矩陣向量,則會繪製數目相同之橢圓。 若x0,y0 與ra 均為不同大小之矩陣,則會繪製總數為兩矩陣數目之乘積。
  • 實例:繪製一個傾斜某30角度之橢圓。

>> ellipse0(2,1,0,0,30,'r')
ans = 152.0020


實例:在相同半長短軸及中心點下,可以變化角度,產生旋轉之橢圓群:

>> ellipse0(2,1,0,0,0:20:360)
ans =
Columns 1 through 8
160.0020 161.0020 162.0020 163.0020 164.0020 165.0020 166.0020 167.0020
Columns 9 through 16
168.0020 169.0020 170.0020 171.0020 172.0020 173.0020 174.0020 175.0020
Columns 17 through 19
176.0020 177.0020 178.0020



實例:若半短軸維持不變(可以輸入單一值),配合半長軸進行變化。

>> ellipse0(1:10,4,0,0)
ans =
Columns 1 through 8
152.0024 156.0024 157.0024 158.0024 159.0024 160.0024 161.0024 162.0024
Columns 9 through 10
163.0024 164.0024



實例:同時變化半長短軸,其他維持不變。

>> ellipse0(1:6,0.5:0.1:1.0)
ans = 152.0026 156.0026 157.0026 158.0026 159.0026 160.0026




實例:變化半長短軸,也變化Y軸之高度。

>> ellipse0([1:10]*2,1:10,0,1:10)
ans =
152.0037 156.0037 157.0037 158.0037 159.0037 160.0037
161.0037 162.0037 163.0037 164.0037



實例:曲線變化半長短軸,也變化Y軸之高度。

>>ellipse0([1:10].^2,1:10,0,[1:10]*10);




程式內容:

function h=ellipse0(ra,rb,x0,y0,ang,C,Nb)
% h=ellipse0(ra,rb,ang,x0,y0,C,Nb)
% Adding ellipse to the current plot
% Variables:
% ra,rb:longitudinal & horizontal axes of a ellipse, scalar or matrix.
% ang: angle the ellipse inclines, in deg.
% x0,y0: Centers of the ellipses, a scalar or row matrix
% C:line colors, a string ('r','b','k'...),or RGB values in column
% Nb:No. of drawing points, a scalar or row matrix(default=300)
% h:handles to the ellipse
% Rules:
% 1. ra,rb= matrix, (x0,y0)=a scalar:Multiple co-centered ellipes
% 2. ra,rb= scalar, (x0,y0)=row matrix: ellipse with ra & rb at each center
% 3. ra,rb,(x0,y0)=same length row matrix: ellipse with coresponding r at
% cooresponding center
% 4. ra,rb & (x0,y0)=different-length row matrix: multiple ellipses with
% different pairs of ra & rb at each center
% 5. ra, rb should have same size
% Examples: (execute the commands "clf;" first)
%% Example 0: ellipse0
% ellipse0(2,1,0,0,0:10:360);
% clf;ellipse0(3,1,[0 2 5],[0 1 4],0:10:360)
% ellipse0(ra,rb,ang,x0,y0,C,Nb), Nb specifies the number of points
% ellipse(1,2,pi/8,1,1,'r')
% author: Din-sue Fon. Bime, NTU, Date:November 18, 2004
axis equal;
if nargin <7,Nb=300;end
if nargin <6,C=get(gca,'colororder');end
if nargin <5,ang=0;end
if nargin <4,y0=0;end
if nargin <3,x0=0;end
if nargin <2,rb=1;end
if nargin <1,ra=2;end
% change the matrices into one row
x0=x0(:);y0=y0(:);ra=ra(:);rb=rb(:);ang=ang(:)*pi/180;
nr=length(ra);nx=length(x0);
if length(rb)>nr&nr==1,ra=ones(length(rb),1)*ra;end;
if nr>length(rb)&length(rb)==1,rb=ones(nr,1)*rb;end;
if length(y0)>nx&nx==1,x0=ones(length(y0),1)*x0;end;
if nx>length(y0)&length(y0)==1,y0=ones(nx,1)*y0;end;
nr=length(ra);nx=length(x0);nnb=length(Nb);nang=length(ang);
if length(y0)~=nx|length(rb)~=nr,
error('The lengths of ra & rb should have same size!');
return;
end
if isstr(C),C=C(:);end;
for k=1:nx,
if nx==nr,
for n=1:nang
coords=ellipsexy(ra(k),rb(k),x0(k),y0(k),ang(n),...
Nb(rem(k-1,nnb)+1)+1);
h(k,n)=line(coords(1,:),coords(2,:));
set(h(k,n),'color',C(rem(k*n-1,size(C,1))+1,:));
end
else
for m=1:nr
for n=1:nang
coords=ellipsexy(ra(m),rb(m),x0(k),y0(k),ang(n),...
Nb(rem(m-1,nnb)+1)+1);
h(k,m)=line(coords(1,:),coords(2,:));
set(h(k,m),'color',C(rem(k*m*n-1,size(C,1))+1,:));
end
end
end
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [coords] = ellipsexy(ra,rb,x0,y0,ang,nn)
% function [coords] = ellipsexy(ra,rb,x0,y0,ang,nn)
% This function draws a ellipse with a long radius ra,
% and short radius rb at the center (x0,y0)
% The inputs:
% ra, rb = long & short radii of the ellipse
% x0, y0= coordinates of the ellipse center
% nn = number of drawing points
% ang = angle of the long axis, in radians
% coords(nn,1-2)= vectors to store the coordinates
% Example: ellixy(10,0,0,10)
jj=0:2*pi/nn:2*pi;
coords=[ra*cos(ang)*cos(jj)-rb*sin(ang)*sin(jj)+x0;...
ra*sin(ang)*cos(jj)+rb*cos(ang)*sin(jj)+y0];

11/10/2006

遞回程序之使用

MATLAB Recursive use of function

遞回程序是利用函數呼叫自己,直到特定條件滿足為止。例如:某一數列連續加法,即


Sum=1 + 2 + 3 + 4 + ...+n

下面為這種遞回程序之應用:

function sum=sigma(n)
%Recursive use of function
%Find the sumation of i, if i=1:n
if n>1
sum=n+sigma(n-1);
else
sum=1;
end


執行結果:

>> sigma(5)
ans =
15

這種結果,在MATLAB中不寫程式也可以指令達到相同的目的:

>> sum(1:5)
ans =
15

另外例子:

>> sigma(100)
ans =
5050

>> sum(1:100)
ans =
5050


同樣的道理,若累加改為累乘則會如何呢?實際上程式內容一樣簡單,函數名稱改為factx就行了:


function sum=factx(n)
%Recursive use of function
%Find the multiple prodcut of i, as i=1:n
if n>1
sum=n*factx(n-1);
else
sum=1;
end

執行結果如下:

>> factx(5)
ans =
120

只是,MATLAB竟然將這項功能也變成一個factorial指令了:

>> factorial(5)
ans =

120

結果是不是一樣呢?

11/07/2006

使用繪圖工具

繪圖工具是一種交談式之繪圖環境,不必寫程式。這是matlab最近加強的功能,它可以產生不同型式之圖形,亦可由工作空間中直接選定要繪製之參數資料。具有併圖的功能,一般圖形特性也可以透過此一繪圖工具來達成。


>> plottools

由圖形窗直接選擇 Show Plot Tools指令亦可,最後會顯示如下之視窗。下面之繪圖程式可先提供繪圖之素材,執行後之結果會直接顯示在圖窗上。

x = 0:pi/100:2*pi;
y1 = sin(x);
y2 = sin(x+.25);
y3 = sin(x+.5);
subplot(2,1,1);
plot(x,y1,x,y2,x,y3);
axis tight;
w1 = cos(x);
w2 = cos(x+.25);
w3 = cos(x+.5);
subplot(2,1,2);
plot(x,w1,x,w2,x,w3);
axis tight;


將上述程式以editor存檔,然後在指令窗下執行,其後再執行plottools,即可得到下面的圖形介面。此時圖形會顯現在正中央,兩側分別為圖形繪製時之參數。左邊為圖形佈置參數,可以隨時增加副圖,包括二維與三維之圖形。此外為輸入之變數資料,這些小窗可以關閉或加入,或在參數設定時宣告即可。例如:

>>plottools( 'on', 'figurepalette')

>>figurepalette




圖形之內容則可直接利用滑鼠選擇,其對應之線圖會在左側之圖形觀視窗內顯示,亦可勾選是否顯示。




圖形窗之使用說明

工作鈕的功能


圖形除由plot等指令繪製外,其結果仍可以在窗形窗下修改,所以即使不會圖形指令之參數者,亦可利用圖形窗上之工作鈕作修正。這些工作鈕包括存檔及列印、縮小及放大、圖形旋轉及座標轉換等等。其外觀如下:


此外,由view選單中可以拉出兩個工作單,其一稱為相機工具(Carmera toolbar),可操作三維之圖像;其二為圖形編輯單(Plot edit toolbar),可以對圖形特徵、註解、指示箭頭等進行編輯。





在MATLAB中,有各種二維及三維之繪圖指令可以應用,以適應不同的需求。其中包括線圖、方塊圖、面積圖、向量圖、極座標圖及散佈圖等,可以參考如下之網頁:

有關各種圖之說明,請按此。。。

MATLAB的圖形介面

MATLAB是利用figure作為圖形顯示介面,可以顯示資料及各類型之圖形。實際上亦可利用figure這一個指令產生所需之圖形環境,利用此環境尚可加添說明及其他資訊。所顯示之圖形可以放大縮小,而且具有下拉式介面。

利用plot指令則可將不同的圖形繪於圖形環境之中。利用plot指令可以顯示表格資料,幾何圖形,物體表面及影像。註釋方面則可增加標題、圖標及顏色標等。圖形可利用二維及三維顯示。即使一維的資料亦可顯示於圖中,而使用資料序號作為橫軸對映繪出。

圖之組成


利用繪圖指令及相關工具可以直接將結果顯示於圖形窗之中,每一圖可以有不同的視窗,最後集成一個圖形組。例如以下面之程式,執行後可以得到二維圖形:

x = [0:.2:20];
y = sin(x)./sqrt(x+1);
y(2,:) = sin(x/2)./sqrt(x+1);
y(3,:) = sin(x/3)./sqrt(x+1);
plot(x,y)






上圖中為執行結果,程式會自動使用不同的線型及顏色分別不同組的資料圖,等到技巧成熟時,也可以透過設定參數的方式更改這些顏色及線型。

10/31/2006

串接指令之應用

MATLAB Catenation Commands

串接兩矩陣,構成新矩陣之指令如下表:








函數名稱說明
cat沿設定方向串接
horzcat沿水平方向串接
vertcat沿垂直方向串接
repmat依垂直與水平方向倍數串接
blkdiag由現存之矩陣產生對角矩陣


下面為執行這些函數指令之例子:

串接矩陣與陣列



除使用中括號[]作簡單串接外,其他串接指令有cat、horzcat及vertcat等三個函數。這些指令可以交互運用,例如要將AB兩矩陣作垂向串接時,下述三個指令均可得到同樣的結果:

水平串接:

 C = [A B] %使用中括號,相隔用分號。
 C = cat(2, A, B); % 第一參數設定為2。
 C = horzcat(A, B); % 無額外參數。


垂直串接:

 C = [A; B] %使用中括號,相隔用分號。
 C = cat(1, A, B); % 第一參數設定為1。
 C = vertcat(A, B); % 無額外參數。


拷貝串接



使用repmat函數在垂向及水平方向產生不同數量之拷貝矩陣,其指令型式如下:

repmat(M, v, h)

MATLAB 將輸入矩陣垂直方向拷貝v 次;水平方向拷貝h次。下面舉例:


A = [8 1 6; 3 5 7; 4 9 2]
A =
8 1 6
3 5 7
4 9 2

B = repmat(A, 2, 4)
B =
8 1 6 8 1 6 8 1 6 8 1 6
3 5 7 3 5 7 3 5 7 3 5 7
4 9 2 4 9 2 4 9 2 4 9 2
8 1 6 8 1 6 8 1 6 8 1 6
3 5 7 3 5 7 3 5 7 3 5 7
4 9 2 4 9 2 4 9 2 4 9 2


區塊對角矩陣



利用blkdiag函數可以結合矩陣,鉗入對角方向,產生許多區塊對角矩陣,在區塊之外的新建元素位置則設定為零:


A = magic(3);
B = [-5 -6 -9; -4 -4 -2];
C = eye(2) * 8;

D = blkdiag(A, B, C)
D =
8 1 6 0 0 0 0 0
3 5 7 0 0 0 0 0
4 9 2 0 0 0 0 0
0 0 0 -5 -6 -9 0 0
0 0 0 -4 -4 -2 0 0
0 0 0 0 0 0 8 0
0 0 0 0 0 0 0 8

如何擴張矩陣

How to expand the size of a Matrix

擴張矩陣有兩種方式:

  1. 增加新元素於一矩陣上。
  2. 儲存一元素於矩陣的範圍之外。


兩矩陣之結合


第一種情況是利用中括號[ ]。這個符號不僅作為產生新矩陣之方法,也可用來增加新元件或新陣列,只是當要要增加新元素或部份矩陣於一舊矩陣上時,必須先確定其大小是否合適。下面為其例:

A = ones(2, 5) * 6; % 2-by-5 matrix of 6's
B = rand(3, 5); % 3-by-5 matrix of random values

C = [A; B] % Vertically concatenate A and B
C =
6.0000 6.0000 6.0000 6.0000 6.0000
6.0000 6.0000 6.0000 6.0000 6.0000
0.9501 0.4860 0.4565 0.4447 0.9218
0.2311 0.8913 0.0185 0.6154 0.7382
0.6068 0.7621 0.8214 0.7919 0.1763



由此可知,矩陣往下延伸時,其行數必須相同。同理,若往右或左向延伸,其列數必須相同。

>>c=[];for k=1:4, c=[c;eye(3)*k];end;
>>c=
1 0 0
0 1 0
0 0 1
2 0 0
0 2 0
0 0 2
3 0 0
0 3 0
0 0 3
4 0 0
0 4 0
0 0 4


結構陣列之結合


結構陣列亦可利用矩陣增列的方式建立。建立之後再利用reshape指令進行重整。

%Concatenating to a Structure
% Create a 3X4 structure array M
for k=1:12
M(k)=struct('Name',{['code', num2str(k)]},'value',10*k+8);
end
M=reshape(M,3,4)
%Create a 3X2 array using the same field name
for kk=1:6
N(kk)=struct('Name',{['code', num2str(kk+12)]},'value',10*kk+2);
end
N=reshape(N,3,2)
%Concalenate N onto M alogn the horizontal dimension
S=[M N]
%-------------------------------------------


上面之程式經執行之後,會顯現結果如下:

>> S

S =

3x6 struct array with fields:
Name
value


原來的欄位為Name與value,利用相同的欄位可以增加同型式之結構矩陣。

小陣列結合大陣列


要將小陣列加入大陣列,其大小顯然不對等,但此時亦可指明置於大陣列中之位置,此位置可以超出大陣列之範圍,因而擴大其領域。大陣列之大小會配合增加,其餘未增加之空位以零補充,以維持其長方形矩陣之型式。

例如,一個 3X5 之矩陣之內容如下:


A = [ 10 20 30 40 50; ...
60 70 80 90 100; ...
110 120 130 140 150];


今若隨便增加一個新元素,以下面的操作方式,會產生錯誤的信息:

>>A = [A; 160]

??? Error using ==> vertcat
All rows in the bracketed expression must have the same
number of columns.


但若直接指定這一個元素置於某特定位置,如第四列第一行時,反而可行,其餘空間會自動以零補足。


A(4,1) = 160
A =
10 20 30 40 50
60 70 80 90 100
110 120 130 140 150
160 0 0 0 0


即使插入的是一組小陣列,只要指定於適當的位置,一樣可行,不會發生錯誤。


A(4:6,1:3) = magic(3)+300
A =
10 20 30 40 50
60 70 80 90 100
110 120 130 140 150
308 301 306 0 0
303 305 307 0 0
304 309 302 0 0



即使增加的新元素離開原矩陣的範圍甚遠,MATLAB一樣會將其他未觸及的部份補足零,以維持一個長方型矩陣:


A(4,8) = 300
A =
10 20 30 40 50 0 0 0
60 70 80 90 100 0 0 0
110 120 130 140 150 0 0 0
0 0 0 0 0 0 0 300


擴充結構陣列或細胞陣列


即使是結構陣列或細胞陣列亦可利用同一方法進行擴充。下面的例子是以儲存一額外細胞於原陣列之範圍之外的情形,同樣,MATLAB會將其他未指定的部份均填以空細胞[],以維持長方矩陣之外型:

設原來陣列為2X3大小:

C = {'Madison', 'G', [5 28 1967]; ...
46, '325 Maple Dr', 3015.28}


此時若增加一新細胞於C{3,1}之位置,則MATLAB 會增加一整列:


C{3, 1} = ...
struct('Fund_A', .45, 'Fund_E', .35, 'Fund_G', 20);
C =
'Madison' 'G' [1x3 double]
[ 46] '325 Maple Dr' [3.0153e+003]
[1x1 struct] [] []


擴充文字陣列


文字陣列以單一文字為元素,其擴充方式實際上與一般陣列相同,只是這種擴充方式並不理想,故也不建議使用這種方法。由於 MATLAB 對陣列擴充時均以零補足未填入的部份,但有些程式常將零值解讀為終止代碼,如此反而會造成擴充部份之長度未達到全長,因而造成錯誤。

下面的例子是將一個1X5之文字陣列擴充至12個字母,其結果變成一個長字串:


greeting = 'Hello'; greeting(1,8:12) = 'World'
greeting =
Hello World


如果細心審視文字之內碼,變成零值之碼就出現了:


uint8(greeting)
ans =
72 101 108 108 111 0 0 87 111 114 108 100


在字串中間由於零值之出現常會造成一些函數產生不可預測的結果。例如:利用strcmp比較兩字串是否相同時,得到不正確的結果,因為這兩個字串內容實際上是一樣的:

strcmp(greeting, 'Hello World')
ans =
0


上述介紹的方法雖然可以達到擴張矩陣的目的,但若需要重覆進行擴張的動作時,仍然建議不要如此作,因為會浪費電腦計算時間。比較妥當的方式是事先安排足夠的空間,如此可以增加記憶體之運用效率。

10/30/2006

多維陣列範例

多維陣列範例

要產生多維陣列,利用zeros、ones、rand、randn等函數指令亦可完成,例如:


>>W=randn(4,3,5)

W(:,:,1) =

-0.4326 -1.1465 0.3273
-1.6656 1.1909 0.1746
0.1253 1.1892 -0.1867
0.2877 -0.0376 0.7258


W(:,:,2) =

-0.5883 1.0668 0.2944
2.1832 0.0593 -1.3362
-0.1364 -0.0956 0.7143
0.1139 -0.8323 1.6236


W(:,:,3) =

-0.6918 -1.4410 0.8156
0.8580 0.5711 0.7119
1.2540 -0.3999 1.2902
-1.5937 0.6900 0.6686


W(:,:,4) =

1.1908 -1.6041 -0.8051
-1.2025 0.2573 0.5287
-0.0198 -1.0565 0.2193
-0.1567 1.4151 -0.9219


W(:,:,5) =

-2.1707 0.5077 0.3803
-0.0592 1.6924 -1.0091
-1.0106 0.5913 -0.0195
0.6145 -0.6436 -0.0482


其結果等於產生一個4x3x5的陣列,等於60個常態分配之值。這些陣列等於形成五頁。

三維陣列所代表之數值可能也有其他物理意義,例如不同長方形隔間之室溫分佈,或一與時間有關之物理量等等。

設若利用排列組合指令perms(1:4)將1、2、3、4作排列,則應有十六種排法:

>> h=perms(1:4)

h =

4 3 2 1
4 3 1 2
4 2 3 1
4 2 1 3
4 1 2 3
4 1 3 2
3 4 2 1
3 4 1 2
3 2 4 1
3 2 1 4
3 1 2 4
3 1 4 2
2 3 4 1
2 3 1 4
2 4 3 1
2 4 1 3
2 1 4 3
2 1 3 4
1 3 2 4
1 3 4 2
1 2 3 4
1 2 4 3
1 4 2 3
1 4 3 2


其後由魔術方陣產生的矩陣依上述組合依行重排,置於三維陣列M內,則M應可由下指令獲得:


>> for k=1:6, M(:,:,k)=A(:,h(k,:));end
>> M

M(:,:,1) =

13 3 2 16
8 10 11 5
12 6 7 9
1 15 14 4


M(:,:,2) =

13 3 16 2
8 10 5 11
12 6 9 7
1 15 4 14


M(:,:,3) =

13 2 3 16
8 11 10 5
12 7 6 9
1 14 15 4


M(:,:,4) =

13 2 16 3
8 11 5 10
12 7 9 6
1 14 4 15


M(:,:,5) =

13 16 2 3
8 5 11 10
12 9 7 6
1 4 14 15


M(:,:,6) =

13 16 3 2
8 5 10 11
12 9 6 7
1 4 15 14


若利用sum(M,d)這個指令進行加總,則第二參數決定其加總方向,d=1時會以行向進行,但每頁會有一個加總;d=2時則為列向加總,同理,亦應有六頁;d=3為依頁向加總,故其結果應為一4X4之矩陣,其結果如下:

>> sum(M,1) %行向加總

ans(:,:,1) =

34 34 34 34


ans(:,:,2) =

34 34 34 34


ans(:,:,3) =

34 34 34 34


ans(:,:,4) =

34 34 34 34


ans(:,:,5) =

34 34 34 34


ans(:,:,6) =

34 34 34 34

>> sum(M,2) %列向加總

ans(:,:,1) =

34
34
34
34


ans(:,:,2) =

34
34
34
34


ans(:,:,3) =

34
34
34
34


ans(:,:,4) =

34
34
34
34


ans(:,:,5) =

34
34
34
34


ans(:,:,6) =

34
34
34
34

>> sum(M,3) %頁向加總

ans =

78 42 42 42
48 52 52 52
72 44 44 44
6 66 66 66

10/24/2006

While 迴圈

While迴圈
利用while...end是可以不確定執行次數下停止,利用if...end則可協助判斷。以求多項式之x²-2x-5之根為例,先確定可能根的範圍,例如:b>x>a,則可利用分段法逐漸迫近解:


% find root of athe polynormial f(x)=x^3-2x-5
a=0;fa=-Inf;
b=3;fb=Inf;
while b-a>eps*b
x=(a+b)/2;
fx=x^3-2*x-5;%polynormial
if sign(fx)==sign(fa)
a=x;fa=fx;
else
b=x;fb=fx;
end
end
x
-------------------------------------

上述之解法中,先設定a與b之值及其對應之f值,由於後者之第一次較難掌握,故只要使用正負無窮大之值作為起點。進入後,即進行二分法,求得新x值即可確定得到f的對應值。當然在這裡設定負無窮大在a=0這邊,也有點冒險。執行的結果如下:

>> format long
>> ex01

x =

2.09455148154233

10/23/2006

排序的問題

陣列的排序常按大小以升幂(asend)或降幂(descend)排列,其指令型式為sort()或sortrows()。這兩種指令之結果略有不同,茲以magic(6)所產生的矩陣為例:


>> AA=magic(6)

AA =

35 1 6 26 19 24
3 32 7 21 23 25
31 9 2 22 27 20
8 28 33 17 10 15
30 5 34 12 14 16
4 36 29 13 18 11

>> sort(AA)%依行向方式排列

ans =

3 1 2 12 10 11
4 5 6 13 14 15
8 9 7 17 18 16
30 28 29 21 19 20
31 32 33 22 23 24
35 36 34 26 27 25

>> sort(AA,2)%依列向方式排列


ans =

1 6 19 24 26 35
3 7 21 23 25 32
2 9 20 22 27 31
8 10 15 17 28 33
5 12 14 16 30 34
4 11 13 18 29 36

>> sort(AA,2,'descend')%依列向且以降幂方式排列

ans =

35 26 24 19 6 1
32 25 23 21 7 3
31 27 22 20 9 2
33 28 17 15 10 8
34 30 16 14 12 5
36 29 18 13 11 4

%可以依
>> D=[[2 2 3 3 4 4]' AA(:,[1:3])] %先造一個新矩陣

D =

2 35 1 6
2 3 32 7
3 31 9 2
3 8 28 33
4 30 5 34
4 4 36 29

>> sortrows(D,[1 2]) %依第一及第二行排列

ans =

2 3 32 7
2 35 1 6
3 8 28 33
3 31 9 2
4 4 36 29
4 30 5 34

最大值與最小值

最大值與最小值分別使用max()與min()兩函數即可求得,兩者之參數型式均相同。但其結果均是以行向比較,不是列向。例如:


>> a=magic(5)

a =

17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9

>> max(a)

ans =

23 24 25 21 22



若要使用列向表示,則必須在第三參數上標明,其第三參數即為ndim值,至於第二參數則為另一組比較的陣列,若僅求一個矩陣之列向最大或最小值,則第二參數以[ ]空矩陣取代即可,而令ndim=2,如:

>> max(a,[],2)

ans =

24
23
22
21
25

>> min(a)

ans =

4 5 1 2 3

>> min(a,[],2)

ans =

1
5
4
3
2

使用轉置指令亦可得到列向最小值,只是所得的為列向量,必須調整才能符合原先之需求:

>> min(a')

ans =

1 5 4 3 2


若是兩個相同大小之矩陣進行比較大小時,則可將第二矩陣置於第二參數位置,而ndim值同樣有效,只是其預設值為ndim=1:

>> B=[1:10]';
>> b=[10:-1:1]';
>> max(B,b)

ans =

10
9
8
7
6
6
7
8
9
10

在左邊的輸出參數第一項為行向或列向之最大或最小值,其第二項輸出則為其在該行向或列向之所在位置:

>> [m,I]=max(a)

m =

23 24 25 21 22


I =

2 1 5 4 3


不過,若兩矩陣作比較,求取陣列中之最大或最小值時,輸出項中不能有第二參數,因為各參數之同列或同行進行比較,均為已知。

10/22/2006

一個向量的絕對值

絕對值為一個向量之無符號正值,其指令為abs()。例如一向量m如下:


>> m=[-5:5]
m =
-5 -4 -3 -2 -1 0 1 2 3 4 5

>> abs(m)
ans =
5 4 3 2 1 0 1 2 3 4 5

但是向量若為複數,則其絕對值為該複數之模數,或實量,例如:


>> mm=[3+4i;4+9i;5-4i],x=abs(mm)
mm =
3 + 4i
4 + 9i
5 - 4i
x =
5
9.8489
6.4031

所以,若以複數型式表示兩相垂直之座標量,則利用abs之絕對值功能可以求得其向量之絕對值。亦即若


R= a + bi


則|R|=(a*a+b*b)1/2,而|R|=abs(a+bi)

若一個向量超過二項單元,則亦可使用下列計算求得其絕對值:

>> aaa=[3 4 5 12];r=sqrt(aaa*aaa')
r =
13.928
>> aaa=[3 4];r=sqrt(aaa*aaa')
r =
5

向量之長度

一個向量之長度及絕對值可以利用length()指令。此指令在於求得向量之長度或元素個數。例如:


>> a=1:9
a =
1 2 3 4 5 6 7 8 9
>> length(a)
ans =
9
>> length(a')
ans =
9

後者顯示:這個length指令不論向量為行向量或列向量,均取其最大數目之行數或列數。即使a為矩陣,其結果應與max(size(a))相同。

>> aa=[0:9;0:9]
aa =
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
>> max(size(aa))
ans =
10
>> length(aa)
ans =
10


下面為向量aa之元素三次方和之指令。開始時先假設aa為數目未知之向量,故必須使用length函數指令來求得其數目,然後再予以三次方並相加:

>> aa=[1 4 3 5];x=0;for i=1:length(aa),x=x+aa(i)^3,end
x =
1
x =
65
x =
92
x =
217

如何延長指令行數

如何延長指令長度

下面是一個將魔術函數轉為行向量,再轉為2X8的矩陣B:


>> A_magic_elements=magic(4);B=reshape(A_magic_elements(:),2,8)
B =
16 9 2 7 3 6 13 12
5 4 11 14 10 15 8 1

>> A_magic_elements=magic(4);B=reshape(A_magic_elements...
(:),2,8)


注意在上一行之最後項加上三連續點後,要按shift-enter才能接續整個指令之陳述,不能只按enter,否則會立即執行該不完整的指令,因而會得到錯誤指示。

B =
16 9 2 7 3 6 13 12
5 4 11 14 10 15 8 1


同一個指令亦可利用這種方式分成好幾行一齊執行:

>> A_magic_elements=magic(4);...
B=reshape(A_magic_elements...
(:),2,8)
B =
16 9 2 7 3 6 13 12
5 4 11 14 10 15 8 1

10/21/2006

資料格式說明

資料格式:資料格式在前面也有些討論,其型式依需求而定,數值之項設值為單精度,其表示型式有多種變化,可參考第二章之應用。

10/20/2006

字串及文字資料

MATLAB 資料結構之連結#links

處理字母(character)及字串(string)資料時,Matlab亦常使用陣列結構。任何一個變數均可置入文字。無論是字母或字串都要使用撇號前後括出來。例如:



>> str1='hello'

str1 =

hello

>> size(str1)

ans =

1 5

顯然,變數str1為一陣列的型式,故:

>> str1(2:4)

ans =

ell

>> a=double(str1) %利用double函數轉換為ASCII code

a =

104 101 108 108 111

>> s=char(a) %利用char函數可以將ASCII轉回字串

s =

hello

Char函數除可轉換ASCII為字母外,亦可以將不同長度之字串以最大的長度對齊,例如:

>> s=char('a','big','sky','that','kisses','the', 'ground.')

s =

a
big
sky
that
kisses
the
ground.

>> size(s)

ans =

7 7


>> s(4,1:7)

ans =

that

>> s' %將其轉置後,可以看到字串中完全以一個字一個位置

ans =

abstktg
ikhihr
gyaseo
ts u
e n
s d
.

>> C={'a','big','sky','that','kisses','the', 'ground.'} %也可以使用細胞陣列

C =

'a' 'big' 'sky' 'that' 'kisses' 'the' 'ground.'

>> CC=cellstr(s) %利用cellstr函數也可以轉為細胞陣列

CC =

'a'
'big'
'sky'
'that'
'kisses'
'the'
'ground.'

>> ss=char(C) %利用char函數再將細胞矩陣轉回字串矩陣

ss =

a
big
sky
that
kisses
the
ground.

10/13/2006

MATLAB Educational Sites

另外一個有關matlab教育性之應用網站為MATLAB Educational Sites。雖然其中有一部份已經失聯,仍可以供參考。