How to create the upper diagonal block matrix in a specific form.

16 views (last 30 days)
c = input('c ');
g = input('g ');
syms Lambda_n
M = cell(c+1,1);
a_t = min([1:c+1;repmat(c-g+1,1,c+1)]);
for i = 1:c+1
v = zeros(1,c+2-i, 'sym');
v(1)= Lambda_n*i;
MCell = repmat({diag(v)}, 1, a_t(i));
M{i} = blkdiag(MCell{:});
end
B=blkdiag(M{:});
'c' will determine the size of blocks which I already explained to you that they will be in decreasing order. 'g' is basically used in a_t = ,min{j,c-g}. Here a_t determines how many time a block should be repeated. So upto c-g the order of block upper diagonal matrix will be (i+1,i) and from c-g+1 upto c+1 it will be (c-g+1,c-g+1).
This is for the main diagonal block matrix which is shown in the picture. Similarly I want to create the upper diagonal as shown by the red line in the picture. I have tried to creat it using kron function but it was just not what i wanted. Kindly help me with this.
  10 Comments
raina RAJ
raina RAJ on 20 Apr 2020
c = input('c ');
g = input('g ');
syms Lambda_n
for i = 1:c+1
for j = 1:c
if i==1 & j==1
A(i,j) = Lambda_n;
else A(i,j)=0;
end
end
end
This is the code for matrix A. Now for the first upper diagonal block [O A] the order of O and A will be (c+1,c). for the second block [O A O ; the order of 'O' and A will be (c,c-1). Similarly for
O O A]
third block the order of 'O' and A will be (c-1,c-2) and so on. 'O' is zero matrix.
raina RAJ
raina RAJ on 21 Apr 2020
Can someone plese help me with this probelm? I am new at MATLAB coding and I really need this job to be done. I am trying hard. If not the whole thing just give me some hint so that I can work in that direction. Please someone consider this.

Sign in to comment.

Accepted Answer

Rik
Rik on 21 Apr 2020
Here is the code that will generate blocks like [O A O;O O A] given the values of c and g.
clear,clc
c = 3;
g = 1;
syms Lambda_n
%replacement for the loop:
A=Lambda_n;
A(c+1,c)=0;
put_A_here=logical([zeros(c-1,1) eye(c-1)]);
big=repmat(sym(0),size(put_A_here).*size(A));
big=insert_matrix(big,A,put_A_here);
function out=insert_matrix(big,small,L)
out=big;
A=reshape(1:numel(small),size(small));
B=repmat({zeros(size(A))},size(L));
B(L)={A};
B=cell2mat(B);
B=B(:);
out(B~=0)=small(B(B~=0));
end
  6 Comments
Rik
Rik on 22 Apr 2020
In response to your email: you can actually use this function to create the entire matrix.
Note that this will be different from the image you posted (on the last line). You can easily confirm this by using this line, instead of generating the real A and B matrices:
A=sym('A');B=sym('B');
Do you notice the difference? You should always try to separate the steps into functions. That way you have a clear flow of the program. Once you have written one part you don't need to worry about the internals. You only need to worry about the interface: what inputs does it need and what will its output be. By writing functions like this, it is easy to re-use a function like insert_matrix, without having to put all the code in here twice. This way a future reader will immediately understand what is happening. (Remember: future you is a different person that may not understand what you did. Write your code so that even strangers like future you understand what you did.)
%separate input and processing: ask the user for the input once and use those as input to your functions
%in your command window (or another function) you can do this:
main(3,1,4)
function big=main(c,g,steps)
if nargin==0
%get user input
c = input('c ');
g = input('g ');
steps = input('number of A blocks ');
end
%create logical arrays for where the B and A arrays should be inserted
sz=[sum(1:steps) sum(1:steps)+1+steps];
put_A_here=generate_put_A_here(steps);
put_B_here=generate_put_B_here(sz);
%create A and B
A=get_A(c,g);
B=get_B(c,g);
%A=sym('A');B=sym('B');%useful for viewing the output array
%insert into a large symbolic array
big=repmat(sym(0),sz.*size(B));
big=insert_matrix(big,B,put_B_here);
big=insert_matrix(big,A,put_A_here);
end
function put_A_here=generate_put_A_here(steps)
%generate the staggered logical array describing where A should end up
sz=[sum(1:steps) sum(1:steps)+1+steps];
offset=floor(sqrt(2*(1:sz(1))) + 1/2);%source: https://oeis.org/A002024
[row,col]=find(eye(sz(1)));%diagonal positions
col=col+1+offset(:);%apply offset
put_A_here=false(sz);%pre-allocate output
put_A_here(sub2ind(sz,row,col))=true;%mark positions
end
function put_B_here=generate_put_B_here(sz)
%generate the extended identity matrix describing where B should end up
put_B_here=logical(eye(sz(1)));%get base positions for B
put_B_here(1,sz(2))=false;%extend to make room for A-blocks
end
function A=get_A(c,g)
syms Lambda_n
A=Lambda_n;
A(c+1,c)=0;
end
function B=get_B(c,g)
syms Lambda_n
M = cell(c+1,1);
a_t = min([1:c+1;repmat(c-g+1,1,c+1)]);
for i = 1:c+1
v = zeros(1,c+2-i, 'sym');
v(1)= Lambda_n*i;
MCell = repmat({diag(v)}, 1, a_t(i));
M{i} = blkdiag(MCell{:});
end
B=blkdiag(M{:});
end
function out=insert_matrix(big,small,L)
out=big;
A=reshape(1:numel(small),size(small));
B=repmat({zeros(size(A))},size(L));
B(L)={A};
B=cell2mat(B);
B=B(:);
out(B~=0)=small(B(B~=0));
end

Sign in to comment.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!