Matlab:基于子矩阵重塑大型矩阵的最佳方法是什么

Matlab:基于子矩阵重塑大型矩阵的最佳方法是什么,matlab,matrix,reshape,Matlab,Matrix,Reshape,我有一个250乘200的大矩阵。里面是50乘50小的5乘4矩阵 重塑矩阵的最佳方式是什么,以使2500个5×4的较小矩阵水平对齐?因此,大型矩阵的末端尺寸应为5×10000。您可以使用,然后最终使用返回矩阵。出于演示目的,我使用了变量n和m。对于你的矩阵,他们都是50 以下代码按您在注释中阐明的行进行操作: 注意:重塑按列操作。因此,我们需要将X转换为”,或者在使用重塑之前,如上面的代码所示。Matlab的重塑函数非常方便(快速),但总是能够读取和写入完整的列。因此,对于您的问题,需要采取一些额

我有一个250乘200的大矩阵。里面是50乘50小的5乘4矩阵

重塑矩阵的最佳方式是什么,以使2500个5×4的较小矩阵水平对齐?因此,大型矩阵的末端尺寸应为5×10000。

您可以使用,然后最终使用返回矩阵。出于演示目的,我使用了变量
n
m
。对于你的矩阵,他们都是50

以下代码按您在注释中阐明的行进行操作:


注意:
重塑
按列操作。因此,我们需要将
X
转换为
,或者在使用
重塑
之前,如上面的代码所示。

Matlab的
重塑
函数非常方便(快速),但总是能够读取和写入完整的列。因此,对于您的问题,需要采取一些额外的步骤

以下是您如何做到这一点:

m = 5 % columns of submatrix
n = 4 % rows of submatrix
k = 50 % num submatrixes in matrix column
l = 50 % num submatrixes in matrix row
A = rand(m*k,n*l); % rand(250,200)
将矩阵重塑为四维矩阵(尺寸x1、x2、x3、x4),其中每个子矩阵位于x1-x3平面中。原始矩阵中的子矩阵列在x2方向,子矩阵行在x4方向

B = reshape(A,[m,k,n,l]); % [4,50,5,50]
置换(“转置”)4D矩阵,使每个子矩阵位于x1-x2平面。(
重塑
首先读取列,然后读取行,然后读取第三维,等等)

将4D矩阵重塑为所需的2D输出矩阵

D = reshape(C,m,[]);

我想我应该添加另一种方法,使用索引和一个内置函数
zero
。也许这种方式不会有任何不必要的错误检查或重塑操作。结果证明它更有效(见下文)

我决定在这里对这三个答案计时,发现这种方法要快得多。以下是测试代码:

% Bastian's approach
m = 5; % columns of submatrix
n = 4; % rows of submatrix
k = 50; % num submatrixes in matrix column
l = 50; % num submatrixes in matrix row
A = rand(m*k,n*l); % rand(250,200)
% start timing
tic
B = reshape(A,[m,k,n,l]); % [4,50,5,50]
C = permute(B,[1,3,4,2]); % For column-wise reshaping, use [1,3,2,4]
D = reshape(C,m,[]);
toc
% stop timing
disp('                ^^^ Bastian');

% Matt's approach
n = 50;                          % rows
m = 50;                          % columns
% start timing
tic
X = mat2cell(A,repmat(5,1,n),repmat(4,1,m));
X = reshape(X.',1,[]);
X = cell2mat(X);
toc
% stop timing
disp('                ^^^ Matt');

% ChisholmKyle
m = 5;
n = 4;
rep_rows = 50;
rep_cols = 50;
% start timing
tic
C = zeros(m, (n * rep_cols) * rep_rows);
for k = 1:rep_rows
   ind_cols = (n * rep_cols) * (k - 1) + 1: (n * rep_cols) * k;
   ind_rows = m * (k - 1) + 1: m * k;
   C(:,ind_cols) = A(ind_rows, :);
end
toc
% stop timing
disp('                ^^^ this approach');
以下是我的机器上的输出:

Elapsed time is 0.004038 seconds.
                ^^^ Bastian
Elapsed time is 0.020217 seconds.
                ^^^ Matt
Elapsed time is 0.000604 seconds.
                ^^^ this approach

当你说50时,你真的是指50x50=2500吗?是的,大矩阵中填充了50x50小5x4矩阵。嗨,马特,我已经补充了一些说明,你能看看你是否理解这个问题吗?子矩阵在输出矩阵中的顺序应该是什么?按列或按行输入矩阵?按行。因此,第二行中的第一个子矩阵被移动到第一行末尾的子矩阵旁边。
重塑
在以前可以按行使用。我的观点是它读取完整的列,这意味着你不能告诉它只读取列的前5个条目,然后继续下一列。我会把它弄清楚的。好的!显然,这些年来循环确实变得快多了=)我注意到,在
清除所有
清除函数
后,我的方法在第一次执行时只会慢得多。否则,两种解决方案的速度大致相同。显然,我的版本需要花很多时间来编译,但是编译脚本的执行时间非常快。一定要喜欢Matlab的即时编译器!
%submatrix size
m = 5;
n = 4;
%repeated submatrix rows and cols
rep_rows = 50;
rep_cols = 50;
% big matrix
A = rand(m * rep_rows, n * rep_cols);
% create new matrix 
C = zeros(m, (n * rep_cols) * rep_rows);
for k = 1:rep_rows
   ind_cols = (n * rep_cols) * (k - 1) + 1: (n * rep_cols) * k;
   ind_rows = m * (k - 1) + 1: m * k;
   C(:, ind_cols) = A(ind_rows, :);
end
% Bastian's approach
m = 5; % columns of submatrix
n = 4; % rows of submatrix
k = 50; % num submatrixes in matrix column
l = 50; % num submatrixes in matrix row
A = rand(m*k,n*l); % rand(250,200)
% start timing
tic
B = reshape(A,[m,k,n,l]); % [4,50,5,50]
C = permute(B,[1,3,4,2]); % For column-wise reshaping, use [1,3,2,4]
D = reshape(C,m,[]);
toc
% stop timing
disp('                ^^^ Bastian');

% Matt's approach
n = 50;                          % rows
m = 50;                          % columns
% start timing
tic
X = mat2cell(A,repmat(5,1,n),repmat(4,1,m));
X = reshape(X.',1,[]);
X = cell2mat(X);
toc
% stop timing
disp('                ^^^ Matt');

% ChisholmKyle
m = 5;
n = 4;
rep_rows = 50;
rep_cols = 50;
% start timing
tic
C = zeros(m, (n * rep_cols) * rep_rows);
for k = 1:rep_rows
   ind_cols = (n * rep_cols) * (k - 1) + 1: (n * rep_cols) * k;
   ind_rows = m * (k - 1) + 1: m * k;
   C(:,ind_cols) = A(ind_rows, :);
end
toc
% stop timing
disp('                ^^^ this approach');
Elapsed time is 0.004038 seconds.
                ^^^ Bastian
Elapsed time is 0.020217 seconds.
                ^^^ Matt
Elapsed time is 0.000604 seconds.
                ^^^ this approach