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));
吗?有什么区别?
答案 0 :(得分:5)
您没有提供周围的代码,但我的猜测是在调用sigma
之前在代码中定义了变量model = svmTrain(X, y, C, @(x1, x2) gaussianKernel(x1, x2, sigma));
。它是parametrized anonymous function的一个示例,它捕获当前范围中变量的值。这也称为closure。对于这个非常有用的编程模式,看起来Matlab有better documentation。
函数句柄@gaussianKernel(x1, x2, sigma)
等同于@gaussianKernel
。如果model = svmTrain(X, y, C, @gaussianKernel(x1, x2, sigma));
的第四个参数必须是具有两个输入参数的函数,则使用svmTrain
在这种情况下可能不起作用。
答案 1 :(得分: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
编写额外的代码。