1

同じ長さの2つのベクトルがあるとします。

A = [1 2 2 1];
B = [2 1 2 2];

dim = m * n、m = max(A)、n = max(B)の行列Cを作成したいと思います。

C = zeros(m,n);
for i = 1:length(A)
   u = A(i);
   v = B(i);
   C(u,v)=C(u,v)+1;
end

取得します

C =[0 2;
    1 1]

より正確には、AとBの対応するインデックスをCの行と列として扱い、C(u、v)は{k | A(i)= uおよびB(i)= v、i = 1,2、...、length(A)}

それを行うためのより速い方法はありますか?

4

1 に答える 1

4

はい。スパースを使用します。行と列のペアを繰り返すためのマトリックス値を組み立てます(つまり、合計します)。マトリックスエントリにアセンブルされる値を持つ追加のベクトルが必要です。ones(size(A))を使用すると、必要なものが正確に得られます-繰り返される行と列のペアのカウント

spA=sparse(A, B, ones(size(A)));
full(spA)

ans =

 0     2
 1     1

同じことは、値のベクトルの代わりにスカラー1をスパース関数に渡すだけで取得できます。

ゼロエントリが多数ある行列の場合、これはスパースストレージを使用することが絶対に重要です。使用できるもう1つの関数はaccumarrayです。それは本質的に同じことをすることができますが、密なマトリックス構造でも機能します:

AA=accumarray([A;B]', 1);

AA =

 0     2
 1     1

特定のサイズの行列を作成する場合は、size引数をaccumarrayに渡すことができます

AA=accumarray([A;B]', 1, [2 3]);
AA =

 0     2     0
 1     1     0

実際には、スパース行列を生成し、アセンブリで別の演算子を使用することもできます(つまり、必ずしも合計ではないことに注意してください)。

AA=accumarray([A;B]', 1, [2 3], @sum, 0, true)

アセンブリの合計と塗りつぶし値として0を使用して、スパース行列(最後のパラメーターをtrueに設定)を生成します。つまり、特定の行と列のペアがA/Bに存在しない場合に使用される値です。

于 2012-09-16T18:08:59.600 に答える