《MATLAB5程序设计.ppt》由会员分享,可在线阅读,更多相关《MATLAB5程序设计.ppt(51页珍藏版)》请在三一文库上搜索。
1、第5章 MATLAB程序设计,5.1 脚本文件和函数文件,M文件有两种形式:M脚本文件和M函数文件。,1、M文本编辑器 2、 M文件的基本形式 M脚本文件(Script File) M函数文件(Function File),3、 M脚本文件,脚本文件的特点: (1) 脚本文件中的命令格式和前后位置,与在命令窗口中输入的没有任何区别。 (2) MATLAB在运行脚本文件时,只是简单地按顺序从文件中读取一条条命令,送到MATLAB命令窗口中去执行。 (3) 与在命令窗口中直接运行命令一样,脚本文件运行产生的变量都是驻留在MATLAB的工作空间(workspace)中,可以很方便地查看变量,除非用c
2、lear命令清除。,4、 M函数文件,函数文件的特点: (1) 第一行总是以“function”引导的函数声明行; 函数声明行的格式: function 输出变量列表 = 函数名(输入变量列表) (2) 函数文件在运行过程中产生的变量都存放在函数本身的工作空间; (3) 当文件执行完最后一条命令或遇到“return”命令时,就结束函数文件的运行,同时函数工作空间的变量就被清除; (4) 函数的工作空间随具体的M函数文件调用而产生,随调用结束而删除,是独立的、临时的,在MATLAB运行过程中可以产生任意多个临时的函数空间。,【例5.0】根据不同阻尼系数,编写M脚本文件和M函数文件分别绘制二阶系统
3、的时域曲线。欠阻尼系统的时域输出y与x的关系为:,5.2 程序流程控制,1、 for . end循环结构,语法: for 循环变量= array (表达式) 循环体 end 说明:array可以是向量也可以是矩阵,循环变量依次取array的各列,每取一次循环体执行一次。循环体被循环执行,执行的次数就是array的列数。,【例5.1】使用for . end循环的array向量编程求出 1+3+5.+99 的值。 % EX0501 使用向量for循环 sum=0; for n=1:2:99 sum=sum+n; end sum,2、 while . end循环结构,语法: while 表达式 循环
4、体 end 说明:只要表达式为逻辑真,就执行循环体;一旦表达式为假,就结束循环。表达式可以是向量也可以是矩阵,如果表达式为矩阵则当所有的元素都为真才执行循环体,如果表达式为nan,MATLAB认为是假,不执行循环体。表达式矩阵通常是11的关系表达式。,*注意: for . end循环的循环次数是确定的,而while . end循环的循环次数不确定。,【例5.2】与【例5.1】相同,计算1+3+5.+99 的值。,% 使用while循环 sum=0; n=1; while n=99 sum=sum+n; n=n+2 ; end sum n sum = 2500 n = 101,3、 Ifelse
5、end条件转移结构,语法: if 条件式1 语句段1 elseif 条件式2 语句段2 . else 语句段n+1 end 说明:当有多个条件时,条件式1为假再判断elseif的条件式2,如果所有的条件式都不满足,则执行else的语句段n+1,当条件式为真则执行相应的语句段;Ifelseend结构也可以是没有elseif和else的简单结构。,条件转移结构框图,if,elseif,elseif,else,【例5.3】用If结构执行二阶系统时域响应。根据阻尼系数01和=1两种情况,得出不同的时域响应表达式:,function y=Ex0503(zeta) % EX0503 使用if结构的二阶系统
6、时域响应 x=0:0.1:20; if (zeta0) end plot(x,y),4、 switchcase开关结构,语法: switch 开关表达式 case 表达式1 语句段1 case表达式2 语句段2 . otherwise 语句段n end,说明: (1) 将开关表达式依次与case后面的表达式进行比较,如果表达式1不满足,则与下一个表达式2比较,如果都不满足则执行otherwise后面的语句段n;一旦开关表达式与某个表达式相等,则执行其后面的语句段。 (2) 开关表达式只能是标量或字符串。 (3) case后面的表达式可以是标量、字符串或元胞数组,只要某个元素与开关表达式相等,就
7、执行其后的语句段。,【例5.4】用switchcase开关结构得出各月份的季节。 % Li 05 使用switch结构 for month=1:12; switch month case3,4,5 season=spring case6,7,8 season=summer case9,10,11 season=autumn otherwise season=winter end end,5、 try. catch. end试探结构,语法: try 语句段1 catch 语句段2 end 说明:首先试探性地执行语句段1,如果在此段语句执行过程中出现错误,则将错误信息赋给保留的lasterr变量,
8、并放弃这段语句,转而执行语句段2中的语句,当执行语句段2又出现错误,则终止该结构。,【例5.5】用try. catch. end结构来进行矩阵相乘运算。,% EX0505 try结构 n=4; a=magic(n); m=3; b=eye(m); try c=a*b catch c=a(1:m,1:m)*b end lasterr,c = 16 2 3 5 11 10 9 7 6 ans = Error using = * Inner matrix dimensions must agree.,6、流程控制语句,(1) break命令 break命令可以使包含break的最内层的for或whi
9、le语句强制终止,立即跳出该结构,执行end后面的命令,break命令一般和If结构结合使用。,【例2.4】计算1+3+5.+100 的值,当和大于1000时终止计算。 % EX0509 用break终止while循环 sum=0; n=1; while n=100 if sum1000 sum=sum+n; n=n+2; else break end end sum n,当程序进入死循环,可按Ctrl+Break组合键终止程序运行,(2) continue命令 continue命令用于结束本次for或while循环,只结束本次循环而继续进行下次循环。例 (3) return命令 return
10、命令是终止当前命令的执行,并且立即返回到上一级调用函数或等待键盘输入命令,可以用来提前结束程序的运行。 (4) pause命令 pause命令用来使程序运行暂停,等待用户按任意键继续。 语法: pause %暂停 pause(n) %暂停n秒 (5) keyboard命令 keyboard命令用来使程序暂停运行,等待键盘命令,执行完自己的工作后,输入return语句,程序就继续运行。,(6) input命令 input命令用来提示用户应该从键盘输入数值、字符串和表达式,并接受该输入。,a=input(input a number:) %输入数值给a input a number:45 a =
11、45 b=input(input a number:,s) %输入字符串给b input a number:45 b = 45 input(input a number:) %将输入值进行运算 input a number:2+3 ans = 5,例5.6 求100,200之间第一个能被21整除的整数。 程序如下: for n=100:200 if rem(n,21)=0 continue end break end n,5.2 循环结构与动画,一、以电影方式产生动画,该方式是以图像的方式预存多个画面,再将这些画面逐帧播放,得到动画效果。,步骤:,(1) 使用getframe命令来抓取图形作为
12、画面,每个画面都是以一个列向量的方式,置于存放整个电影的矩阵M中。 (2) 使用movie(M,k)命令来播放电影,并可指定矩阵M播放的重复次数k。,二、以对象方式产生动画,1擦除属性Erase Mode 以对象方式产生动画需要设置EraseMode属性,EraseMode为一个字符串,代表对象的擦除方式,即对于旧对象的处理方式。EraseMode属性有: xor:将旧对象的点以xor的方式还原,即只画与屏幕色不一致的新对象点,擦除不一致的原对象点,这种方式不会擦除被擦对象下面的其他图像。 background:将旧对象的点变成背景颜色,实现擦除,这种方式会擦除被擦对象下面的其他图像。 non
13、e:保留旧对象的点,不做任何擦除。,以对象方式产生动画就是擦除旧对象,产生相似但不同的新对象。使用句柄图形的概念,对其中选的对象可以通过属性设置进行修改。,2对象的位置属性,通常在动画过程中,会改变对象的位置或尺寸、颜色等外观属性,位置属性有: xdata:为一个向量,代表对象的x坐标值。 ydata:为一个向量,代表对象的y坐标值。,3屏幕刷新 当新对象的属性设置后,应刷新屏幕,使新对象显示出来,刷新屏幕用drawnow命令实现。 也可使用pause命令暂停。,产生动画的具体步骤是: (1) 先产生一个对象,其EraseMode属性为xor、background或none; (2) 在循环中
14、产生动画,每次循环改变此对象的xdata或ydata(或两者); (3) 使用drawnow命令刷新屏幕,例 使用对象方式产生用一个红色小球沿曲线 运动的动画。,5.3 函数调用和参数传递,子函数 在一个M函数文件中,可以包含一个以上的函数,其中只有一个是主函数,其它则为子函数。 (1) 在一个M文件中,主函数必须出现在最上方,其后是子函数,子函数的次序无任何限制; (2) 子函数不能被其它文件的函数调用,只能被同一文件中的函数(可以是主函数或子函数)调用; (3) 同一文件的主函数和子函数变量的工作空间相互独立; (4) 用help和lookfor命令不能提供子函数的帮助信息。,1、子函数和
15、私有函数,【例5.11】将画二阶系统时域曲线的函数作为子函数,编写画多条曲线的程序。,function Ex0511() % EX0511 使用函数调用绘制二阶系统时域响应 z1=0.3; Ex0502(z1); %调用Ex0502 hold on z1=0.5 Ex0502(z1) %调用Ex0502 z1=0.707; Ex0502(z1) %调用Ex0502 function y=Ex0502(zeta) %子函数,画二阶系统时域曲线 x=0:0.1:20; y=1-1/sqrt(1-zeta2)*exp(-zeta*x).*sin(sqrt(1-zeta2)*x+acos(zeta)
16、plot(x,y),私有函数是指存放在private子目录中的M函数文件,具有以下性质: (1) 在private目录下的私有函数,只能被其父目录的M函数文件所调用,而不能被其它目录的函数调用,对其它目录的文件私有函数是不可见的,私有函数可以和其它目录下的函数重名; (2) 私有函数父目录的M脚本文件也不可调用私有函数; (3) 在函数调用搜索时,私有函数优先于其它MATLAB路径上的函数。,私有函数,调用函数的搜索顺序,在MATLAB中调用一个函数,搜索的顺序如下: 查找是否子函数; 查找是否私有函数; 从当前路径中搜索此函数; 从搜索路径中搜索此函数。,2、 局部变量和全局变量,局部(Lo
17、cal)变量:它存在于函数空间内部的中间变量,产生于该函数的运行过程中,其影响范围也仅限于该函数本身 。函数文件中的变量都是局部变量。,全局(Global)变量:命令文件中的变量都是全局变量。通过 global 指令,MATLAB允许几个不同的函数空间以及基本工作空间共享同一个变量,这种被共享的变量称为全局变量。,【例5.12】在主函数和子函数中使用全局变量。,function Ex0512() % EX0512 使用全局变量绘制二阶系统时域响应 global X X=0:0.1:20; z1=0.3; Ex0502(z1); hold on z1=0.5; Ex0502(z1); z1=0.
18、707; Ex0502(z1); function Ex0502(zeta) %子函数,画二阶系统时域曲线 global X y=1-1/sqrt(1-zeta2)*exp(-zeta*X).*sin(sqrt(1-zeta2)*X+acos(zeta); plot(X,y);,建议把全局变量的定义放在函数体的开始,全局变量用大写字符命名。,3、 函数调用,在MATLAB中,调用函数的常用形式是:,输出参数1,输出参数2, = 函数名(输入参数1,输入参数2, ),函数调用可以嵌套,一个函数可以调用别的函数,甚至调用它自己 (递归调用)。 函数调用过程实际上就是参数传递的过程。,【例5.13】
19、画二阶系统时域的函数,使用输入输出参数来实现参数传递。,function Ex0513() % EX0513 参数传递绘制二阶系统时域响应 z1=0.3; x1,y1=Ex0502(z1); plot(x1,y1) hold on z1=0.5; x2,y2=Ex0502(z1); plot(x2,y2) z1=0.707; x3,y3=Ex0502(z1); plot(x3,y3);,function x,y=Ex0502(zeta) %子函数,画二阶系统时域曲线 x=0:0.1:20; y=1-1/sqrt(1-zeta2)*exp(-zeta*x).*sin. (sqrt(1-zeta2
20、)*x+acos(zeta);,图5.3 参数传递,4、函数参数的个数,MATLAB在函数调用上有一个与众不同之处 : 函数所传递的参数数目具有可调性 。,传递参数数目的可调性来源于如下两个MATLAB特殊变量:,函数体内的 nargin 给出调用该函数时的输入参数数目。,函数体内的 nargout 给出调用该函数时的输出参数数目。,只要在函数文件中包括这两个变量,就可以知道该函数文件调用时的输入参数和输出参数数目。,注意:nargin、 nargout 本身都是函数,不是变量,所以用户不能赋值,也不能显示。,还有两个特殊变量:varargin 、 varargout。可以获得输入输出变量的各
21、元素内容,具有接受 “任意多输入” 、返回“任意多输出”的能力 。,【例5.14】计算两个数的和,根据输入的参数个数不同使用不同的运算表达式。,function sum,n=Ex0514(x,y) % EX0514 参数个数可变,计算x和y的和 if nargin=1 sum=x+0; %输入一个参数就计算与0的和 elseif nargin=0 sum=0; %无输入参数就输出0 else sum=x+y; %输入的是两个数则就计算和 end,【例5.17】根据阻尼系数绘制不同二阶系统的时域响应,当欠阻尼时, 当临界阻尼时, 当过阻尼时,,四、 M文件的调试,编写 M文件时,错误(Bug)在
22、所难免。错误有两种:语法(Syntax)错误和运行(Run-time)错误。,语法错误是指变量名、函数名的误写,标点符号的缺、漏等。对于这类错误,通常能在运行时发现,终止执行,并给出相应的错误原因以及所在行号。,运行错误是算法本身引起的,发生在运行过程中。相对语法错误而言,运行错误较难处理 。尤其是M函数文件,它一旦运行停止,其中间变量被删除一空,错误很难查找。,启动调试工具: m-文件编辑器中的Debug工具 设置断点监控 检查变量 继续调试,工具调试法:,五、 M文件性能的优化和加速,1. P码文件的生成 P码文件使用pcode命令生成,生成的P码文件与原M文件名相同,其扩展名为“.p”。
23、 语法: P code Filename.m %在当前目录生成Filename.p pcode Filename.m -inplace %在Filename.m所在目录生成Filename.p pcode Ex0517.m 则在当前目录生成了P码文件Ex0517.p 2. P码文件的特点 (1) P码文件的运行速度比原M文件速度快 (2) 存在同名的M文件和P码文件时则P码文件被调用 (3) P码文件保密性好 用字处理软件打开Ex0517.p文件,看到的是乱码。,(一) P码文件,1. 使用循环时提高速度的措施 2. 大型矩阵的预先定维 3. 优先考虑内在函数 4. 采用高效的算法 5. 尽量
24、使用M函数文件代替M脚本文件,(二) M文件性能优化,使用循环时提高速度的措施:,循环语句及循环体是MATLAB编程的瓶颈问题,改进这种状况有三种方法: 尽量用向量的运算来代替循环操作。 在必须使用多重循环的情况下,如果两个循环执行的次数不同,则建议在循环的外环执行循环次数少的,内环执行循环次数多的,也可以显著提高速度。 循环前给予适当的尺寸定义。,(三)测定程序执行时间和时间分配 使用程序性能剖析窗口,(1) 打开程序性能剖析窗口 选择菜单“Desktop”“Profiler”; 使用在命令窗口输入“profile viewer”命令 (2) 对MATLAB的命令进行剖析 (3) 查看剖析报
25、告,例5.8 计算1到50000之间整数的正弦值,程序ex05081 X=1:50000 %预定了数组的大小 Y=sin(X) 程序ex05082 i=1 While i=50000 x(i)=i y(i)=sin(x(i) i=i+1 end,练习: 鸡兔同笼问题:鸡和兔子关在一个笼子里,已知共有36头,脚100个,求笼内关了多少只兔子和多少只鸡?,(四)内联函数,1. 内联函数的创建 创建内联函数可以使用inline命令实现。 语法: inline(string,arg1,arg2,) %创建内联函数 说明:string必须是不带赋值号(“=”)的字符串;arg1和arg2是函数的输入变量
26、。,【例5.19】创建内联函数实现。 f=inline(sin(x)*exp(-z*x),x,z) %创建内联函数 f = Inline function: f(x,z) = sin(x)*exp(-z*x) y=f(5,0.3) %调用函数f y = -0.2140,3. 使内联函数适用于数组运算 内联函数的输入变量不能是数组,但可以使用vectorize命令将内联函数适用于数组运算。 语法: vectorize(inline_fun) %使内联函数适用于数组运算 【例5.19续】使内联函数适用于数组运算。 ff=vectorize(f) %使内联函数f转换为适合数组运算 ff = Inli
27、ne function: ff(x,z) = sin(x).*exp(-z.*x) x=0:0.1:20; y=ff(x,0.3); 4. 执行内联函数 内联函数还可以直接使用feval命令执行。 语法: y1,y2,=feval(inline_fun,arg1,arg2) 【例5.19续】执行内联函数。 x=0:0.1:20; z=0:0.05:10; y=feval(ff,x,z),(五)利用函数句柄执行函数,1. 函数句柄的创建 语法: h_fun=fun %创建函数句柄 h_fun=str2func(fun) %创建函数句柄 h_array=str2func(fun1,fun2,) %
28、创建函数句柄数组 说明:fun是函数名,h_fun是函数句柄,h_array是函数句柄数组。,【例5.20】创建MATLAB内部函数的句柄。 h_sin=sin; %创建函数句柄 h_cos=str2func(cos); %创建函数句柄数组,2. 使用函数句柄的优点,(1) 在更大范围调用函数 函数句柄包含了函数文件的路径和函数类型,即函数是否为内部函数、M或P文件、子函数、私有函数等,因此无论函数所在的文件是否在搜索路径上,是否是当前路径,是否是子函数或私有函数,只要函数句柄存在,函数就能执行。 (2) 提高函数调用的速度 不使用函数句柄时,对函数的每次调用都要为该函数进行全面的路径搜索,直
29、接影响了速度。 (3) 使函数调用象使用变量一样方便、简单。 (4) 可迅速获得同名重载函数的位置、类型信息。,3. 用feval命令执行函数,函数可以使用feval命令直接执行,feval命令可以使用于函数句柄或函数名。 语法: y1,y2,=feval(h_fun,arg1,arg2) y1,y2,=feval(funname,arg1,arg2) 说明:h_fun是函数句柄,funname是函数名,arg1、arg2是输入参数,y1、y2是输出参数。,【例5.21】将【例5.17】编写的绘制二阶系统时域响应曲线中的调用各子函数改为利用函数句柄实现。 function y=Ex0521(z
30、1) % EX0521 利用函数句柄执行函数,二阶系统时域响应 t=0:0.1:20; h_plotxy1=str2func(plotxy1) %创建函数句柄 h_plotxy2=str2func(plotxy2) %创建函数句柄 h_plotxy3=str2func(plotxy3 %创建函数句柄 if (z1=0) plot(x,y3),在MATLAB的命令窗口调用该Ex0521函数有三种格式:,(1) 用feval命令利用函数句柄执行 h_Ex0521=str2func(Ex0521) h_Ex0521 = Ex0521 y=feval(h_Ex0521,1); h_plotxy1 =
31、plotxy1 (2) 用feval命令利用函数名执行 y=feval(Ex0521,1); (3) 直接调用函数 y=Ex0521(1);,(六)利用泛函命令进行数值分析,在MATLAB中,所有以函数为输入变量的命令,都称为泛函命令。 常见语法: 输出变量列表=函数名(h_fun,输入变量列表) 输出变量列表=函数名(funname,输入变量列表) 说明:h_fun是要被执行的M函数文件的句柄,或者是内联函数和字符串;funname是M函数文件名。,求极小值,1. fminbnd函数 fminbnd函数是求单变量无约束非线性函数的最小值。 语法: x,y=fminbnd(h_fun,x1,x2,options) x,y=fminbnd(funname,x1,x2,options) 说明:h_fun是函数句柄,funname是函数名,必须是单值非线性函数;options是用来控制算法的参数向量,默认值为0可省略;x是fun函数在区间x1xx2上的局部最小值的发生点;y是对应的最小值。,2. fminsearch函数 fminsearch函数是求多变量无约束非线性最小值。 语法: x=fminsearch(h_fun,x0) x=fminsearch(funname,x0) 说明:x0是最小值点的初始猜测值。,
链接地址:https://www.31doc.com/p-3650494.html