我有两个2d矩阵a和b。我们说a = randn(10, 20)
和b = randn(10, 30)
。我想计算笛卡尔和!这两个阵列中的每一个,即每列a和b的每一列应该被选择一次,并且一起加入到尺寸为(10,20 * 30)的矩阵c中。这可以通过使用bsxfun
,permute
和reshape
来完成:
c = bsxfun(@plus, a, permute(b, [1 3 2]));
c = reshape(c, [size(a,1), size(a,2)*size(b,2)]);
我想知道是否存在更快更直接的方式,而不需要置换或重塑。我知道为此编写一个mex函数很容易,但我想知道是否有必要使用mex。
谢谢!
答案 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(:));