笛卡尔矩阵的总和没有置换或重塑

时间:2012-10-29 21:17:17

标签: matlab bsxfun

我有两个2d矩阵a和b。我们说a = randn(10, 20)b = randn(10, 30)。我想计算笛卡尔和!这两个阵列中的每一个,即每列a和b的每一列应该被选择一次,并且一起加入到尺寸为(10,20 * 30)的矩阵c中。这可以通过使用bsxfunpermutereshape来完成:

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

我想知道是否存在更快更直接的方式,而不需要置换或重塑。我知道为此编写一个mex函数很容易,但我想知道是否有必要使用mex。

谢谢!

2 个答案:

答案 0 :(得分: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倍......

答案 1 :(得分: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(:));