Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have a matrix $M$, whose dimension I am unsure of, which has only $\lbrace0,1\rbrace$ entries. I would like to generate all the possible matrices that result from changing (some subset) of the $1$'s to $-1$'s. For example, if $M=\lbrace\lbrace0,1\rbrace,\lbrace 1,0\rbrace\rbrace$, then I would like to generate the list: $$ \lbrace\lbrace\lbrace0,1\rbrace,\lbrace 1,0\rbrace\rbrace,\lbrace\lbrace0,-1\rbrace,\lbrace 1,0\rbrace\rbrace,\lbrace\lbrace0,1\rbrace,\lbrace -1,0\rbrace\rbrace,\lbrace\lbrace0,-1\rbrace,\lbrace -1,0\rbrace\rbrace\rbrace.$$

I am trying to use ReplaceList to do this, but it is not working out exactly as I would want. For example, here is an example for a 2x2 matrix:

ReplaceList[{1, 1, 1, 1}, 
{{x___, 1, y___} -> {x, -1, y},
{z___, 1, x___, 1, y___} -> {z, -1, x, -1, y},
{t___, 1, z___, 1, x___, 1, y___} -> {t, -1, z, -1, x, -1, y},
{1, 1, 1, 1} -> {-1, -1, -1, -1}}]

Not exactly extensible (nor very pretty). Is there a nice way to do this? Again, I would like to have code that works regardless of dimension, and also accepts as input a matrix (you might notice I Flattened my 2x2 above), and returns a list of matrices.

Thanks!

share|improve this question
add comment

4 Answers

up vote 6 down vote accepted

You can do it by generating all possible subsets of the positions of the ones:

m = {{0, 1}, {1, 0}}
ReplacePart[m, # -> -1] & /@ Subsets[Position[m, 1]]
(* {{{0,1},{1,0}},{{0,-1},{1,0}},{{0,1},{-1,0}},{{0,-1},{-1,0}}} *)

I guess you can't go around the problem of it being inefficient since getting all combinations of something always is.

share|improve this answer
    
great answer, thanks! –  Steve D Nov 28 '12 at 0:36
add comment

For example

m = {{0, 1}, {1, 0}};

ReplacePart[m, #] & /@ Thread[Rest[Subsets@Position[m, 1]] -> -1]

(* {{{0, -1}, {1, 0}}, {{0, 1}, {-1, 0}}, {{0, -1}, {-1, 0}}} *)
share|improve this answer
    
I gave this one to ssch, only because you have more Rep than (s)he does! –  Steve D Nov 28 '12 at 0:36
    
@SteveD It's OK. However, if you don't mind whether ssch is a he or she, perhaps I should've hold my answer :=) –  belisarius Nov 28 '12 at 2:51
add comment

Find the posituions of the 1s. Then create a list of all tuples of that length, but with either 1 or -1. Last use that as replacements for the 1s in the original matrix.

Your example:

mat = {{0, 1}, {1, 0}};
pos1 = Position[mat, 1];
lposn = Length[pos1];
vallists = IntegerDigits[Range[0, 2^lposn - 1], 2, lposn] /. 0 -> -1

(* Out[17]= {{-1, -1}, {-1, 1}, {1, -1}, {1, 1}} *)

Map[ReplacePart[mat, Thread[pos1 -> #]] &, vallists]

(* Out[21]= {{{0, -1}, {-1, 0}}, {{0, -1}, {1, 0}}, {{0, 1}, {-1, 
   0}}, {{0, 1}, {1, 0}}} *)
share|improve this answer
add comment
 mat = {{0, 1}, {1, 0}};
 spar = SparseArray[mat];
 pos = Rest@Subsets@spar["NonzeroPositions"];
 MapAt[-1 &, spar, #] & /@ pos
 (* or *)
 MapAt[#/. (1)-> -1 &, spar, #] & /@ pos
 (* {{{0, -1}, {1, 0}}, {{0, 1}, {-1, 0}}, {{0, -1}, {-1, 0}}} *)
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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