1
$\begingroup$

This question already has an answer here:

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]] *)
$\endgroup$

marked as duplicate by Carl Woll, george2079, LCarvalho, m_goldberg, aardvark2012 Nov 2 '17 at 0:10

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

Browse other questions tagged or ask your own question.