690 likes | 983 Views
1 . MATLAB 概述. 1.1 MATLAB 的发展历程和影响. MATLAB 是 MATrix LABoratory (“矩阵实验室”)的缩写,是由美国 MathWorks 公司开发的集 数值计算 、 符号计算 和 图形可视化 三大基本功能于一体,功能强大、操作简单的语言。是国际公认的优秀数学应用软件之一。
E N D
1.MATLAB概述 1.1 MATLAB的发展历程和影响 MATLAB 是MATrix LABoratory(“矩阵实验室”)的缩写,是由美国MathWorks 公司开发的集数值计算、符号计算和图形可视化三大基本功能于一体,功能强大、操作简单的语言。是国际公认的优秀数学应用软件之一。 20世纪80年代初期,Cleve Moler与John Little等利用C语言开发了新一代的MATLAB语言,此时的MATLAB语言已同时具备了数值计算功能和简单的图形处理功能。1984年,Cleve Moler与John Little等正式成立了Mathworks公司,把MATLAB语言推向市场,并开始了对MATLAB工具箱等的开发设计。1993年,Mathworks公司推出了基于个人计算机的MATLAB 4.0版本,到了1997年又推出了MATLAB 5.X版本(Release 11),并在2000年又推出了最新的MATLAB 6版本(Release 12)。 现在,MATLAB已经发展成为适合多学科的大型软件,在世界各高校,MATLAB已经成为线性代数、数值分析、数理统计、优化方法、自动控制、数字信号处理、动态系统仿真等高级课程的基本教学工具。特别是最近几年,MATLAB在我国大学生数学建模竞赛中的应用,为参赛者在有限的时间内准确、有效的解决问题提供了有力的保证。
1.2 MATLAB语言的优点 概括地讲,整个MATLAB系统由两部分组成,即MATLAB内核及辅助工具箱,两者的调用构成了MATLAB的强大功能。MATLAB语言以矩阵为基本数据单位,包括控制流语句、函数、数据结构、输入输出及面向对象等特点的高级语言,它具有以下主要特点: 1)运算符和库函数极其丰富,语言简洁,编程效率高,MATLAB除了提供和C语言一样的运算符号外,还提供广泛的矩阵和向量运算符。 2)既具有结构化的控制语句(如for循环、while循环、break语句、if语句和switch语句),又有面向对象的编程特性。 3)图形功能强大。它既包括对二维和三维数据可视化、图像处理、动画制作等高层次的绘图命令,也包括可以修改图形及编制完整图形界面的、低层次的绘图命令。 4)功能强大的工具箱。工具箱可分为两类:功能性工具箱和学科性工具箱。 5)易于扩充。除内部函数外,所有MATLAB的核心文件和工具箱文件都是可读可改的源文件,用户可修改源文件和加入自己的文件。
2.MATLAB开发环境 ◆ MATLAB 6对硬件的要求 CPU要求:Pentium II、Pentium III、AMD Athlon或者更高; 光驱:8倍速以上; 内存:至少64MB,但推荐128MB以上; 硬盘:视安装方式不同要求不统一,但至少留1GB用于安装; 显卡:8位; ◆ MATLAB 6对软件的要求 Windows95 、Window98、Windows NT或Windows2000; Word97或word2000等,用于使用MATLAB Notebook; Adobe Acrobat Reader 用于阅读MATLAB的PDF的帮助信息。 MATLAB 6的安装和其它应用软件类似,可按照安装向导进行安装。 2.1 MATLAB的安装
与常规的应用软件相同,MATLAB的启动也有多种方式,首先常用的方法就是双击桌面的MATLAB图标,也可以在开始菜单的程序选项中选择MATLAB组件中的快捷方式,当然也可以在MATLAB的安装路径的子目录中选择可执行文件“MATLAB.exe”。与常规的应用软件相同,MATLAB的启动也有多种方式,首先常用的方法就是双击桌面的MATLAB图标,也可以在开始菜单的程序选项中选择MATLAB组件中的快捷方式,当然也可以在MATLAB的安装路径的子目录中选择可执行文件“MATLAB.exe”。 启动MATLAB后,将打开一个MATLAB的欢迎界面,随后打开MATLAB的桌面系统(Desktop)如右图所示。 2.2 MATLAB的启动和退出
运行Matlab将会在计算机显示器上生成一个或者多个窗口。其中标题为MATLAB的窗口是MATLAB主要的图形用户界面,称为MATLAB桌面。与标准的WINDOWS应用程序界面相似,具有标题栏、菜单栏、工具条、状态栏、窗口控制按钮和工作区。在工作区内根据不同的设置将显示一个或者多个不同功能的子窗口,并且同时只有一个窗口是活动的。这些窗口可以通过View菜单来进行打开或关闭,它们的名称及描述如下表所示。运行Matlab将会在计算机显示器上生成一个或者多个窗口。其中标题为MATLAB的窗口是MATLAB主要的图形用户界面,称为MATLAB桌面。与标准的WINDOWS应用程序界面相似,具有标题栏、菜单栏、工具条、状态栏、窗口控制按钮和工作区。在工作区内根据不同的设置将显示一个或者多个不同功能的子窗口,并且同时只有一个窗口是活动的。这些窗口可以通过View菜单来进行打开或关闭,它们的名称及描述如下表所示。 (1) 命令窗口(Command Window) 命令窗口是对MATLAB进行操作的主要载体,默认的情况下,启动MATLAB时就会打开命令窗口。一般来说,MATLAB的所有函数和命令都可以在命令窗口中执行。在MATLAB命令窗口中,命令的实现不仅可以由菜单操作来实现,也可以由命令行操作来执行。 例如: 在命令窗口中输入sin(pi/5),然后单击回车键,则会得到该表达式的值 sin(pi/5) ans= 0.5878 2.3 MATLAB的桌面
(2)历史窗口(Command History) 历史命令窗口是MATLAB6新增添的一个用户界面窗口,默认设置下历史命令窗口会保留自安装时起所有命令的历史记录,并标明使用时间,以方便使用者的查询。而且双击某一行命令,即在命令窗口中执行该命令。 (3) 发行说明书窗口(Launch Pad) 发行说明书窗口是MATLAB6所特有的,用来说明用户所拥有的Mathworks公司产品的工具包、演示以及帮助信息。当选中该窗口中的某个组件之后,可以打开相应的窗口工具包。 (4) 当前目录窗口(Current Directory ) 在当前目录窗口中可显示或改变当前目录,还可以显示当前目录下的文件,包括文件名、文件类型、最后修改时间以及该文件的说明信息等并提供搜索功能。 (5)工作空间管理窗口(Workspace) 工作空间管理窗口是MATLAB的重要组成部分。在工作空间管理窗口中将显示所有目前保存在内存中的MATLAB变量的变量名、数据结构、字节数以及类型,而不同的变量类型分别对应不同的变量名图标。
2.4 MATLAB的帮助系统 完善的帮助系统是任何应用软件必要的组成部分。MATLAB提供了相当丰富的帮助信息,同时也提供了获得帮助的方法。首先,可以通过桌面平台的【Help】菜单来获得帮助,也可以通过工具栏的帮助选项获得帮助。此外,MATLAB也提供了在命令窗口中的获得帮助的多种方法,在命令窗口中获得MATLAB帮助的命令及说明列于下表中。其调用格式为: 命令+指定参数
2.5 注释、标点符号 (1)分号(;) 在一条命令的最后输入一个分号,Matlab就不会在屏幕上显示这条命令的计算结果。 在一行中输入多条命令,则可以用分号来做为间隔,且不显示计算结果。 (2)逗号(,) 在一行中输入多条命令,则可以用逗号来做为间隔,且显示计算结果。 (3)三个连续句点(…) 续行符号,允许一条指令写在多行上。 (4)百分号(%) 在一个百分号后面的所有文本都被看作是一条注释,不被执行。注释语句中不能出现续行符号。
3. MATLAB的数据类型 3.1 变量与常量 MATLAB的数据类型主要包括:数字、字符串、矩阵、单元型数据及结构型数据等。 3.1.1 变量 变量是任何程序设计语言的基本要素之一,MATLAB语言当然也不例外。与常规的程序设计语言不同的是MATLAB并不要求事先对所使用的变量进行声明,也不需要指定变量类型,MATLAB语言会自动依据所赋予变量的值或对变量所进行的操作来识别变量的类型。在赋值过程中如果赋值变量已存在时,MATLAB语言将使用新值代替旧值,并以新值类型代替旧值类型。 在MATLAB语言中变量的命名应遵循如下规则: (1)变量名区分大小写。 (2)变量名长度不超31位,第31个字符之后的字符将被MATLAB语言所忽略。 (3)变量名以字母开头,可以是字母、数字、下划线组成,但不能使用标点。
定义的所有变量的各种信息在Workspace窗口中可以显示出来,包括 Name、Size、Bytes和Class四种信息。通过Who和Whos指令显示出来。 (1)Who 用来显示当前工作区中的所有变量的名称。 >>who Your variables are: ans a b c (2)Whos 将以列表的形式显示所有变量的Name、Size、Bytes和Class四种信息。 >>whos Name Size Bytes Class ans 1x1 8 double array a 1x1 8 double array b 1x1 8 double array c 1x1 8 double array Grand total is 4 elements using 4 bytes (3)Clear [Var] 该指令用来清除工作区中的变量。若不带参数则清除所有的变量,若指定参数则清除指定的变量。
3.1.2 常量 MATLAB语言本身也具有一些预定义的变量,这些特殊的变量称为常量。下表给出了MATLAB语言中经常使用的一些常量值。 在MATLAB语言中,定义变量时应避免与常量名重复,以防改变这些常量的值,如果已改变了某个常量的值,可以通过“clear+常量名”命令恢复该常量的初始设定值(当然,也可通过重新启动MATLAB系统来恢复这些常量值)。
2.4 复数 Matlab功能最强大的特性之一就是它在处理复数的时候,不需要任何其他操作。在Matlab 中,有好几种方式来表示复数,常用的表示方式有如下几种: >>c1=1-2i c1= 1.0000-2.0000i >>c1=1-2j c1= 1.0000-2.0000i >>c2=3*(2-sqrt(-1)*3) c2= 6.0000-9.0000i >>c3=sqrt(-2) c3= 0+1.4142i
>>c4=6+sin(0.5)*i c4= 6.0000-0.4794i >>c5=6+sin(0.5)*j c5= 6.0000-0.4794i 在最后两个例子中,因为只有数字才能和i,j直接连接,sin(0.5)i和sin(0.5)j没有任何意义,所以乘i或者j是必须的。 对复数的数学运算的写法与对实数的数学运算的写法是一样的。 >>c6=(c1+c2)/c3 c6= -7.7782-4.9497i >>c6r=real(c6) c6r= -7.7782 >>c6i=imag(c6) c6i= -4.9497
3.2 矩阵和矩阵运算 3.2.1 简单矩阵 定义一个矩阵,只需要将数值按顺序列表,放在一对方括号中,中间用空格间隔即可。如果将这个列表赋给一个变量,则这个变量即成为一个矩阵。 >> [1.1 2 3 4 5 6 7 8 9 10] ans = Columns 1 through 7 1.1000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 Columns 8 through 10 8.0000 9.0000 10.0000 >> x=[1 2 3 4 5 6 7 8 9 10] x = 1 2 3 4 5 6 7 8 9 10 >> y=8*x y = 8 16 24 32 40 48 56 64 72 80 因为空格将矩阵值分隔开了,所以矩阵元素中的复数中不能间杂空格,除非这种带空格的表达式是用括号括起来的。 [1 -2i 3 4 5+6i] [(1 -2i) 3 4 5+6i] [1-2i 3 4 5+6i]
3.2.2 矩阵寻址或者下标单独的矩阵元素通过下标来访问,用小括号来表示。>> x(3)ans = 3为了同时访问一块数据,使用冒号。>> x(1:6)ans = 1 2 3 4 5 6>> y(5:end)ans = 40 48 56 64 72 80除了可以给出元素的上下边界之外,还可以给出步长。>> x(5:-1:2)ans = 5 4 3 2>> y(3:2:7)ans = 24 40 56还可以通过一个矩阵给定要输出的元素的下标值。>> y([8 4 6 1 1])ans = 64 32 48 8 8
3.2.3矩阵赋值除了利用前一节的赋值列表赋值外,还可以利用冒号(:)表示法来赋值。>> x=(0:0.2:1)*pix = 0 0.6283 1.2566 1.8850 2.5133 3.1416>> x=linspace(0,pi,5) x = 0 0.7854 1.5708 2.3562 3.1416linspace(first,last,num)创建从first开始,到last结束,共num个值的矩阵。>> x=logspace(0,2,6)x = 1.0000 2.5119 6.3096 15.8489 39.8107 100.0000logspace(first,last,num)创建从10first开始,到10last结束,共num个值的矩阵。除了上面的赋值形式之外,还允许使用下面的方式。>>a=[1:6]>>b=[linspace(1,7,5)]>>a=(1:7)' % '为转置运算符>>a=1:5,b=1:2:9>>d=[a(1:2:5) 1 0 1]
3.2.4 矩阵方向 上边创建的矩阵都是一行多列的行向量,也要以创建列向量。>> x=[1;2;3]x = 1 2 3利用转置操作符(’)和点-转置操作符(.’)可以将数组行列互换。对于实数矩阵,两种操作符的效果是等价的。但对于复数来说,(')给出的结果是复数共轭转置,虚部的符号改变。而(.')不进行共轭操作。>> y=x'y = 1 2 3>> y=x.'y = 1 2 3>> d=y+y*id = 1.0000 + 1.0000i 2.0000 + 2.0000i 3.0000 + 3.0000i
>> e=d’e = 1.0000 - 1.0000i 2.0000 - 2.0000i 3.0000 - 3.0000i>> e=d.’e = 1.0000 + 1.0000i 2.0000 + 2.0000i 3.0000 + 3.0000i如果矩阵是多行多列的,可以用下面的方式来创建。>> g=[1 2 3 4;5 6 7 8]g = 1 2 3 4 5 6 7 8>> h=[1 2 3 4 5 6 7 8]h = 1 2 3 4 5 6 7 8
3.2.5 标量-矩阵运算被标量加、减、乘、除都是简单地将这些运算应用到矩阵的所有元素之上。>> 2*g/5+1ans = 1.4000 1.8000 2.2000 2.6000 3.0000 3.4000 3.8000 4.2000 3.2.6 矩阵-矩阵运算当两个矩阵有相同的维数的时候,加、减、乘、除就可以在元素对元素的基础上应用。 >> g+h ans = 2 4 6 8 10 12 14 16 元素对元素的乘、除与普通的乘、除法类似,但使用的点-乘和点-除符号。
>> g.*hans = 1 4 9 16 25 36 49 64>> g./hans = 1 1 1 1 1 1 1 1除此之外,还有点-乘方和点-倒数运算。>> g.^2ans = 1 4 9 16 25 36 49 64>> g.^hans = 1 4 27 256 3125 46656 823543 16777216>> g.^-1ans = 1.0000 0.5000 0.3333 0.2500 0.2000 0.1667 0.1429 0.1250
3.2.7 标准矩阵标准矩阵包括全1矩阵和全0矩阵,单位矩阵,随机矩阵,对角矩阵,以及元素为指定常数的矩阵。>> ones(3)%ones(n):n*n的全1矩阵ans = 1 1 1 1 1 1 1 1 1>> ones(2,4) %ones(r,c):r*c的全1矩阵ans = 1 1 1 1 1 1 1 1>> zeros(3) %zeros(n):n*n的全0矩阵ans = 0 0 0 0 0 0 0 0 0>> zeros(2,4) %zeros(r,c):r*c的全0矩阵ans = 0 0 0 0 0 0 0 0
>> rand(3) %rand(n):n*n的随机矩阵 ans = 0.9501 0.4860 0.4565 0.2311 0.8913 0.0185 0.6068 0.7621 0.8214 >> rand(2,4) %rand(r,c):r*c的随机矩阵 ans = 0.4447 0.7919 0.7382 0.4057 0.6154 0.9218 0.1763 0.9355 >> eye(3) %eye(n):n*n的单位矩阵 ans = 1 0 0 0 1 0 0 0 1 >> eye(2,4) %eye(r,c):r*c的单位矩阵 ans = 1 0 0 0 0 1 0 0 >> a=1:4 a = 1 2 3 4
>> diag(a) ans = 1 0 0 0 0 2 0 0 0 0 3 0 0 0 0 4 >> diag(a,1) ans = 0 1 0 0 0 0 0 2 0 0 0 0 0 3 0 0 0 0 0 4 0 0 0 0 0 >> diag(a,-1) ans = 0 0 0 0 0 1 0 0 0 0 0 2 0 0 0 0 0 3 0 0 0 0 0 4 0 函数diag生成对角矩阵,一个向量可以被放在与矩阵的主对角线平行的任何位置上。
3.2.8 矩阵大小获取数组大小的函数有size,length和numel三个。size(array[,n]):若省略参数n,则函数按顺序返回数组array的行数列数的值;若有参数n,则返回第n维的长度。length(array):返回行数或列数中较大的那个值。numel(array):返回一个数组中元素的总数。 3.2.9 矩阵排序sort(array):返回一个或两个输出,第一个输出是输入参数的升序排列,第二个参数是排序结果的索引。>> x=[7 5 2 1 3 6 4 8]x = 7 5 2 1 3 6 4 8>> xs=sort(x)xs = 1 2 3 4 5 6 7 8
>> [xs,idx]=sort(x) xs = 1 2 3 4 5 6 7 8 idx = 4 3 5 7 2 6 1 8 若要得到矩阵的降序排列,则必须用索引技术将结果前后调换。 >> xsd=xs(end:-1:1) xsd = 8 7 6 5 4 3 2 1 >> idxd=idx(end:-1:1) idxd = 8 1 6 2 7 5 3 4 对二维矩阵排序时,是将每一列单独进行升序排列。若想按行排列,则需要使用第二个参数,sort(array,2)。 若想按某一列为依据,对整个数组进行排序,则可以用如下方法实现。 >>[tmp,idx]=sort(a(:,4)); >>as=a(idx,:)
3.2.10 应用举例例3.1一维矩阵不同赋值方式示例。x=rand(1,5) %产生的均布随机矩阵x =0.9501 0.2311 0.6068 0.4860 0.8913 x(3) %寻访矩阵x的第三个元素。ans =0.6068 x([1 2 5]) %寻访矩阵x的第一、二、五个元素组成的子矩阵。 ans =0.9501 0.2311 0.8913 x(1:3) %寻访前三个元素组成的子矩阵ans = 0.9501 0.2311 0.6068 x(3:end) %寻访除前2个元素外的全部其他元素。end是最后一个元素的下标。 ans = 0.6068 0.4860 0.8913
x(3:-1:1) %由前三个元素倒排构成的子矩阵ans = 0.6068 0.2311 0.9501 x(find(x>0.5)) %由大于0.5的元素构成的子矩阵ans =0.9501 0.6068 0.8913 x([1 2 3 4 4 3 2 1]) %对元素可以重复寻访,使所得矩阵长度允许大于原数矩阵。ans = Columns 1 through 7 0.9501 0.2311 0.6068 0.4860 0.4860 0.6068 0.2311 Column 8 0.9501例3.2 二维矩阵不同赋值方式示例。A=zeros(2,4) %创建的全零矩阵 A = 0 0 0 0 0 0 0 0
A(:)=1:8 %全元素赋值方式 A = 1 3 5 7 2 4 6 8 s=[2 3 5]; %产生单下标矩阵行矩阵 A(s) %由“单下标行矩阵”寻访产生A元素组成的行矩阵 Sa=[10 20 30]' %Sa是长度为3的“列矩阵” A(s)=Sa %单下标方式赋值 ans = 2 3 5 Sa = 10 20 30 A = 1 20 30 7 10 4 6 8 A(:,[2 3])=ones(2) %双下标赋值方式:把A的第2、3列元素全赋为1 A = 1 1 1 7 10 1 1 8
3.3 字符串 3.3.1 字符串的构造 一个字符串就是用单引号括起来的简单文本。每一个字符都是数组中的一个元素,每一个字符用两个字节来存储。 >> t='How about this character string?' t = How about this character string? >> whos Name Size Bytes Class t 1x32 64 char array Grand total is 32 elements using 64 bytes 在数值与字符之间的相互转换,可以使用double和char函数。 >> t='abc' t = abcde >> u=double(t) u = 97 98 99 100 101 >> t=char(u+3) t = defgh
因为字符串矩阵,因此它们可以用Matlab中提供的所有处理工具进行处理。例如:因为字符串矩阵,因此它们可以用Matlab中提供的所有处理工具进行处理。例如: >> u=t(end:-1:1) u = hgfed 函数disp允许显示一个字符串而不用输出字符串的变量的变量名。 >> disp([t u]) defghhgfed 字符串也可以是多行的,但是每一行都必须有相同的列数。因此,需要显式的输入空格,使得所有行的长度相同。 >> v=['abc';'def';'gih'] v = abc def gih >> v=['abc' 'def' 'gih'] v = abc def gih
函数char和strvcat利用各个不同长度的字符串生成多行字符串矩阵。这两个函数的区别在于strvcat忽略空字符串输入,而char遇到空字符串就插入一个空行。例如:函数char和strvcat利用各个不同长度的字符串生成多行字符串矩阵。这两个函数的区别在于strvcat忽略空字符串输入,而char遇到空字符串就插入一个空行。例如: >> v=char('one','','two','three') v = one two three >> v=strvcat('one','','two','three') v = one two three
同行数的字符串矩阵在水平方向上的连接是用函数strcat来实现的。各字符串中填补的空格将被去掉,连接完成之后,再在需要的地方补上空格。例如:同行数的字符串矩阵在水平方向上的连接是用函数strcat来实现的。各字符串中填补的空格将被去掉,连接完成之后,再在需要的地方补上空格。例如: >> a=char('abc','abcdef') a = abc abcdef >> b=char('hijkl','mnopqrst') b = hijkl mnopqrst >> c=strcat(a,b) c = abchijkl abcdefmnopqrst 这样在单独提取c的第一行时,将含有填补的空格可以用deblank将其删除。 >> deblank(c(1,:)) ans = abchijkl
3.3.2 转换函数产生数码字符串最常用的矩阵/字符串转换函数int2str , num2str ,mat2str示例。(1)int2str把整数矩阵转换成串矩阵(非整数将被四舍五入后再转换)>>A=eye(2,4); %生成一个2*4数值矩阵>>A_str1=int2str(A) %转换成2*10串矩阵。可以用size检验。 A_str1 =1 0 0 00 1 0 0 (2)num2str把非整数矩阵转换为串矩阵(常用于图形中,数据点的标识)B=rand(2,4); %生成数值矩阵B3=num2str(B,3) %保持3位有效数字,转换为串 B3 = 0.95 0.607 0.891 0.4560.231 0.486 0.762 0.0185(3)mat2str把数值矩阵转换成输入形态的串矩阵(常与eval指令配用)B_str=mat2str(B,4) %保持4位有效数字,转换为“矩阵输入形式”串 B_str =[0.9501 0.6068 0.8913 0.4565;0.2311 0.486 0.7621 0.0185]
3.3.3 串转换函数fprintf, sprintf, sscanf的用法示例。a=rand(2,2); %产生2*2随机阵s1=num2str(a) %把数值矩阵转换为串矩阵s_s=sprintf(‘%.10e\n’,a) %10数位科学记述串,每写一个元素就换行。 s1 =0.95013 0.606840.23114 0.48598s_s =9.5012928515e-0012.3113851357e-0016.0684258354e-0014.8598246871e-001 fprintf(‘%.5g\\’,a) %以5位数位最短形式显示。不能赋值用。 0.95013\0.23114\0.60684\0.48598\ s_sscan=sscanf(s_s,'%f',[3,2])%浮点格式把串转换成成3*2数值矩阵。 s_sscan = 0.9501 0.4860 0.2311 0 0.6068 0
3.4 单元矩阵和结构 3.4.1 单元矩阵 单元矩阵是元素为单元的Matlab矩阵,在单元矩阵中的每一个单元都可以包含任何的Matlab数据类型,包括数值型矩阵、字符串、符号对象、其他单元矩阵以及结构。例如: >> A(1,1)={[1 2 3;4 5 6;7 8 9]}; >> A(1,2)={2+3i}; >> A(2,1)={'abcdefg'}; >> A(2,2)={12:-2:0} A = [3x3 double] [2.0000+ 3.0000i] 'abcdefg' [1x7 double]
3.4.2 结构 结构允许用户将相异的数据集用一个单一的变量来组织,结构用被称作域的名字来对结构元素进行寻址的,而不是象单元矩阵那样通过数字进行元素寻址。结构用点号形式来访问域中的数据。例如: >> B.i=2.5; >> B.j=[0,1]; >> B.m='--' B = i: 2.5000 j: [0 1] m: '--'
4.MATLAB的程序设计 4.1 流程控制 计算机编程语言和可编程计算器提供许多功能,它允许你根据决策结构控制命令执行流程。 控制流极其重要,因为它使过去的计算影响将来的运算。MATLAB提供三种决策或控制流结构。它们是:For循环,While循环和If-Else-End结构。由于这些结构经常包含大量的MATLAB命令,故经常出现在M文件中,而不是直接加在MATLAB提示符下。
4.1.1 for循环结构 for循环可使一组命令被反复执行一个固定的、预先指定的次数。 For循环的总体结构如下: for x=array (commands) end array中有多少列,在for和end语句之间的(commands)就对应执行多少次。每重复一次,x就被赋值为array的下一个列值;当循环结束时,x=array(:,n)。例如: >> for i=10:-1:1; x(i)=i*i; end >> x x = 1 4 9 16 25 36 49 64 81 100
For循环的其它重要方面是: 1. For循环不能用For循环内重新赋值循环变量n来终止。 » for n=1:10 x(n)=sin(n*pi/10); n=10; end 2. 在For循环内接受任何有效的MATLAB数组。 » data=[3 9 45 6; 7 16 -1 5] data = 3 9 45 6 7 16 -1 5 for n=data x=n(1)-n(2) end
3. For循环可按需要嵌套。 for n=1:5 for m=5:-1:1 A(n,m)=n^2+m^2; end disp(n) end 4. 当有一个等效的数组方法来解给定的问题时,应避免用For循环。 » n=1:10; » x=sin(n*pi/10) 5. 为了得到最大的速度,在For循环(While循环)被执行之前,应预先分配数组。 »x=zeros(1,10); % preallocated memory for x » for n=1:10 x(n)=sin(n*pi/10); end
4.1.2 while循环结构 While 循环以不定的次数求一组语句的值。总体结构如下: while expression (commands) End 只要在表达式expression里的所有元素为真,就执行while和end 语句之间的{commands}。通常,表达式的求值给出一个标量值,但数组值也同样有效。在数组情况下,所得到数组的所有元素必须都为真。
Fibonacci数组的元素满足Fibonacci 规则:a(1)=1,a(2)=1; a(i+1)=a(i-1)+a(i+1)且i>2。现要求该数组中第一个大于10000的元素。 >>a(1)=1;a(2)=1;i=2; while a(i)<=10000 a(i+1)=a(i-1)+a(i); %当现有的元素仍小于10000时,求解下一个元素。 i=i+1; end; >>i,a(i) i = 21 ans = 10946
4.1.3 if-else-end分支结构 很多情况下,命令的序列必须根据关系的检验有条件地执行。在编程语言里,这种逻辑由某种If-Else-End结构来提供。最简单的If-Else-End结构是: if expression {commands} end 如果在表达式中的所有元素为真(非零),那么就执行if和end语言之间的{commands}。 一个简单的分支结构。 >>cost=10;number=12; if number>8 sums=number*0.95*cost; end 在表达式包含有几个逻辑子表达式时,即使前一个子表达式决定了表达式的最后逻辑状态,仍要计算所有的子表达式。
假如有两个选择,If-Else-End结构是: if expression commands evaluated if True else commands evaluated if False end 如果表达式为真,执行第一组命令;如果表达式是假,执行第二组命令。 当有三个或更多的选择时,If-Else-End结构采用形式: if expression1 commands evaluated if expression1 is True elseif expression2 commands evaluated if expression2 is True elseif …… . . . else commands evaluated if no other expression is True end
最后的这种形式,只和所碰到的、与第一个真值表达式相关的命令被执行;接下来的关系表达式不检验,跳过其余的If-Else-End结构。而且,最后的else命令可有可无。最后的这种形式,只和所碰到的、与第一个真值表达式相关的命令被执行;接下来的关系表达式不检验,跳过其余的If-Else-End结构。而且,最后的else命令可有可无。 利用If-Else-End结构来控制,得到一种合理的方法来跳出或中断For循环和While循环。 » EPS=1; » for num=1:1000 EPS=EPS/2; if (1+EPS)<=1 EPS=EPS*2 break end end 当执行break 语句时,MATLAB跳到循环外下一个语句。在现在情况下,它返回到MATLAB的提示符并显示EPS。如果一个break语句出现在一个嵌套的For循环或While循环结构里,那么MATLAB只跳出break所在的那个循环,不跳出整个嵌套结构。
4.1.4 switch-case结构 多分支选择结构,格式如下: switch expression case test_expression1 (commands1) case {test_expression2[,test_expression3[,…]]} (commands2) …… otherwise (commandsn) end expression必须是一个标量或者是一个字符串。 >> switch x case {'Y','y'} y='Yes'; case {'N','n'} y='No'; otherwise y='Error'; end
4.2 关系和逻辑运算符 除了传统的数学运算之外,Matlab还支持关系和逻辑运算。这些操作符和函数的目的是提供求解真/假命题的答案。一个重要的应用是控制基于真/假命题的一系列MATLAB命令(通常在M文件中)的流程,或执行次序。 作为所有关系和逻辑表达式的输入值,Matlab把所有的非0数值当作true,而把0当作false。所有关系和逻辑表达式,如果为真就返回逻辑数组1,如果为假,就返回逻辑数组0。
4.2.1 关系运算符 Matlab的关系运算符包括所有常用的比较运算符,如下表所示: 例如下面的例子: >> A=1:9,B=9-A A = 1 2 3 4 5 6 7 8 9 B = 8 7 6 5 4 3 2 1 0 >> tf=A>=B tf = 0 0 0 0 1 1 1 1 1 >> tf=A==B tf = 0 0 0 0 0 0 0 0 0 >> tf=A<=5 tf = 1 1 1 1 1 0 0 0 0
下面演示,表明如何用特殊的MATLAB数eps来代替在一个数组中的零元素,eps近似为2.2e-16。这种特殊的表达式在避免被0除时是很有用的。下面演示,表明如何用特殊的MATLAB数eps来代替在一个数组中的零元素,eps近似为2.2e-16。这种特殊的表达式在避免被0除时是很有用的。 » x=(-3:3)/3 x = -1.0000 -0.6667 -0.3333 0 0.3333 0.6667 1.0000 » sin(x)./x Warning: Divide by zero ans = 0.8415 0.9276 0.9816 NaN 0.9816 0.9276 0.8415 由于第四个数据是0 ,计算函数sin(x)/x时给出了一个警告。由于sin(0)/0是没定义的,在该处结果返回NaN。用eps替代0以后,再试一次, » x=x+(x==0)*eps; » sin(x)./x ans = 0.8415 0.9276 0.9816 1.0000 0.9816 0.9276 0.8415 现在sin(x)/x在x=0处给出了正确的极限。
4.2.2 逻辑运算符 逻辑运算符提供了将多个关系表达式组合在一起,或者对关系表达式取反的方法,逻辑运算符包括如下表所示的三个。 例如下面的例子: >> A=1:9,B=9-A A = 1 2 3 4 5 6 7 8 9 B = 8 7 6 5 4 3 2 1 0 >> tf=(A>2) & (A<6) tf = 0 0 1 1 1 0 0 0 0 >> tf=(A>8) | (A<3) tf = 1 1 0 0 0 0 0 0 1 >> tf=~(A<5) tf = 0 0 0 0 1 1 1 1 1