Octave中的函数句柄格式

4
Octave中的函数处理方式如下所示:
f = @sin;

从现在开始,调用函数f(x)与调用sin(x)具有相同的效果。到目前为止一切顺利。我的问题始于下面这个函数,它来自我的编程作业之一。

function sim = gaussianKernel(x1, x2, sigma)

上面的行表示函数 gaussianKernel 的头部。 它需要三个变量作为输入。但是,下面的调用让我困惑,因为它只传递了两个变量,然后在引用 gaussianKernel 时又传递了三个变量。
model = svmTrain(X, y, C, @(x1, x2) gaussianKernel(x1, x2, sigma));

这不应该只是简单地写成model = svmTrain(X, y, C, @gaussianKernel(x1, x2, sigma));吗?这有什么区别呢?

2个回答

5
您没有提供相关代码,但我猜测变量sigma在调用model = svmTrain(X, y, C, @(x1, x2) gaussianKernel(x1, x2, sigma));之前在代码中已被定义。这是一个参数化匿名函数的示例,可以捕获当前作用域中变量的值。这也被称为闭包。看起来Matlab有更好的文档介绍了这种非常有用的编程模式。

函数句柄@gaussianKernel(x1, x2, sigma)等同于@gaussianKernel。如果要求svmTrain的第四个参数必须是带有两个输入参数的函数,则使用model = svmTrain(X, y, C, @gaussianKernel(x1, x2, sigma));可能无法正常工作。


2

sigma变量已经在代码的其他地方定义过了。因此,svmTrain从现有作用域中提取该值。

创建匿名函数@(x1, x2) gaussianKernel(x1, x2, sigma)的目的是创建一个只接受两个参数而不是三个参数的函数。如果您查看svmTrain中的代码,它会接受一个参数kernelFunction并仅使用两个参数调用它。实际上,svmTrain本身并不关心sigma的值,只知道传递给它的kernelFunction应该只有两个参数。

另一种方法是定义一个新函数:

function sim = gKwithoutSigma(x1, x2)
    sim = gaussianKernel(x1, x2, sigma)
endfunction

请注意,这必须在首次调用svmTrain的脚本中定义。然后,您可以如下调用svmTrain
model = svmTrain(X, y, C, @gKwithoutSigma(x1, x2))

使用匿名参数函数可以避免编写额外的代码来实现 gKwithoutSigma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接