Combining several asymmetric matrices to fit each other
1 view (last 30 days)
Show older comments
There are matrices in an array going on and on (there can be zeros, or no zeros filling lower right elements, all elements differ):
1 1 1 1 1
1 1 1 1
1 1 1
1 1
1
8 2 2 2 2
8 2 2 2
8 2 2
8 2
8
3 3 3 3 3
3 3 3 3
3 3 3
3 3
3
6 4 4 4 4
6 4 4 4
6 4 4
6 4
6
How to stack each other matrice onto the other half to create full sizes ones, like:
1 1 1 1 1 8
1 1 1 1 8 2
1 1 1 8 2 2
1 1 8 2 2 2
1 8 2 2 2 2
3 3 3 3 3 6
3 3 3 3 6 4
3 3 3 6 4 4
3 3 6 4 4 4
3 6 4 4 4 4
And on.
A solution to flip one over the other may also work.
4 Comments
Bruno Luong
on 25 Sep 2019
Edited: Bruno Luong
on 25 Sep 2019
Yes but what do you have in the "empty" part of the matrix (NaN).
Migh be you could attach a small example rather for anyone to try.
The details are important.
Accepted Answer
Stephen23
on 25 Sep 2019
Edited: Stephen23
on 25 Sep 2019
Do this for each pair of matrices A and B:
>> A = [-2,6,2,7,1;4,-5,2,3,NaN;6,1,3,NaN,NaN;2,2,NaN,NaN,NaN;4,NaN,NaN,NaN,NaN]
A =
-2 6 2 7 1
4 -5 2 3 NaN
6 1 3 NaN NaN
2 2 NaN NaN NaN
4 NaN NaN NaN NaN
>> B = [9,2,-1,6,4;5,-3,5,8,NaN;2,2,6,NaN,NaN;1,3,NaN,NaN,NaN;7,NaN,NaN,NaN,NaN]
B =
9 2 -1 6 4
5 -3 5 8 NaN
2 2 6 NaN NaN
1 3 NaN NaN NaN
7 NaN NaN NaN NaN
>> N = size(A,2);
>> X = flipud(tril(flipud(reshape(1:N*N+N,N,N+1))));
>> Y = nonzeros(sort(X.',2));
>> Z = nan(N,N+1);
>> Z(X~=0) = A(X~=0);
>> Z(X==0) = B(Y)
Z =
-2 6 2 7 1 7
4 -5 2 3 1 3
6 1 3 2 2 6
2 2 5 -3 5 8
4 9 2 -1 6 4
Note that X and Y can be calculated before the loop, assuming that N is the same for all matrices, so actually the only code you need to repeat is that for generating Z.
Note that this method does NOT rely on your data being free of NaNs, and it does not change the original data!
2 Comments
Andrei Bobrov
on 25 Sep 2019
Edited: Andrei Bobrov
on 25 Sep 2019
+1
[m,n] = size(A);
out = [A,nan(m,1)];
out(isnan(out)) = B(nonzeros(sort(tril(flip(reshape(1:m*n+m,m,[]))),2)));
Stephen23
on 25 Sep 2019
Edited: Stephen23
on 26 Sep 2019
@Andrei Bobrov: thank you for the vote! I did not assume that the data is free of NaNs, so that precluded the use of constructs like isnan(out) and is why I generated the indices independently of the data.
More Answers (1)
Andrei Bobrov
on 25 Sep 2019
m = [1 1 1 1 1
1 1 1 1 NaN
1 1 1 NaN NaN
1 1 NaN NaN NaN
1 NaN NaN NaN NaN
8 2 2 2 2
8 2 2 2 NaN
8 2 2 NaN NaN
8 2 NaN NaN NaN
8 NaN NaN NaN NaN
3 3 3 3 3
3 3 3 3 NaN
3 3 3 NaN NaN
3 3 NaN NaN NaN
3 NaN NaN NaN NaN
6 4 4 4 4
6 4 4 4 NaN
6 4 4 NaN NaN
6 4 NaN NaN NaN
6 NaN NaN NaN NaN];
v = m(all(~isnan(m),2),:)
n = size(v,1)/2;
c = cell(n,1);
for ii = 1:n
c{ii} = hankel(v(ii*2-1,:),[v(ii*2-1,end),v(2*ii,:)]);
end
out = cat(1,c{:});
4 Comments
Andrei Bobrov
on 25 Sep 2019
Edited: Andrei Bobrov
on 25 Sep 2019
A = [-2,6,2,7,1;4,-5,2,3,NaN;6,1,3,NaN,NaN;2,2,NaN,NaN,NaN;4,NaN,NaN,NaN,NaN];
B = [9,2,-1,6,4;5,-3,5,8,NaN;2,2,6,NaN,NaN;1,3,NaN,NaN,NaN;7,NaN,NaN,NaN,NaN];
[m,n] = size(A);
K = spdiags(flip(B));
K = K(:,1:m);
K = tril(nan(m,n),-1) + K;
out = [A,nan(size(A,1),1)];
out(isnan(out)) = K(~isnan(K));
or
K = rot90([A,nan(size(A,1),1)],-1);
Bt = B.';
K(isnan(K)) = Bt(~isnan(Bt));
out = rot90(K);
See Also
Categories
Find more on Matrices and Arrays 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!