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
.
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
.
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?
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.
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.
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 .
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 .
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
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)
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));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With