Reputation: 67
I have an algorithm that creates random nxn
-matrices A(i,j)
and now I want this matrices in a tridiagonal shape:
A(1,1) A(1,2) 0 0 0
A(2,1) A(2,2) A(2,3) 0 0
0 A(3,2) A(3,3) A(3,4) 0
0 0 A(4,3) A(4,4) A(4,5)
And so on.
I tried the commands diag
and tridiag
but both are just working for integers.
EDIT
I will explain my problem with an example:
I create different random 3x3
matrices:
a=randi(10,3);
b=randi(10,3);
...
k=randi(10,3)
And now I want to create a big tridiagonal matrix L
where the random matrices a,...,k
are on the sub-, super- and diagonal line:
L= a b 0 0 0
c d e 0 0
0 f g h 0
0 0 i j k
Upvotes: 1
Views: 871
Reputation: 221644
It seems you want to keep both subdiagonal and superdiagonal elements in there alongwith the diagonal ones.
Approach #1
First approach could be with bsxfun
there for a generic m x n sized matrix -
[m,n] = size(A); %// get size
Aout = A.*( bsxfun(@le,[0:m-1]',1:n) & bsxfun(@ge,[1:m]',0:n-1))
Sample run -
A =
1 2 2 2 6
6 4 8 4 3
8 5 6 5 4
7 9 4 2 6
Aout =
1 2 0 0 0
6 4 8 0 0
0 5 6 5 0
0 0 4 2 6
Approach #2
If you were working with tridiag
obtained from here, you could have just done the following for n x n
sized matrices -
Aout = A.*tridiag(1,1,1,n)
With reference to the edited part of the question, this code should work -
%// Create regularly shaped all matrices holding variable.
%// This regularity would be used for cutting into a 3D array in the next step
A = cat(1,NaN(3),a,c,b,d,f,e,g,i,h,j,NaN(3),k,NaN(3),NaN(3));
%// Cut A after every 9 rows
N = 9;
Acut = permute(reshape(A,N,size(A,1)/N,[]),[1 3 2])
%// Create mask that will act as the building unit for L
m = 4;n = 5;
mask = bsxfun(@le,[0:m-1]',1:n) & bsxfun(@ge,[1:m]',0:n-1)
%// Setup L with ones at places where elements from matrices are top be put
sf = 3; %// scaling factor
L = double(mask(ceil(1/sf:1/sf:size(mask,1)), ceil(1/sf:1/sf:size(mask,2))))
%// Finally, place the elements from matrices into their respective places
L(L==1) = Acut(~isnan(Acut))
Upvotes: 0
Reputation: 4336
You have to figure out a combination of trill
and triu
a = randi(9,4,5);
a .* triu(ones(4,5),-1).*tril(ones(4,5),1)
>>ans =
4 6 0 0 0
9 1 7 0 0
0 8 7 7 0
0 0 4 1 8
And for floating data it will do the same,
a = rand(4,5);
a .* triu(ones(4,5),-1).*tril(ones(4,5),1)
>>ans =
0.6948 0.4387 0 0 0
0.3171 0.3816 0.4898 0 0
0 0.7655 0.4456 0.2760 0
0 0 0.6463 0.6797 0.4984
More efficiently (thanks to @Divakar),
a.*(triu(ones(4,5),-1) & tril(ones(4,5),1));
Or even more simpler (thanks to @LuisMendo),
tril(triu(a,-1),1);
Upvotes: 2