平臺:Win7 64 bit,Matlab R2014a(8.3)html
「Matlab」是「Matrix Laboratory」 的縮寫,中文「矩陣實驗室」,是強大的數學工具。本文側重於Matlab的編程語言側面,講述Matlab的基本語法,以及用Matlab語言進行程序設計。值得一提的是,Matlab從R2014a版本開始支持中文語言了!程序員
1.基本概念算法
Matlab默認啓動後界面:數據庫
Matlab有關的文件後綴:express
File Extension編程 |
Descriptionapi |
.m數組 |
MATLAB Code — A MATLAB script, function, or class.dom |
.p編程語言 |
MATLAB P-Code — Protected function file. |
.mat |
MATLAB Data — Binary file that stores MATLAB variables. |
.fig |
MATLAB Figure. |
.mdl, .slx |
Simulink Model. |
.mdlp, .slxp |
Simulink Protected Model. |
.mex |
MATLAB MEX — Shared library files that can be dynamically loaded into MATLAB. The MEX-file extensions are platform-dependent. |
參考Matlab R2014a幫助文檔「MathWorks File Extensions」,搜索便可,下同。
命令行執行命令:
能夠在命令行窗口(Matlab默認啓後動界面的中間)中執行命令,除了運算公式外,關閉Matlab、改變當前文件夾、新建.m文件之類的均可以以命令形式執行,下面對最爲經常使用的基本命令進行總結:
Class |
Function |
Description |
Shutdown |
exit, quit |
Terminate MATLAB program |
Search Path |
pwd |
Identify current folder |
cd |
Change current folder |
|
dir, ls |
List folder contents |
|
type |
Display contents of file |
|
what |
List MATLAB files in folder |
|
path |
View or change search path |
|
which |
Locate functions and files |
|
Command History |
clc |
Clear Command Window |
diary |
Save Command Window text to file |
|
Help |
format |
Set display format for output |
help |
Help for functions in Command Window |
|
doc |
Reference page in Help browser |
|
iskeyword |
Determine whether input is MATLAB keyword |
|
WorkSpace |
clear |
Remove items from workspace, freeing up system memory |
clf |
Clear current figure window |
|
pack |
Consolidate workspace memory |
|
who |
List variables in workspace |
|
whos |
List variables in workspace, with sizes and types |
|
save |
Save workspace variables to file |
|
load |
Load data from MAT-file into workspace |
|
Other |
disp |
Display text or array |
display |
Display text or array (overloaded method) |
|
tic, toc |
Start stopwatch timer(Read elapsed time from stopwatch) |
上面全部函數均可以用「help funcName」或「doc funcName」命令查看幫助,參考Matlab R2012a幫助文檔「MATLAB/Functions」。
當前文件夾(Current Folder)和搜索路徑(Search Path):
Matlab之因此強大,很重要的緣由是它實現了不少數學算法,也就是有一個龐大的函數庫。和其餘編程語言同樣,這些函數以實現文件或源文件形式存在(.m,.p,.mex等)。在咱們執行命令(或者說是運行m code)時,例如「y=sin(x)」,Matlab須要搜索「sin」,這就是在「當前文件夾」和「搜索路徑」中進行的。Matlab以「文件名」進行搜索,因此要求函數(Main Function)等名子和文件名相同。
「當前文件夾」就是程序員的工做文件夾,裏面有咱們寫的M代碼,在上圖Matlab默認啓動後界面中「當前文件夾」如紅色框所示,其內容能夠在左側瀏覽。初用Matlab的人可能遇到過這個問題:打開一個.m文件,點擊「運行」按鈕,出現以下提示(若是你的Matlab版本不是最新的,那就是英語提示):
這是由於當咱們點「運行」(或快捷鍵F5)時,其實至關於在命令行執行命令運行文件,Matlab搜索當前文件夾和搜索路徑,但沒找到。
要設置添加搜索路徑,能夠在菜單「主頁 >> 環境 >> 設置路徑」中進行(也能夠用命令形式):
工做區(WorkSpace):
「工做區」相似於棧,是運行Matlab命令(或程序)時在內存產生變量的集合(也就是說它是一塊內存區域),在Matlab默認啓動後界面中顯示在右側。在「工做區」窗口顯示的全部變量,能夠雙擊查看其內容,也能夠修改或刪除。工做區分基本工做區(Base Workspace)和函數工做區(Function Workspace),函數工做區通常在函數調用過程當中產生,咱們通常接觸的就是基本工做區。基本工做區中的變量在關閉Matlab前都不會自動清除,除非用clear命令,因此若是想讓程序不依賴於歷史數據的話,最好在運行程序前執行「clear all」命令。參考Matlab R2014a幫助文檔「Base and Function Workspaces」。
M腳本文件:
全部能夠在命令行窗口中輸入的命令均可以出如今.m文件中,這裏的所謂腳本文件就是咱們一般說的Matlab程序。關於Matlab程序有幾個最爲基本的點須要知道:以「%」開頭的行是註釋;語句後面加「;」可讓Matlab執行語句但不輸出結果;一行代碼太長寫不下用「...」續行;Matlab程序通常是解釋執行,因此有些錯誤在執行時纔會報告。
2.基本語法
首先來看Matlab的符號表(參考Matlab R2014a幫助文檔「Symbol Reference」):
Name |
Symbol |
Description |
Asterisk |
* |
Filename Wildcard |
At |
@ |
Function Handle Constructor Class Folder Designator |
Colon |
: |
Numeric Sequence Range(step) Indexing Range Specifier Conversion to Column Vector Preserving Array Shape on Assignment |
Comma |
, |
Row Element Separator Array Index Separator Function Input and Output Separator Command or Statement Separator |
Curly Braces |
{ } |
Cell Array Constructor Cell Array Indexing |
Dot |
. |
Decimal Point Structure Field Definition Object Method Specifier |
Dot-Dot |
.. |
Parent Folder |
Dot-Dot-Dot (Ellipsis) |
… |
Line Continuation Entering Long Strings Defining Arrays |
Dot-Parentheses |
.( ) |
Dynamic Structure Fields |
Exclamation Point |
! |
Shell Escape |
Parentheses |
( ) |
Array Indexing Function Input Arguments |
Percent |
% |
Single Line Comments Conversion Specifiers |
Percent-Brace |
%{ %} |
Block Comments |
Plus |
+ |
Designate the names of package folders |
Semicolon |
; |
Array Row Separator Output Suppression Command or Statement Separator |
Single Quotes |
‘ ’ |
Character and String Constructor |
Space Character |
Space |
Row Element Separator Function Output Separator |
Slash and Backslash |
/ \ |
Separate the elements of a path or folder string |
Square Brackets |
[ ] |
Array Constructor Concatenation Function Declarations and Calls |
Tilde |
~ |
Not Equal to Logical NOT Argument Placeholder |
下圖清晰的說明了Matlab的基本數據類型(類)(取自Matlab R2014a幫助文檔「Fundamental MATLAB Classes」),其中double是默認數據類型,字符串用單引號‘’:
Matlab是高級動態語言,變量(對象)在使用以前不須要聲明,標識符的第一次出現視爲變量的建立,標識符由字母開頭接字母數字或下劃線的不超過63個字符組成。一個標識符只是一個引用,它能夠指向任意類型,好比執行「a=1」後,a做爲一個名字指向double型變量,再執行「a=’hello’」後,a又指向一個字符串變量,原來的double變量由於再也不引用而進入垃圾回收,這和Python相似。
對於邏輯類型(布爾類型),和C語言相似,Matlab將非 0 數看作 true,0 看作 false,Matlab將邏輯型輸出爲 0 和 1。
Matlab號稱是矩陣實驗室,除了函數句柄和多維數組外,每一個變量都看作是矩陣(二維數組),標量被看作1x1矩陣,一維數組被看作1xN或Nx1矩陣,Matlab支持將矩陣做爲總體進行運算。矩陣的行元素間用空格或逗號「,」分隔,列元素間用回車或分號「;」分隔,矩陣用中括號「[]」表示,索引數組用小括號「()」(從1開始,多維數組各維索引用逗號隔開),以下例所示:
Matlab內置了一些常量或約定名字(參考Matlab R2014a幫助文檔「Special Values」、Matlab R2012a幫助文檔「MATLAB/Functions/Mathematics/Math Constants」):
Name |
Description |
eps |
Floating-point relative accuracy |
i, j |
Imaginary unit |
Inf |
Infinity |
NaN |
Not-a-Number |
pi |
Ratio of circle's circumference to its diameter |
intmax (intmin) |
Largest(Smallest) value of specified integer type |
realmax (realmin) |
Largest positive(Smallest positive normalized) floating-point number |
ans |
Most recent answer (variable) |
Matlab基本算符和表達式(參考Matlab R2014a幫助文檔「Operators and Elementary Operations」、Matlab R2012a幫助文檔「MATLAB/User’s Guide/Programming Fundamentals/Language/Program Components/Operators」、《MATLAB R2011a教程》第3章p130、p13八、p139):
Class |
Description |
Array operator |
Matrix operator |
Arithmetic |
Addition |
+ |
+ |
Subtraction |
- |
- |
|
Multiplication |
.* |
* |
|
Right(Left) division |
./(.\) |
/(\) |
|
Power |
.^ |
^ |
|
Transpose |
.’ |
’ (Complex conjugate transpose) |
|
Relational |
Less than |
< |
|
Less than or equal to |
<= |
|
|
Greater than |
> |
|
|
Greater than or equal to |
>= |
|
|
Equal to |
== |
|
|
Not equal to |
~= |
|
|
Logical |
And |
& |
|
Or |
| |
|
|
Not |
~ |
|
|
Xor |
xor |
|
|
Bit-Wise |
Bit-and |
bitand |
|
Bit-or |
bitor |
|
|
Bit-xor |
bitxor |
|
|
Short-Circuit |
And |
&& |
|
Or |
|| |
|
其中,「數組運算」指的是兩個尺寸相同(行數列數相同)數組(或一個是標量)逐個元素之間進行運算獲得尺寸相同的數組做爲結果,「矩陣運算」則是按照數學上矩陣的運算法則運算。下面是一些例子:
其中,a、b、c 都是double類型,l 是Logical類型(布爾類型數組)。
Matlab和其餘大多數語言相同,有以下控制流(參考Matlab R2014a幫助文檔「Control Flow」),Matlab代碼是Pascal風格的,須要以end結尾:
Class |
Control-Flow |
Syntax |
Remarks |
Conditional Statements |
if-else |
if expression statements elseif expression statements else statements end |
|
switch-case |
switch switch_expression case case_expression statements case case_expression statements ... otherwise statements end |
only one case(or otherwise) statement will be executed |
|
Loop Control Statements |
for |
for index = values program statements : end |
break, continue |
parallel-for |
parfor loopvar = initval:endval; statements; end parfor (loopvar = initval:endval, M); statements; end |
|
|
while |
while expression statements end |
break, continue |
|
Other |
pause |
pause pause(n) pause on pause off pause query state = pause('query') oldstate = pause(newstate) |
|
return |
return |
return to the invoking function or to the keyboard |
|
try-catch |
try statements catch exception statements end |
|
|
assert |
assert(expression) assert(expression, 'msgString') assert(expression, 'msgString', value1, value2, ...) assert(expression, 'msgIdent', 'msgString', value1, value2, ...) |
|
|
warning |
warning('message') warning('message', a1, a2,...) warning('message_id', 'message') warning('message_id', 'message', a1, a2, ..., an) s = warning(state, 'message_id') s = warning(state, mode) |
|
|
error |
error('msgIdent', 'msgString', v1, v2, ..., vN) error('msgString', v1, v2, ...) error('msgString') error(msgStruct) |
|
|
input |
result = input(prompt) (displays the prompt string on the screen, waits for input from the keyboard, evaluates any expressions in the input, and returns the result.) str = input(prompt,'s') (returns the entered text as a MATLAB string, without evaluating expressions.) |
|
|
keyboard |
keyboard (when placed in a program .m file, stops execution of the file and gives control to the keyboard.) |
|
3.函數
Matlab的函數以M函數文件(後綴.m)形式存在,主函數(Main Function,這裏主函數和C語言主函數不一樣,它指該函數文件中第一個定義的函數,能夠理解爲文件的對外接口)名要和文件名相同,一個主函數的例子以下(文件「rank.m」,位於「C:\Program Files\MATLAB\R2014a\toolbox\matlab\matfun\」):
1 function r = rank(A,tol) 2 % RANK Matrix rank. 3 % RANK(A) provides an estimate of the number of linearly 4 % independent rows or columns of a matrix A. 5 % RANK(A,tol) is the number of singular values of A 6 % that are larger than tol. 7 % RANK(A) uses the default tol = max(size(A)) * norm(A) * eps. 8 9 s = svd(A); 10 if nargin==1 11 tol = max(size(A)') * max(s) * eps; 12 end 13 r = sum(s > tol);
上面文件首行以function開頭的稱爲函數聲明行(function declaration line),緊接一行註釋稱爲H1行(用做lookfor指令),H1行及以後的連續註釋稱爲在線幫助文本(help text,用做help指令),再以後的註釋稱爲編寫和修改記錄(上面例子中沒有,用做軟件歸檔管理),以後是函數體。固然,除函數聲明和函數體外其餘都是可選的。
除主函數(main function)外,還有局部函數(Local functions),它定義在M函數文件裏的除第一個位置外的地方(因此,它只能依附在主函數文件中,不能出如今M腳本文件中),它只在該文件內可見,下面是一個例子(取自Matlab R2014幫助文檔「Local Functions」,文件「mystats.m」):
1 function [avg, med] = mystats(x) 2 n = length(x); 3 avg = mymean(x,n); 4 med = mymedian(x,n); 5 end 6 7 function a = mymean(v,n) 8 % MYMEAN Example of a local function. 9 10 a = sum(v)/n; 11 end 12 13 function m = mymedian(v,n) 14 % MYMEDIAN Another example of a local function. 15 16 w = sort(v); 17 if rem(n,2) == 1 18 m = w((n + 1)/2); 19 else 20 m = (w(n/2) + w(n/2 + 1))/2; 21 end 22 end
另外,還有嵌套函數(Nested Functions),顧名思義,它定義在別的函數內,以下例子(取自Matlab R2014幫助文檔「Nested Functions」,文件「parent.m」):
1 function parent 2 disp('This is the parent function') 3 nestedfx 4 5 function nestedfx 6 disp('This is the nested function') 7 end 8 9 end
嵌套函數和其餘函數的區別是,它可使用包含它的父函數的變量,也就是說,它可使用除了參數及在函數內部定義的變量以外的變量,這涉及函數工做區(Function Workspace)的概念,前面說過有個基本工做區,函數調用時產生函數工做區,見例子。
當前文件夾裏有兩個文件:abc.m,f.m,f.m是M函數文件,abc.m是M腳本文件,其內容以下:
1 % f.m 2 function [ out ] = f( x ) 3 out = x^2+6; 4 end
1 % abc.m 2 a = 9; 3 b = 10; 4 c = [1 2 3]; 5 d = f(a); 6 d
運行abc.m後工做區以下(基本工做區):
在f.m中設置以下斷點(第三行紅點):
再運行abc.m,程序停在斷點處,此時工做區和調試界面以下:
咱們能夠類比C語言的函數調用棧來理解函數工做區。想要跨越函數工做區傳遞變量能夠用 global 關鍵字聲明全局共享變量,要在函數內部定義相似C語言的 static 變量,使用 persistent 關鍵字聲明變量。
函數句柄(function_handle)相似於C語言的函數指針,它用「@」來建立,以下是一個例子(接上面):
這樣咱們在調用函數時就能夠這樣寫:
b=fh(a)
有了函數句柄,咱們就能夠建立匿名函數(Anonymous Functions):
sqr = @(x) x.^2; a = sqr(5);
利用nargin和nargout能夠實現以不一樣於函數定義的參數和返回值個數調用函數,例子以下(取自Matlab R2014幫助文檔):
1 % file: addme.m 2 function c = addme(a,b) 3 switch nargin 4 case 2 5 c = a + b; 6 case 1 7 c = a + a; 8 otherwise 9 c = 0; 10 end
1 % file: subtract.m 2 function [dif,absdif] = subtract(y,x) 3 dif = y - x; 4 if nargout > 1 5 disp('Calculating absolute value') 6 absdif = abs(dif); 7 end
利用varargin和varargout能夠實現可變參數和返回值列表,例子以下(取自Matlab R2014幫助文檔):
1 % file: varlist.m 2 function varlist(varargin) 3 fprintf('Number of arguments: %d\n',nargin); 4 celldisp(varargin)
1 % file: sizeout.m 2 function [s,varargout] = sizeout(x) 3 nout = max(nargout,1) - 1; 4 s = size(x); 5 for k=1:nout 6 varargout{k} = s(k); 7 end
Matlab函數的參數只是個符號,它自己能夠是任何類型,能夠是標量或向量或矩陣,能夠在函數內部利用一些內置指令來獲得參數個數類型等信息,這就是說,Matlab的函數自己是多態或是重載的。爲方便進行程序設計,Matlab任然支持顯示的函數重載,參考Matlab R2014a幫助文檔「Types of Functions」、Matlab R2012a幫助文檔「Matlab/Getting Started/Programming/Scripts and Functions/Types of Functions」。
4.矩陣及矩陣化編程
矩陣的建立(參考Matlab R2014a幫助文檔「Array Creation and Concatenation」、《MATLAB R2011a教程》第3章p124):
Function |
Description |
a:b, a:inc:b |
Generating a Numeric Sequence(row vector) |
ones |
Create a matrix or array of all ones |
zeros |
Create a matrix or array of all zeros |
eye |
Create a matrix with ones on the diagonal and zeros elsewhere |
accumarray |
Distribute elements of an input matrix to specified locations in an output matrix, also allowing for accumulation |
diag |
Create a diagonal matrix from a vector |
magic |
Create a square matrix with rows, columns, and diagonals that add up to the same number |
rand |
Create a matrix or array of uniformly distributed random numbers |
randn |
Create a matrix or array of normally distributed random numbers and arrays |
randperm |
Create a vector (1-by-n matrix) containing a random permutation of the specified integers |
矩陣維度信息(參考Matlab R2014a幫助文檔「Array Dimensions」):
Function |
Description |
length |
Length of vector or largest array dimension |
ndims |
Number of array dimensions |
numel |
Number of array elements |
size |
Array dimensions |
isempty |
Determine whether array is empty([ ]) |
isscalar |
Determine whether input is scalar(1x1) |
iscolumn |
Determine whether input is column vector(Nx1) |
isrow |
Determine whether input is row vector(1xN) |
isvector |
Determine whether input is vector |
ismatrix |
Determine whether input is matrix |
矩陣元素索引(indexing,參考Matlab R2014a幫助文檔「Indexing」、《MATLAB R2011a教程》第3章p125):
矩陣的操縱(參考Matlab R2014a幫助文檔「Sorting and Reshaping Arrays」、《MATLAB R2011a教程》第3章p127):
Function |
Description |
diag |
Get diagonal elements or create diagonal matrix |
repmat |
Replicate and tile array |
reshape |
Reshape array |
flipud |
Flip array up to down |
fliplr |
Flip array left to right |
rot90 |
Rotate array 90 degrees |
[ ], =[ ] |
Empty array(delete) |
[a, b], [a; b] |
Concatenate arrays horizontally(vertically) |
矩陣索引例子(《MATLAB R2011a教程》第3章p125 例3.2-6):
A=zeros(2,6) A(:)=1:12 A = 0 0 0 0 0 0 0 0 0 0 0 0 A = 1 3 5 7 9 11 2 4 6 8 10 12 A(2,4) A(8) ans = 8 ans = 8 A(:,[1,3]) A([1,2,5,6]') ans = 1 5 2 6 ans = 1 2 5 6 A(:,4:end) ans = 7 9 11 8 10 12 A(2,1:2:5)=[-1,-3,-5] A = 1 3 5 7 9 11 -1 4 -3 8 -5 12 B=A([1,2,2,2],[1,3,5] ) B = 1 5 9 -1 -3 -5 -1 -3 -5 -1 -3 -5 L=A<3 A(L)=NaN L = 1 0 0 0 0 0 1 0 1 0 1 0 A = NaN 3 5 7 9 11 NaN 4 NaN 8 NaN 12
矩陣操縱例子(《MATLAB R2011a教程》第3章p127 例3.2-七、3.2-8):
a=1:8 A=reshape(a,4,2) A=reshape(A,2,4) a = 1 2 3 4 5 6 7 8 A = 1 5 2 6 3 7 4 8 A = 1 3 5 7 2 4 6 8 b=diag(A) B=diag(b) b = 1 4 B = 1 0 0 4 D1=repmat(B,2,4) D1 = 1 0 1 0 1 0 1 0 0 4 0 4 0 4 0 4 1 0 1 0 1 0 1 0 0 4 0 4 0 4 0 4 D1([1,3],: )=[ ] D1 = 0 4 0 4 0 4 0 4 0 4 0 4 0 4 0 4
A=reshape(1:9,3,3) A = 1 4 7 2 5 8 3 6 9 B=flipud(A) B = 3 6 9 2 5 8 1 4 7 C=fliplr(A) C = 7 4 1 8 5 2 9 6 3 D=rot90(A,2) D = 9 6 3 8 5 2 7 4 1
矩陣化編程:
矩陣的邏輯標示法索引方式,和前面提到的算符和表達式的「數組運算」方式結合能夠產生強大的「矩陣化」編程方式,用這種方式替代循環結構不只能夠簡化代碼,還能夠大大提升代碼執行效率,例子以下。
程序要計算下面的函數:
其中theta在二維下爲10/(7*pi*h^2),函數圖像以下所示(類高斯函數):
下面比較普通循環實現和矩陣實現的效率差異:
% file: w1.m function [ out ] = w1(r, h) if nargin==1 h = 1; end if 0<=r && r<h q = r/(h/2); theta = 10/(7*pi*h^2); if q<=1 out = theta* (1-1.5*q^2+0.75*q^3); else out = theta* (0.25*(2-q)^3); end else out = 0; end end
% file: w2.m function [ out ] = w2(r, h) if nargin==1 h = 1; end theta = 10/(7*pi*h^2); q = r./(h/2); R = 0<=r & r<h; W = q<=1; out = zeros(size(r)); L = R & W; ql = q(L); out(L) = theta* (1-1.5*ql.^2+0.75*ql.^3); L = R & ~W; ql = q(L); out(L) = theta* (0.25*(2-ql).^3); end
% file: abc.m inc = 0.005; x = -1:inc:1; y = x; t = []; % 循環版本 tic; Z = zeros(numel(x),numel(y)); for i=1:numel(x) for j=1:numel(y) Z(i,j) = w1((x(i)^2+y(j)^2)^0.5); end end t = [t,toc]; disp('循環版本時間'); disp(t(1)); % 矩陣版本 tic; [X,Y] = meshgrid(x,y); D = (X.^2+Y.^2).^0.5; Z = w2(D); t = [t,toc]; disp('矩陣版本時間'); disp(t(2)); disp('加速比爲'); disp(t(1)/t(2)); % 繪製時間圖 figure; bar(t,0.2);
運行結果以下:
>> abc 循環版本時間 1.9316 矩陣版本時間 0.0462 加速比爲 41.8445
矩陣化編程的通常思路是利用數學上矩陣運算規則、矩陣的數組運算以及bsxfun函數,必要時輔以矩陣操縱。
字符串,Cell數組,Table,Struct:
字符串,Cell數組,Table,Struct本質上都是數組。字符串的元素是char;Cell數組的元素是cell,cell至關於一個容器,其中能夠存任意類型,如double型矩陣,字符串,甚至是cell,cell 的內容用{}提取;Table有點像數據庫的表;Struct相似於C語言的結構體。請讀者參考Matlab R2014a幫助文檔「Fundamental MATLAB Classes」。
5.總結及進一步學習
進一步的學習內容可能包括Matlab面向對象編程(類)、GUI編程、Simullink等。我最近有可能會再發一篇「Matlab繪圖基礎」,敬請期待。
參考文獻: