Original Method
tables[n1_, n2_] := Join @@ Table[{a[i, j], b[i, j]}, {i, n2}, {j, 0, n1}]
Short@tables[100, 100]
{{a[1,0],b[1,0]},{a[1,1],b[1,1]},<<10097>>,{a[100,100],b[100,100]}}
Other Methods
And a comparison of a few other ways that are albeit surprisingly slower, but also get the job done. Also a good example at the optimization of Table
.
With[
{n = 10},
SameQ[
Join @@ Table[{a[i, j], b[i, j]}, {i, n}, {j, 0, n}],
{a@##, b@##} & @@@ Tuples@Range[{1, 0}, {n, n}],
Replace[Tuples@Range[{1, 0}, {n, n}], {x__} :> {a[x], b[x]}, 1],
Tuples@Range[{1, 0}, {n, n}] /. {x__Integer} :> {a[x], b[x]},
Join @@ Array[{a@##, b@##} &, {n, n + 1}, {1, 0}]
]
]
True
DiscretePlot[
{
AbsoluteTiming[Join @@ Table[{a[i, j], b[i, j]}, {i, n}, {j, 0, n}]][[1]],
AbsoluteTiming[Join @@ Array[{a@##, b@##} &, {n, n + 1}, {1, 0}]][[1]],
AbsoluteTiming[{a@##, b@##} & @@@ Tuples@Range[{1, 0}, {n, n}]][[1]],
AbsoluteTiming[Replace[Tuples@Range[{1, 0}, {n, n}], {x__} :> {a[x], b[x]}, 1]][[1]],
AbsoluteTiming[Tuples@Range[{1, 0}, {n, n}] /. {x__Integer} :> {a[x], b[x]}][[1]]
},
{n, 1, 501, 10},
Frame -> True,
FrameLabel -> {"List Length (n)", "Timing (s)"},
Joined -> True,
Filling -> None,
PlotLegends -> {"Table", "Array", "Apply", "Replace", "ReplaceAll"},
PlotLabel -> "Method Timing Comparison \r",
ImageSize -> Large,
BaseStyle -> {12, FontFamily -> Times}
]
I was surprised because the creation of the index list using Tuples
was much faster than creating the same list with Table
(by at least an order of magnitude), but the subsequent either application or replacement ended up making it much slower than just using Table[{a[i, j], b[i, j]},...]
in the first place.
Table[Tablei[k],{k,1,OtherLargeNumber}]
. Or justTable[{a[i,j], b[i,j]},{j,0,LargeNumber,1},{i,1,OtherLargeNumber}]
in one go. $\endgroup$Flatten[....,1]
$\endgroup$