# How to append a matrix element by element?

Consider if I have some matrices constructed as such:

A = {
{ {} , {} },
{ {} , {} }
}
B = {
{ a , b },
{ c , d }
}
C = {
{ e , f },
{ g , h }
}
...


A serves as a matrix of empty lists. I want to be able to append B, C, etc. to A, to obtain a final matrix like

A = {
{ {a, e, ...} , {b, f, ...} },
{ {c, g, ...} , {d, h, ...} }
}


How can I do this? My matrices are always square and of the same dimensions. An alternative which could also be useful is to Join two matrices element by element, if the matrix elements of both are already lists.

• You wrote "My matrices are always square and of the same dimensions". That is not true. Try Dimensions/@{A,B} Commented Jun 21, 2019 at 20:47
• Kai, with A and B as inputs what is the desired result: {{{a}, {b}}, {{c}, {d}}} or {{{{}, a}, {{}, b}}, {{{}, c}, {{}, d}}}?
– kglr
Commented Jun 22, 2019 at 0:45
• @Fortsaint my meaning is that the matrices which are being appended are always the same dimension. Matrix A is simply a matrix of empty lists to append to.
– Kai
Commented Jun 22, 2019 at 2:20
• @kglr see the update
– Kai
Commented Jun 22, 2019 at 2:22
• with A = {{{}, {}}, {{}, {}}};B = {{a, b}, {c, d}};cc = {{e, f}, {g, h}}; if you use Transpose[{A, B, cc}, {3, 1, 2}] you get {{{{}, a, e}, {{}, b, f}}, {{{}, c, g}, {{}, d, h}}}. But your post says you want {{{a, e}, {b, f}}, {{c, g}, {d, h}}}, no?
– kglr
Commented Jun 22, 2019 at 3:10

Suppose you have 4 matrices:

SeedRandom[1]
{a, b, c, d} = RandomInteger[1, {4, 2, 2}];


Then, you can use Transpose to construct the desired matrix:

Transpose[{a, b, c, d}, {3, 1, 2}]


{{{1, 0, 0, 0}, {1, 0, 1, 0}}, {{0, 0, 0, 0}, {1, 1, 0, 0}}}

• I think Transpose[{a, b, c, d}, {3, 1, 2}] may be enough. Commented Jun 21, 2019 at 23:14
• @Roman Thanks, much simpler! Commented Jun 21, 2019 at 23:23
• I'm still wrapping my head around the second argument of transpose, but this looks like the simplest way for me to achieve what I want.
– Kai
Commented Jun 22, 2019 at 2:24

To join nested arrays elementwise, use the third argument of Join. For matrices, depth 1 (default) is rows, 2 is columns, and 3 is elements.

a = Array[{}&, {2,2}];

b = {
{b1, b2},
{b3, b4}
};

listEach = Map[List, #, {2}]&

appendEach[x_,y_] := Join[x, listEach[y], 3]

Print[appendEach[appendEach[a, b], b+5]]
(* {{{b1, 5 + b1}, {b2, 5 + b2}}, {{b3, 5 + b3}, {b4, 5 + b4}}} *)


Try it online!

However, if you are appending many matrices it may be more efficient to create a list of matrices using Sow / Reap, then Transpose into a matrix of lists.

• What is the function of the & in the first line?
– Kai
Commented Jun 22, 2019 at 2:26
• It's the syntax for a pure function. Commented Jun 22, 2019 at 6:34
• right but there's no argument so I'm confused what it does
– Kai
Commented Jun 22, 2019 at 19:26
• {}& takes no arguments and returns an empty list. The & is there because Array needs to be passed a function. Commented Jun 22, 2019 at 20:39
• I see, this is the equivalent of ConstantArray[{},{2,2}] then?
– Kai
Commented Jun 23, 2019 at 4:40

Update:

ClearAll[f1, f2]
f1 = MapThread[List, #, 2] &;
f2 = Flatten[#, {{2}, {3}}] &;


Using Carl's example setup:

SeedRandom[1]
{a, b, c, d} = RandomInteger[1, {4, 2, 2}];

f1[{a, b, c, d}]


{{{1, 0, 0, 0}, {1, 0, 1, 0}}, {{0, 0, 0, 0}, {1, 1, 0, 0}}}

f2[{a, b, c, d}] == f1[{a, b, c, d}] == Transpose[{a, b, c, d}, {3, 1, 2}]


True

If some input matrices might have {} as an element all methods above retain {}s in the combined matrix:

f1[{a, A, c, d}]


{{{1, {}, 0, 0}, {1, {}, 1, 0}}, {{0, {}, 0, 0}, {1, {}, 0, 0}}}

MapThread with Flatten[{##}] & as the first argument eliminates {}s:

MapThread[Flatten[{##}] &, {a, A, c, d}, 2]


{{{1, 0, 0}, {1, 1, 0}}, {{0, 0, 0}, {1, 0, 0}}}

MapThread[Flatten[{##}] &, {A, B}, 2]