61
MATLAB 程程程程程程 程程程程

MATLAB 程序设计基础

  • Upload
    jadyn

  • View
    179

  • Download
    0

Embed Size (px)

DESCRIPTION

MATLAB 程序设计基础. 程序设计. M 文件 两种形式:命令形式( Script ) 函数形式( Function ) 命令式 M 文件在运行过程中可以调用 MATLAB 工作域内所有的数据,而且,所产生的所有变量均为全局变量,直到用户执行 clear 命令清除;函数式文件中所有变量除特殊声明,均为局部变量。. 命令式 M 文件 提示: 标点符号要运用恰当; 注意程序的书写风格,保持程序的可读性; 要以 m 为文件扩展名,在低版本的 matlab 中,文件名要符合 8.3 格式。. - PowerPoint PPT Presentation

Citation preview

Page 1: MATLAB 程序设计基础

MATLAB 程序设计基础

程序设计

Page 2: MATLAB 程序设计基础

M 文件 两种形式:命令形式( Script ) 函数形式( Function ) 命令式 M 文件在运行过程中可以调用 MATLAB 工作域内所

有的数据,而且,所产生的所有变量均为全局变量,直到用户执行 clear 命令清除;函数式文件中所有变量除特殊声明,均为局部变量。

Page 3: MATLAB 程序设计基础

命令式 M 文件 提示:

标点符号要运用恰当; 注意程序的书写风格,保持程序的可读性; 要以 m 为文件扩展名,在低版本的 matlab 中,文件名要符合 8.3 格式。

Page 4: MATLAB 程序设计基础

函数式 M 文件 function [ 返回变量列表 ]= 函数名 ( 输入变量列表 ) 注释说明语句段 函数体 提示:

第一行为 function 语句; function 后定义函数名和输入输出参数,函数被调用时

按此格式执行; 文件名必须与函数名一一对应; 函数执行完后,只保留返回结果,不保留中间过程;

Page 5: MATLAB 程序设计基础

例:function f=fibfun(n)%FIBFUN for calculating fibonacci numbers.%Incidengtally, the name fibonacci comes from%Filius Bonassi, or "son of Bonassus"%fibfun.mif n>2 f=fibfun(n-1)+fibfun(n-2);else f=1;end

Page 6: MATLAB 程序设计基础

?help fibfun

FIBFUN for calculating fibonacci numbers. Incidengtally, the name fibonacci comes from Filius Bonassi, or "son of Bonassus" fibfun.m

?lookfor fibFIBFUN for calculating fibonacci numbers.注:为了利用 MATLAB 的关键字搜索功能,应该在 M 文件的

第一行注释中,尽可能多的包含函数的特征信息。

Page 7: MATLAB 程序设计基础

控制语句 循环语句 有两种方式: for 循环和 while 循环

for 循环 for 循环变量 =s1:s3:s2 循环体语句组 end说明:

for 语句一定要有 end 结束标志; 循环语句中要用“;”防止中间结果的输出; 书写时采用锯齿结构以增加可读性;

Page 8: MATLAB 程序设计基础

例:求

mysum=0;

for i=1:1:100

mysum=mysum+i;

end;

mysum

求取 s1 的值- >i

i 在 s1 和 s2 之间?

循环体语句组

i+s3->i

结束循环

100

1ii

Page 9: MATLAB 程序设计基础

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

Page 10: MATLAB 程序设计基础

while 循环 while 逻辑变量 循环体语句组 end

例(见前例): mysum=0;i=1; while (i<=100) mysum=mysum+i; i=i+1; end mysum

条件为真?

循环体语句

结束循环

Page 11: MATLAB 程序设计基础

条件转移结构 if 逻辑变量 条件语句组 end例: mysum=0; for m=1:1000 if (mysum>10000), break; end mysum=mysum+m; end [m, mysum]

Page 12: MATLAB 程序设计基础

if 条件式 条件块语句组 1

else

条件块语句组 2

end

条件语句组

语句组 1 语句组 2

是 否

