# How to arrange two tables in the following way?

Consider two tables:

tab1 = Flatten[Table[{x, y}, {x, 1, 2, 0.1}, {y, 1, 3, 0.5}], {1, 2}];
tab2 = Flatten[
Table[{p, q}, {p, 0.1, 10, 0.2}, {q, 20, 199, 11}], {1, 2}];


I would like to glue it in the form

{tab1[[i]][[1]], tab1[[i]][[2]], tab2[[j]][[1]],
tab2[[j]][[2]]}


where i runs from 1 to Length[tab1] and j from 1 to Length[tab2]. My attempt is a brute force:

Table[{tab1[[i]][[1]], tab1[[i]][[2]], tab2[[j]][[1]],
tab2[[j]][[2]]}, {i, 1, Length[tab1], 1}, {j, 1, Length[tab2], 1}]


But it seems to be extremely slow. Could you please tell me whether some faster way exists?

aa = Table[{tab1[[i]][[1]], tab1[[i]][[2]], tab2[[j]][[1]], tab2[[j]][[2]]},
{i, 1, Length[tab1], 1}, {j, 1, Length[tab2], 1}]; // AbsoluteTiming // First


0.146368

You can use Outer:

bb = Outer[Join, tab1, tab2, 1]; // AbsoluteTiming // First
aa == bb


0.040488

True

Or, if you have to execute it more often, you can Compile the code:

cf = Compile[{{x, _Real, 1}, {y, _Real, 2}},
Table[Join[x, CompileGetElement[y, i]], {i, 1, Length[y]}],
CompilationTarget -> "C",
RuntimeAttributes -> {Listable},
Parallelization -> True,
RuntimeOptions -> "Speed"
];


Then

cc = cf[tab1, tab2]; // AbsoluteTiming // First
aa == cc


0.002277

True

Using Tuples and Reshape is even better, provided that you turn tab2 into an array of reals only (and thus into a packed array):

tab1 = Flatten[Table[{x, y}, {x, 1, 2, 0.1}, {y, 1, 3, 0.5}], {1, 2}];
tab2 = Flatten[Table[{p, q}, {p, 0.1, 10., 0.2}, {q, 20., 199., 11.}], {1, 2}];

dd = ArrayReshape[
Tuples[{tab1, tab2}],
{Dimensions[tab1][[1]], Dimensions[tab2][[1]], Dimensions[tab1][[2]] + Dimensions[tab2][[2]]}
]; // AbsoluteTiming // First
aa == dd


0.000416

True

And Flatten[aa, {1, 2}] can be obtained like this:

ee = ArrayReshape[
Tuples[{tab1, tab2}],
{Dimensions[tab1][[1]] Dimensions[tab2][[1]], Dimensions[tab1][[2]] + Dimensions[tab2][[2]]}
]; // AbsoluteTiming // First
Flatten[aa, {1, 2}] == ee
`

0.000413

True