# How to generate a matrix with certain conditions

I want to generate a $$n \times n$$ matrix.

1. I want the diagonal entries to be all 0
2. I want a random choice of matrix elements with 0 or 1.
3. The probability of having a 1 as a matrix element is $$1/m$$ and the probability of having a 0 as a matrix element is $$1-1/m$$.

I used the following command but it is wrong.

A[n_, m_] :=Table[If[i == j, 0,RandomVariate[BernoulliDistribution[m],{n,n}]]]


And I tried to test this command with n=4, m=0.4 but it didn't work.

Could anyone kindly tell me how to do this please? Thank you!

• For a start, your code seems to set the diagonal elements to 1 rather than zero. – MarcoB Mar 2 at 15:38
• Same question posted here. – Rohit Namjoshi Mar 2 at 22:23
• tiffany, please go here to get your accounts merged, so you can easily access your question. – J. M. will be back soon Mar 3 at 2:43

Binary random variables are often modeled using the BernoulliDistribution. You can use the function RandomVariate to get a matrix of such variables.

mat = RandomVariate[BernoulliDistribution[0.9], {5, 5}];
mat - DiagonalMatrix[Diagonal[mat]]
% // MatrixForm


$$\begin{pmatrix} 0&1&1&1&1\\ 1&0&1&1&1\\ 1&1&0&1&1\\ 1&0&1&0&1\\ 0&1&1&1&0\end{pmatrix}$$

You can change the 0.9 to any value (this is your m). The second line sets all the diagonal elements to zero.

It's easy enough to make this into a function:

makeMat[n_, m_] := (mat = RandomVariate[BernoulliDistribution[m], {n, n}];
mat - DiagonalMatrix[Diagonal[mat]])


Then the above example is makeMat[5, 0.9]

• Thank you bill s How will the command be if I do not restrict what n and m be? For example, I would like to generate a set of commands which I can replace m and n easily by any number. – tiffany Mar 2 at 16:51
• @tiffany, just do With[{n = 8, m = 3}, (# - DiagonalMatrix[Diagonal[#]]) &[RandomVariate[BernoulliDistribution[1/m], {n, n}]]]. – J. M. will be back soon Mar 2 at 20:08

You can use weight option in RandomChoice

n = 5;
m = 2;
mat = RandomChoice[{1/m, 1 - 1/m} -> {1, 0}, {n, n}];
(mat - DiagonalMatrix[Diagonal@mat]) // MatrixForm


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

• Altho using the BernoulliDistribution[] is best, this is likely to be more easy to read for someone who is not accustomed to discrete probability distributions. – J. M. will be back soon Mar 2 at 20:09

Since all the simple answers have been given, here is a SparseArray[] solution that may be useful if you want to generate large matrices without storing unneeded zero entries:

tiffany[n_Integer?Positive, m_] :=
SparseArray[{j_, k_} /; j != k && RandomReal[] < 1/m :> 1, {n, n}]


As an example:

BlockRandom[SeedRandom["tiffany"]; tiffany[7, 2.5] // Normal]
{{0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 1},
{0, 0, 0, 1, 0, 1, 1}, {0, 0, 0, 0, 1, 0, 0},
{0, 1, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 1}, {0, 0, 0, 0, 0, 1, 0}}

m = 2;
n = 5;
rnd[x_] := If[RandomReal[{0, 1}] < 1/m, 1, 0];
t = Table[rnd[x_]*(1 - KroneckerDelta[i, j]), {i, 1, n}, {j, 1, n}];
t // MatrixForm

• Thank you Vsevolod A. How will the command be if I do not restrict what n and m be? – tiffany Mar 2 at 15:47
• @tiffany you set m and n in the first two lines... – Vsevolod A. Mar 2 at 17:27
• Just rnd := If[RandomReal[{0, 1}] < 1/m, 1, 0]; will do, since the function never uses its argument. – J. M. will be back soon Mar 2 at 20:10