资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,MATLAB,与科学计算,第,5,章 程序设计,本章要点,1.M,文件介绍,2.,控制语句,3.,程序的调试,5,.1,M,文件介绍,5.2,控制语句,5,.3,函数变量及变量作用域,5,.4,子函数与局部函数,5,.5,程序设计的辅助函数,5.6,程序设计的优化,5.7,程序调试,5.8,函数句柄,5.9,文件格式与读写,本章主要内容,5.1 M,文件介绍,本节主要内容,1 M,文件的特点与形式,2,命令式文件,3,函数式文件,M,文件,两种形式:命令形式(,Script,),函数形式(,Function,),命令式,M,文件就是命令行的简单叠加,,MATLAB,自动按顺序执行文件中的命令;,函数式文件主要解决参数传递和函数调用的问题,以,function,语句为引导。,1 M,文件的特点与形式,命令式,M,文件在运行过程中可以调用,MATLAB,工作域内所有的数据,而且,所产生的所有变量均为全局变量,直到用户执行,clear,命令清除;,函数式文件中所有变量除特殊声明,均为局部变量。,命令式,M,文件,编制时,只需要把所要执行的命令按行编辑到指定的文件中,变量不需要预先定义,不存在文件名对应问题。,2,命令式,M,文件,提示:,标点符号要运用恰当;,注意程序的书写风格,保持程序的可读性;,要以,m,为文件扩展名,在低版本的,matlab,中,文件名不要超过,8,位。,3,函数式文件,函数式,M,文件,实现计算中的参数传递;,标志是第一行为,function,语句;,函数式文件可以有返回值,也可以只执行操作而无返回值。,函数式,M,文件,function,返回变量列表,=,函数名,(,输入变量列表,),注释说明语句段,函数体,提示:,第一行为,function,语句;,function,后定义函数名和输入输出参数,函数被调用时按此格式执行;,文件名必须与函数名一一对应;,函数执行完后,只保留返回结果,不保留中间过程;,例:,function f=,fibfun(n,),%FIBFUN for calculating,fibonacci,numbers.,%,Incidengtally,the name,fibonacci,comes from,%,Filius,Bonassi,or son of,Bonassus,%,fibfun.m,if n2,f=fibfun(n-1)+fibfun(n-2);,else,f=1;,end,help,fibfun,FIBFUN for calculating,fibonacci,numbers.,Incidengtally,the name,fibonacci,comes from,Filius,Bonassi,or son of,Bonassus,fibfun.m,lookfor,fib,FIBFUN for calculating,fibonacci,numbers.,注:为了利用,MATLAB,的关键字搜索功能,应该在,M,文件的第一行注释中,尽可能多的包含函数的特征信息。,5.2,控制语句,本节主要内容,1,循环语句,2,选择语句,3,分支语句,4,人机交互语句,1,循环语句,循环语句,对于有规律的重复运算,要用循环语句来进行控制;,循环体:一组被重复执行的语句;,循环的终止条件:判断是继续执行循环还是终止执行跳出循环;,有两种方式:,for,循环和,while,循环。,for,循环,特点:循环判断条件是对循环次数的判断,即循环次数是 预先定义好的。,for,循环变量,=s1:s3:s2,循环体语句组,end,说明:,for,语句一定要有,end,结束标志;,循环语句中要用“;”防止中间结果的输出;,书写时采用锯齿结构以增加可读性;,例:求,mysum,=0;,for i=1:1:100,mysum,=,mysum+i,;,end;,mysum,求取,s1,的值,i,i,在,s1,和,s2,之间?,循环体语句组,i+s3-i,是,否,结束循环,for,循环的一般形式,for v=,vect,statements,end,vect,为任意给定的向量,则循环变量从向量的第一个数值一直循环到最后一个数值。,例,1(,见前例,),:,mysum,=0;,v=1:100;,for i=,v;mysum,=,mysum+i;end,mysum,例,2,:,x=;for i=Hello,x=i x;end,x,while,循环,while,逻辑变量,循环体语句组,end,例(见前例):,mysum,=0;i=1;,while(i10000),break;end,mysum,=,mysum+m,;,end,m,mysum,if,条件式,条件块语句组,1,else,条件块语句组,2,end,条件语句组,语句组,1,语句组,2,是,否,例:多项式加,p1=1 5 4;p2=1 6 11 6;,n1=length(p1);n2=length(p2);,if n1,r=,input(How,many apples:),How many apples:2,r=,2,r=,input(Whats,your,name?,s,),Whats your,name?Gundam,r=,Gundam,yesinput,智能输入命令,answer=,yesinput(question,default,possib,),question,为屏幕提示问题,,default,为默认值,,possib,为检验范围。,请求键盘输入命令,keyboard,当程序遇到此命令时,暂停执行程序并等待键盘输入状态。处理完毕后,键入,return,并回车,程序将继续运行。,通常用来对程序调试及在程序中修改变量。,等待用户反应命令,pause,使程序暂时终止运行,等待用户按任意键后继续运行。,pause,暂停程序,等待回应;,pause(n,),等待,n,秒后继续执行;,pause on,显示并执行,pause,命令;,pause off,显示但不执行,pause,命令。,中断命令,break,用在循环语句或条件语句中,使得不必等待循环的自然结束。,例:鸡兔同笼,头有,36,,,脚共,100,,求鸡兔各多少?,i=1;,while i,if rem(100-i*2,4)=0&(i+(100-i*2)/4)=36,break;,end,i=i+1;,end,chicken=i,rabit,=(100-2*i)/4,执行后结果为:,chicken=,22,rabit,=,14,5.3,函数变量及变量作用域,MATLAB,语言的函数中,主要有输入变量、输出变量和内部变量;,输入变量是函数的入口数据,是函数操作的主要对象;,函数的作用就是对输入变量进行操作以实现一定的功能。,nargin,函数,控制输入变量的个数,例:编制函数,test1,实现如下功能:如果只提供一个输入变量,则求该输入变量的模,如果有两个输入变量则求它们的和。,function c=test1(a,b),if(nargin,=1),c=,det(a,);,elseif,(,nargin,=2),c=,a+b,;,end,test1(4,5),ans,=,9,test1(6),ans,=,6,运行结果,varargin,可以实现不定数目的输入变量的函数,函数的一切输入变量均存储在单元数组,varargin,中。,与之相对应,输出变量也有相应的函数,如:,nargout,、,varargout,等。,test(90,80,70,100),maavg,=,80,engavg,=,90,test(90,80,70,100,85,78),maavg,=,81.6667,engavg,=,86,可以实现不定数目输入变量的计算,变量作用域,函数内部定义的变量均为局部变量,如果需要使用全局变量,则应当使用命令,global,定义,并且在任何使用该全局变量的函数中都应加以定义。,定义全局变量时,变量之间必须用空格分隔,不能以逗号分隔。,global,firstlevel,secondlevel,firstlevel=85,;,secondlevel=75,;,a,b,c,=test3(90,89,60,79,89,60,99,98,100),a=,1,b=,2,c=,0,在命令窗口中的运行:,5.4,子函数与局部函数,函数文件中题头定义的函数为主函数,在函数体内定义的其他函数即为子函数。子函数只能为主函数或同一主函数下其他的子函数所调用。,function c=,test(a,b,)%main function,c=test1(a,b)*test2(a,b);,function c=test1(a,b),%,sub function,c=,a+b,;,function c=test2(a,b),%,sub function,c=a-b;,放置于目录,private,下的函数称为局部函数,这些函数只有,private,目录的父目录中的函数才可以调用,其他目录的函数不能调用。局部函数与一般函数文件的编辑相同。,MATLAB,在调用函数时,首先检测该函数是否为此文件的子函数;如果不是,再检测是否为可用的局部函数;如果仍不是,则检测,MATLAB,搜索路径中其他的,M,文件。,5.5,程序设计的辅助函数,MATLAB,程序设计中辅助函数的合理使用,可以增强函数的,“,鲁棒性,”,、丰富函数功能;,常用的辅助函数有:,执行函数,容错函数,时间控制函数,执行函数,y1,y2,yn,=feval(function,x1,x2,xn,),以函数名为输入变量的函数。,evalin(workspacename,expression,),对指定工作空间,workspacename,中的变量进行操作,计算表达式,expression,的值。,容错函数,error(,错误信息,),触发函数,error,时,中断程序的运行,显示错误信息。,warning,用法类似于,error,函数,但不会中断程序。,function c=,testerror(a,b,),flag=0;,if,ischar(a)&ischar(b,),flag=1;,else,error(Input,must be a string!);,end,if flag,c=,strcat(a,b,);,end,testerror(1,you),?Error using=,testerror,Input must be a string!,testerror(1,you),ans,=,1you,时间控制函数,日期表达形式:,dd-mmm-yyyy,mm/,dd/yy,mm/,dd,12-Oct-2003 10/12/03 10/12,时间表达形式:,HH:MM:SS,HH:MM:SS,PM,cputime,的调用:,t=,cputime,;,程序段;,t=,cputime-t,;,显示该程序段运行所占用的,CPU,时间。,tic,、,toc,的调用方法,tic,;,程序段;,toc,;,显示运行该程序段所需的时间。,etime,(,time2,,,time1,),计算两时刻的时间差。,试探式语句,try,语句段,1,catch,语句段,2,end,首先试探性的执行语句段,1,,如果在执行过程中出现错误,则将错误信息赋给,lasterr,变量,并放弃该段语句,转而执行语句段,2,中的语句。,testtry(i,love,matlab,),ans,=,214 129 224 219 215 199,testtry(i,love,matlab,),ans,=,i love,matlab,5.6,程序设计优化,以矩阵为操作主体,以向量运算代替循环运算,提倡矩阵操作,tic;x=1;for,i=1:1000,y(i)=,sin(x);x,=x+0.1*,pi;end,toc,elapsed_time,=,0.0500,tic;x=1:0.1*pi:1000*pi;y=sin(x,);toc,elapsed_time,=,0.0100,在多重循环的情况下,建议外循环执行循环次数少的,内循环执行循环次数多的。,例:生成,510000,的,Hilbert,矩阵,其中,h,i,j,=1/(i+j-1),test2.m,tic,for j=1:10000,for i=1:5,H(i,j,)=1/(i+j-1);,end,end,toc,test1.m,tic,for i=1:5,for j=1:10000,H(i,j,)=1/(i+j-1);,end,end,toc,test1,elapsed_time,=,0.2970,test2,elapsed_time,=,0.6100,大型矩阵预先定维,大型矩阵动态的定维会降低程序运行效率,所以,应预先估计变量的最大维数,用,zeros,或,ones,等进行预先定维。,test1.m,tic,H=zeros(5,10000);,for i=1:5,for j=1:10000,H(i,j,)=1/(i+j-1);,end,end,toc,test2.m,tic,H=zeros(5,10000);,for i=1:5,H(i,:)=1./i:i+9999;,end,toc,test1,elapsed_time,=,0.2970,test2,elapsed_time,=,0.0310,对于二重循环,还可以使用,meshgrid,函数来构造。,tic,i,j,=meshgrid(1:5,1:10000);H=1./(i+j-1);toc,elapsed_time,=,0.0150,优先考虑内在函数,采用有效算法,采用,Mex,技术,内存的合理管理,5.7,程序调试,主要内容,M,文件错误的种类,错误的识别,调试过程,M,文件错误的种类,语法错误,发生在程序代码的解释过程中,一般由函数参数输入类型有误或矩阵运算阶数不符等情况。,a,=1 2;3 4;,b,=1 2 3;4 5 6;7 8 9;,a*b,?Error using=*,Inner matrix dimensions must agree.,执行错误,发生在程序运行过程中,出现溢出或死循环等引起,错误与程序有关,较难发现,。,a,=NaN,;,isnan(a,),ans,=,1,a=,;,isempty(a,),ans,=,1,尽量避免出现,NaN,、,inf,或空矩阵等异常数据,要适当采取方法来控制。,错误的识别,语法错误会给出相应的信息,容易检查定位;,将程序执行的中间结果输出到命令窗口,以方便检查;,使用,keyboard,函数中断程序,进入调试状态,实现交互式调试;,将函数头注释掉,从而函数变为脚本文件调试;,使用调试菜单或调试函数。,调试函数,dbstop,in at,用来在,M,文件中设置断点;,函数,dbstatus,用来显示断点信息;,函数,dbtype,显示,M,文件文本(包括行号);,函数,dbstep,从断点处继续执行,M,文件;,函数,dbstack,显示,M,文件执行时调用的堆栈等;,函数,dbup/dbdown,可以实现工作空间的切换;,dbtype,db_test,1 function C=,db_test(A,B,),2 num11,num12=,size(A,);,3 num21,num22=,size(B,);,4 if(num12=num21),5 C=A*B,6 else,7 if(num11=num22),8 C=B*A;,9 else,10,error(input,error!),11 end,12 end,13 return,例:,function C=,db_test(A,B,),num11,num12=,size(A,);,num21,num22=,size(B,);,if(num12=num21),C=A*B,else,if(num11=num22),C=B*A;,else,error(input,error!),end,end,return,dbstop,in,db_test,at 5,a,=1 2;3 4;,b,=1 2 3;4 5 6;,db_test(a,b,),K,dbstatus,Breakpoint for e:MATLABR11workdb_test is on line 5.,K,dbstack,In e:MATLABR11workdb_test.m at line 5,K,whos,Name Size Bytes Class,A 2x2 32 double array,B 2x3 48 double array,num11 1x1 8 double array,num12 1x1 8 double array,num21 1x1 8 double array,num22 1x1 8 double array,Grand total is 14 elements using 112 bytes,K,dbup,In base workspace.,K,dbquit,5.8,函数句柄,函数句柄的优点,方便地实现函数间互相调用;,获得函数加载的所有方式;,拓宽子函数以及局部函数的使用范围;,提高函数调用过程中的可靠性;,减少程序设计中的冗余;,提高重复执行的效率;,可以与数组、结构型数组以及细胞型数组结合定义数据。,函数句柄的创建和显示,通过特殊符号,引导函数名即可实现相应的函数句柄定义;,定义时只需要在提示符号,后添加相应的函数名;,函数句柄的内容可以通过函数,functions,来显示。,函数类型,说明,simple,未加载的,MATLAB,内部函数、,M,文件,或只有在执行过程中才能用,type,函数显示内容的函数,subfunction,MATLAB,子函数,private,MATLAB,局部函数,constructor,MATLAB,类的创建函数,overloaded,加载的,MATLAB,内部函数、,M,文件,MATLAB,的函数类型,函数句柄的调用和操作,通过函数,feval,可以实现函数句柄的调用,Feval(,,参数列表,),;,相当于执行以参数列表为输入变量的函数句柄所对应的函数。,函数句柄与函数名字符串之间可以进行转换,转换函数为,fun2str,和,str2fun,;,通过函数,isa,可以判断变量是否为函数句柄;,通过函数,isequal,可以判断两函数句柄是否相同;,函数,save,可以将函数句柄保存为,MATLAB,的数据文件,函数,load,可以打开该文件。,5.9,文件格式与读写,Matlab,的文件,MDL,文件,simulink,生成的模型描述文件;,DLL,文件由,Mex,技术生成的,matlab,可调用函数库;,MAT,文件,matlab,格式存储的二进制数据文件,P,文件 ,M,文件变换后的伪代码文件。,变量存储命令,save,文件名 变量列表,文件名为要存储的文件名,如果不给出文件名则默认为,matlab.mat,;变量列表为要存储的变量,各个变量名间用空格分割,如果不给出变量名列表,则将整个工作空间中所有变量都存入该文件。,例:,save,tmp,a b c,将,a,,,b,,,c,三个变量存到,tmp.mat,文件中,默认目录为,work,目录。,save(temp,space,a,b,c,),可以使用任意的合法文件名。,变量装载命令,load,文件名 或,load,(文件名),从,mat,文件中将变量数据装载入工作空间。,ASCII,格式的变量存储,save,temp.dat,/,ascii,此时,文件内容为可读的,当变量的精度被降低。,文件操作函数,打开文件,文件句柄,=,fopen,(,文件名,打开方式,),如果句柄的值大于,0,,说明文件打开成功;打开方式:,r,只读,w,只写,a,追加,r+,可读又可写,关闭文件,fclose,(,文件句柄,),成功,则返回,0,;否则返回,1,。,如果想关闭,matlab,运行中打开的所有文件,可以用,fclose(all,),命令。,有格式读文件,A=,fscanf,(,文件句柄,输入格式,变量大小,N),从文件中读取,N,个元素,赋给,A,。,有格式写文件,fprintf,(,文件句柄,输出格式,输出变量表,),输出格式控制变量的输出形式,每个描述格式的字符串以引导,如,s,表示字符格式,,d,表示整型数格式,,23.13g,表示双精度浮点格式;,输出变量表中,变量名之间用逗号隔开。,读入整个一行,str,=,fgetl,(,文件句柄,),或,str,=,fgets,(,文件句柄,),从文件中读入一整行信息,前者舍弃字符串末尾的回车符号,后者不舍弃。,字符串读写,类似于文件读写,把文件句柄替换为字符串变量。,sscanf,(,字符串变量,输入格式,变量大小,),字符串变量,=,sprintf,(,输出格式,输出变量列表,),例:,文本文件显示。,function,fileprint(fname,),if,nargin,=1,f_id,=,eval(fopen,(,fname,.m,r,);,else,fname,fpath,=,uigetfile,(*.,m,Please,enter a file name);,f_id,=,fopen(fpath,fname,r,);,end,i=0;,while,feof(f_id,)=0,strText,=,fgetl(f_id,);,i=i+1;,disp(sprintf(%4d:%s,i,strText);,end,fclose(f_id,);,fileprint,(fileprint,),1:function,fileprint(fname,),2:if,nargin,=1,3:,f_id,=,eval(fopen,(,fname,.m,r,);,4:else,5:,fname,fpath,=,uigetfile,(*.,m,Please,enter a file name);,6:,f_id,=,fopen(fpath,fname,r,);,7:end,8:i=0;,9:while,feof(f_id,)=0,10:,strText,=,fgetl(f_id,);,11:i=i+1;,12:disp(sprintf(%4d:%s,i,strText);,13:end,14:fclose(f_id);,结束,
展开阅读全文