# Insert all elements from one matrix into another

I have two matrices $A$ and $B$ which are the same size. Each element of $A$ is a list of numbers. Each element of $B$ is just a number. How do I insert each element of $B$ into the corresponding list of $A$?

For example say I have:

A = {{{1,2},{3,4}},{{5,6},{7,8}},{{9,10},{11,12}}}


$= \begin{pmatrix} (1,2) & (3,4)\\ (5,6) & (7,8) \\ (9,10) & (11,12) \end{pmatrix}$

and

B = {{0,0},{1,1},{2,2}}


$=\begin{pmatrix} 0 & 0\\1&1\\2&2 \end{pmatrix}$

How do I form:

{{{1,2,0},{3,4,0}},{{5,6,1},{7,8,1}},{{9,10,2},{11,12,2}}}


$= \begin{pmatrix} (1,2,0) & (3,4,0)\\ (5,6,1) & (7,8,1) \\ (9,10,2) & (11,12,2) \end{pmatrix}$

Thanks very much for any help

• Are the columns of B always identical as shown in this example? – Mr.Wizard Jun 24 '14 at 18:24
• No, just giving a simple example so I can understand. :) – Tom Jun 24 '14 at 18:48

f = Module[{tmp = ConstantArray[0, Dimensions[#1] + {0, 0, 1}]},
tmp[[All, All, ;; -2]] = #1; tmp[[All, All, -1]] = #2; tmp] &;
f[a, b]
(* {{{1, 2, 0}, {3, 4, 0}},
{{5, 6, 1}, {7, 8, 1}},
{{9, 10, 2}, {11, 12, 2}}}*)


All methods posted so far:

f1 = MapThread[Append, {#1, #2}, 2] &;
f2 = Join[#1, Transpose[{#2}, {3, 1, 2}], 3] &;
f3 = MapThread[{Sequence @@ #1, #2} &, {#1, #2}, 2] &;
f4 = MapThread[Flatten[{##}] &, {#1, #2}, 2] &;
f5 = MapThread[Insert[#1, #2, -1] &, {#1, #2}, 2] &;
f6 = MapThread[Join[#1, {#2}] &, {#1, #2}, 2] &;
f7 = Partition[MapThread[Append, {Flatten[#1, 1], #2 // Flatten}], 2] &;
f8 = Join[#1, Map[List, #2, {-1}], 3] &;
f9 = Module[{tmp = ConstantArray[0, Dimensions[#1] + {0, 0, 1}]},
tmp[[All, All, ;; -2]] = #1; tmp[[All, All, -1]] = #2; tmp] &;


Timings and ByteCounts using Mr.W's test setup:

A = RandomInteger[99, {700, 400, 200}];
B = RandomInteger[99, {700, 400}];
Grid[Prepend[Timing@ByteCount@#[A, B], #] & /@
{f1, f2, f3, f4, f5, f6, f7, f8, f9}, Dividers -> All]~Style~24 (* thanks: Mr.W *) • +1 for timings. Regarding the update, why not Sequence @@ Timing @ ByteCount @ #[A, B]? Shorter and clearer IMO. – Mr.Wizard Jun 24 '14 at 22:22
• Thank you @Mr.W (you should have seen the first version of Grid[...]:)) – kglr Jun 24 '14 at 22:25
• Hey look, you picked up the Accept. Since you're open to suggestion how about: Grid[Prepend[Timing @ ByteCount @ #[A, B], #] & /@ {f1, f2, f3, f4, f5, f6, f7, f8, f9}, Dividers -> All] ~Style~ 24 – Mr.Wizard Jun 24 '14 at 22:32
• Thank you againm @Mr.W. Accept is likely to be a mistake -- soon to be corrected now that timings table, with larger fonts, is more readable:) Thomas, thank you .. but are you sure?:) – kglr Jun 24 '14 at 22:50
• Well it contains the most information for future readers. – Tom Jun 28 '14 at 10:03
MapThread[Append, {A, B}, 2] // MatrixForm • +1... what sort of code is your email addr expressed in? – alancalvitti Jun 24 '14 at 14:16
• @alancalvitti brainf*ck :D. Interpreter / generator. – mfvonh Jun 24 '14 at 14:18
• That's the ticket. Thank you user mfvonh. – Tom Jun 24 '14 at 14:21

just a nonpractical variation:

Join[A, Map[List, B, {-1}], 3]

• +1 for using Join. Actually, this too will preserve packed arrays as above the "MapCompileLength" it will compile. Would you prefer that I delete my answer and include the examples in yours instead? (Though Transpose is still faster I believe.) – Mr.Wizard Jun 24 '14 at 18:37
• @Mr.Wizard Please do not delete your answer :) Let both of them stay, if not then yours is more valuable :) – Kuba Jun 24 '14 at 18:49

Here are some more ways to do what is asked

a = {{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}, {{9, 10}, {11, 12}}};
b = {{0, 0}, {1, 1}, {2, 2}};

MapThread[{Sequence @@ #1, #2} &, {a, b}, 2]

MapThread[Insert[#1, #2, -1] &, {a, b}, 2]

MapThread[Join[#1, {#2}] &, {a, b}, 2]


and finally, using argument destructuring,

Block[{f},
f[{x_, y_}, z_] := {x, y, z};


All of the above return

{{{1, 2, 0}, {3, 4, 0}}, {{5, 6, 1}, {7, 8, 1}}, {{9, 10, 2}, {11, 12, 2}}}


The common thread (pun intended) running through all these examples is that any function accepting a 1st arg matching {x_, y_} and a 2nd arg matching z_ and producing {x, y, z} can be MapThread-ed at level 2 to produce the required result.

Unlike other answers here the combination of Join and Transpose will preserve a fully packed array:

<< Developer

A = {{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}, {{9, 10}, {11, 12}}} // ToPackedArray;
B = {{0, 0}, {1, 1}, {2, 2}} // ToPackedArray;

Join[A, Transpose[{B}, {3, 1, 2}], 3] // PackedArrayQ

True


This allows superior speed and memory management:

A = RandomInteger[99, {700, 400, 200}];
B = RandomInteger[99, {700, 400}];

MapThread[Append, {A, B}, 2]          // ByteCount // Timing
Join[A, Transpose[{B}, {3, 1, 2}], 3] // ByteCount // Timing

{0.436, 262108032}

{0.0393, 225120132}


Edit: Kuba's method will also preserve a packed array when given input large enough to invoke compilation according to the value defined in SystemOptions["CompileOptions" -> "MapCompileLength"].

One solution could be like this:

Partition[MapThread[Append, {Flatten[A, 1], B // Flatten}], 2]
`