Loading...
墨滴

图像处理与MATLAB

2021/09/27  阅读:20  主题:姹紫

匿名函数(Anonymous Function)

匿名函数(Anonymous Function)

今天分享的内容是匿名函数,虽然比较基础,但却很重要。

匿名函数在编程过程中非常常见,用好它可以起到事半功倍的效果。下面分别讨论下 Matlab 和 Python 中的匿名函数。

Matlab 中的匿名函数

基础用法

匿名函数是存储在程序文件中、但与数据类型是 function_handle 的变量相关的函数,它是 MATLAB 函数的一种简单形式,其语法为:

funcHandle = @(arglist) expression

其中arglist是输入参数列表,expression是匿名函数的函数体(matlab 的有效表达式),funcHandle是返回的函数句柄,数据类型为function_handle

等号右边必须以@符号开始,@符号获得此函数的句柄。匿名函数可以接受多个输入并返回一个输出。

例如

sqr = @(x) x.^2
sqr(6)

ans =

    36

注:不包含任何输入参数时,@后面的参数列表仍然用空的括号表示,以表示后面表达式是函数,如

t = @() datestr(now);

调用此匿名函数同样也要使用括号。

t()

ans =

    '06-Apr-2021 22:05:15'

匿名函数数组

可以建立匿名函数数组,用单元数组来存储,如

A = {@(x) x .^ 2; @(y) y + 10; @(x, y) x .^ 2 + y + 10};

调用情况如下:

A{1}(4) + A{2}(7);
A{3}(47);

在函数定义中使用空格可增加函数的可读性,但是在单元数组(Cell Array)中定义的匿名函数体中使用空格却容易产生歧义。解决办法如下:

a1 = @(x) x .^ 2;
a2 = @(y) y + 10;
a3 = @(x, y) x .^ 2 + y + 10;
a = {a1; a2; a3};

匿名函数的嵌套

许多 MATLAB^®^ 函数接受将函数句柄用作输入,这样可以在特定值范围内计算函数。

例如,通过将函数句柄传递到 integral 函数,计算 sqr 函数从 01 范围内的积分:

q = integral(sqr, 01)
q =

    0.3333

当然,对于简单函数可以在表达式内创建临时函数句柄,上面例子也可以重写为:

q = integral(@(x) x.^201);

匿名函数中的表达式可以包含其他匿名函数。例如计算下面的定积分:

具体过程如下:

  • 将被积函数写成匿名函数

    @(x) (x.^2 + c*x + 1)
  • 通过将函数句柄传递给integral,从0到1求函数值

    integral(@(x) (x.^2 + c*x + 1), 01)
  • 通过为整个方程构造一个匿名函数来提供c的值

    g = @(c) (integral(@(x) (x.^2 + c*x + 1), 01))g(2)ans =    2.3333

带有多个输入或输出的函数

匿名函数需要像标准函数一样显式指定输入参数,用逗号隔开多个输入。例如,以下函数接受两个输入 xy

myfunction = @(x, y) (x^2 + y^2 + x*y);x = 1;y = 10;z = myfunction(x, y)z =   111

然而,匿名函数只返回一个输出。如果函数中的表达式返回多个输出,那么我们可以在调用函数句柄时请求他们。

例如,ndgrid 函数可以返回与输入向量数量一样多的输出。调用 ndgrid 的匿名函数只返回一个输出 (mygrid)。通过调用 mygrid 可访问 ndgrid 函数返回的输出。

c = 10;mygrid = @(x, y) ndgrid((-x :x/c:x), (-y:y/c:y));[x, y] = mygrid(pi2*pi);

当然,可以使用mygrid的输出来创建一个网格或曲面图:

z = sin(x) + cos(y);mesh(x, y, z)

应用

除了将函数句柄作为输入参数传递给另一个函数使用外,一般应用匿名函数完全是因为其简单和方便。

比如我们要将当前路径中名为toolbox_signal的文件夹加载到 Matlab 的搜索路径,那么可以用下面的语句来处理这样的事

addp = @(p) path(p, path);% Oraddp = @(p) addpath(genpath(p));% Executeaddp('toolbox_signal')

去年在知乎上遇到了这样的一个提问:https://www.zhihu.com/question/434149196

如何用MATLAB设计计算阶乘的函数?主程序调用该函数计算:求和1/n!,n=1:100

非常喜欢易夕的回答:

f1 = @(n) sum(1./factorial(n));% Orf2 = @(n) sum(1./cumprod(1:n));% Recommendf = @(n) sum(1./cumprod(1:min(n, 18)));f(100)ans =    1.7183

还有更多的例子......

因此,我们在搬砖的过程中,如果是一个简短的表达式,那么没必要用function定义函数,将其定义为匿名函数会更合适些。

Python 中的匿名函数

Python 中的匿名函数也称为 Lambda 表达式,只是语法规则与 Matlab 不同而已,剩下的完全是照猫画虎。

具体的语法规则为:

funcHandle = lambda arglist: expression

其中arglist为输入参数列表,expression为有效的 Python 表达式,funcHandle为函数句柄(或者是对象:Python中万物皆对象啊)

下面以简单的例子说明最基本的用法:

无输入参数形式

import datetimefunc = lambda: datetime.datetime.now()func()>>> datetime.datetime(202146103818114044)

有参数形式

from scipy import integrateg = lambda c: (integrate.quad(lambda x: (x**2 + c*x + 1), 01))[0]g(2)>>> 2.3333333333333335

匿名函数数组

b1 = lambda x: x ** 2b2 = lambda x, y: (x + y) ** 2b = list([b1, b2])b[0](6)b[1](36)

结语

以上总结了 Matlab 和 Python 中关于匿名函数的一些基本用法,我们只要熟悉一种语言的用法就可以了,除了语法规则不同外,其余基本上都通用。

希望今天分享的内容能对朋友们有所帮助和方便查阅。

参考文献

https://www.mathworks.com/help/matlab/matlab_prog/anonymous-functions.html

图像处理与MATLAB

2021/09/27  阅读:20  主题:姹紫

作者介绍

图像处理与MATLAB