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$
  • $\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 '14 at 22:22
  • $\begingroup$ Related: (30664), (47285) $\endgroup$ – Mr.Wizard Oct 12 '14 at 1:26
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 (# &)

|improve this answer|||||
$\endgroup$
  • $\begingroup$ I knew there was a simple way...thank you. $\endgroup$ – user21349 Oct 11 '14 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 '14 at 1:14
  • $\begingroup$ @Mr.Wizard Indeed better, thanks. $\endgroup$ – rhermans Oct 12 '14 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}
|improve this answer|||||
$\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}} *)
|improve this answer|||||
$\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.

|improve this answer|||||
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy