Reputation: 59
Like the title says, I have several matrices that I would like to stack in the 3rd dimension. I currently have a solution for stacking unequal vectors horizontally, which reads like so:
A = [1;2;3;4];
B = [1;2];
[i1,j1] = ndgrid(1:size(A,1),1:size(A,2));
[i2,j2] = ndgrid(1:size(B,1),(1:size(B,2))+size(A,2));
plane_stats = accumarray([i1(:),j1(:);i2(:),j2(:)],[A(:);B(:)]);
for any two vectors A and B of unequal size (caveat: I have only tested this for column vectors, stacked horizontally). Wherever there would be a gap, this adds zeros as padding, so the result looks as follows:
1 1
2 2
3 0
4 0
However, I would like to generalize this to 3D so I can stack a third (also unequal) matrix C behind the combination of A and B, like so:
C = [1 2;3 4;5 6]
%some modification of existing ndgrid code
combo(:,:,1) =
1 1
2 2
3 0
4 0
combo(:,:,2) =
1 2
3 4
5 6
0 0
However I am not sure how to extend the solution I currently have. Any and all help/insight is appreciated
Upvotes: 0
Views: 207
Reputation: 23675
Your approach for merging A
and B
is totally fine, it doesn't require any improvement and you can keep on using it:
A = [1;2;3;4];
B = [1;2];
[i1,j1] = ndgrid(1:size(A,1),1:size(A,2));
[i2,j2] = ndgrid(1:size(B,1),(1:size(B,2))+size(A,2));
plane_stats = accumarray([i1(:),j1(:);i2(:),j2(:)],[A(:);B(:)]);
Now... what's great about Matlab is that matrices are automatically expanded (and zero-padded) whenever the code requires it. Hence, for a given matrix C
, all you have to do is:
combo = plane_stats;
[C_m,C_n] = size(C);
combo(1:C_m,1:C_n,2) = C;
A few examples:
combo = plane_stats;
C = [1 2; 3 4; 5 6];
[C_m,C_n] = size(C);
combo(1:C_m,1:C_n,2) = C
combo(:,:,1) =
1 1
2 2
3 0
4 0
combo(:,:,2) =
1 2
3 4
5 6
0 0
combo = plane_stats;
C = [1 2; 3 4; 5 6; 7 8; 9 10];
[C_m,C_n] = size(C);
combo(1:C_m,1:C_n,2) = C
combo(:,:,1) =
1 1
2 2
3 0
4 0
0 0
combo(:,:,2) =
1 2
3 4
5 6
7 8
9 10
combo = plane_stats;
C = [1 2 3; 3 4 5; 5 6 7; 7 8 9; 10 11 12; 13 14 15];
[C_m,C_n] = size(C);
combo(1:C_m,1:C_n,2) = C
combo(:,:,1) =
1 1 0
2 2 0
3 0 0
4 0 0
0 0 0
0 0 0
combo(:,:,2) =
1 2 3
3 4 5
5 6 7
7 8 9
10 11 12
13 14 15
combo = plane_stats;
C = [1; 2];
[C_m,C_n] = size(C);
combo(1:C_m,1:C_n,2) = C
combo(:,:,1) =
1 1
2 2
3 0
4 0
combo(:,:,2) =
1 0
2 0
0 0
0 0
Upvotes: 2
Reputation: 46
I would suggest something like this:
Given unequal sized 2D matrices A, B, C
,
A = [1;2;3];
B = [1 2 3];
C = [1 2;3 4;5 6;7 8];
Solution 1
To stack at the 3rd dimension, we can simply do this:
n_rows = max([size(A,1),size(B,1),size(C,1)]);
n_cols = max([size(A,2),size(B,2),size(C,2)]);
combo = zeros(n_rows, n_cols, 3);
combo(1:size(A,1),1:size(A,2),1) = A
combo(1:size(B,1),1:size(B,2),2) = B
combo(1:size(C,1),1:size(C,2),3) = C
Solution 2
In additionally, to stack matrices incrementally in a loop:
matrices = {A,B,C};
for i = 1:numel(matrices)
mat = matrices{i};
combo(1:size(mat,1),1:size(mat,2),i) = mat;
end
Matlab will automatically padding zeros for you.
Solution 3
Another version without warning:
matrices = {A,B,C};
n_rows = 0; n_cols = 0;
for i = 1:numel(matrices)
mat = matrices{i};
n_rows = max(n_rows, size(mat,1));
n_cols = max(n_cols, size(mat,2));
end
combo = zeros(n_rows, n_cols, numel(matrices));
for i = 1:numel(matrices)
combo(1:size(matrices{i},1),1:size(matrices{i},2),i) = matrices{i};
end
Result
All above 3 solutions resulting the same:
>> combo
combo(:,:,1) =
1 0 0
2 0 0
3 0 0
0 0 0
combo(:,:,2) =
1 2 3
0 0 0
0 0 0
0 0 0
combo(:,:,3) =
1 2 0
3 4 0
5 6 0
7 8 0
Upvotes: 3