5
$\begingroup$

Given {a, b, c, ...} with $n$ elements generate a list with $2^n$ elements.

For example, if the list were {a, b, c}, then the output should be

{{a, b, c}, {a, b, -c}, {a, -b, c}, ..., {-a, -b, -c}}

If possible, I want to use buit-in functions so that the task can be performed without looping. My own solutions using Subsets[{-1,-1,...} are very messy.

$\endgroup$
2
  • $\begingroup$ Hi, welcome to Mathematica.SE, please consider taking the tour so you learn the basic rules of the site. Once you gain enough reputation by making good questions you will be able to vote up and down both questions and answers. Your question has been answered, but its a good idea to wait a few hour for other answers before accepting the best one for you. $\endgroup$
    – rhermans
    Oct 11, 2014 at 22:22
  • $\begingroup$ Related: (30664), (47285) $\endgroup$
    – Mr.Wizard
    Oct 12, 2014 at 1:26

4 Answers 4

6
$\begingroup$

Solution

f[list_] := list # & /@ Tuples[{1, -1}, Length[list]]

Example

f[{a, b, c, d}]
{{a, b, c, d}, {a, b, c, -d}, {a, b, -c, d}, {a, b, -c, -d}, {a, -b, c, d}, {a, -b, c, -d}, {a, -b, -c, d}, {a, -b, -c, -d}, {-a, b, c, d}, {-a, b, c, -d}, {-a, b, -c, d}, {-a, b, -c, -d}, {-a, -b, c, d}, {-a, -b, c, -d}, {-a, -b, -c, d}, {-a, -b, -c, -d}}

Explanation

Tuples generates a list of all possible n-tuples of elements from list.

Tuples[{-1, 1}, 3]
{{-1, -1, -1}, {-1, -1, 1}, {-1, 1, -1}, {-1, 1, 1}, {1, -1, -1}, {1, -1, 1}, {1, 1, -1}, {1, 1, 1}}

Then the hieroglyphics part, list # & /@, multiplies the list to each sublist of the combinations of 1s and -1s, using Map (/@) and Function (# &)

$\endgroup$
3
  • $\begingroup$ I knew there was a simple way...thank you. $\endgroup$
    – user21349
    Oct 11, 2014 at 22:16
  • 1
    $\begingroup$ +1 for Tuples but there is a cleaner and faster formulation available; please see my answer. $\endgroup$
    – Mr.Wizard
    Oct 12, 2014 at 1:14
  • $\begingroup$ @Mr.Wizard Indeed better, thanks. $\endgroup$
    – rhermans
    Oct 12, 2014 at 23:10
8
$\begingroup$

I too would use Tuples but a bit differently. I propose:

f2[a_List] := Tuples[ {a, -a}\[Transpose] ]

Now:

f2[{a, b, c}]
{{a,b,c}, {a,b,-c}, {a,-b,c}, {a,-b,-c}, {-a,b,c}, {-a,b,-c}, {-a,-b,c}, {-a,-b,-c}}

This is both shorter and an order of magnitude faster than rhermans's formulation:

First @ Timing @ Do[# @ Range @ 18, {100}] & /@ {f, f2}
{4.368028, 0.358802}
$\endgroup$
5
$\begingroup$

Another method:

plusMinus[symlist_List] := 
 With[{n = Length[symlist]}, 
  Map[symlist*# &, 
   Table[IntegerDigits[j, 2, n], {j, 2^n - 1}] /. 0 -> -1]]

plusMinus[{a, b, c, d}]

(*  Out[11]= {{-a, -b, -c, d}, {-a, -b, c, -d}, {-a, -b, c, d}, {-a, 
  b, -c, -d}, {-a, b, -c, d}, {-a, b, c, -d}, {-a, b, c, 
  d}, {a, -b, -c, -d}, {a, -b, -c, d}, {a, -b, c, -d}, {a, -b, c, 
  d}, {a, b, -c, -d}, {a, b, -c, d}, {a, b, c, -d}, {a, b, c, d}} *)

If you do not need to maintain ordering there is also this.

plusMinus2[symlist_List] := 
 Map[Join[-Complement[symlist, #], #] &, Subsets[symlist]]

plusMinus2[{a, b, c, d}]

(* Out[19]= {{-a, -b, -c, -d}, {-b, -c, -d, a}, {-a, -c, -d, 
  b}, {-a, -b, -d, c}, {-a, -b, -c, d}, {-c, -d, a, b}, {-b, -d, a, 
  c}, {-b, -c, a, d}, {-a, -d, b, c}, {-a, -c, b, d}, {-a, -b, c, 
  d}, {-d, a, b, c}, {-c, a, b, d}, {-b, a, c, d}, {-a, b, c, d}, {a, 
  b, c, d}} *)
$\endgroup$
3
$\begingroup$

For symbolic input data BooleanMinterms and BooleanMaxterms may be of use:

g = Block[{And = List, Not = (-# &)}, Table[BooleanMinterms[{i-1}, {##}], {i, 2^Length[{##}]}]] &;

g[a, b, c, d]
(* {{-a,-b,-c,-d},{-a,-b,-c,d},{-a,-b,c,-d},{-a,-b,c,d},{-a,b,-c,-d},{-a,b,-c,d},
    {-a,b,c,-d},{-a,b,c,d},{a,-b,-c,-d},{a,-b,-c,d},{a,-b,c,-d},{a,-b,c,d},
    {a,b,-c,-d},{a,b,-c,d},{a,b,c,-d},{a,b,c,d}} *)

BooelanMaxTerms can be used similarly with || playing the role of && above.

$\endgroup$

Your Answer

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