Page 13: MATLAB 程序设计基础

例:多项式加 p1=[1 5 4]; p2=[1 6 11 6]; n1=length(p1); n2=length(p2); if n1<n2,

p1=[zeros(1,n2-n1) p1]; else

p2=[zeros(1,n1-n2) p2]; end psum=p1+p2 psum = 1 7 16 10

Page 14: MATLAB 程序设计基础

if 条件式 1

条件块语句组 1

elseif 条件式 2

条件块语句组 2

else

条件块语句组 n+1

end

条件 1

语句组 1

条件 2是

语句组 2

条件 n

语句组 n 语句组 n+1

Page 15: MATLAB 程序设计基础

分支语句 switch 开关表达式 case 表达式 1 语句段 1 case { 表达式 2, 表达式 3,…, 表达式 m} 语句段 2 … otherwise 语句段 n end

Page 16: MATLAB 程序设计基础

注意:无需像 C 语言那样在下一个 case 语句前加 brea

k 语句;当需要在开关表达式满足若干个表达式之一时,

用单元结构来表示; otherwise 等价于 C 语言的 default 语句;程序的执行结果与 case 语句的次序无关。

Page 17: MATLAB 程序设计基础

试探式语句 try 语句段 1 catch

语句段 2 end

首先试探性的执行语句段 1 ,如果在执行过程中出现错误,则将错误信息赋给 lasterr 变量,并放弃该段语句,转而执行语句段 2 中的语句。

Page 18: MATLAB 程序设计基础

function c=testtry(a,b)

try

c=a+b;

catch

c=strcat(a,b);

end

Page 19: MATLAB 程序设计基础

人机交互语句 echo 语句 echo on 打开命令式文件的回应命令; echo off 关闭回应命令; echo file on 使 file 文件的命令在执行中被显示; echo file off 关闭 file 文件的命令执行中的回应; echo on all 显示所有执行文件的执行过程; echo off all 关闭所有执行文件的回应显示;

Page 20: MATLAB 程序设计基础

用户输入提示命令 input 用来提示用户从键盘输入数据、字符

串或表达式,并接收输入值。 ?r=input('How many apples:')

How many apples:2

r =

2

?r=input('What''s your name?','s')What's your name?Gundam

r =

Gundam

Page 21: MATLAB 程序设计基础

yesinput 智能输入命令 answer=yesinput(question,default,possib)

question 为屏幕提示问题, default 为默认值, possib 为检验范围。

Page 22: MATLAB 程序设计基础

keyboard 暂停执行程序并等待键盘输入状态,处理完毕后,

键入 return 并回车,程序将继续运行,通常用来对程序调试及在程序中修改变量。

pause pause 暂停程序,等待回应; pause(n) 等待 n秒后继续执行; pause on 显示并执行 pause 命令; pause off 显示但不执行 pause 命令。

Page 23: MATLAB 程序设计基础

中断命令 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;endchicken=irabit=(100-2*i)/4

Page 24: MATLAB 程序设计基础

函数变量 nargin 函数输入变量的个数 例:编制函数 test1实现如下功能:如果只提供一个输入变

量,则求该输入变量的模,如果有两个输入变量则求它们的和。

function c=test1(a,b)if(nargin==1) c=det(a);elseif (nargin==2) c=a+b;end

Page 25: MATLAB 程序设计基础

varargin

可以实现不定数目的输入变量的函数,函数的一切输入变量均存储在单元数组 varargin 中。

与之相对应,输出变量也有相应的函数 , 如:nargout 、 varargout 等。

Page 26: MATLAB 程序设计基础

变量作用域 函数内部定义的变量均为局部变量,如果需

要使用全局变量,则应当使用命令 global 定义,并且在任何使用该全局变量的函数中都应加以定义。

定义全局变量时,变量之间必须用空格分隔,不能以逗号分隔。

Page 27: MATLAB 程序设计基础

