1

我有两个二维矩阵 a 和 b。让我们说a = randn(10, 20)b = randn(10, 30)。我想计算笛卡尔和!这两个数组中,即a的每一列和b的每一列都应该选择一次,并加在一起形成一个大小为(10, 20*30)的矩阵c。这可以通过使用bsxfunpermutereshapeas 来完成:

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,then 并行添加正确索引的矩阵值以用于[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 回答