ch07M文件和函数句柄.docx

上传人:b****1 文档编号:14237544 上传时间:2023-06-21 格式:DOCX 页数:24 大小:48.08KB
下载 相关 举报
ch07M文件和函数句柄.docx_第1页
第1页 / 共24页
ch07M文件和函数句柄.docx_第2页
第2页 / 共24页
ch07M文件和函数句柄.docx_第3页
第3页 / 共24页
ch07M文件和函数句柄.docx_第4页
第4页 / 共24页
ch07M文件和函数句柄.docx_第5页
第5页 / 共24页
ch07M文件和函数句柄.docx_第6页
第6页 / 共24页
ch07M文件和函数句柄.docx_第7页
第7页 / 共24页
ch07M文件和函数句柄.docx_第8页
第8页 / 共24页
ch07M文件和函数句柄.docx_第9页
第9页 / 共24页
ch07M文件和函数句柄.docx_第10页
第10页 / 共24页
ch07M文件和函数句柄.docx_第11页
第11页 / 共24页
ch07M文件和函数句柄.docx_第12页
第12页 / 共24页
ch07M文件和函数句柄.docx_第13页
第13页 / 共24页
ch07M文件和函数句柄.docx_第14页
第14页 / 共24页
ch07M文件和函数句柄.docx_第15页
第15页 / 共24页
ch07M文件和函数句柄.docx_第16页
第16页 / 共24页
ch07M文件和函数句柄.docx_第17页
第17页 / 共24页
ch07M文件和函数句柄.docx_第18页
第18页 / 共24页
ch07M文件和函数句柄.docx_第19页
第19页 / 共24页
ch07M文件和函数句柄.docx_第20页
第20页 / 共24页
亲,该文档总共24页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

ch07M文件和函数句柄.docx

《ch07M文件和函数句柄.docx》由会员分享,可在线阅读,更多相关《ch07M文件和函数句柄.docx(24页珍藏版)》请在冰点文库上搜索。

ch07M文件和函数句柄.docx

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'

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2