function [num1,num2,num3]=test3(varargin)global firstlevel secondlevelnum1=0;num2=0;num3=0;list=zeros(nargin);for i=1:nargin list(i)=sum(varargin{i}(:)); list(i)=list(i)/length(varargin{i}); if list(i)>firstlevel num1=num1+1; elseif list(i)>secondlevel num2=num2+1; else num3=num3+1; endend

?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

Page 28: MATLAB 程序设计基础

子函数与局部函数 函数文件中题头定义的函数为主函数,在函数体内

定义的其他函数即为子函数。子函数只能为主函数或同一主函数下其他的子函数所调用。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;

Page 29: MATLAB 程序设计基础

放置于目录 private 下的函数称为局部函数,这些函数只有 private目录的父目录中的函数才可以调用,其他目录的函数不能调用。局部函数与一般函数文件的编辑相同。

MATLAB 在调用函数时,首先检测该函数是否为此文件的子函数;如果不是,再检测是否为可用的局部函数;如果仍不是,则检测MATLAB 搜索路径中其他的 M 文件。

Page 30: MATLAB 程序设计基础

程序设计的辅助函数 执行函数 [y1,y2,…,yn]=feval(function,x1,x2,…,xn)

以函数名为输入变量的函数。 evalin(workspacename,’expression’)

对指定工作空间 workspacename 中的变量进行操作,计算表达式 expression 的值。

Page 31: MATLAB 程序设计基础

容错函数 error(‘ 错误信息’ ) 触发函数 error 时,中断程序的运行,显示错误信息。 warning 用法类似, 但不会中断程序。

function c=testerror(a,b)flag=0;if ischar(a)&ischar(b) flag=1;else error('Input must be a string!');endif flag c=strcat(a,b);end

Page 32: MATLAB 程序设计基础

时间控制函数 日期表达形式: dd-mmm-yyyy mm/dd/yy mm/dd

12-Oct-2003 10/12/03 10/12

时间表达形式: HH:MM:SS HH:MM:SS PM

Page 33: MATLAB 程序设计基础

cputime 的调用: t=cputime;

程序段; t=cputime-t;

显示该程序段运行所占用的 CPU 时间。

Page 34: MATLAB 程序设计基础

tic 、 toc 的调用方法 tic;

程序段; toc ; 显示运行该程序段所需的时间。 etime ( time2 , time1 ) 计算两时刻的时间差。

Page 35: MATLAB 程序设计基础

程序设计优化 以矩阵为操作主体 以向量运算代替循环运算 , 提倡矩阵操作

?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

Page 36: MATLAB 程序设计基础

在多重循环的情况下,建议外循环执行循环次数少的,内循环执行循环次数多的。

例:生成 5×10000 的 Hilbert矩阵,其中 hi,j=1/(i+j-1)

Test2.mticfor j=1:10000 for i=1:5 H(i,j)=1/(i+j-1); endendtoc

Test1.mticfor i=1:5 for j=1:10000 H(i,j)=1/(i+j-1); endendtoc

?test1elapsed_time =

0.2970?test2elapsed_time =

0.6100

Page 37: MATLAB 程序设计基础

大型矩阵预先定维 大型矩阵动态的定维会降低程序运行效率,

所以,应预先估计变量的最大维数,用 zeros或 ones 等进行预先定维。ticH=zeros(5,10000);for i=1:5 for j=1:10000 H(i,j)=1/(i+j-1); endendtoc

ticH=zeros(5,10000);for i=1:5 H(i,:)=1./[i:i+9999];endtoc

?test1elapsed_time =

0.2970?test2elapsed_time =

0.0310

Page 38: MATLAB 程序设计基础

对于二重循环,还可以使用 meshgrid 函数来构造。

优先考虑内在函数 采用有效算法 采用 Mex技术

?tic,[i,j]=meshgrid(1:5,1:10000);H=1./(i+j-1);toc

elapsed_time =

0.0150

Page 39: MATLAB 程序设计基础

面向对象的程序设计类和对象的构造 类的概念是结构体的拓展,类中可以包含变

量形成员,也可以包含与这些变量相关联的函数或运算。对象是类的一个实例。首先定义一个适当的名字 ;以这个名字建立一个子目录,目录名为该名称前

