# Restricting Numbers in a Matrix

I am generating a random N x N matrix, but with a certain restriction. What I'm trying to do is that when there's a "1" in a position, all neighboring positions must turn to "0" (so if [i,j] = 1, then [i+1,j] = [i-1,j] = [i,j-1] = [i, j+1] = 0.)

Currently I am working with something like this:

Num = 10
mat = RandomInteger[{0,1},{Num, Num}]

Table[If[themat[[i,j]] == 1, themat[[i+1,j]]==0, themat[[i,j]]]


However, I keep getting the error that "Part specification i is neither a machine-sized integer nor a list of machine-sized integers". Could someone please help me with this? Thank you!

• Look at your last line of code. Assuming mat[[row,col]] notation. What happens if it finds a 1 in row 10? When you have figured that out then think about finding a 1 in column 10 or row 1 or column 1 or in each of the four corners? That should be enough of a hint for you to fix the code. Using Table may not be the easiest method to understand in this case. – Bill Nov 7 '14 at 1:49
• @WayneFullen does this only apply to internal elements, i.e. what about corners of array ({1,1},{1,num},{num,1},{num,num}) or boundary? – ubpdqn Nov 7 '14 at 3:58

Your problem is not well defined because you do not specify adequately what you mean by "random." You imply that the only entries are 0 and 1. Is that what you want? Do you have a required proportion P of 1s in the entire matrix where P< 0.5)? There are numerous trivial "solutions," for instance setting the entries of the entire matrix to 0 except a single entry to 1.

• Sorry for not being clear; what I'm looking for is a uniform distribution for the entire matrix, where the probability of 0 or 1 is equal (the only exception is when there are neighboring 1's, I would want to change those to 0's). – Wayne Fullen Nov 7 '14 at 0:52
• David, you address the unclear issues very nicely, but this might be better off as a comment (yet) . @WayneFullen please add all necessary info to the question. – Yves Klett Nov 7 '14 at 7:24
• If your matrix has 50% 1s and 50% 0s and obeys your neighborhood restriction, isn't the only solution equivalent to a checkerboard? – David G. Stork Nov 8 '14 at 0:32

Starting data, biased to zero for a reason that will become apparent:

Num = 10
SeedRandom[0]
mat = RandomChoice[{4, 1} -> {0, 1}, {Num, Num}];


$\left( \begin{array}{cccccccccc} 0 & 0 & 0 & 0 & 1 & 1 & 0 & 0 & 0 & 0 \\ 0 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\ 1 & 1 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 1 & 0 \\ 1 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\ \end{array} \right)$

A matrix with zero in every position that in the original has a one in one of the eight neighboring places:

ker = 1 - BoxMatrix[0, 3]

mask = 1 - Unitize@ListCorrelate[ker, mat, {2, 2}]

{{1, 1, 1}, {1, 0, 1}, {1, 1, 1}}


$\left( \begin{array}{cccccccccc} 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ 1 & 0 & 1 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 1 & 1 & 1 & 1 & 0 & 0 & 0 & 0 \\ 1 & 1 & 1 & 1 & 1 & 0 & 0 & 0 & 1 & 1 \\ 0 & 0 & 0 & 1 & 1 & 0 & 0 & 0 & 0 & 1 \\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ \end{array} \right)$

Multiply (simple multiplication, not matrix multiplication) the two and you get:

mask * mat // MatrixForm


$\left( \begin{array}{cccccccccc} 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ \end{array} \right)$

As you can see only three ones survive.

ClearAll[filterF];
filterF[mat_, cornerneighbors_: True] := Block[{ker = If[cornerneighbors, 1 - BoxMatrix[0, 3],
{{0, 1, 0}, {1, 0, 1}, {0, 1, 0}}]},
DeveloperPartitionMap[If[FreeQ[ker #, 1], #[[2, 2]], 0] &, mat, {3, 3}, 1, 2, mat]]


Using Mr.Wizard's example:

SeedRandom[0];
mat = RandomChoice[{4, 1} -> {0, 1}, {10, 10}];
Row[Labeled[MatrixForm@#, #2, Top] & @@@ {{mat, "mat"},
{filterF@mat, "filterF@mat"}, {filterF[mat, False],"filterF[mat,False]" }}, Spacer[10]]


Here's my attempt to arrive at what I think you meant. However, I doubt that this matrix will have a random distribution since it was processed from a random matrix.

Module[{onePositions,aloneOnePositions,onePositionsDeleted,newMatrix,redHighLight},
(* All positions of 1 *)
onePositions=Position[mat,1];

(* All positions of 1 that are not in the neighborhood of any previous positions *)
aloneOnePositions=onePositions//.{a___,b_,c___,d_,e___}/;d==b+{0,1}||d==b+{1,0}:>{a,b,c,e};

(* All positions of 1 that are in the neighborhood of any previous positions *)
onePositionsDeleted=Complement[onePositions,aloneOnePositions];

(* New matrix is formed by replacing all positions of 1 in the neighboorhood of any previous positions to 0 *)
newMatrix=ReplacePart[mat,onePositionsDeleted->0];

(* Display and compare *)
redHighLight[m_]:=ReplacePart[m,aloneOnePositions->Style[1,Red]]//Grid;
redHighLight/@{mat,newMatrix}//Grid[{{"mat","newMatrix"},#},Frame->All]&
]
`