How to create the upper diagonal block matrix in a specific form.
16 views (last 30 days)
Show older comments
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
Accepted Answer
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
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
More Answers (0)
See Also
Categories
Find more on Number Theory in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!