Skip to main content
edited tags
Link
Tweeted twitter.com/StackMma/status/707836278419673088
edited tags
Link
Leonid Shifrin
  • 115.8k
  • 16
  • 341
  • 435
functionality is also like Tuples
Source Link
Manuel --Moe-- G
  • 1.1k
  • 1
  • 8
  • 17

Lazy form of OuterTuples/Outer to loop over list of lists

This is less a question and more asking if someone has implemented this already, with more skill.

I need to perform the OuterOuter-like generalized outer product of a list of lists (also a form of Tuples). I need to do it in a lazy way because the lists will become very large (many tens of thousands of elements).

I am using a Module to hold state as iterate over the products

loopOver[list0_]:=Module[ {len0,index,get,increment,isDoneQ,doneB}, len0=Length[list0]; Do[index[j]=1,{j,len0}]; doneB=False; get[]:=Table[list0[[j,index[j]]],{j,len0}]; increment[]:=Block[ {stack,p}, If[doneB,Return[]]; stack={len0}; While[Length[stack]>0, p=First@stack; stack=Rest@stack; index[p]=index[p]+1; If[index[p]>Length[list0[[p]]], ( If[p===1,doneB=True;Return[]]; index[p]=1;stack=Append[stack,p-1] ) ] ] ]; isDoneQ[]:=doneB; { "get"->get, "increment"->increment, "isDoneQ"->isDoneQ } ] 

And you use it as such:

Block[ {a, get, increment, isDoneQ}, a = { {"11", "12", "13"}, {"21", "22"}, {"31"}, {"41", "42"} }; {get,increment,isDoneQ}=loopOver[a][[All,2]]; While[!isDoneQ[], Print[get[]]; increment[] ] ] 

outputting the expected outer of 321*2=12 products:

{11,21,31,41} {11,21,31,42} {11,22,31,41} {11,22,31,42} {12,21,31,41} {12,21,31,42} {12,22,31,41} {12,22,31,42} {13,21,31,41} {13,21,31,42} {13,22,31,41} {13,22,31,42} 

Code review would be appreciated too. I hope my code is high on self documentation where it is low on performance and use of MMA functional coding style.

Lazy form of Outer to loop over list of lists

This is less a question and more asking if someone has implemented this already, with more skill.

I need to perform the Outer-like generalized outer product of a list of lists. I need to do it in a lazy way because the lists will become very large (many tens of thousands of elements).

I am using a Module to hold state as iterate over the products

loopOver[list0_]:=Module[ {len0,index,get,increment,isDoneQ,doneB}, len0=Length[list0]; Do[index[j]=1,{j,len0}]; doneB=False; get[]:=Table[list0[[j,index[j]]],{j,len0}]; increment[]:=Block[ {stack,p}, If[doneB,Return[]]; stack={len0}; While[Length[stack]>0, p=First@stack; stack=Rest@stack; index[p]=index[p]+1; If[index[p]>Length[list0[[p]]], ( If[p===1,doneB=True;Return[]]; index[p]=1;stack=Append[stack,p-1] ) ] ] ]; isDoneQ[]:=doneB; { "get"->get, "increment"->increment, "isDoneQ"->isDoneQ } ] 

And you use it as such:

Block[ {a, get, increment, isDoneQ}, a = { {"11", "12", "13"}, {"21", "22"}, {"31"}, {"41", "42"} }; {get,increment,isDoneQ}=loopOver[a][[All,2]]; While[!isDoneQ[], Print[get[]]; increment[] ] ] 

outputting the expected outer of 321*2=12 products:

{11,21,31,41} {11,21,31,42} {11,22,31,41} {11,22,31,42} {12,21,31,41} {12,21,31,42} {12,22,31,41} {12,22,31,42} {13,21,31,41} {13,21,31,42} {13,22,31,41} {13,22,31,42} 

Code review would be appreciated too. I hope my code is high on self documentation where it is low on performance and use of MMA functional coding style.

Lazy form of Tuples/Outer to loop over list of lists

This is less a question and more asking if someone has implemented this already, with more skill.

I need to perform the Outer-like generalized outer product of a list of lists (also a form of Tuples). I need to do it in a lazy way because the lists will become very large (many tens of thousands of elements).

I am using a Module to hold state as iterate over the products

loopOver[list0_]:=Module[ {len0,index,get,increment,isDoneQ,doneB}, len0=Length[list0]; Do[index[j]=1,{j,len0}]; doneB=False; get[]:=Table[list0[[j,index[j]]],{j,len0}]; increment[]:=Block[ {stack,p}, If[doneB,Return[]]; stack={len0}; While[Length[stack]>0, p=First@stack; stack=Rest@stack; index[p]=index[p]+1; If[index[p]>Length[list0[[p]]], ( If[p===1,doneB=True;Return[]]; index[p]=1;stack=Append[stack,p-1] ) ] ] ]; isDoneQ[]:=doneB; { "get"->get, "increment"->increment, "isDoneQ"->isDoneQ } ] 

And you use it as such:

Block[ {a, get, increment, isDoneQ}, a = { {"11", "12", "13"}, {"21", "22"}, {"31"}, {"41", "42"} }; {get,increment,isDoneQ}=loopOver[a][[All,2]]; While[!isDoneQ[], Print[get[]]; increment[] ] ] 

outputting the expected outer of 321*2=12 products:

{11,21,31,41} {11,21,31,42} {11,22,31,41} {11,22,31,42} {12,21,31,41} {12,21,31,42} {12,22,31,41} {12,22,31,42} {13,21,31,41} {13,21,31,42} {13,22,31,41} {13,22,31,42} 

Code review would be appreciated too. I hope my code is high on self documentation where it is low on performance and use of MMA functional coding style.

Source Link
Manuel --Moe-- G
  • 1.1k
  • 1
  • 8
  • 17
Loading