这里有一种替代方法,不像
Luis Mendo的答案那样生成一个完整的矩阵来选择块对角线元素,而是直接生成这些元素的索引。对于非常大的矩阵来说,创建索引矩阵会很昂贵,因此这种方法可能会更快。
AA = rand(8,8);
n = 2;
m=size(AA,1);
bi = (1:n)+(0:m:n*m-1).';
bi = bi(:);
di = 1:n*(m+1):m*m;
BB = AA(di+bi-1);
BB = reshape(BB,n,[]).'
基准测试
AA = rand(5000);
n = 2;
BB1 = method1(AA,n);
BB2 = method2(AA,n);
BB3 = method3(AA,n);
assert(isequal(BB1,BB2))
assert(isequal(BB1,BB3))
timeit(@()method1(AA,n))
timeit(@()method2(AA,n))
timeit(@()method3(AA,n))
function BB = method1(AA,n)
m = size(AA,1);
BB = zeros(m,n);
for i = 1:m/n
BB(n*(i-1)+1:n*i,:) = AA(n*(i-1)+1:n*i,n*(i-1)+1:n*i);
end
end
function BB = method2(AA,n)
mask = repelem(logical(eye(size(AA,1)/n)), n, n);
BB = reshape(permute(reshape(AA(mask), n, n, []), [1 3 2]), [], n);
end
function BB = method3(AA,n)
m = size(AA,1);
bi = (1:n)+(0:m:n*m-1).';
bi = bi(:);
di = 0:n*(m+1):m*m-1;
BB = reshape(AA(di+bi),n,[]).';
end
在我的电脑上,使用MATLAB R2017a,我得到以下结果:
method1
(OP的循环):0.0034秒
method2
(Luis的掩码矩阵):0.0599秒
method3
(Cris的索引):1.5617e-04秒
请注意,对于一个5000x5000的数组,这个答案中的方法比一个循环快约20倍,而循环又比Luis的解决方案快约20倍。
对于较小的矩阵,情况略有不同,对于50x50的矩阵,Luis的方法几乎比循环代码快两倍(尽管这个方法仍然比它快约3倍)。
AA
的大小总是可以被2整除的吗? - Luis Mendo