MATLAB函数句柄和M文件

MATLAB函数句柄和M文件


2024年4月27日发(作者:)

第 6 章 M文件和函数句柄

6.1 Matlab控制流

6.2 脚本文件和函数文件

6.3 Matlab的函数类别

6.4 函数句柄

6.1 MATLAB控制流

6.1.1 if-else-end 条件控制

6.1.2 swith-case 控制语句

6.1.3 for循环和while循环

6.1.4 控制程序流和的其他常用指令

6.1.1 if-else-end条件控制

【例6.1-1】已知

2

ye

0.1x

sinx0.5(x0.1)sinx

,在

50x5

区间,求函数的最小值。

1

sin(x)

2

/exp(x/10) - (sin(x) (x + 1/10))/2

70

60

50

40

30

20

10

0

-50-45-40-35-30-25

x

-20-15-10-505

回顾与复习:

[x,fval,exitflag,output]=fminbnd(fun,x1,x2,options)

求一元函数在区间(x1, x2)中极小值

在第四章中采用的方法

(1)采用优化算法求极小值

x1=-50;x2=5; %

yx=@(x)(sin(x)^2*exp(-0.1*x)-0.5*sin(x)*(x+0.1));

[xc0,fc0,exitflag,output]=fminbnd(yx,x1,x2)

<9>

%

2)据图形观察,重设fminbnd的搜索区间

xx=[-23,-20,-18]; %

fc=fc0;xc=xc0; %

for k=1:2

[xw,fw]=fminbnd(yx,xx(k),xx(k+1));

<16>

if fw

xc=xw;

fc=fw;

end

end

fprintf('函数最小值%6.5f发生在x=%6.5f处',fc,xc)

函数最小值-3.34765发生在x=-19.60721处

1)

%

%

function [xmin,fmin,n]=exm060101(fx,a,b,Nt)

2

% exm060101.m

% fx

% a、b

% Nt

% xmin、ymin

% n

[~,f0]=fminbnd(fx,a,b); %

n=1; %

jj=1; %

while 1

n=2*n; %

d=(b-a)/n; %

x=a:d:b; %

ii=0;

xc=zeros(1,n);fc=xc; %

for k=1:n %

[w,f,eflag]=fminbnd(fx,x(k),x(k+1)); %

if eflag>0 %

ii=ii+1;

xc(ii)=w;

fc(ii)=f;

end

end

[fmin,kk]=min(fc); %

xmin=xc(kk); %

if abs(f0-fmin)<1e-6 %

jj=jj+1; %

if jj>Nt %

break %

end

elseif f0-fmin>1e-6 %

f0=fmin; %

jj=1; %

end

end

2)

clear

fx=@(x)(sin(x)^2*exp(-0.1*x)-0.5*sin(x)*(x+0.1));

a=-50;b=5;

3

[xmin,fmin,n]=exm060101(fx,a,b,3);

