2
$\begingroup$

I have subsets formed from a list using the Subsets command and want to do a particular calculation, lets say subtraction using the Subtract command only with the sets I want. For example,

m = {4, 5, 3, 2, 8};

Subsets[m, {2}]

{{4, 5}, {4, 3}, {4, 2}, {4, 8}, {5, 3}, {5, 2}, {5, 8}, {3, 2}, {3, 8}, {2, 8}}

From this list first I want to take the subsets that contains 4 and do subtraction. Then I want to take all subsets that contain 5, including {4,5} and do subtraction and so on.

$\endgroup$
1
  • $\begingroup$ (Sub)sets are not ordered while subtraction is non-commutative. Are you sure this is exactly what you meant (or that it is subtraction that you want)? $\endgroup$
    – Szabolcs
    Commented Jul 18, 2012 at 14:35

4 Answers 4

4
$\begingroup$

For the first part of your question, one possibility:

Select[Subsets[m, {2}], MemberQ[#, 4] &]
Select[Subsets[m, {2}], MemberQ[#, 4 | 5] &]
Select[Subsets[m, {2}], MemberQ[#, 4 | 5] && FreeQ[#, 8] &]

giving

(*{{4, 5}, {4, 3}, {4, 2}, {4, 8}}

{{4, 5}, {4, 3}, {4, 2}, {4, 8}, {5, 3}, {5, 2}, {5, 8}}

{{4, 5}, {4, 3}, {4, 2}, {5, 3}, {5, 2}}

*)

$\endgroup$
1
  • 1
    $\begingroup$ And then if you want to apply subtraction to each subset you can simply use the shorthand for Apply: Subtract@@@Select[Subsets[m, {2}], MemberQ[#, 4] &] $\endgroup$
    – jVincent
    Commented Jul 18, 2012 at 12:58
2
$\begingroup$

Sets are not ordered, so the (non-commutative) subtraction can be done either as a - b or b - a for the subset {a, b}. Keeping this in mind, here's a solution that computes all results in one go:

m = {4, 5, 3, 2, 8};
ss = Subsets[m, {2}]
g = GatherBy[Join[ss, Reverse /@ ss], First]
Apply[Subtract, g, {2}]

(* ==> 
  {{-1, 1, 2, -4}, {2, 3, -3, 1}, {1, -5, -1, -2}, {-6, -2, -3, -1}, {4, 3, 5, 6}}
*)

This gives results for subsets that contain the following elements, respectively:

g[[All, 1, 1]]

(* ==> {4, 5, 3, 2, 8} *)
$\endgroup$
2
$\begingroup$
list = Subsets[{4, 5, 3, 2, 8}, {2}];

Using ContainsAny and ContainsNone (new in 10.2)

Select[list, ContainsAny[{4, 5}]]

{{4, 5}, {4, 3}, {4, 2}, {4, 8}, {5, 3}, {5, 2}, {5, 8}}

Using MapApply (new in 13.1)

MapApply[Subtract][%]

{-1, 1, 2, -4, 2, 3, -3}

Likewise

Cases[list, x_ /; ContainsAny[x, {4, 5}]]

{{4, 5}, {4, 3}, {4, 2}, {4, 8}, {5, 3}, {5, 2}, {5, 8}}

DeleteCases[list, x_ /; ContainsNone[x, {4, 5}]]

{{4, 5}, {4, 3}, {4, 2}, {4, 8}, {5, 3}, {5, 2}, {5, 8}}

$\endgroup$
1
$\begingroup$
Special thanks to Belisarius. 

Based on his idea I had written the below code

list = {4, 10, 16, 7, 18}

c = Subsets[Range[Length@list], {2}];

m = Table[Cases[c, {_, i} | {i, _}], {i, Length@list}]

s[{i_, j_}] := Subtract[list[[i]], list[[j]]];

Table[Map[s, m[[f]]], {f, Length@m}]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.