平台:Win7 64 bit,Matlab R2014a(8.3)
“Matlab”是“Matrix Laboratory” 的缩写,中文“矩阵实验室”,是强大的数学工具。本文侧重于Matlab的编程语言侧面,讲述Matlab的基本语法,以及用Matlab语言进行程序设计。值得一提的是,Matlab从R2014a版本开始支持中文语言了!
1.基本概念
Matlab默认启动后界面:
Matlab有关的文件后缀:
File Extension |
Description |
.m |
MATLAB Code — A MATLAB script, function, or class. |
.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、p138、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-7、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
字符串,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绘图基础”,敬请期待。
参考文献:
原文:http://www.cnblogs.com/liangliangh/p/3734261.html