Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expanding a matrix diagonally with Matlab

I have a matrix B and I want to obtain a matrix C of dimension (L+k)*m by L*n. L and k are input values. B0 , B1 , ... , Bk has size m by n.

enter image description here

For example :

If I have a matrix B = [1 1 ; 1 1 ; 1 1] with B0 = [1 1], B1 = [1 1] and B2 = [1 1], and each B0 , B1 , B2 of dimension 1 by 2 with k = 2 and L = 4.

Then the matrix C obtained is given by 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] and of dimension 6 by 8.

enter image description here

I would like to generalize my program for any size matrix B.

My program solves the problem for B = [1 1 ; 1 1 ; 1 1] with m = 1 , n = 2 , k = 2 and L = 4.

My code :

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

Result : 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

I have difficulties to generalize for any given matrix B and for any value of k and L.

Any suggestions?

like image 929
m2016b Avatar asked Nov 11 '20 23:11

m2016b


People also ask

How do you fill a matrix diagonally in Matlab?

D = diag( v ) returns a square diagonal matrix with the elements of vector v on the main diagonal. D = diag( v , k ) places the elements of vector v on the k th diagonal. k=0 represents the main diagonal, k>0 is above the main diagonal, and k<0 is below the main diagonal.

How do you enlarge a matrix in Matlab?

Expanding a Matrix MATLAB automatically pads the matrix with zeros to keep it rectangular. For example, create a 2-by-3 matrix and add an additional row and column to it by inserting an element in the (3,4) position. You can also expand the size by inserting a new matrix outside of the existing index ranges.

How do you make a diagonal matrix?

The most common and easiest way to create a diagonal matrix is using the built-in function diag. The expression diag (v) , with v a vector, will create a square diagonal matrix with elements on the main diagonal given by the elements of v , and size equal to the length of v .

How do you sum diagonals in Matlab?

b = trace( A ) calculates the sum of the diagonal elements of matrix A : tr ( A ) = ∑ i = 1 n a i i = a 11 + a 22 + ... + a n n .


3 Answers

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

The second-to-last line uses linear indexing. The last line applies two-dimensional convolution. The result in this example is

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
like image 192
Luis Mendo Avatar answered Oct 25 '22 16:10

Luis Mendo


In addition to @LuisMendo's answer:

If size(B,1)/(k+1) do not produce an integer, then his solution can fail.

I would suggest to create the C matrix with sparse():

n = size(B,2)
C = full(sparse(1:k:k*L,1:n:n*L,1))

So the whole code become:

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

(all credits goes to LuisMendo for the idea)

like image 33
obchardon Avatar answered Oct 25 '22 15:10

obchardon


This solution as @obchardon's answer uses sparse but unlike the @LuisMendo's answer doesn't use conv2. Indices of blocks are computed and used in sparse to form the desired matrix.

    [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));
like image 34
rahnema1 Avatar answered Oct 25 '22 17:10

rahnema1