2016-12-10 12 views
1

具体的には、ベクトルを入力として受け取り、出力としてスカラーを生成するカーネル関数からカーネル行列を作成しようとしています。カーネル行列は、ベクトルの各対に対するそのような出力の2次元行列である。ベクトル入力の場合Matlabのベクトルのbsxfun型関数はありますか?

自体は1Dであり、Iはbsxfunこれに行う使用することができます:予想通り

x = [1;2;3;4]; kerfun = @(s,t) (s-t) % some function, doesn't matter, except that it returns a scalar kernel = bsxfun(kerfun, x, x');

出力は、カーネルである:

kernel = 

    0 -1 -2 -3 
    1  0 -1 -2 
    2  1  0 -1 
    3  2  1  0 

しかし、 xの点をNDベクトルに変更すると、この方法は失敗します。私の質問です:ループを使用せずにカーネル行列を構築する効率的な方法はありますか?私はcellfunを使ってみましたが、どちらもうまくいきませんでした。ありがとう。

編集:次のように私はxkerfunを変更した場合に期待される成果の一例として、:

x = [1,15;23,2;13,5;4,7]; 
kerfun = @(s,t) norm(s-t); %some function, returns a scalar 
ker = zeros(4,4); 

その後、力ずくでカーネルを計算する:

for i=1:size(x,1) 
    for j=1:size(x,1) 
     ker(i,j) = kerfun(x(i,:),x(j,:)); 
    end 
end 

私が手:

ker = 

     0 25.5539 15.6205 8.5440 
    25.5539   0 10.4403 19.6469 
    15.6205 10.4403   0 9.2195 
    8.5440 19.6469 9.2195   0 
+1

を生成し、あなたは私たちの例の入力と期待される出力を表示することができますか? 'bsxfun'は、正しい形状ならどんな次元の入力でも動作します。 – Suever

+0

こんにちは、私は質問を更新しました。今見てください。私はこれが私が求めている質問を明確にすることを願っています。関数評価(bsxfunのような)が要素ごとにではなくベクトルに基づく関数評価の行列を返すようにしたいと思います。 (2番目の例ではxのように)ベクトルのリストを与えると、xとx 'が通常同じサイズではないので、bsxfunがクラッシュします。さらに、マトリックスの数字は間違っていて、私が探しているドロイドではありません。 – nevakanezzar

+0

あなたはフィルタ/畳み込みをしていますよね? – beaker

答えて

1

bsxfunは、N次元配列で、シングルトンディメンションを拡張します。しかしそれは要素的に機能します。あなたの例のように、行に沿って何らかの「集約」操作を行う関数が必要な場合は、bsxfunは要素単位の部分(シングルトン拡張あり)しか実行できません。最終結果を得るには、他の集約関数を補完する必要があります。

例の特定の場合、必要な関数は要素ごとの減算(これはbsxfunになります)に分解し、行(集計部分)、要素ごとの平方根に沿って合計することができます。 bsxfunで減算を行うには、xのコピーの最初のディメンションを3番目のディメンションに並べ替える必要があります。そのようにして、第1および第3次元は、あなたの2つのループ内でijのすべての組み合わせに及んでいます。

次に、得られた3次元アレイの第2の次元に沿う合計の平方根をとること、およびマトリックス結果を有するようにバック入れ替え:

ker = sqrt(permute(sum(bsxfun(@minus, x, permute(x, [3 2 1])).^2, 2), [1 3 2])); 

注意がbsxfunの組み込みのいずれかを使用する高速だと関数(例えば、minusなど)はカスタム関数よりも優先されます。

x = [1,15;23,2;13,5;4,7]については、これは

ker = 
     0 25.5539 15.6205 8.5440 
    25.5539   0 10.4403 19.6469 
    15.6205 10.4403   0 9.2195 
    8.5440 19.6469 9.2195   0 
関連する問題