加 @ 符号;编写一个引导函数,函数名与类同名。

Page 40: MATLAB 程序设计基础

例:定义一个多项式类 如果不给出输入变量,则建立一个空多项式; 如果输入变量 a 为多项式类,则直接把它传送给输出变

量 p ; 如果 a 为向量,则将此向量变换成行向量,再构造一个

多项式对象;function p=polynom(a)if nargin==0 p.c=[];p=class(p,'polynom');elseif isa(a,'polynom'), p=a;else p.c=a(:).';p=class(p,'polynom');end

Page 41: MATLAB 程序设计基础

类的显示 在此目录下重新建立

display() 函数。 函数自动按照多项式

显示的格式构造字符串,并显示出来。function display(p)disp(' ');disp([inputname(1),' = '])disp(' ');disp([' ' char(p)]);disp(' ');

function s=char(p)if all(p.c==0) s='0';else d=length(p.c)-1;s=[]; for a=p.c; if a~=0 if ~isempty(s) if a>0, s=[s,'+']; else, s=[s,'-'];a=-a; end end if a~=1|d==0, s=[s, num2str(a)]; if d>0, s=[s,'*']; end end if d>=2, s=[s,'x^',int2str(d)]; elseif d==1, s=[s 'x']; end end d=d-1; endend

Page 42: MATLAB 程序设计基础

各种运算的建立 加法运算:对 plus() 函数进行重载定义; 减法运算:对 minus() 函数进行重载定义; 乘法运算:对 mtimes() 函数进行重载定义; 乘方运算:对 mpower() 函数进行重载定义;

Page 43: MATLAB 程序设计基础

function p=minus(a,b)a=polynom(a);b=polynom(b);k=length(b.c)-length(a.c);p=polynom([zeros(1,k) a.c] -[zeros(1,-k) b.c]);

function p=minus(a,b)a=polynom(a);b=polynom(b);k=length(b.c)-length(a.c);p=polynom([zeros(1,k) a.c] -[zeros(1,-k) b.c]);

function p=mtimes(a,b)a=polynom(a);b=polynom(b);p=polynom(conv(a.c,b.c));

function p=mpower(a,n)if n>=0, n=floor(n);a=polynom(a);p=1; if n>=1 for i=1:n, p=p*a;end endelse error('Power should be a non-negative integer.')end

Page 44: MATLAB 程序设计基础

