MATLAB:按特定行减去矩阵子集

标签 matlab matrix vectorization

这是我要使用的矩阵子集的一个示例:

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/

相关文章:

arrays - 一维向量与三维数组相乘求和的向量化

c++ - 如何将 MATLAB 图像处理库内置函数转换为 matlab coder 代码生成不支持的 c++?

matlab - 一旦创建了 Matlab 结构,如何使它保持不变?

r - 使用 R 将矩阵划分为 N 个大小相等的 block

gcc - 使用 GCC 进行循环版本控制

matlab - Camera Calibration Intrinsic Matrix 值代表什么?

matrix - Kotlin:对矩阵中各行元素求和的优雅方法?

python - 从 Numpy 中的 2 个向量形成矩阵,重复 1 个向量

c# - 在 CLR C++ 库中使用 SIMD

matlab - 向量化嵌套的 for 循环和 if 语句