fprintf('在x=%6.5f处,函数到达最小值

%6.5fn',xmin,fmin)

fprintf('最终子区间分割数为 %dn',n)

在x=-19.60721处,函数到达最小值-3.34765

最终子区间分割数为 128

6.1.2 switch-case控制结构

【例6.1-2】已知学生姓名和百分制分数,用“满分”,优秀、

良好、及格和不及格表示学生成绩

clear;

%

for k=1:10

a(k)={89+k};b(k)={79+k};c(k)={69+k};d(k)=

{59+k};

end;

c=[d,c];

%

A=cell(3,5); %

A(1,:)={'Jack','Marry','Peter','Rose','Tom'

};% <7>

A(2,:)={72,83,56,94,100}; % <8>

%

4

for k=1:5

switch A{2,k}

case 100

r='满分';

case a

r='优秀';

case b

r='良好';

case c

r='及格';

otherwise

r='不及格';

end

A(3,k)={r};

end

A

%

%

%

%

%

%

A =

'Jack' 'Marry' 'Peter' 'Rose' 'Tom'

[ 72] [ 83] [ 56] [ 94] [100]

'及格' '良好' '不及格' '优秀' '满分'

6.1.3 for循环和while循环

表 6.1-3 循环结构的使用方式

for 循环

for ix=array

(commands)

end

while循环

while expression

(commands)

end

【例6.1-3】请分别写出用for 和while 循环语句计算

1000000

K

i21000000

0.210.20.2

0.2

的程序。此外,还请写出避

i0

免循环的数值、符号计算程序。

(1)for 循环方法

tic

s1=0;

for k=0:1e6

s1=s1+0.2^(k);

5

end;

s1

toc

(2)while循环方法

tic

s2=1;k=1;

while k<1e6+1 %注意:上限与for循环不同

s2=s2+0.2^k;

k=k+1;

end

s2

toc

(3)数值求和指令

tic

s3=sum(0.2.^(0:1e6))

toc

(4)符号求和指令

tic

syms k;

s4=vpa(symsum(0.2^k,0,1e6))

toc



N



1

1

【例6.1-4】编写计算

S

n

,其中

Nargmin

N

是预先

n1

k

k



k1

k1

给定的控制精度。

(1)

function [S,N]=exm060104(epsilon)

% [S,N]=exm060104(epsilon)

% Calculate the sum of a special series S=1+1/(1+2)+…+1/(1+2+…+N)

% S Sum of a special series

% N The minimum among all numbers to have 1/sum(1:N)

% epsilon Given accuracy

k=0;

s=0;

d=inf;

S=0;

while d>epsilon

6

k=k+1;

s=s+k;

d=1/s;

S=S+d;

end

N=k;

(2)

(3)

[S,N]=exm060104(0.0001)

syms k n N

SINF=limit(symsum(1/symsum(k,1,n),n,1,N),N,inf)

N=141;

SN=vpa(symsum(1/symsum(k,1,n),n,1,N))

6.1.4 控制程序流的其它常用指令

 break语句和continue语句 一般与if语句配合使用。 break语句用于终止循环的执行。 continue语句跳过当前循环,进入下一次。

例: 求[100,200]之间第一个能被21整除的整数。

程序如下:

for n=100:200

if rem(n,21)~=0

continue

7

end

break

end

n

n =

105

 try语句

try

语句组1

catch

语句组2

end

try语句先试探性执行语句组1,如果语句组1在执行过程中出现

错误,则将错误信息赋给保留的lasterr变量,并转去执行语句组

2

例:矩阵乘法运算要求两矩阵的维数相容,否则会出错。先

求两矩阵的乘积,若出错,则自动转去求两矩阵的点乘。

A=[1,2,3;4,5,6]; B=[7,8,9;10,11,12];

try

C=A*B;

catch

C=A.*B;

end

lasterr

ans =

错误使用 *

内部矩阵维度必须一致。

脚本文件和函数文件

 M脚本文件

 M函数文件

 局部变量和全局变量

 M函数文件的一般结构

6.2.1 M脚本文件 指令集合 所产生变量驻留在matlab工作空间

8

Clear指令或者matlab关闭时才删除

6.2.2 M函数文件 从形式上看,第一行是function引导的函数申明行 中间变量存放在临时工作空间,函数调用结束时,临时工

作空间变量立即被清除。

 M函数文件的一般结构

function 输出形参表=函数名(输入形参表)

注释说明部分;

函数体语句;

具体: 1.函数申明行。 和lookfor帮助使用。 3.在线帮助文本区,包括函数输入输出宗量的含义,调用

格式说明。(在线帮助文本,help菜单下matlab help)。 4.编写和修改记录。用于软件档案管理。 5.函数体。Matlab指令。

6.2.3 局部变量和全局变量 局部变量: 存在于函数空间内部的中间变量。产生于该

函数的运行之中,影响范围也仅仅限于该函数。 全局变量:基本工作空间和几个不同函数空间共享一个变

量,即全局变量。必须逐个用global函数加以定义。一个函

数改变其值,则所有的同名变量值改变。

【例6.2-1】编写一个M函数文件。它具有以下功能:(A)

根据指定的半径,画出蓝色圆周线;(B)可以通过输入字

符串,改变圆周线的颜色、线型;(C)假若需要输出圆面

积,则绘出圆。

(1)

function [S,L]=exm060201(N,R,str)

%

exm060201.m The area and perimeter of a regular polygon (正多边形的面积和周长)

%

%

%

N

R

str

The number of sides

The circumradius

A line specification to determine line type/color

9

% S

% L

% exm060201

% exm060201(N)

% exm060201(N,R)

% exm060201(N,R,str)

% S=exm060201(...)

% [S,L]=exm060201(...)

The area of the regular polygon

The perimeter of the regular polygon

用蓝实线画半径为 1 的圆

用蓝实线画外接半径为 1 的正 N 边形

用蓝实线画外接半径为 R 的正 N 边形

用 str 指定的线画外接半径为 R 的正 N 边形

给出多边形面积 S ,并画相应正多边形填色图

给出多边形面积 S 和周长L,并画相应正多边形填色图

% Zhang Zhiyong 编写于 2006-1-31

switch nargin

case 0

N=100;R=1;str='-b';

case 1

R=1;str='-b';

case 2

str='-b';

case 3

; %

otherwise

error('输入量太多。');

end;

t=0:2*pi/N:2*pi;

x=R*sin(t);y=R*cos(t);

if nargout==0

plot(x,y,str);

elseif nargout>2

error('输出量太多。');

else

S=N*R*R*sin(2*pi/N)/2; %

L=2*N*R*sin(pi/N); %

fill(x,y,str)

end

axis equal square

box on

shg

(2)

[S,L]=exm060201(6,2,'-g') %

图 6.2-1 绿色正六边形

例2:求圆周率

function piva = PiMonteCarlo(n)

10

% PiMonteCarlo(n),用随机投点法模拟圆周率pi,作出模拟

图. n为投点次数,可以是非负整数标量或向量.

% piva = PiMonteCarlo(n),用随机投点法模拟圆周率pi,

返回模拟值piva. 若n为标量(向量),则piva也为标量(向量).

x = 0;y = 0;d = 0;

m = length(n); % 求变量n的长度

pivalue = zeros(m,1); % 为变量pivalue赋初值

% 通过循环用投点法模拟圆周率pi

for i = 1:m

x = 2*rand(n(i),1)-1; % 随机投点的横坐标

y = 2*rand(n(i),1)-1; % 随机投点的纵坐标

d = x.^2+y.^2;

pivalue(i) = 4*sum(d <= 1)/n(i); % 圆周率的模拟

end

if nargout == 0

% 不输出圆周率的模拟值,返回模拟图

if m > 1

% 如果n为向量,则返回圆周率的模拟值与投点个数的散

点图

figure; % 新建一个图形窗口

plot(n,pivalue,'k.'); % 绘制散点图

h = refline(0,pi); % 添加参考线

set(h,'linewidth',2,'color','k'); % 设置参

考线属性

text(1.05*n(end),pi,'pi','fontsize',15);

% 添加文本信息

xlabel('投点个数'); ylabel('pi的模拟值'); %

添加坐标轴标签

else

% 如果n为标量,则返回投点法模拟圆周率的示意图

figure; % 新建一个图形窗口

plot(x,y,'k.'); % 绘制散点图

hold on;

% 绘制边长为2的正方形

h = rectangle('Position',[-1 -1 2

2],'LineWidth',2);

11

t = linspace(0,2*pi,100); % 定义一个角度向

plot(cos(t),sin(t),'k','linewidth',2); %

绘制单位圆

xlabel('X'); ylabel('Y'); % 添加坐标轴标签

title(['Pi的模拟值: ' num2str(pivalue)]); %

添加标题

axis([-1.1 1.1 -1.1 1.1]); axis equal; % 设

置坐标轴属性

end

else

piva = pivalue; % 输出圆周率的模拟值

end

p = PiMonteCarlo([1000:5000:50000])' % 返回圆周率

pi的模拟值向量

PiMonteCarlo([100:50:20000]) % 绘制模拟值与投点个数

的散点图

PiMonteCarlo(1000)

6.2 MATLAB的函数类别

从扩展名M观察,MATLAB的M文件分为M脚本文件和M函数文

件。那么,在MATLAB中,函数Function 又被细分为:主函数;子

函数;嵌套函数;私用函数;匿名函数等。限于篇幅,本节只对主函

数、子函数及匿名函数进行阐述。

6.2.1

6.2.2

主函数(Primary function)

子函数(Subfunction)

【例6.3-1】编写一个内含子函数的M函数绘图文件。

(1)

function Hr=exm060301(flag )

% exm060301.m Demo for handles of primary functions and

subfunctions

% flag 可以取字符串 'line' 或 'circle' 。

% Hr 子函数cirline的句柄

t=(0:50)/50*2*pi;

12

x=sin(t);

y=cos(t);

Hr=@cirline; %

feval(Hr,flag,x,y,t)

%

function cirline(wd,x,y,t)

%

switch wd

case 'line'

plot(t, x, 'b' ,t , y, 'r', 'LineWidth', 2)

case 'circle'

plot(x, y, '-g', 'LineWidth', 8),

axis square off

otherwise

error('输入宗量只能取 ''line'' 或 ''circle'' ! ')

end

shg

(2)

HH=exm060301('circle')

??? 未定义与 'char' 类型的输入参数相对应的函数

'exm060301'。HH =

@cirline

6.3-1 绿色圆周线

HH=exm060301('line')

HH =

@cirline

13

1

0.8

0.6

0.4

0.2

0

-0.2

-0.4

-0.6

-0.8

-1

01234567

(3)

t=0:2*pi/5:2*pi;x=cos(t);y=sin(t); %

HH('circle',x,y,t)

CC=functions(HH)

CC =

function: 'cirline'

type: 'scopedfunction'

file: 'E:2016秋Matlabprogramexm060301.m'

parentage: {'cirline' 'exm060301'}

图 6.3-2 由子函数绘制的绿色正五边形

6.2.3 匿名函数(Anonymous function)

(1)匿名函数的创建

FH=@(arglist)expr

(2)匿名函数的调用

FH(arglist) 直接调用格式

6.3 函数句柄

 函数句柄(Function handle)是MATLAB的一种数据类型。

 包含了函数的路径、函数名、类型以及可能存在的重载方法;

好处:

(1). 引入函数句柄是为了使feval及借助于它的泛函指令工作更可靠;

(2). 使“函数调用”像“变量调用”一样方便灵活;

(3). 提高函数调用速度,特别在反复调用情况下更显效率;

(4). 提高软件重用性,扩大子函数和私用函数的可调用范围;

(5). 迅速获得同名重载函数的位置、类型信息。

可以与变量一样方便地使用:比如说,在现在这个目录运行时,创建了本目录一

14

个函数的句柄,当转到其他目录时,可以通过函数句柄直接调用上一个目录的函

数,而不需要把那个函数文件复制过来,因为创建的函数句柄中已经包含了路径

信息;

提高函数调用速度:因为matlab对函数的调用每次都是要搜索所有的路径,从

set path中可以看到,路径是非常的多的,所以如果一个函数在程序中需要经常

用到的话,使用函数句柄,对速度会有提高的

6.3.1 函数句柄的创建和观察

(1)创建函数句柄

hm=@magic

hm =

@magic

2)函数句柄的调用

