# Replacing elements of a matrix

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?

• ReplacePart[list1, {##} -> -list2[[##]]] & @@@ {{i1, j1}, {i2, j2}} ? Jan 26 '16 at 2:49

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


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

flipsome[a, 10] // MatrixForm


• 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? Jan 26 '16 at 4:01
• 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]. Jan 26 '16 at 4:05
• @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. Jan 26 '16 at 4:05

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]]