7
$\begingroup$

I'm trying to write a program that takes a given matrix A of 1's and 0's and flips a designated amount of 1's to -1's.

lis1 = ArrayRules[A];
For[i = 1, i < Length[lis1] , i++
   lis2 = RandomChoice[ArrayRules[A], n];
 {a, b} = lis2[[i]];
ReplacePart[lis1, {a,b} -> -1];

This obviously doesn't work, and I'm not sure I even need the For loop for this, but what syntax do I need specifically to replace the [i,j] element of lis1 with -[i,j] of lis2?
Is there a more efficient way of doing this?

$\endgroup$
1
  • $\begingroup$ ReplacePart[list1, {##} -> -list2[[##]]] & @@@ {{i1, j1}, {i2, j2}} ? $\endgroup$ Commented Jan 26, 2016 at 2:49

2 Answers 2

7
$\begingroup$

Here's a quick helper function to do so. It first finds the position of each $1$ in the original matrix using Position; it then selects $n$ of these positions randomly using RandomSample and replaces their value with $-1$ using ReplacePart:

Clear[flipsome]
flipsome[matrix_?MatrixQ, n_Integer] :=
 ReplacePart[matrix, RandomSample[Position[matrix, 1], n] -> -1]

Let's generate a random matrix of ones and zeros:

(a = RandomInteger[{0, 1}, {10, 10}]) // MatrixForm

Mathematica graphics

.. and use flipsome to flip 10 randomly selected $1$s to $-1$:

flipsome[a, 10] // MatrixForm

Mathematica graphics

$\endgroup$
3
  • $\begingroup$ I'm getting the error ""RandomSample cannot generate a sample of length 2, which is greater \ than the length of the sample set {}. If you want a choice of \ possibly repeated elements from the set, use RandomChoice"" when I try to flip 2 elements, any suggestions? $\endgroup$
    – TeeJay
    Commented Jan 26, 2016 at 4:01
  • $\begingroup$ Position[matrix, 1] seems to be the problem. I can fix it by substituting Normal[matrix] for matrix, but this is pretty inefficient. I can't figure out how to do this with ArrayRules[matrix]. $\endgroup$
    – TeeJay
    Commented Jan 26, 2016 at 4:05
  • $\begingroup$ @TeeJay That seems to indicate that you are applying flipsome to an array that does not actually contain any $1$s, so Position returns an empty list. $\endgroup$
    – MarcoB
    Commented Jan 26, 2016 at 4:05
1
$\begingroup$

Also

ClearAll[flipF]
flipF = MapAt[-1 &, #, RandomSample[Position[#, 1], #2]] &;
(* or *) flipF = MapAt[-1 &, #, RandomSample[SparseArray[#]["NonzeroPositions"], #2]] &

a = RandomInteger[{0, 1}, {9, 9}];
Row[Labeled[MatrixForm@ToExpression@#, #, Top] & /@ {"a", "flipF[a,5]"}, Spacer[5]] 

Mathematica graphics

$\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.