在MATLAB中重塑/变换上三角矩阵

时间:2013-08-20 10:17:03

标签: matlab matrix transformation

我有一个上三角矩阵(没有对角线),由下式给出:

M = [0 3 2 2 0 0; 0 0 8 6 3 2; 0 0 0 3 2 1; 0 0 0 0 2 1; 0 0 0 0 0 0]

结果矩阵应如下所示:

R = [0 0 0 0 0 0; 0 2 0 0 0 0; 2 3 1 0 0 0; 2 6 2 1 0 0; 3 8 3 2 0 0]

由于我找不到描述我目标的简单解释,我试图用图像来形象化它:

enter image description here

我已经尝试过rot90transposeflipud等许多不同的组合,但我找不到能够给出矩阵R的正确转换

编辑:

矩阵M的行并不总是如上例所示那样排序。对于另一个矩阵M_2

M_2 = [0 2 3 1 0 0; 0 0 3 6 3 9; 0 0 0 1 2 4; 0 0 0 0 2 6; 0 0 0 0 0 0]

生成的矩阵R_2必须如下:

R_2 = [0 0 0 0 0 0; 0 9 0 0 0 0; 1 3 4 0 0 0; 3 6 2 6 0 0; 2 3 1 2 0 0]

再次显示以下内容:

enter image description here

3 个答案:

答案 0 :(得分:5)

修改 受@ Dan评论提示的启发,它可以进一步简化为

R = reshape(rot90(M), size(M));

原始答案:

这应该是一种简单的方法

F = rot90(M);
R = F(reshape(1:numel(M), size(M)))

返回

R =
     0     0     0     0     0     0
     0     2     0     0     0     0
     2     3     1     0     0     0
     2     6     2     1     0     0
     3     8     3     2     0     0

这个想法是当你旋转矩阵时得到

>> F = rot90(M)
F =
     0     2     1     1     0
     0     3     2     2     0
     2     6     3     0     0
     2     8     0     0     0
     3     0     0     0     0
     0     0     0     0     0

是6乘5矩阵。如果考虑F上的线性索引,则相应的索引为

>> reshape(1:30, size(F))
     1     7    13    19    25
     2     8    14    20    26
     3     9    15    21    27
     4    10    16    22    28
     5    11    17    23    29
     6    12    18    24    30

其中元素6,11,12,16,17,18和...现在为零,如果你将其重新整形为5乘6矩阵

>> reshape(1:30, size(M))
     1     6    11    16    21    26
     2     7    12    17    22    27
     3     8    13    18    23    28
     4     9    14    19    24    29
     5    10    15    20    25    30

现在那些与零值对应的元素位于顶部,正是我们想要的。因此,通过将此索引数组传递给F,我们得到了所需的R

答案 1 :(得分:4)

不依赖于订单(只需旋转彩色条带并将它们推到底部)。

第一个解决方案:请注意,如果“数据”值之间存在零,则它不起作用(例如,如果给定的示例中M(1,3)0)。如果可能有零,请参阅下面的第二个解决方案:

[nRows nCols]= size(M);
R = [flipud(M(:,2:nCols).') zeros(nRows,1)];
[~, rowSubIndex] = sort(~~R);
index = sub2ind([nRows nCols],rowSubIndex,repmat(1:nCols,nRows,1));
R = R(index);

第二种解决方案:即使数据中存在零,也能正常工作:

[nRows nCols]= size(M);
S = [flipud(M(:,2:nCols).') zeros(nRows,1)];
mask = 1 + fliplr(tril(NaN*ones(nRows, nCols)));
S = S .* mask;
[~, rowSubIndex] = sort(~isnan(S));
index = sub2ind([nRows nCols],rowSubIndex,repmat(1:nCols,nRows,1));
R = S(index);
R(isnan(R)) = 0;

答案 2 :(得分:1)

备用选项,使用循环:

[nRows nCols]= size(M);
R = zeros(nRows,nCols);
for n = 1:nRows
  R((n+1):nCols,n)=fliplr(M(n,(n+1):nCols));
end