2017-08-25 8 views
4

Octaveでの関数ハンドルは以下の例として定義されています。機能f(x)を呼び出すオクターブでの関数ハンドルフォーマット

今から
f = @sin; 

は、sin(x)を呼び出すのと同じ効果があります。ここまでは順調ですね。私の問題は、以下の私のプログラミング課題からの機能から始まります。

function sim = gaussianKernel(x1, x2, sigma) 

上記の行は、関数gaussianKernelのヘッダーを表します。これは3つの変数を入力として受け取ります。しかし、以下の呼び出しは、gaussianKernelを参照している間に、2つの変数と3つしか渡していないので、私の心が混乱します。

model = svmTrain(X, y, C, @(x1, x2) gaussianKernel(x1, x2, sigma)); 

単純にmodel = svmTrain(X, y, C, @gaussianKernel(x1, x2, sigma));ではありませんか?違いはなんですか?

答えて

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に相当します。 svmTrainの第4引数が2つの入力引数を持つ関数である必要がある場合、model = svmTrain(X, y, C, @gaussianKernel(x1, x2, sigma));を使用すると、この場合には機能しない可能性があります。

2

sigma変数はすでにコード内の他の場所で定義されています。したがって、svmTrainはその値を既存のスコープから引き出します。

匿名関数@(x1, x2) gaussianKernel(x1, x2, sigma)を作成する目的は、3つではなく2つの引数をとる関数を作成することです。 svmTrainのコードを見ると、パラメータkernelFunctionが入力され、2つの引数だけが呼び出されます。 svmTrain自体はsigmaという値には関係せず、実際にはkernelFunctionに2つの引数しか渡されていないことがわかります。これが最初の場所でsvmTrainを呼び出すスクリプト内のどこかに定義されなければならないことを

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

注:

別のアプローチは、新しい関数を定義することであっただろう。次に、あなたのようにsvmTrainを呼び出すことができます:匿名のパラメータ化機能を使用して

model = svmTrain(X, y, C, @gKwithoutSigma(x1, x2)) 

gKwithoutSigmaのための余分なコードを記述する必要がなくなります。

関連する問題