875.135)(

74)(234

23

xxxxsQ

xxsP?P=polynom([1 4 0 -7]) P = x^3+4*x^2-7 ?Q=polynom([5 3 -1.5 7 8]) Q = 5*x^4+3*x^3-1.5*x^2+7*x+8

?P+Qans = -5*x^4-2*x^3+5.5*x^2-7*x-15?P-Qans = -5*x^4-2*x^3+5.5*x^2-7*x-15?P*Qans = 5*x^7+23*x^6+10.5*x^5-34*x^4+15*x^3+42.5*x^2-49*x-56?P^3ans = x^9+12*x^8+48*x^7+43*x^6-168*x^5-336*x^4+147*x^3+588*x^2-343

Page 45: MATLAB 程序设计基础

文件格式与读写 Matlab 的文件 MDL 文件- simulink 生成的模型描述文件; DLL 文件-由Mex技术生成的 matlab 可调用函数库; MAT 文件- matlab 格式存储的二进制数据文件 P 文件 - M 文件变换后的伪代码文件。

Page 46: MATLAB 程序设计基础

变量存储命令 save 文件名 变量列表 文件名为要存储的文件名,如果不给出文件

名则默认为 matlab.mat ;变量列表为要存储的变量,各个变量名间用空格分割,如果不给出变量名列表,则将整个工作空间中所有变量都存入该文件。

Page 47: MATLAB 程序设计基础

例: save tmp a b c

将 a , b , c三个变量存到 tmp.mat 文件中,默认目录为 work目录。

save(‘temp space’,’a’,’b’,’c’)

可以使用任意的合法文件名。

Page 48: MATLAB 程序设计基础

变量装载命令 load 文件名 或 load (文件名) 从 mat 文件中将变量数据装载入工作空间。 ASCII 格式的变量存储 save temp.dat /ascii

此时,文件内容为可读的,当变量的精度被降低。

Page 49: MATLAB 程序设计基础

文件操作函数 打开文件 文件句柄 =fopen(‘ 文件名’,’打开方式‘ )

如果句柄的值大于 0 ,说明文件打开成功;打开方式:r - 只读w - 只写a - 追加r+ - 可读又可写…

Page 50: MATLAB 程序设计基础

关闭文件 fclose( 文件句柄 ) 成功,则返回 0 ;否则返回- 1 。 如果想关闭 matlab 运行中打开的所有文件,可

以用 fclose(‘all’) 命令。 有格式读文件 A=fscanf( 文件句柄 ,’ 输入格式’ , 变量大小 N) 从文件中读取 N 个元素,赋给 A 。

Page 51: MATLAB 程序设计基础

有格式写文件 fprintf( 文件句柄 ,’ 输出格式’ , 输出变量表 )

输出格式控制变量的输出形式,每个描述格式的字符串以%引导,如% s 表示字符格式,% d 表示整型数格式,% 23.13g 表示双精度浮点格式;

输出变量表中,变量名之间用逗号隔开。

Page 52: MATLAB 程序设计基础

读入整个一行 str=fgetl( 文件句柄 ) 或 str=fgets( 文件句柄 )

从文件中读入一整行信息,前者舍弃字符串末尾的回车符号,后者不舍弃。

字符串读写 类似于文件读写,把文件句柄替换为字符串变量。 sscanf( 字符串变量 ,‘ 输入格式’ , 变量大小 )

字符串变量 =sprintf(‘ 输出格式’,输出变量列表 )

Page 53: MATLAB 程序设计基础

例:文本文件显示。

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');endi=0;while feof(f_id)==0 strText=fgetl(f_id); i=i+1; disp(sprintf('%4d:%s',i,strText));endfclose(f_id);

Page 54: MATLAB 程序设计基础

?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);

Page 55: MATLAB 程序设计基础

程序调试 语法错误 发生在程序代码的解释

过程中,一般有函数参数输入类型有误或矩阵运算阶数不符等情况。

执行错误 发生在程序运行过程中,

出现溢出或死循环等引起,错误与程序有关,较难发现。

?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或空矩阵等异常数据,要适当采取方法来控制。

Page 56: MATLAB 程序设计基础

错误检测 语法错误会给出相应的信息,容易检查定位; 将程序执行的中间结果输出到命令窗口,以方便检查;

使用 keyboard 函数中断程序,进入调试状态,实现交互式调试;

将函数头注释掉,从而函数变为脚本文件调试; 使用调试菜单或调试函数。

Page 57: MATLAB 程序设计基础

调试函数dbstop in <M 文件名 > at < 行号 > 用来在 M 文

件中设置断点;函数 dbstatus 用来显示断点信息;函数 dbtype 显示 M 文件文本(包括行号);函数 dbstep 从断点处继续执行 M 文件;函数 dbstack 显示 M 文件执行时调用的堆栈等;函数 dbup/dbdown 可以实现工作空间的切换;

Page 58: MATLAB 程序设计基础

?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*B6 else7 if(num11==num22)8 C=B*A;9 else10 error('input error!')11 end12 end13 return

例:

function C=db_test(A,B)[num11,num12]=size(A);[num21,num22]=size(B);if(num12==num21) C=A*Belse if(num11==num22) C=B*A; else error('input error!') endendreturn

Page 59: MATLAB 程序设计基础

?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:\MATLABR11\work\db_test is on line 5.K?dbstack> In e:\MATLABR11\work\db_test.m at line 5K?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?dbupIn base workspace.K?dbquit?

Page 60: MATLAB 程序设计基础
Page 61: MATLAB 程序设计基础