ch07M文件和函数句柄.docx
- 文档编号:14237544
- 上传时间:2023-06-21
- 格式:DOCX
- 页数:24
- 大小:48.08KB
ch07M文件和函数句柄.docx
《ch07M文件和函数句柄.docx》由会员分享,可在线阅读,更多相关《ch07M文件和函数句柄.docx(24页珍藏版)》请在冰点文库上搜索。
ch07M文件和函数句柄
第7章M文件和函数句柄
除极简单问题外,大多数实际问题不可能仅仅依靠MATLAB指令窗中一条条零碎的指令解决,而需要编程。
本章就是为帮助读者编写解决实际问题的程序文件而设置的。
本章的前三节介绍MATLAB程序文件的编写基础,包括程序的基本构件、数据流控制、M文件的基本类型等。
从第7.4节起到第7.7节止,由浅入深地用四大节篇幅分别叙述了编写复杂程序所必需的组件和技术:
●各类函数、子函数及对象:
主函数、子函数、匿名函数和嵌套函数;内联对象;
●直接句柄和匿名句柄。
●构成泛函计算能力的eval和feval指令。
●变量的使用域和跨内存调用和赋值。
.1M码编程的基本构件
101变量
(Variables)
局域(local)变量、全域(global)变量、持存(persistent)变量。
102运算及运算符
算术运算、关系运算、逻辑运算。
103标点符号
(Symbol)
104关键词
(Keywords)运行iskeyword指令
105特殊值
(SpecialValues)
106MATLAB函数
(InternalMATLABFunctions)
(Built-InFunctions)
(M-fileFunctions)
(OverloadedFunctions)
107指令及指令行
(CommandsandCommandline)
.2MATLAB的数据流控制
.2.1for循环和while循环控制
101循环结构的基本形式
【例7.2-1】创建Hilbert矩阵。
(1)
(2)
clear
forK=1:
15
A=zeros(K,K);%<2>
forii=1:
K%<3>
forjj=1:
K%<4>
A(ii,jj)=1/(ii+jj-1);
end
end%<7>
CA(K)=cond(A);
ifK==5
formatrat
disp('A5='),disp(A)
format
end
end
semilogy(CA)
gridon
xlabel('矩阵的阶'),ylabel('矩阵条件数')
title('Hilbert矩阵的条件数')
102辅助控制指令continue和break
【例7.2-4】创建n阶魔方矩阵,限定条件是n为能被4整除的偶数。
(1)每列、每行、每条对角线元素的和都等于
(2)
%exm070204_1.m只用while-end指令直接生成“4倍数阶”魔方矩阵
clear,clc,n=1;
whilemod(n,4)~=0
n=input('请输入一个能被4整除的正整数!
n=');
end
G=logical(eye(4,4)+rot90(eye(4,4)));
m=n/4;
K=repmat(G,m,m);
N=n^2;
A=reshape(1:
N,n,n);
A(K)=N-A(K)+1
%exm070204_2.m借助continue,break生成“4倍数阶”魔方矩阵
clear,clc
while1
n=input('请输入一个能被4整除的正整数!
n=');
ifmod(n,4)~=0
continue
end
break
end
G=logical(eye(4,4)+rot90(eye(4,4)));
m=n/4;
K=repmat(G,m,m);
N=n^2;
A=reshape(1:
N,n,n);
A(K)=N-A(K)+1
(3)
(4)
A=
64917403241498
255472634231558
354462735221459
611220372944525
601321362845534
651433038191162
750423139181063
571624332548561
.2.2if-elseif-else条件分支控制
【例7.2-5】借助“if-else条件分支控制”编写M码,以实现式(7.2-1)分域函数的可视化(参见图7.2-5)。
(7.2-1)
(1)
a=2;b=2;
x=-a:
0.2:
a;y=-b:
0.2:
b;
forii=1:
length(x)
forjj=1:
length(y)
ifx(ii)+y(jj)<=-1
z(ii,jj)=0.5457*exp(-0.75*y(jj)^2-3.75*x(ii)^2+1.5*x(ii));
elseif-1 z(ii,jj)=0.7575*exp(-y(jj)^2-6*x(ii)^2); else z(ii,jj)=0.5457*exp(-0.75*y(jj)^2-3.75*x(ii)^2-1.5*x(ii)); end end end surf(x,y,z) colormap(flipud(autumn)) xlabel('x'),ylabel('y'),zlabel('z') axis([-a,a,-b,b,min(min(z)),max(max(z))]) .2.3switch-case切换多分支控制 .2.4try-catch容错控制 .2.5编程用的其他指令 101return返回和pause暂定 102error出错信息和warning警告 103与键盘交互指令input和keyboard .3M文件和P文件 .3.1M文件 101M脚本文件 (一)一般性说明 (二)M脚本文件的基本结构 由%起首的H1行,包括文件名和功能简述。 以%开头的在线帮助文本区,涉及对文件中关键变量的简短说明。 编写和修改记录,也以%开头。 程序体(附带关键指令功能注解)。 102M函数文件 (一)一般性说明 (二)M函数文件的基本结构 函数声明行。 以关键字function开头,函数名及函数的输入/输出量名都在这一行被定义。 H1行。 在线帮助文本区。 编写和修改记录。 函数体(FunctionBody) 【例7.3-1】编写一个M函数文件。 它具有以下功能: (A)根据指定的半径,画出蓝色圆周线;(B)可以通过输入字符串,改变圆周线的颜色、线型;(C)假若需要输出圆面积,则绘出圆。 (1) function[S,L]=exm070301(N,R,str) switchnargin case0 N=100;R=1;str='-b'; case1 R=1;str='-b'; case2 str='-b'; case3 ; otherwise error('输入量太多。 '); end; t=0: 2*pi/N: 2*pi; x=R*sin(t);y=R*cos(t); ifnargout==0 plot(x,y,str); elseifnargout>2 error('输出量太多。 '); else S=N*R*R*sin(2*pi/N)/2; L=2*N*R*sin(pi/N); fill(x,y,str) end axisequalsquare boxon shg (2) [S,L]=exm070301(6,2,'-g') S= 10.3923 L= 12.0000 图7.3-1绿色正六边形 .4MATLAB的函数类别 .4.1主函数和子函数 101主函数 102子函数 【例7.4-1】编写一个内含子函数的M函数绘图文件。 (1) functionHr=exm070401(flag) t=(0: 50)/50*2*pi; x=sin(t); y=cos(t); Hr=@cirline; feval(Hr,flag,x,y,t) %------------- functioncirline(wd,x,y,t) switchwd case'line' plot(t,x,'b',t,y,'r','LineWidth',2) case'circle' plot(x,y,'-g','LineWidth',8), axissquareoff otherwise error('输入宗量只能取''line''或''circle''! ') end shg (2) HH=exm070401('circle') HH= @cirline 图7.4-1绿色圆周线 (3) t=0: 2*pi/5: 2*pi;x=cos(t);y=sin(t); HH('circle',x,y,t) 图7.4-2由子函数绘制的绿色正五边形 .4.2匿名函数 101匿名函数及其句柄的创建 FH=@(arglist)expression 102匿名函数的调用 FH(arglist)直接调用格式 feval(FH,arglist)间接调用格式 .4.3嵌套函数 101嵌套函数的结构特点 以关键词function和end作为起首和结尾。 102调用规则 103变量作用域 【例7.4-2】嵌套函数的调用和变量作用域运行示例。 functionexm070402_Azy clear,clc u='在主函数exm070402_Azy中的定义变量u。 ' disp(''),disp('Pressanykeytocontinue'),pause B1 functionB1 disp('******第二层嵌套函数B1被主函数调用******') u disp('以上显示是: 在第二层嵌套函数B1中,访问u的结果。 ') disp(''),disp('Pressanykeytocontinue'),pause u='现在第二层嵌套函数B1中,u被重新赋为此字符串了。 ' disp(''),disp('Pressanykeytocontinue'),pause C1 functionC1 disp('******第三层嵌套函数C1被直系父函数B1调用******') u disp('以上显示是: 在第二层嵌套函数C1中,访问u的结果。 ') disp(''),disp('Pressanykeytocontinue'),pause u='现在第三层嵌套函数C1中,u被第2次改写了。 ' disp(''),disp('Pressanykeytocontinue'),pause B2; end end %----------------------% functionB2 disp('******第二层嵌套函数B2被“旁系”B1的子函数C1调用了! ******') u disp('以上显示是: 在“旁系”B2中,访问u的结果。 ') disp('这是由于变量u的“根”在主函数中缘故。 ') disp(''),disp('Pressanykeytocontinue'),pause C2 functionC2 disp('******第三层嵌套函数C2被直系父函数B2调用! ******') u disp('以上显示是: 在“旁系”B2\C2中,访问u的结果。 ') disp('这也是由于变量u的“根”在主函数Azy中缘故。 ') disp(''),disp('Pressanykeytocontinue'),pause u='在B2\C2嵌套函数中,u被隔层重新设置。 ' w='在B2\C2嵌套函数中,新定义的变量w。 ' end end disp(''),disp('Pressanykeytocontinue'),pause disp('******现在回到主函数了! ******') u disp('历经多个嵌套函数后,所保留下的最后在B2\C2所赋的值。 ') w disp('不管哪个嵌套函数定义的变量(如w),主函数总能对此变量访问和设置。 ') end .5函数句柄 .5.1函数作用域和优先等级 .5.2函数句柄的创建 101直接句柄创建法 Fh=@Function_Name Fh=str2func('Function_Name') 102匿名句柄创建法 a=value1; b=value2; Fh2=@(x)Function_Name(x,a,b) .5.3函数句柄的调用格式 101直接句柄调用格式 [argout1,argout2,argoutM]=Fh(x,a,b) [argout1,argout2,argoutM]=feval(Fh,x,a,b) 102匿名句柄调用格式 [argout1,argout2,argoutM]=Fh2(x) [argout1,argout2,argoutM]=feval(Fh2,x) .5.4观察函数句柄的内涵 【例7.5-1】采用M函数文件描写 ,其中 是可变参数。 试画出 区间上的函数曲线。 (1) functiony=exm070501_chirp(t,a) switchnargin case1 a=1; case2 otherwise error('本函数只允许1个或2个输入量! ') end y=cos(1./(a*t.^2)); (2) a=1.5; t=0.2: 0.0001: 0.3; y0=exm070501_chirp(t,a);%<3> (3) Fy=@exm070501_chirp;%<4> a=1.5; t=0.2: 0.0001: 0.3; y1=Fy(t,a);%<7> (4) a=1.5; Gy=@(t)exm070501_chirp(t,a);%<9> t=0.2: 0.0001: 0.3; y2=Gy(t);%<11> (5) CFy=functions(Fy)%<12> CGy=functions(Gy)%<13> CFy= function: 'exm070501_chirp' type: 'simple' file: 'D: \NewBook\Master20101204\Ch07_编程\exm070501_chirp.m' CGy= function: '@(t)exm070501_chirp(t,a)' type: 'anonymous' file: '' workspace: {[1x1struct]} CGy.workspace{1} ans= a: 1.5000 (6) same01=(norm(y0-y1)/norm(y0)<1e-12) same02=(norm(y0-y2)/norm(y0)<1e-12) same01= 1 same02= 1 .6泛函演算指令 .6.1eval 【例7.6-1】计算“表达式”串,产生向量值。 (1) clear t=pi; cem='[t/2,t*2,sin(t)]'; y=eval(cem) y= 1.57086.28320.0000 (2) clear t=pi; eval('theta=t/2,y=sin(theta)'); theta= 1.5708 y= 1 (3) A=ones(2,1); B=ones(1,3); c=eval('A*B') c= 111 111 (4) clearall CEM={'cos','exp','10^'}; fork=1: 3 theta=pi*k/12; y(1,k)=eval([CEM{k},'(',num2str(theta),')']); end y y= 0.96591.68816.1010 (5) B=magic(4); [Q,D]=eval('eig(B)'); Q= -0.5000-0.82360.3764-0.2236 -0.50000.42360.0236-0.6708 -0.50000.02360.42360.6708 -0.50000.3764-0.82360.2236 D= 34.0000000 08.944300 00-8.94430 0000.0000 .6.2feval 【例7.6-2】feval和eval的调用区别 eval可用于表达式计算,而feval不能 两者都可以使用的情况下,feval运行效率更高 feval主要用来构造“泛函”型M函数文件 (1) formatshort x=pi/4; Ve=eval('1+sin(x)') Ve= 1.7071 Vf=feval('1+sin(x)',x) ? ? ? Errorusing==>feval Invalidfunctionname'1+sin(x)'. (2) rng(1,'v5normal') A=randn(2,2); [u1,d1,v1]=svd(A); Hs=@svd; [u2,d2,v2]=Hs(A); [u3,d3,v3]=feval(Hs,A); [u4,d4,v4]=eval('svd(A)'); disp('A阵奇异值分解三对组') disp([blanks(11),'u1',blanks(18),'d1',blanks(17),'v1']) disp([u1,d1,v1]) A阵奇异值分解三对组 u1d1v1 -0.85660.51601.36830-0.50560.8627 0.51600.856600.61050.86270.5056 .6.3内联对象 FI=inline('CE',arg1,arg2,…) 把表达式CE转化成以arg1,arg2等为输入量的内联对象FI 【例7.6-5】用内联对象表达 。 (1) Y=inline('[a^2;b*sin(x)]','a','b','x') Y= Inlinefunction: Y(a,b,x)=[a^2;b*sin(x)] (2) disp('函数表达式'),disp(char(Y)) disp('内联对象的输入量'),disp(argnames(Y)) 函数表达式 [a^2;b*sin(x)] 内联对象的输入量 'a' 'b' 'x' (3) a=3;b=3;x=pi/3; disp('Y值为'),disp(Y(a,b,x)) Y值为 9.0000 2.5981 feval(Y,a,b,x) ans= 9.0000 2.5981 (4) Yv=vectorize(Y) Yv= Inlinefunction: Yv(a,b,x)=[a.^2;b.*sin(x)] a=1: 5;b=5: -1: 1;x=(0.2: 0.2: 1)*pi; Yv1=Yv(a,b,x) Yv1= 1.00004.00009.000016.000025.0000 2.93893.80422.85321.17560.0000 .7变量的使用域和跨内存交换 .7.1输入输出检测指令 nargin nargout nargin('fun') nargout('fun') inputname(n) .7.2“变长度”输入输出量 varargin varargout 【例7.7-1】变长度输入输出量的应用示例。 (1)编写函数文件exm070701.m functionvarargout=exm070701(N,varargin) if~any(nargout==[0,2,3]) error('输出量数目必须在集合{0,2,3}中') end ifnargin<4&&nargout==3%<5> error('想获得导函数数据,输入量数目必须大于等于4') end flagplot=1; switchnargin case0 N=2;a=2;nx=100;der1=0; case1 a=2;nx=100;der1=0; case2 a=varargin{1};%<15> nx=100;der1=0; case3 a=varargin{1}; nx=varargin{2}; der1=0; case{4,5} a=varargin{1}; nx=varargin{2}; der1=varargin{3}; ifnargin==5 flagplot=varargin{4}; end end%<28> N1=N-1; x=linspace(-N,N,nx); dx=2*N/nx; b=-(N-2): 2: (N-2); fsum=0; forii=1: N1 fsum=fsum+2./(1+exp(-a*(x+b(ii)))); end y=fsum-N1; ifder1==0 h0=plot(x,y,'-r',x,x,'-g'); set(h0 (1),'LineWidth',2) axis([-N1,N1,-N1,N1]),axisequal,gridon xlabel('x'),ylabel('y'
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ch07M 文件 函数 句柄