Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 沿对角线的子集对称矩阵_Arrays_Matlab_Matrix - Fatal编程技术网

Arrays 沿对角线的子集对称矩阵

Arrays 沿对角线的子集对称矩阵,arrays,matlab,matrix,Arrays,Matlab,Matrix,我有一个8x8矩阵,例如A=rand(8,8)。我需要做的是沿着对角线将所有2x2矩阵子集。这意味着我需要保存矩阵A(1:2,1:2),A(3:4,3:4),A(5:6,5:6),A(7:8,7:8)。为了更好地解释我自己,我目前使用的版本如下: AA = rand(8,8); BB = zeros(8,2); for i = 1:4 BB(2*i-1:2*i,:) = AA(2*i-1:2*i,2*i-1:2*i); end 这适用于小型AA矩阵和小型AA子矩阵,但是,随着

我有一个8x8矩阵,例如
A=rand(8,8)
。我需要做的是沿着对角线将所有2x2矩阵子集。这意味着我需要保存矩阵
A(1:2,1:2)
A(3:4,3:4)
A(5:6,5:6)
A(7:8,7:8)
。为了更好地解释我自己,我目前使用的版本如下:

 AA = rand(8,8);
 BB = zeros(8,2);
 for i = 1:4
     BB(2*i-1:2*i,:) = AA(2*i-1:2*i,2*i-1:2*i);
 end
这适用于小型
AA
矩阵和小型
AA
子矩阵,但是,随着大小的显著增长(甚至可以达到50000x50000),使用
for
循环(如上图中的循环不可行)。有没有一种方法可以在没有循环的情况下实现上述目标?我想到了其他可能利用上三角矩阵和下三角矩阵的方法,然而,即使这些方法似乎在某些点上也需要一个循环。感谢您的帮助

这里有一个方法:

AA = rand(8,8); % example matrix. Assumed square
n = 2; % submatrix size. Assumed to divide the size of A
mask = repelem(logical(eye(size(AA,1)/n)), n, n);
BB = reshape(permute(reshape(AA(mask), n, n, []), [1 3 2]), [], n);

这将生成一个选择所需元素的矩阵,然后使用and根据需要重新排列它们。

这里有一个替代方法,它不生成完整矩阵来选择块对角线,如中所示,而是直接生成这些元素的索引。对于非常大的矩阵,这可能会更快,因为在这种情况下创建索引矩阵的成本会很高

AA=rand(8,8);%示例矩阵。假定平方
n=2;%子矩阵大小。被假定为划分一个物体的大小
m=尺寸(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=重塑(BB,n,[])。%按所需顺序放置这些元素

基准
AA=rand(5000);%不能做50000x50000,因为太大了!
n=2;
BB1=方法1(AA,n);
BB2=方法2(AA,n);
BB3=方法3(AA,n);
断言(相等(BB1,BB2))
断言(相等(BB1,BB3))
timeit(@()方法1(AA,n))
timeit(@()方法2(AA,n))
timeit(@()方法3(AA,n))
%奥普氏环
函数BB=method1(AA,n)
m=尺寸(AA,1);
BB=零(m,n);
对于i=1:m/n
BB(n*(i-1)+1:n*i,:)=AA(n*(i-1)+1:n*i,n*(i-1)+1:n*i);
结束
结束
%路易斯面具矩阵
函数BB=method2(AA,n)
遮罩=重复(逻辑(眼睛大小(AA,1)/n)),n,n;
BB=整形(置换(整形(AA(掩模),n,n,[]),[1 3 2]),[],n);
结束
%克里斯指数
函数BB=method3(AA,n)
m=尺寸(AA,1);
bi=(1:n)+(0:m:n*m-1)。”;
bi=bi(:);
di=0:n*(m+1):m*m-1;
BB=重塑(AA(di+bi),n,[]);
结束
在我的计算机上,通过MATLAB R2017a,我得到:

  • 方法1
    (OP循环):0.0034秒
  • 方法2
    (路易斯面具矩阵):0.0599秒
  • 方法3
    (Cris’索引):1.5617e-04 s
请注意,对于5000x5000阵列,此答案中的方法比循环快约20倍,而循环比Luis的解决方案快约20倍


对于较小的矩阵,情况略有不同,Luis的方法的速度几乎是50x50矩阵循环代码的两倍(尽管这种方法仍然比它快约3倍)。

AA的大小是否总是可以被2整除?不一定。我们需要子集的矩阵的大小可能会改变,但它们始终是原始矩阵的完美除法器。例如,对于当前矩阵,我们还可以沿对角线将所有4x4矩阵子集(但不包括3x3或5x5)。对于9x9矩阵,我们将沿着对角线对3x3矩阵进行子集,等等,LM,即slick@greengrass62谢谢:-)这太棒了!我自己永远也不会想出这么优雅的东西。非常感谢@很高兴你喜欢它你会恨我的。你可能已经这么做了。OP的循环代码比我的计算机上的此解决方案快20倍左右。:)