1

2つの2次元行列aとbがあります。a = randn(10, 20)と言いましょうb = randn(10, 30)。デカルト和を計算したい!これらの2つの配列のうち、aの各列とbの各列を一度選択し、サイズ(10、20 * 30)の行列cに一緒に追加する必要があります。bsxfunこれは、、、permuteおよびreshapeasを使用して実行できます。

c = bsxfun(@plus, a, permute(b, [1 3 2]));
c = reshape(c, [size(a,1), size(a,2)*size(b,2)]);

並べ替えや再形成を必要とせずに、これを行うためのより高速でより直接的な方法が存在するかどうか疑問に思いました。このためのmex関数を書くのは簡単ですが、mexが必要かどうか疑問に思います。

ありがとう!

4

2 に答える 2

1

最も直接的なアプローチが最も速い場合もあります。

c = zeros(size(a, 1), size(a, 2) * size(b, 2));
ic = 1;
for ib = 1:size(b, 2)
    for ia = 1:size(a, 2)
        c(:, ic) = a(:, ia) + b(:, ib);
        ic = ic + 1;
    end
end

a = randn(10, 20); 
b = randn(10, 30);

% # Originally proposed method
tic
c1 = bsxfun(@plus, a, permute(b, [1 3 2]));
c1 = reshape(c1, [size(a, 1), size(a, 2) * size(b, 2)]);
toc

% # Method suggested by gevang
tic
[pB, pA] = meshgrid(1:size(b, 2), 1:size(a, 2));
c2 = a(:, pA(:)) + b(:, pB(:));
toc

% # Direct approach
tic
c3 = zeros(size(a, 1), size(a, 2) * size(b, 2));
ic = 1;
for ib = 1:size(b, 2)
    for ia = 1:size(a, 2)
        c3(:, ic) = a(:, ia) + b(:, ib);
        ic = ic + 1;
    end
end
toc

結果は次のとおりです。

 Elapsed time is 0.005850 seconds.
 Elapsed time is 0.009442 seconds.
 Elapsed time is 0.000328 seconds.

ご覧のとおりfor、この場合の二重ループはほぼ 20 倍高速です...

于 2012-10-30T00:27:40.237 に答える
0

すべての列インデックスの組み合わせを前もって生成できます。たとえばmeshgrid,、適切にインデックス付けされたマトリックス値を並列に追加して、[size(a,1), size(a,2)*size(b,2)]最終的な値のマトリックスを作成します。

a = randn(10, 20); 
b = randn(10, 30);

[pA, pB] = meshgrid(1: size(a,2), 1: size(b,2));
c = a(:, pA(:)) + b(:, pB(:));
于 2012-10-29T23:58:15.437 に答える