2017-08-25 81 views
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));?有什么不同?

回答

5

您没有提供周围的代码,但我的猜测是在调用model = svmTrain(X, y, C, @(x1, x2) gaussianKernel(x1, x2, sigma));之前在代码中定义了变量sigma。这是一个parametrized anonymous function的示例,它捕获当前范围中变量的值。这也被称为closure。它看起来像Matlab有better documentation这个非常有用的编程模式。

函数句柄@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