使用Matlab对矩阵进行对角线扩展

5
我有一个矩阵B,想要得到一个维度为(L+k)*m乘以L*n的矩阵C。其中L和k是输入值。B0、B1、...、Bk的大小为m乘以n。请保留HTML标签。

enter image description here

例如:
如果我有一个矩阵B = [1 1 ; 1 1 ; 1 1],其中B0 = [1 1]B1 = [1 1]B2 = [1 1],每个B0,B1,B2的维度为1乘以2,其中k = 2L = 4
那么得到的矩阵CC = [1 1 0 0 0 0 0 0 ; 1 1 1 1 0 0 0 0 ; 1 1 1 1 1 1 0 0 ; 0 0 1 1 1 1 1 1 ; 0 0 0 0 1 1 1 1 ; 0 0 0 0 0 0 1 1],维度为6乘以8

enter image description here

我希望能将我的程序推广到任何大小的矩阵 B
我的程序解决了 B = [1 1 ; 1 1 ; 1 1] 的问题,其中 m = 1n = 2k = 2L = 4
我的代码:
clc;
clear;

k = 2;                    
L = 4;                   

B = [1 1 ; 1 1 ; 1 1];    
B0 = [1 1];
B1 = [1 1];
B2 = [1 1];
m = size(B0,1);
n = size(B0,2);

c = [B ; zeros(size(B))];
C = zeros((L+k)*m,L*n);

for i = 1:L
    
    C(:,2*i-1:2*i) = circshift(c,i-1,1);
    
end

结果:

结果: C =

1   1   0   0   0   0   0   0
1   1   1   1   0   0   0   0
1   1   1   1   1   1   0   0
0   0   1   1   1   1   1   1
0   0   0   0   1   1   1   1
0   0   0   0   0   0   1   1

我很难为任何给定的矩阵 B 以及任何值的 k 和 L 进行概括。
有什么建议吗?
3个回答

4
B = [1 2 3; 4 5 6; 7 8 9; 100 110 120; 130 140 150; 160 170 180];  % input
L = 4;                                                             % input
k = 2;                                                             % input
m = size(B,1)/(k+1);              % obtain m
n = size(B,2);                    % obtain n
C = zeros((L-1)*m+1, (L-1)*n+1);  % initiallize result
C(1:((L-1)*m+1)*n+m:end) = 1;     % each 1 marks the upper-left corner for a copy of B
C = conv2(C, B);                  % insert copies of B, extending size

倒数第二行使用线性索引。最后一行应用二维卷积。此示例的结果为

B =
     1     2     3
     4     5     6
     7     8     9
   100   110   120
   130   140   150
   160   170   180

C =
     1     2     3     0     0     0     0     0     0     0     0     0
     4     5     6     0     0     0     0     0     0     0     0     0
     7     8     9     1     2     3     0     0     0     0     0     0
   100   110   120     4     5     6     0     0     0     0     0     0
   130   140   150     7     8     9     1     2     3     0     0     0
   160   170   180   100   110   120     4     5     6     0     0     0
     0     0     0   130   140   150     7     8     9     1     2     3
     0     0     0   160   170   180   100   110   120     4     5     6
     0     0     0     0     0     0   130   140   150     7     8     9
     0     0     0     0     0     0   160   170   180   100   110   120
     0     0     0     0     0     0     0     0     0   130   140   150
     0     0     0     0     0     0     0     0     0   160   170   180

1
这正是我想要的。谢谢@Luis Mendo。 - m2016b
1
嗨,路易斯,我建议进行一些小修改,以考虑 size(B,1)/(k+1) 不输出整数的情况。你可以在你的答案中加入这个选项,这样我就可以删除我的建议了。 - obchardon
1
@obchardon 不,我认为最好保留你的答案。此外,它使用了不同的方法(sparse)来创建0-1矩阵。 - Luis Mendo

4
除了@LuisMendo的答案之外:
如果size(B,1)/(k+1)不能产生整数,那么他的解决方案就会失败。
我建议使用sparse()创建C矩阵:
n = size(B,2)
C = full(sparse(1:k:k*L,1:n:n*L,1))

因此,整个代码变成:
B = ones(7,3);                       % An input matrix that will produce an error with the linear indexing solution. 
L = 6;                               % number of repetition
k = 2;                               % row-shift
n = size(B,2);                       % obtain n
C = full(sparse(1:k:k*L,1:n:n*L,1)); % Create C using full(sparse())
C = conv2(C, B)                      % insert copies of B, extending size

(感谢LuisMendo提供的灵感)

3

这个解决方案使用了 @obchardon 的答案中提到的 sparse,但不像 @LuisMendo 的答案那样使用 conv2。块的索引被计算并用于 sparse 中形成所需的矩阵。

    [row col] = find(true(size(B)));
    ROW = row + (0:L-1)*k;
    COL = col + (0:L-1)*size(B,2);
    C = sparse (ROW, COL, repmat (B, 1, L));

2
最简单的解决方案!非常好。 - Luis Mendo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接