Octave 中的函数句柄格式

Function handle formats in Octave

Octave中的函数句柄定义如下例。

f = @sin;

从现在开始,调用函数f(x)与调用sin(x)效果相同。到目前为止,一切都很好。我的问题始于我的一项编程作业中的以下函数。

function sim = gaussianKernel(x1, x2, sigma)

上面这行表示函数gaussianKernel的header。这需要三个变量作为输入。但是,下面的调用让我很困惑,因为它只传递了两个变量,然后在引用 gaussianKernel.

时传递了三个变量
model = svmTrain(X, y, C, @(x1, x2) gaussianKernel(x1, x2, sigma));

不应该是model = svmTrain(X, y, C, @gaussianKernel(x1, x2, sigma));吗?有什么区别?

你没有提供周围的代码,但我的猜测是在调用model = svmTrain(X, y, C, @(x1, x2) gaussianKernel(x1, x2, sigma));之前的代码中定义了变量sigma。这是一个非常有用的编程模式的 parametrized anonymous function that captures the values of variables in the current scope. This is also known as a closure. It looks like Matlab has better documentation 示例。

函数句柄 @gaussianKernel(x1, x2, sigma) 等同于 @gaussianKernel。如果要求 svmTrain 的第四个参数是具有两个输入参数的函数,则在这种情况下使用 model = svmTrain(X, y, C, @gaussianKernel(x1, x2, sigma)); 可能不起作用。

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 编写额外的代码。