# Using the elements of a subset in a Do loop

I would like to use the elements of Subsets in a Do loop. I have:

w = Subsets[{3, 4, 5, 6}, {2}]


which yields:

{{3, 4}, {3, 5}, {3, 6}, {4, 5}, {4, 6}, {5, 6}}

Now I want to use these ordered pairs in a Do loop. For example:

Do[ma[i]+mb[j],{i,...},{j,...}]


where {i,j} should be only these ordered pairs.

-
If you are using Do loops you are most likely new to Mathematica, so I would suggest reading up on Map and Apply. Do is very rarely needed. As for your question, if you simply run Subsets[{3, 4, 5, 6}, {2}] it prints the output, why would you want to loop through each element and print it separately? I assume you have a different problem, which I would suggest you post, most likely it can be solved without Do. –  jVincent Aug 1 '12 at 9:13
Welcome to Mathematica.SE! And congratulations for posting the 2500th question. No prices for that unfortunately. If you are going to post more questions here, you might want to read a bit about formatting questions here using Markup. There is a small link on that in the top right of your 'Ask question box' –  Sjoerd C. de Vries Aug 1 '12 at 9:16
yes I have a different problem. I have a loop which in this loop two indices {i,j} should take the above values(ordered pairs). –  Soodeh Z. Aug 1 '12 at 9:17
If you append this problem to your question I am sure it could be solved using Map/Apply, which are somewhat the cornerstones of Mathematica. It would likely be of value for you to learn the concepts of these. If for instance you have a function f[{i_,j_}]:=i+j and want to use it on each pair, you would use Map[f,Subsets[{3,4,5,6},{2}] which can also be written using the shorthand for Map as: f/@Subsets[{3,4,5,6},{2}] –  jVincent Aug 1 '12 at 9:25
Please consider registering your account, so that any votes you get for this question are added to those received for future questions. As you gain reputation points, you will be able to do more things like participate in the chat room. –  Verbeia Aug 1 '12 at 13:44
show 1 more comment

 w = Subsets[{3, 4, 5, 6}, {2}]


{{3, 4}, {3, 5}, {3, 6}, {4, 5}, {4, 6}, {5, 6}}

This will run only over this ordered pairs. Is this what you need? -

Do[Print[k], {k, w}];


In Mathematica you can also use other constructs similar to Do. For example

Table[Print[k], {k, w}];


Or even better, use functional programming:

Print /@ w;


All these give same result. Here /@ is a shortcut notation for Map which in full form would be Map[Print, w]. The major difference with Do and Table - there is no running index specification.

If you need to run a computation that separates the indexes (as you mentioned in the comment), it is still easy:

ma[#1] + mb[#2] & @@@ w


where @@@ is is a flavor of Apply . These will work too:

ma[#[[1]]] + mb[#[[2]]] & /@ w

Table[ma[k[[1]]] + mb[k[[2]]], {k, w}]


but why would you stray away from elegance? ;-) These [[...]] mean Part.

-
(+1) or Do[Print[k],{k,w}]. –  kguler Aug 1 '12 at 9:18
Thanks @kguler - you're mind reader ;-) –  Vitaliy Kaurov Aug 1 '12 at 9:20
yes exactly. thanks alot. –  Soodeh Z. Aug 1 '12 at 9:21
For typical beginner questions like this I'd suggest to explain the rather cryptic /@, @@ etc. prefix command forms of Mathematica if you use them. Makes them easier to find in the documentation as well. –  Sjoerd C. de Vries Aug 1 '12 at 9:26
my problem remains. –  Soodeh Z. Aug 1 '12 at 9:30

I suppose that the most likely reason to use subsets in a Do loop rather than just mapping (/@) a function is to conserve memory. Therefore I would like to point out that the third argument of Subsets specifies which subset(s) within the sequence to return. If one were attempting to find all subsets that sum to a certain value without first storing all subsets in memory one might use it like this:

SeedRandom[1]

set = RandomInteger[123, 50];

n = 3;

Do[
If[Total@# == 37, Print@#] & @@ Subsets[set, {n}, {i}],
{i, Binomial[Length@set, n]}
]


{14,0,23} {0,4,33} {3,24,10} {3,4,30} {3,1,33} {23,4,10} {15,4,18} {1,26,10}

(This is a brute force approach to that particular problem and there are better ways, but it serves as an illustration.)

In practice this is painfully slow. To make it practical you would process the subsets in blocks. Here in blocks of 10,000 subsets each:

SeedRandom[1]
set = RandomInteger[2000, 250];
n = 3;
Do[
If[Total@# == 137, Print@#] & /@ Quiet@Subsets[set, {n}, {i, i + 10000}],
{i, 1, Binomial[Length@set, n], 10000}
]


{28,16,93}

{28,106,3}

-