matlab 匿名函数函数句柄.docx
- 文档编号:14289125
- 上传时间:2023-06-22
- 格式:DOCX
- 页数:15
- 大小:22.37KB
matlab 匿名函数函数句柄.docx
《matlab 匿名函数函数句柄.docx》由会员分享,可在线阅读,更多相关《matlab 匿名函数函数句柄.docx(15页珍藏版)》请在冰点文库上搜索。
matlab匿名函数函数句柄
matlab 匿名函数 函数句柄
(2012-05-1111:
35:
05)
转载▼
标签:
教育
分类:
study与matlab
一、函数句柄
所谓函数句柄,个人认为可以将其理解成一个函数的代号,就像一个人的名字。
这样在调用时可以调用函数句柄而不用调用该函数。
语法如下:
变量名=@函数名;
@的作用就是将一个函数的函数句柄赋值给等号左边的变量。
在调用函数时就可以调用该句柄,可以实现同样的功能。
例:
首先我们写一个求均值的函数:
functiony=average(x)
y=mymean(x);
functiona=mymean(v)
a=sum(v)/length(v);
定义一个数组z:
z=[1,2,3,4,5,6,7];
>>average(z)
ans=
4
>> handle=@average
handle=
@average
>> ave=@average
ave=
@average
>>ave(z)
ans=
4
二、匿名函数 相当于C语言中的函数指针(入口地址),只不过句柄就用一个唯一的常整数来指出
匿名函数是函数句柄的一种特殊用法,这里所得到的函数句柄变量不指向特定的函数(即不指向函数M文件中的函数名),而是指向一个函数表达式(具体表达式)。
语法如下:
变量名=@(输入参数列表)运算表达式;
例子:
为了说明问题,我们用简单的两个数相加,
>> sum=@(x,y)x+y
sum=
@(x,y)x+y
>>sum(2,3)
ans=
5
%%%%%%%%%%%%%%%%%%%
比如定义f(x)=x^2,可以写为
f=@(x)(x.^2)
其中@(x)(x.^2)就是匿名函数,第一个括号里面是自变量,第二个括号里面是表达式,@是函数指针
f=@(x)(x.^2)表示将匿名函数@(x)(x.^2)赋值给f,于是f就表示该函数。
于是f
(2)=2.^2=4;f(1:
3)=[1:
3].^2=[149]等等
定义匿名函数时也可以调用别的匿名函数,比如
f1=@(x,y)(x.^2+y.^2)
定义了函数x^2+y^2
f2=@(t)(f1(t,2))
定义了函数t^2+4
f3=@(x)(f1(x
(1),x
(2)))
定义了函数x
(1)^2+x
(2)^2
使用匿名函数时一定要注意函数本身的参数形式,如
f1(2,3)
表示2^2+3^2
f2(3)=3
表示3^2+4
f3([1,2])
表示1^2+2^2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
三、内联函数
内联函数和普通的函数句柄,准确说跟匿名函数比较类似,可以通过一个函数表达式近而得到该函数。
语法格式如下:
1变量名=inline(表达式);
2 变量名=inline('函数表达式','变量名1','变量名2',...,'变量名n');(推荐)
例如:
1
>>a='x+y'
a=
x+y
>>f=inline(a)
f=
Inlinefunction:
f(x,y)=x+y
>>f(2,3)
ans=
5
2
>>f=inline('x+y','x','y')
f=
Inlinefunction:
f(x,y)=x+y
>>f(2,3)
ans=
5
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
创建句柄函数
str2func函数才支持生成匿名函数句柄
1.>>symsx
2.f=diff(sin(x)*exp(sqrt(x)),2)
3.g= str2func(['@(x)'vectorize(char(f))])
4.f1=quad(g,1,2)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
sqr=@(x)x.^2;
可以将它传递到其他函数的参数列表中。
下面的代码将sqr匿名函数传递给matlab函数quad来计算它从0到1的积分:
[c-sharp] viewplaincopyprint?
>> quad(sqr,0,1)
ans =
0.3333
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
匿名函数在定义过程中可以调用任何Matlab函数(包括用户自定义的函数),也可以使用当时Matlab工作区中存在的任何变量。
例如,下例中的匿名函数b_humpsab在定义时就是用了Matlab工作区中的变量a和b:
>> a = -.3;b=-.9;
>> b_humpsab = @ (x) 1./((x+a).^2+0.01)+1./((x+b).^2+0.04)-6;
>> b_humpsab([-1 0 1])
ans =
-5.1378 5.1765 16.0000
我们看到:
b_humpsab在定义时引用了前面定义的变量a和b。
应当注意,当a或b的值变化时,匿名函数并不改变,这是因为函数句柄值捕捉它创建时刻的变量的值,并不随变量的变化而变化。
>> a = 0; %changing the value of a does not chang the function.
>> b_humpsab([-1 0 1]) %evaluate again , get the same results
ans =
-5.1378 5.1765 16.0000
我们也可以针对一个内置函数或一个M文件函数创建匿名函数句柄。
下面函数分别给予M文件函数humps和Matlab内置函数cos创建了两个文件句柄:
>> c_Mfile = @humps %function handle for M-file function
c_Mfile =
@humps
>> c_Mfile
(1) %evaluate humps
(1)
ans =
16
>> c_builtin = @cos
c_builtin =
@cos
>> c_builtin(pi)
ans =
-1
由上面可知,要创建一个内置函数或一个M文件函数的句柄也很容易,只要在等号右边使用@符号,并在该符号后紧跟内置函数名或M文件函数名即可。
我们还可以利用单元数组同时创建多个内置函数和M文件函数的句柄,验证这些函数时,只要引用该函数所在单元即可。
例如,下面的代码将上面两个独立创建的句柄利用一个单元数组c_dan创建在一起:
>> c_dan = {@humps @cos}
c_dan =
@humps @cos
>>c_dan{1}
(1) %evaluate humps
(1)
ans =
16
>> c_dan{2}(pi) %evaluate cos(pi)
ans =
-1
Matlab还专门提供了一些函数来处理和应用句柄。
例如,函数functions将返回一个句柄的详细信息,如下例所示:
>> functions(c_Mfile)
ans =
function:
'humps'
type:
'simple'
file:
'C:
\Program Files\MATLAB\R2009a\toolbox\matlab\demos\humps.m'
>> functions(c_builtin)
ans =
function:
'cos'
type:
'simple'
file:
''
>> functions(b_humps)
ans =
function:
'@(x)1./((x+a).^2+0.01)+1./((x+b).^2+0.04)-6'
type:
'anonymous'
file:
''
workspace:
{[1x1 struct]}
需要注意的是:
fuctions函数通常只在调试程序时使用,因为它的返回值很容易发生变化。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
句柄函数
所谓句柄函数,个人理解其实和别名差不太多,比较类似于linux下alias命令,即可以对某个函数以别名来调用,而同时并不改变原来的命令名.这样当我们想使用某个函数的时候只要直接调用函数句柄而不用调用整个函数.
这里我们的函数句柄也是存放在变量的里面,我们知道在matlab环境中变量可以用来存放很多东西,包括数值,字符串等等,在这里不妨可以理解为存放函数.不过显然我们以前所调用的各个函数都是一个一个的m文件,不可能直接放到变量的里面,因此我们是抓住函数的句柄(handle)来实现.将句柄函数赋值给变量需要用到@符号,晕,@原来在matlab里面也是有的....
语法:
变量名=@函数名.此处的函数名可以使当前matlab中可以使用的任意函数.@的作用就是将一个函数的函数句柄赋值给等号左边的变量.在需要调用函数的时候直接调用句柄即可实现同样的功能.
示例
z=[123];s=@sum;s(z)
此后可以直接用使用s()来替代原来的求和函数sum().
匿名函数
匿名函数可以说是函数句柄的一种特殊的用法,这里所得到的函数句柄变量不指定向特定的函数(即不指向函数m文件中的函数名),而是指向一个具体的函数表达式.
语法:
变量名=@(输入参数列表)运算表达式示例
lc=@(x,y,z)(x*y*z);lc(2,3,4);
即可得到结果为24.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
varargin和varargout函数的使用举例:
functiontestvar(argA,argB,varargin)
optargin=size(varargin,2);
stdargin=nargin-optargin;
fprintf('Numberofinputs=%d\n',nargin)
fprintf('Inputsfromindividualarguments(%d):
\n',stdargin)
ifstdargin>=1
fprintf(' %d\n,argA')
end
ifstdargin==2
fprintf(' %d\n,argB')
end
fprintf('Inputspackagedinvarargin(%d):
\n',optargin)
fork=1:
size(varargin,2)
fprintf(' %d\n',varargin{k})
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
函数句柄的调用:
functionx=plotfhandle(fhandle,data)
plot(data,fhandle(data))
调用:
plotfhandle(@sin,-pi:
0.01:
pi)
函数句柄的操作:
functions:
返回函数句柄的相关信息
func2str:
根据函数句柄创建一个函数名的字符串
str2func:
由一个函数名的字符串创建一个函数句柄
save:
从当前工作区间向M文件保存函数句柄
load:
从一个M文件中向当前工作区间调用函数句柄
isa:
判断一个变量是否包含一个函数句柄
isequal:
判断两个函数句柄是否为某一相同函数的句柄
传送特定类型的参数
(1)传送字串
使用命令方式调用函数,本身就传送字串
使用函数方式调用函数时,被传送的字串一定要放在单引号内,其实这就是字串的定义。
要建立一个名为myapptests的新目录。
使用函数mkdir。
mkdir('myapptests')或
dirname='myapptests';
mkdir(dirname)或
mkdirmyapptests
(2)传送文件名
文件名可以作为参数传递,有两种方式:
对save和load函数,文件扩展名.mat是可选择的
loadmydata.mat 命令格式
load('mydata.mat') 函数格式
指定加载ASCII文件,文件扩展名.dat是必需的
loadmydata.dat-ascii 命令格式
load('mydata.dat','-ascii') 函数格式
指定输出给变量,一定用函数格式
savedata=load('mydata.dat')
函数执行时,如果程序中用到文件名,可以用下面的方法得到,而无须死板地将文件名编在代码中。
(作为一个参数传送文件名;
functionmyfun(datafile)
用input函数在提示符下写入:
filename=input('Enternameoffile:
','s');
(用uigetfile函数浏览文件
[filename,pathname]=uigetfile('*.mat','SelectMAT-File');
(3)传送函数句柄
函数句柄作为输入参数传送给另一个函数
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
当我们将一个函数名作为字符串传递给函数str2func时,也可以创建该函数的函数句柄。
如下例:
>>myfunc='humps' %placenameofhumps.minastringvariable
myfunc=
humps
>>fh2=@myfunc
?
?
?
Error:
"myfunc"waspreviouslyusedasavariable,
conflictingwithitsusehereasthenameofafunctionorcommand.
SeeMATLABProgramming,"HowMATLABRecognizesFunctionCallsThatUseCommand
Syntax"fordetails.
>>fh2=str2func(myfunc)
fh2=
@humps
>>fh2=str2func('humps')
fh2=
@humps
>>isequal(fh2,fh_Mfile)
ans=
1
func2str函数执行与str2func相反的操作,它从一个函数句柄中提取函数名,并保存戴一个字符串变量中。
当函数句柄是一个内置函数或M文件函数句柄时,该函数返回函数的名称,当函数句柄是一个匿名函数句柄时,该函数返回匿名函数的函数表达式。
如下,利用func2str函数分别从句柄fh2和af_humps中获取函数的名称:
>>func2str(fh2)
ans=
humps
>>func2str(af_humps)
ans=
@(x)1./((x+a).^2+0.01)+1./((x+b).^2+0.04)-6
>>class(ans)
ans=
char
>>isa(fh2,'function_handle')
ans=
1
函数句柄是Matlab提供给用户的一个强而有力的工具。
首先,当一个函数句柄被创建时,它将记录函数的详细信息(见前面的functions函数的返回结果),因此,当使用一个函数的句柄调用该函数时,Matlab会立即执行,不再要进行文件搜索。
尤其是当反复调用一个文件时,可以节省大量的搜索和时间,从而提高函数的执行效率。
函数句柄的另一个重要的特性是将它们可以用来标识子函数、私有函数和嵌套函数。
一般情况下,这些函数对于用户来说都是“隐蔽”的,这些标识对于用户正确使用这些函数非常有用。
例如,当我们在编写一个含有子函数的M文件时,可以为子函数创建一个句柄,并作为主函数的一个输出参数提供给用户,这样就是本来“隐蔽”的子函数“显现”出来,以便于用户对其进行验证和使用。
下面的M文件函数框架(因为该函数并不执行实际有意义的操作)演示了一个在主函数中返回子函数句柄的例子:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
functionout=myfunction(select)
%MYFUNCTIONReturnfunctionhandletoasubfunction.
%Examplefunctiondemonstratingfunctionhandlestosubfunction
switchselect
case'case1'
out=@local_subfun1;
case'case2'
out=@local_subfun2;
otherwise
out=[];
error('UnknownInput');
end
functiona=local_fun1(b,c)
%LOCAL_SUBFUNSomefunctionoperation.
%codethatoperatesontheinputargumentsbandc
%andreturnscontentinthevariablea
%endoflocal_subfun1
functiond=local_fun2(e,f)
%LOCAL_SUBFUNCSomefunctonoperation.
%codethatoperatesontheinputargumentseandf
%andreturnscontentinthevariabled
%endofloacl_fun2
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
下面的代码通过设置select参数的值获取了一个子函数的句柄,并在主函数的调用环境中调用这个子函数:
>>h_subfun=myfunction('case2');
>>dout=h_subfun(x,y);
上面代码之所以能运行,是因为子函数句柄记录了子函数的所有信息,包括子函数的声明、代码和位置等。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clc;clear;
symsx;
y=x^3+2*x^2+x+1;
dy=diff(y,x);
ddy=diff(dy,x);
ddy11=@(x)eval_r(diff(dy,x));
ddy12=@(x)eval_r(ddy);
ddy21=inline(eval_r(diff(dy,x)));
ddy22=inline(eval_r(ddy));
ddy11=ddy11
(2)
ddy12=ddy12
(2)
ddy21=ddy21
(2)
ddy22=ddy22
(2)
为什么ddy11和ddy12,ddy21,ddy22所得的值不一样呢?
inline函数和@究竟有些什么区别?
请高手指点!
!
谢谢!
!
恩是这个原因在使用@创建匿名函数时,@(varlist)之后的表达式一般不能是符号变量,只能是因变量和常数
但是inline函数可以将符号表达式转换为inline函数
另外eval计算的也是字符串表达式的结果,一般不处理符号表达式,如果表达式不是字符串,Matlab使用char函数将其转换为字符串
总结性说,inline()可以将符号表达式转换为函数,@()不可以,匿名函数一般用于自定义简单函数
我们来分析下ddy11=@(x)eval_r(diff(dy,x));
首先将计算diff(dy,x)返回符号表达式6*x+4,eval不管它的输入参数是什么,首先使用char函数将输入参数符号表达式6*x+4转换为字符串'6*x+4',然后创建匿名函数,该匿名函数将调用eval函数进行计算函数值
上面分析是我们认为的过程,好像没有问题!
其实问题出在了diff(dy,x),由于Matlab中diff的参数可以多种格式,而匿名函数直接提供了x的值,此时Matlab直接将x看成是对dy的x次导数,而不是对dy进行关于变量x的一阶就到,故实际过程是
1、调用匿名函数的时候,将数据x直接传递给嵌套函数eval
2、此时x是一个常数,不是一个符号变量
3、diff(dy,x)对dy进行x阶级求导,注意不是对dy进行关于x的一阶导数
4、导数计算完毕后,eval函数将返回的参数转换为字符串
5、eval计算函数值
也许你会问,为什么只是将diff(
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- matlab 匿名函数 函数句柄 匿名 函数 句柄