# Tuples with more criteria

I have seen that there is question here which does almost what I wanted to ask but it's not quite what I wanted.

Efficiently generating tuples with Outer

What I would like to have is a Tuples of a fixed number elements such that, that combination needs to satisfy a condition. Not very efficiently is

Select[Tuples[{a1,a2,a3,...,aN},fixeddimension],criterion]


I know that it seems similar to the other one, but what I want is an efficient way to write Tuples of fixeddimension each of them satisfying a criterion. I don't know if it's possible to generalize to a multiple criteria the previous idea, so something like

Select[Tuples[{a1,a2,a3,...,aN}],criterion1 && criterion2]


but I already have a problem with Tuples[{a1,a2,a3,...aN}] because the inputs "aN" contain subscripts and I would like to have Tuples which leave the expression as it is, without expanding the subscripts. This is solved ones I add the "fixeddimension" of the tuplet.

What I wrote is anyway inefficient because the machine needs to store all the possible tuples before starting to select them (which was also the problem with the previous question). So here what I would like to have:

• A generalization of the previous question for multiple criteria and a way to solve why when I don't specify the dimension of the tuples, the variables with subscripts are separated by their subscript.
• A generalization of the previous question in which we make a selection of the tuplet of fixed length which satisfy a condition.

I'm not seeing how subscripts or multiple criteria change anything.

xs = Array[Subscript[x, #] &, 5]
pairs = Tuples[xs, 2]
multcrit[pr_] := OddQ@Last@First@pr && EvenQ@Last@Last@pr
Select[pairs, multcrit]  (* the selected elements *)


Replace this Select with the approach from the referenced question and then use ReplaceAll to substitute expressions for the subscripted variables. If the selection is based on the expressions to be substituted, then you can instead Map across the tuples, substituting and replacing as you go.

Edit:

If you are sure that you cannot hold all the tuples in memory but can hold all the selected tuples in memory, you can chunk the list. E.g.,

xs = Array[Subscript[x, #] &, 5]  (* array *)
n = 2  (* length of tuples *)
size = 2  (* chunk size *)
chunks = Partition[xs, UpTo[size]]
idxs = Range[Length[chunks]]  (* chunk ids *)
multcrit[pr_] := OddQ@Last@First@pr && EvenQ@Last@Last@pr
getTuples[ids_, crit_] := Select[Tuples[chunks[[ids]]], crit]
ParallelMap[getTuples[#, multcrit] &, Tuples[idxs, n]]  (* can catenate this *)


What you really want is a tuple iterator, but as far as I know (?) we are still waiting on the Streaming packages for such things.

• Multiple criteria once you have all the tuples is ok, but suppose that all the tuples create an array bigger than what mathematica can support (like taking all the possible combination of 9 elements among 45), then I cannot give a criteria. I would like to have a way to find a combination which have a fixed number of element, such that that combination has another condition among the elements. Example: xs={1,2,3,4,5}, pairs=Tuples[xs,5], Select[pairs, total[pairs[[i]]]=12]. Now suppose that pairs has 45^9 components, I cannot save it all. Oct 31 '19 at 12:08
• However, I can define an array that at priori define pairs as tuples of 5 elements satisfying that their sum is 12. Oct 31 '19 at 12:09
• Abount the subscript. If you try directly to do Tuples[xs] without specifying how big you want it, you have the subscript considered as possible elements. It was just a suggestion in case in which would have been to difficult to program two criteria for a generic Tuples[xs] or one criteria with a Tuples[xs,9] Oct 31 '19 at 12:16
• @AlessandroMininno Does chunking meet your needs? (See edit.)
– Alan
Oct 31 '19 at 14:57
• thanks for the edit, I'm now trying to use the functions that have been suggested in a comment because for small value seems to reproduce what I wanted. If for instance that is not working, I'll try your code. Thanks! Oct 31 '19 at 16:50