MATLAB 基本功能介紹
黃聰明 min@math.ntnu.edu.tw
http://math.ntnu.edu.tw/~min
臺灣師範大學數學系
1.1 變數和陣列
變數
第一個字必須是文字,其後可用文 字、數字及底線任意組合。
使用者設定名稱的陣列,在實體上 是由一塊記憶體區域所組成。
變數名稱
不可超過 63 個字
元 大小寫字母有別
常用變數型態
doubl e
char
佔 64 位元 擁有 15 到 16 個有效位
數
可處理實數、虛數和複數 內定 i 和 j 代表虛數1
Var = 10 + 10i;
1.2 MATLAB 變數的初始化
三種用來初始化變數的方式
利用宣告的方式,指定資料給變數
從鍵盤輸入資料給變數 從檔案讀取資料
var = expression
var = 40i;
var2 = var/5;
array = [ 1 2 3
特殊符號 (I)
分號 (;)
冒號 (:)
轉置
transpose(’)
first:incr:la st
特殊符號 (II)
百分比符號
( % )
程式中加入註解( Comments
)
>> y = (5*2+3.5)/5; % 將運算結果儲存在變數 y ,但不用顯示於螢幕
>> z = y^2 % 將運算結果儲存在變數 z ,並顯示於螢幕 z =
特殊用途矩陣
指令 說明
zeros(m, n) 產生維度為 m×n ,構成元素全為 0 的矩陣
ones(m, n) 產生維度為 m×n ,構成元素全為 1 的矩陣
eye(n) 產生維度為 n×n ,對角線的各元素全為 1 ,其他各元素全為 0 的單
位矩陣
pascal(m, n) 產生維度為 m×n 的 Pascal 矩陣
vander(m, n) 產生維度為 m×n 的 Vandermonde 矩陣 hilb(n) 產生維度為 n×n 的 Hilbert 矩陣
rand(m, n) 產生 [0, 1] 均勻分佈的亂數矩陣,其維度為 m×n
randn(m, n) 產生 µ = 0, σ= 1 的正規分佈亂數矩陣,其維度為 m×n
magic(n) 產生維度為 n×n 的魔方陣,其各個直行、橫列及兩對角線的元素和都相
等
從鍵盤輸入初始化變數
浮點數資料
字元字串型態
3
0
1.3 多維陣列與子陣列
在 MATLAB 的資料型態中,向量可視
為一維陣列,矩陣可視二維陣列,對於
維度 (Dimensions) 超過 1 的陣列則
均可視為「多維陣列」 (Multidimesio
nal Arrays ,簡稱 N-D Arrays) 。
矩陣的索引或下標 (I)
A(i, j)
第 i 橫列、第 j 直行的元素
i 與 j 即是此元素 的下標 ( Subscript )或 索引( Index )
所有矩陣的內部表 示法都是以直行為 主的一維向量
A(i, j) 和 A(i+(j-
1)*m) 是完全一樣的
~m 為矩陣 A 的列數
可以使用一維或
二維下標來存取
矩陣
矩陣的索引或下標 (II)
4
110
61
116
162
218
22
79
124
177
227
35
87
131
185
230
43
94
145
194
2423
513
1013
150
203
25A =
A(2,3 ) A(12
) A(4:5,2:3)
A([ 9 14; 10 15 ])
A(1:5,5 )
A(:,5) A(21;2
5)
A(1:5,en d)
A(:,end) A(21;end
)
1.4 特殊的數值
函式 目 的 pi 代表 到 15 位有效數字的值 i, j 代表 的值
inf 代表無窮大,通常是除以 0 的結果
Nan ` 不是數字’,是由未定義的數學運算而來 eps 電腦上兩個數字間的最小差異
ans 用來儲存一個敘述式的結果
1
1.5 顯示輸出資料
指令格式 結 果 舉 例
format short 顯示 4 位小數 ( 預設值 ) 12.3457
format long 顯示 14 位小數 12.345678901234567
format short e 顯示 5 個數字加冪次方 1.2346e+001 format short g 總共顯示 5 個數字 ( 可加或不加冪次
方 )
12.346
format long e 顯示 15 位小數字加冪次方 1.234567890123457e+001
format long g 總共顯示 15 個數字 ( 可加或不加冪次 方 )
12.3456789012346
format hex 16 位元進位格式 4028b0fcd32f707a
disp
num2st r
轉換數字成字串
>> str = [' The value of pi = ' ,
num2str(pi)];
>> disp(str);
The value of pi = 3.1416
int2st r
轉換整數成字串
>> FileName1 = 'rslt_w';
>> FileName = strcat(FileName1,
int2str(10))
FileName =
fprintf 格式化輸出
fprintf(format, data)
字串:描述輸出資料的方式
一個或多個陣列變數
>> fprintf('The value of pi is %f \n', pi) The value of pi is 3.141593
>> fprintf('The value of pi is %6.2f \n', pi) The value of pi is 3.14
Example/conv_rate/conv_rati o.m 格式字串 說 明
%d 以指數格式顯示數值
%e 以指數格式顯示數值
%f 以浮點數格式顯示數值
%g 以浮點數或指數格式顯示數值,由何者 較短為優先顯示
\n 跳到新的一行
1.6 資料檔案
sav e
loa d
把工作區的資 料存進一個磁 碟檔案中
save filename var1 var2
var3
檔案延伸檔名為 “ .
mat”
把磁碟檔案中 的資料存進工 作區
load
filename
1.7 純量與陣列運算
variable_name = expression;
計算等號右邊敘 述式的結果並將 其儲存於左邊變 數內
ii = ii + 1;
運算方法 MATLAB 形式
加法 a + b
減法 a - b
乘法 a * b
除法 a / b
冪次方 a^b
陣列與矩陣運算
矩陣的加減與一般純量( Scalar )的加減類
似 相加或相減的矩陣必需具有相同的維度
矩陣與純量可以直接進行加減, MATLAB 會 直接將加減應用到每一個元素
>> A = [1 2 3 2 1]
+ 5 A =
6 7 8 7
>> A = [12 34 56 20];
>> B = [1 3 2 4];
>> C = A + B C =
13 37 58 24
矩陣的乘法與除法
純量對矩陣的乘或除,可比照一般寫法
>> A = [123 , 442]; >> C = A/3
>> B = 2*A C =
B = 41.0000 147.3333 246 884
欲進行矩陣相乘,必需確認第一個矩陣的直行 數目( Column Dimension ) 必需等於第 二個矩陣的橫列數目( Row Dimension )
矩陣的除法,常藉由反矩陣或解線性方程式來 達成
>> A = [1; 2];
>> B = [3, 4, 5];
>> C = A * B C =
矩陣的左、右除法
>> A = magic(3) A =
8 1 6 3 5 7 4 9 2
>> b = [1; 2;
3];
A\b :矩陣除法由 inv(A)*b 來定義,其中 i nv(A) 為 A 的反矩陣
>> x = A \ b x =
0.0500 0.3000 0.0500
>> e = A * x - b
e =
1.0e-015 * 0
0 -0.4441
a\B :矩陣除法由 a*inv(B) 來定義
>> y = b' / A y =
-0.0333 0.4667 -0.0333
>> f = y * A - b' f =
1.0e-015 *
0 0.4441 0
矩陣的次方運算
矩陣的次方運算,可由「 ^ 」來達成,但矩陣 必需是方陣,其次方運算才有意義
在「 * 」,「 / 」及「 ^ 」之前加上一個句點
, MATLAB 將會執行矩陣內「元素對元素」
( Element-by-element ) 的運算
>> A =
magic(3);
>> B = A^2 B =
91 67 67 67 91 67 67 67 91
>> A = [12;
45];
>> B = [2; 3];
>> C = A.*B C =
>> D = A./B D =
>> E = A.^2 E =
>> C = A. * B
??? C = A. * B |
Error: Unexpected MATLAB
* 前後不能有任何空
格
轉置和「共軛轉置」矩陣
複數矩陣 z ,其「共軛轉置」矩陣( Conju gate Transpose ) 可表示成矩陣 z'
想得到任何矩陣 z 的轉置( Transpose )
,則可表示成矩陣 z. '
若 z 為實數,則 z' 和 z.' 的結果是一樣的
2.1 邏輯資料型態
運算子 說明
== 等於
~= 不等於
> 大於
>= 大於或等於
邏輯資料型態
true false
關係運算子 邏輯運算子
運算子 說明
& AND
&& 快速求值的 AND
| OR
2.2 分支 (Branching Comman d)
條件指令
if-else switch - case - otherwise if expression
statements
elseif expression
statements else
statements end
switch switch_expr
case case_expr, statements case {case_expr1, case_expr2,...}
statements ...
otherwise,
statements
end
範例:一元二次方程式
2
b x c 0 x
a
0
2
4 a c b
a
ac b
x b
2
2
4
輸入係數 a, b, c
不同的實數根
輸出二次方程式的根
重複的實數根 b 2 4 a c 0
disp ('This program solves for the roots of a quadratic ');
disp ('equation of the form A*X^2 + B*X + C = 0. ');
a = input ('Enter the coefficient A: ');
b = input ('Enter the coefficient B: ');
c = input ('Enter the coefficient C: ');
% Calculate discriminant
discriminant = b^2 - 4 * a * c;
% Solve for the roots, depending on the value of the discriminant if discriminant > 0 % there are two real roots, so...
x1 = ( -b + sqrt(discriminant) ) / ( 2 * a );
x2 = ( -b - sqrt(discriminant) ) / ( 2 * a );
disp ('This equation has two real roots:');
fprintf ('x1 = %f\n', x1);
fprintf ('x2 = %f\n', x2);
elseif discriminant == 0 % there is one repeated root, so...
x1 = ( -b ) / ( 2 * a );
disp ('This equation has two identical real roots:');
fprintf ('x1 = x2 = %f\n', x1);
else % there are complex roots, so ...
real_part = ( -b ) / ( 2 * a );
imag_part = sqrt ( abs ( discriminant ) ) / ( 2 * a );
disp ('This equation has complex roots:');
fprintf('x1 = %f +i %f\n', real_part, imag_part );
fprintf('x1 = %f -i %f\n', real_part, imag_part );
範例:根據月份來判斷其季別 (I)
for month = 1:12 switch month
case {3,4,5}
season = 'Spring';
case {6,7,8}
season = 'Summer';
case {9,10,11}
season = 'Autumn';
case {12,1,2}
season = 'Winter';
end
fprintf('Month %d ===> %s.\n', month, season);
3.1 while 迴圈
迴圈
while for
不確定重複執 確定重複執行 行次數
之次數
while
expression
statements end
for variable = expr
statements
end
範例:統計分析
每個樣品均大於或等於 零,但個數未知
輸入一小於零之樣品值,
做為樣品輸入之結束。
給與
: ,
, ,
21
x x
nx n 個樣品
計算
1
2
1
2
x x
n s
n i
n i
i
i
:標準差
ni
x
ix n
1
1 :算術平均數 while
% Read in first value
x = input('Enter first value: ');
if ( x < 0 )
fprintf('At least one nonnegative value must be entere d!');
else
n = 0; sum_x = 0; sum_x2 = 0;
% While Loop to read input values.
while x >= 0
% Accumulate sums.
n = n + 1;
sum_x = sum_x + x;
sum_x2 = sum_x2 + x^2;
% Read in next value
x = input('Enter next value: ');
end
% Calculate the mean and standard deviation x_bar = sum_x / n;
std_dev = sqrt( (n * sum_x2 - sum_x^2) / (n * (n-1)) );
% Tell user.
fprintf('The mean of this data set is: %f\n', x_bar);
fprintf('The standard deviation is: %f\n', std_dev);
fprintf('The number of data points is: %f\n', n);
end
3.2 for 迴圈
for ii = 1:4
statement 1 …
statement n end
1 2 3 4
ii = 1
statement 1 …
statement n ii = 2
statement 1 …
statement n ii = 3
statement 1 …
statement n ii = 4
statement 1
…
statement
n
for ii = 1:2:6 statement 1 …
statement n end
1 3 5
ii = 1
statement 1 …
statement n ii = 3
statement 1 …
statement n ii = 5
statement 1 …
statement n
end
範例—計算某年的第幾天 (I)
輸入某年某月某日,計算出相對於當年的第幾天
西元年能被 400 除盡,便
是閏年
西元年能被 100 除盡,但
不能被 400 除盡者,不是 閏年
西元年能被 4 除盡,但不
能被 100 除盡者,是閏年
其它西元年,皆不是閏年
if mod(year,400) == 0 leap_day = 1;
elseif mod(year,100)
== 0
leap_day = 0;
elseif mod(year,4) ==
0
leap_day = 1;
else mod(year,400)
= 0
mod(year,100)
= 0
mod(year,4)
= 0
範例—計算某年的第幾天 (II)
day_of_year = day;
for ii = 1:month-1
% Add days in months from January to last
month
switch (ii)
case {1,3,5,7,8,10,12},
day_of_year = day_of_year + 31;
case {4,6,9,11},
day_of_year = day_of_year + 30;
case 2,
day_of_year = day_of_year + 28 + leap_day;
end
預先分配陣列與向量化陣列
n = 20000; tic;
square = zeros(1,n);
for ii = 1:n
square(ii) = ii^2;
end
fprintf('Total cpu time = %g \n',
toc);
n = 20000; tic;
for ii = 1:n
square(ii) = ii^2;
end
fprintf('Total cpu time = %g
\n', toc);
Total cpu time =
1.60449
Total cpu time =0.00066042
n = 20000; tic;ii = 1:n;
square = ii.^2; Total cpu time =
4.1 MATLAB 函式介紹
function [out1, out2, ...] = funname(in1, in2, ...)
statements
輸出引數 函式名稱 輸入引數
儲存之檔案名稱
須與函式名
稱一樣
計算點 (x1,y1) 與點 (x2,y2) 的距離
function distance = dist2(x1, y1, x2, y2)
%DIST2 Calculate the distance between two points
% Function DIST2 calculates the distance between
% two points (x1,y1) and (x2,y2) in a Cartesian
% coordinate system.
%
% Calling sequence:
% distance = dist2(x1, y1, x2, y2)
% Define variables:
% x1 -- x-position of point 1
% y1 -- y-position of point 1
% x2 -- x-position of point 2
% y2 -- y-position of point 2
% distance -- Distance between points
% Calculate distance.
distance = sqrt((x2-x1).^2 + (y2-y1).^2);
儲存之檔案名稱為 dist2.m
H1 comment line
>> lookfor distance
DIST2 Calculate the distance between two points
>> help dist2
DIST2 Calculate the distance between two points Function DIST2 calculates the distance between two points (x1,y1) and (x2,y2) in a Cartesian coordinate system.
Calling sequence:
distance = dist2(x1, y1, x2, y2)
呼叫 dist2
% Get input data.
disp('Calculate the distance between two points:');
ax = input('Enter x value of point a: ');
ay = input('Enter y value of point a: ');
bx = input('Enter x value of point b: ');
by = input('Enter y value of point b: ');
% Evaluate function
result = dist2 (ax, ay, bx, by);
% Write out result.
fprintf('The distance between points a and b is %f\n',result);
function distance = dist2(x1, y1, x2, y2)
4.2 MATLAB 的變數傳遞方式:按值傳 遞
MATLAB 程式使用 pass-by-value 的方
式,進行程式與函式間的溝通聯絡,當
程式呼叫函式時, MATLAB 便複製實質
引數,並傳遞這些實質引數的備份提供
函式使用。
function out = sample(a, b)
fprintf('In sample: a = %f, b = %f %f\n',a,b);
a = b(1) + 2*a;
b = a .* b;
out = a + b(1);
fprintf('In sample: a = %f, b = %f %f\n',a,b);
輸入引數值改變
a = 2; b = [6 4];
fprintf('Before sample: a = %f, b = %f %f\n',a,b);
out = sample(a,b);
fprintf('After sample: a = %f, b = %f %f\n',a,b);
fprintf('After sample: out = %f\n',out);
>> test_sample
Before sample: a = 2.000000, b = 6.000000 4.000000
In sample: a = 2.000000, b = 6.000000 4.000000
In sample: a = 10.000000, b = 60.000000 40.000000
After sample: a = 2.000000, b = 6.000000 4.000000
After sample: out = 70.000000
4.3 選擇性的引數
nargin :決定函式實際輸入變數的個 數
nargout :決定函式實際輸出變數的個 數
nargchk :假如用來呼叫函式的引數太 少或太多,這個函式將傳回一個標準的 錯誤訊息
error :顯示錯誤的訊息,並放棄執行
產生錯誤的函式
使用語法
message = nargchk(min_args, max_args, num_args);
引數的最小數目 引數的最大數目 實際引數的數目 error(‘msg’);
錯誤訊息的字元字串 可與 nargchk 互相搭配,當 程式發生錯誤時,便會產 生一個錯誤訊息
warning(‘msg’);
範例
輸入直角座標 (x,y) ,轉換成極座標 輸 出
如果只輸入一個引數,則函式假設 y 值為 0
如果呼叫此函式的敘述式只有一個輸出引數,則 傳回距離值
) , ( r
angle : angle in degree mag :magnitude
if nargin < 2 y = 0;
end
if nargout == 2
function [mag, angle] = polar_value(x,y)
%POLAR_VALUE Converts (x,y) to (r,theta)
% Check for a legal number of input arguments.
msg = nargchk(1,2,nargin);
error(msg);
% If the y argument is missing, set it to 0.
if nargin < 2 y = 0;
end
% a warning message.
if x == 0 & y == 0
msg = 'Both x and y are zero: angle is meaningless!';
warning(msg);
end
% Now calculate the magnitude.
mag = sqrt(x.^2 + y.^2);
% If the second output argument is present, calculate
% angle in degrees.
if nargout == 2
angle = atan2(y,x) * 180/pi;
end
>> [mag angle] = polar_value
??? Error using ==> polar_value Not enough input arguments.
>> [mag angle] = polar_value(1,-1,1)
??? Error using ==> polar_value Too many input arguments.
>> [mag angle] = polar_value(1) mag =
1 angle = 0
>> [mag angle] = polar_value(1,-1) mag =
1.4142 angle = -45
>> [mag angle] = polar_value(0,0)
Warning: Both x and y are zero: angle is meaningless!
> In polar_value at 32 mag =
0
angle =
0
4.4 含函式的函式
是一種輸入引數包含其他函式名稱的函式,而這些傳入函 式名稱的函式,會在含函式的函式執行過程中,被呼叫來 使用。
fzero :內建函式,找出只含一個變數函式之零點
>> fzero('cos',[0 pi]) ans =
1.5708
>> fzero('exp(x)-2',[0 pi]) ans =
0.6931 function val = exp_2(x)
val = exp(x) - 2;
>> fzero( @exp_2,[0 pi] ) ans =
0.6931
>> fzero('exp_2' ,[0 pi] )
內建函式 eval
eval(string)
eval 會針對 string 字元字串求 值
>> x = eval('sin(pi/4)') x =
0.7071
>> x= 1;
>> str = ['exp(' num2str(x) ') - 1'];
>> res = eval(str) res =
1.7183 for d=1:10
s = ['load August' int2str(d) '.mat']
eval(s) end
s =
load August1.mat s =
load August2.mat s =
load August3.mat - etc. -
內建函式 feval
feval(fun,value)
feval 會針對 M 檔案中的 (fun) 函 式,在特定輸入值 (value) 下計 算其函式值
>> feval('sin',pi/4) ans =
0.7071 function val = exp_2(x)
val = exp(x) - 2;
>> feval( @exp_2, 0) ans =
-1
>> feval('exp_2' , 0) ans =
-1
6.1 繪圖功能簡介
x = 0:0.1:10;
y = x.^2–10.*x+15;
plot(x,y);
title('Plot of y = x.^2-10.*x+15')
grid on;
grid off;
xlabel('x');
ylabel('y');
多重線條繪圖
x = 0:pi/100:2*pi;
y1 = sin(2*x);
y2 = 2*cos(2*x);
plot( x, y1, x, y2 );
plot(x, y1);
hold on;
plot(x, y2);
hold off
線條顏色、形式、資料標記及說明文 字 (I)
plot(x, y1);
hold on;
plot(x, y2);
hold off
plot(x,y1,'ro-.' );
hold on;
plot(x, y2,'gx:');
hold off
legend('sin(2x)','2cos(2x)','Location','NorthW est');
text(1.5, 0.5, 'sin(2x)')
text(3.3, 1.5,
‘2cos(2x)')
線條顏色、形式、資料標記及說明文 字 (II)
x = 0:pi/100:2*pi;
y1 = sin(2*x);
y2 = 2*cos(2*x);
plot(x, y1,'ro-.' );
hold on;
plot(x, y2,'gx:');
hold off
legend('sin(2x)','2cos(2x)','Location','NorthWest');
text(1.5, 0.5, 'sin(2x)') text(3.3, 1.5, '2cos(2x)')
set(gca,'xtick',[0 1/2*pi pi 3/2*pi 2*pi])
額外的繪圖功能
x = -2.5*pi:pi/100:2.5*pi;
y1 = sin(2*x);
y2 = 2*cos(2*x);
plot(x, y1,'ro-.');
hold on
plot(x, y2, 'gx:');
hold off
legend('sin(2x)','2cos(2x)','Location','NorthWest');
text(1.5, 0.5, 'sin(2x)') text(3.3, 1.5, '2cos(2x)') xlabel('x');
ylabel('y');
title('Plot figure of sin(2x) and 2cos(2x)');
set(gca,'xtick',[-2*pi -pi 0 pi 2*pi])
set(gca,'xticklabel',{'-2 pi','- pi','0','pi','2 pi'})
axis([-2*pi 2*pi -2.5 2.5])
axis equal axis square
axis normal
axis of