这是我要使用的矩阵子集的一个示例:
1 3 5
2 3 6
1 1 1
3 5 4
5 5 5
8 8 0
该矩阵实际上为3000 x 3。
对于前三行,我希望将这三行中的每一行减去这三行中的第一行。
对于后三行,我希望将这三行中的每一行相减,以此类推。
这样,输出矩阵将如下所示:
0 0 0
1 0 1
0 -2 -4
0 0 0
2 0 1
5 3 -4
MATLAB中的哪些代码将为我做到这一点?
最佳答案
稍微短一些和向量化的方式将会是(如果a
是您的矩阵):
b=a-kron(a(1:3:end,:),ones(3,1));
让我们测试一下:
a=[1 3 5
2 3 6
1 1 1
3 5 4
5 5 5
8 8 0]
a-kron(a(1:3:end,:),ones(3,1))
ans =
0 0 0
1 0 1
0 -2 -4
0 0 0
2 0 1
5 3 -4
编辑
这是一个bsxfun解决方案(虽然不太优雅,但是希望更快):
a-reshape(bsxfun(@times,ones(1,3),permute(a(1:3:end,:),[2 3 1])),3,[])'
ans =
0 0 0
1 0 1
0 -2 -4
0 0 0
2 0 1
5 3 -4
编辑2
好的,这让我感到好奇,因为我知道bsxfun对于更大的阵列大小开始变得效率较低。因此,我尝试使用
timeit
检查我的两个解决方案(因为它们是一种衬板,所以很容易)。这里是:range=3*round(logspace(1,6,200));
for n=1:numel(range)
a=rand(range(n),3);
f=@()a-kron(a(1:3:end,:),ones(3,1));
g=@() a-reshape(bsxfun(@times,ones(1,3),permute(a(1:3:end,:),[2 3 1])),3,[])';
t1(n)=timeit(f);
t2(n)=timeit(g);
end
semilogx(range,t1./t2);
因此,我没有测试for循环和Divkar的bsxfun,但是您可以看到,对于小于3e4的数组,kron比bsxfun更好,并且这种变化在较大的数组上(比率<1意味着kron花费的时间更少。数组)。这是在Matlab 2012a win7(i5机器)上完成的
关于MATLAB:按特定行减去矩阵子集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23879888/