3
$\begingroup$

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?

$\endgroup$

1 Answer 1

5
$\begingroup$
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, Compile`GetElement[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

$\endgroup$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.