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
ye
0.1x
sinx0.5(x0.1)sinx
,在
50x5
区间,求函数的最小值。
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.210.20.2 0.2 的程序。此外,还请写出避 i0 免循环的数值、符号计算程序。 (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 ,其中 Nargmin N , 是预先 n1 k k k1 k1 给定的控制精度。 (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条)