I need to use Tuples[tab] where tab={vec1,vec2,vec3} and vec1,vec2,vec3 are vectors of possibly different lengths n1,n2,n3. Therefore, it is:
Dimensions[Tuples[tab]] -> {n1*n2*n3,3}
Now, if n1,n2,n3 are large, Tuples[tab] occupies a lot of memory. Is it possible not to create Tuples[tab] but rather evaluate on demand its i-th element?
Note added: Thank you for pointing me to Lazy form of Tuples/Outer to loop over list of lists; I was not familiar with the terminology "lazy evaluation".
The solution is LazyTuples which can be loaded using:
Import["https://gist.githubusercontent.com/lshifr/56c6fcfe7cafcd73bdf8/raw/LazyTuples.m"]
A self-contained answer is:
ClearAll[next];
next[{left_, _}, dim_] := {left - dim*(# - 1), #} &[IntegerPart[(left - 1)/dim] + 1];
ClearAll[multiDims];
multiDims[dims_] := Rest@Reverse@FoldList[Times, 1, Reverse@dims];
ClearAll[multiIndex];
multiIndex[pos_, dims : {__Integer}] := Rest@FoldList[next, {pos, 0}, multiDims@dims][[All, 2]]
ClearAll[take];
take[lists : {__List}, {start_, end_}] := With[{rend = Min[end, Times @@Map[Length, lists]]},Transpose@MapThread[Part, {lists, multiIndex[Range[start, rend], Length /@ lists]}]];
take[tab,{i,i}][[1]] (* which gives the same output of Tuples[tab][[i]] *)