Combining several asymmetric matrices to fit each other

1 view (last 30 days)
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
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.
Alek
Alek on 25 Sep 2019
Alright, thanks for having a look. This is data from a mesh of sensors and are individual sensor readings from 4x 2ms frames. All empty spaces in the 11x11 matrice is assigned NaN, when imported to matlab.
Normally the NaN's are ciriumvented when performing some processing, but of course, I've been looking for a way to make it more compact before the processing, these cell arrays are large.
Raw example: (In matlab headers are gone and empty spaces are replaced by NaN)
## frame 12802 (25602 msec)
0.661 -0.020 -0.025 -0.017 -0.011 0.204 0.750 0.836 0.895 0.960 1.160
0.915 0.017 -0.010 -0.018 -0.011 0.031 0.038 0.044 0.045 0.023
1.463 0.015 -0.020 -0.029 -0.007 -0.001 0.004 0.002 -0.012
0.810 -0.000 -0.027 -0.011 -0.005 -0.000 -0.001 -0.009
0.620 -0.006 -0.011 -0.003 0.002 0.002 -0.002
0.878 0.008 0.021 0.027 0.026 0.020
0.830 0.700 0.647 0.600 0.557
2.115 1.432 1.714 1.715
1.782 1.377 1.762
1.665 1.458
1.850
## frame 12803 (25604 msec)
0.654 -0.020 -0.025 -0.017 -0.011 0.207 0.767 0.857 0.918 0.985 1.210
0.912 0.017 -0.010 -0.018 -0.011 0.032 0.039 0.045 0.047 0.025
1.460 0.015 -0.020 -0.029 -0.006 -0.001 0.004 0.002 -0.012
0.806 -0.000 -0.027 -0.011 -0.005 -0.001 -0.001 -0.009
0.618 -0.006 -0.011 -0.003 0.002 0.002 -0.003
0.874 0.008 0.021 0.027 0.025 0.020
0.825 0.695 0.642 0.594 0.551
2.118 1.432 1.714 1.709
1.782 1.377 1.758
1.663 1.458
1.846
## frame 12804 (25606 msec)
0.645 -0.020 -0.025 -0.016 -0.010 0.211 0.785 0.878 0.941 1.011 1.264
0.909 0.017 -0.010 -0.017 -0.011 0.033 0.041 0.047 0.049 0.027
1.455 0.015 -0.019 -0.028 -0.006 -0.000 0.005 0.003 -0.011
0.802 -0.000 -0.027 -0.011 -0.006 -0.001 -0.001 -0.009
0.616 -0.006 -0.011 -0.003 0.002 0.002 -0.002
0.872 0.007 0.021 0.027 0.025 0.019
0.817 0.690 0.636 0.589 0.545
2.120 1.432 1.714 1.704
1.784 1.377 1.755
1.663 1.458
1.844
## frame 12805 (25608 msec)
0.636 -0.021 -0.025 -0.016 -0.009 0.216 0.804 0.900 0.966 1.038 1.319
0.906 0.017 -0.010 -0.017 -0.010 0.034 0.042 0.048 0.050 0.030
1.452 0.015 -0.019 -0.028 -0.006 -0.000 0.005 0.003 -0.011
0.799 -0.000 -0.026 -0.011 -0.006 -0.001 -0.001 -0.009
0.614 -0.006 -0.011 -0.003 0.002 0.002 -0.002
0.869 0.007 0.021 0.027 0.025 0.019
0.810 0.685 0.631 0.583 0.538
2.122 1.432 1.714 1.698
1.784 1.377 1.751
1.662 1.458
1.841

Sign in to comment.

Accepted Answer

Stephen23
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
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
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.

Sign in to comment.

More Answers (1)

Andrei Bobrov
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
Alek
Alek on 25 Sep 2019
Edited: Alek on 25 Sep 2019
Sorry, I attempted to simplyfy the specification of output matrices with a defined border in the main question, but it was probably poorly done.
Where matrice elements/values are different for each triangle.
In: [] <- only to mark where combination occurs
-2 6 2 7 1
4 -5 2 3
6 1 3
2 2
4
[9] 2 -1 6 4
[5] -3 5 8
[2] 2 6
[1] 3
[7]
-2 6 2 7 1
4 -5 2 3
6 1 3
2 2
4
[9] 2 -1 6 4
[5] -3 5 8
[2] 2 6
[1] 3
[7]
Out, paring each other triangle so that: [] <- Marking beginning of other triangle elements
-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
-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
Andrei Bobrov
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);

Sign in to comment.

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!