M1=hm(4)

M2=feval(hm,4)

M1 =

16 2 3 13

5 11 10 8

9 7 6 12

4 14 15 1

M2 =

16 2 3 13

5 11 10 8

9 7 6 12

4 14 15 1

【例6.4-1】为magic函数创建文件句柄,并观察其内涵

(1)

hm=@magic

hm =

@magic

(2)

class(hm)

isa(hm, 'function_handle')

ans =

function_handle

ans =

1

(3)

CC=functions(hm)

CC =

function: 'magic'

type: 'simple'

file: 'D:'

4)

M1=hm(4)

M1 =

16 2 3 13

15

5 11 10 8

9 7 6 12

4 14 15 1

(5)

M2=feval(hm,4)

M2 =

16 2 3 13

5 11 10 8

9 7 6 12

4 14 15 1

6.3.2 函数句柄的基本用法

原函数调用格式

[argout1, argout2, …, argoutn]=FunName(argin1,

argin2, …, arginn)

Hfun=@FunName

函数句柄调用格式

[argout1, argout2, …, argoutn]=Hfun(argin1,

argin2, …, arginn)

【例6.4-2】

(1)[S,L]=exm060201(3,2,'-r') %

S =

5.1962

L =

10.3923

2

1.5

1

0.5

0

-0.5

-1

-2-1.5-1-0.500.511.52

S =

图 6.4-1 直接调用函数exm060201所画的红色等边三角形

(2)

Hexm=@exm060201, %

(3)

which('exm060201')

16

(5)

[S,L]=exm060201(3,2,'-r')

(6)[S,L]=Hexm(3,2,'-r') %

图 6.4-2 在新视野中里用函数句柄Hexm所画的红色等边三角形

思考题1:猜数游戏

首先由计算机产生[1,100]之间的随机整数,然后由用户猜测所

产生的随机数。根据用户猜测的情况给出不同提示,如猜测的数大于

产生的数,则显示“High”,小于则显示“Low”,等于则显示“You won”,

同时退出游戏。用户最多可以猜7次。

a=ceil(100*rand(1));

for i=1:7

b=input('the number is ?');

if b>a

xx='high'

else if b

xx='low'

else

xx='you are right'

a

break

end

end

end

17


发布者:admin,转转请注明出处:http://www.yc00.com/news/1714194936a2399856.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信