tashton
tashton

Reputation: 59

How to concatenate matrices of unequal dimensions in 3rd dimension in MATLAB?

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

Answers (2)

Tommaso Belluzzo
Tommaso Belluzzo

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

Yicheng Cheng
Yicheng Cheng

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

Related Questions