# Obtain a table of non-uniformly-distributed random 0 and 1 draws

I wish to produce a n x m matrix of randomly-drawn 0s and 1s, in which draws are fresh with each compilation. So far, I have achieved this with the following code for a 15 x 10 table.

However, 0s and 1s are each drawn each time with probability p=0.5. I would like to be able to input any p. How can I do this?

I would also be grateful for a less clunky way to input/change the number of rows and columns of this table/matrix.

\documentclass{standalone}
\usepackage{pgf}

\pgfmathsetseed{\pdfuniformdeviate 10000000} % fresh draws with each comile
\newcommand{\Rand}{\pgfmathparse{int(random(2)-1)}\pgfmathresult}

\begin{document}
\begin{tabular}{*{10}{c}}
\Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand \\
\Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand \\
\Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand \\
\Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand \\
\Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand \\
\Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand \\
\Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand \\
\Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand \\
\Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand \\
\Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand \\
\Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand \\
\Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand \\
\Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand \\
\Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand \\
\Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand & \Rand
\end{tabular}
\end{document}


p=0.5 is equal to there is 1 in 2. So I can say p=m/n which means there is m in n. Then it is easy to use \int_rand:n {<number (here is n)>} in expl3 to get a pseudo-random number between 1 and n. If the random number is greater than m, output 1 otherwise output 0.

\documentclass{article}
\usepackage{nicematrix}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand {\Rand} { O{1} O{2} } {
\int_compare:nTF {\int_rand:n {#2} <= #1}{0}{1}
}
\ExplSyntaxOff

\begin{document}
$\AutoNiceMatrix{15-10}{\Rand} \mskip 100mu \AutoNiceMatrix{15-10}{\Rand[1][10]}$
\end{document}


## Random matrix with tikz

\documentclass[tikz, border=1cm]{standalone}
\usetikzlibrary{matrix, positioning}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand {\Rand} { O{1} O{2} } {
\int_compare:nTF {\int_rand:n {#2} <= #1}{0}{1}
}
\tl_new:N \l__rand_matrix_body_tl
% https://tex.stackexchange.com/a/548881/201158 @egrep
\NewDocumentCommand {\RandMatrix} { O{} D(){matrix} m m O{1} O{2} } {
\group_begin:
\tl_clear:N \l__rand_matrix_body_tl
\int_step_inline:nn {#3} {
\tl_put_right:Nn \l__rand_matrix_body_tl {\use_none:n}
\int_step_inline:nn {#4} {
\tl_put_right:Nn \l__rand_matrix_body_tl {
\pgfmatrixnextcell \Rand[#5][#6]
}
}
\tl_put_right:Nn \l__rand_matrix_body_tl {\\}
}
\matrix [#1] (#2) {\tl_use:N \l__rand_matrix_body_tl};
\group_end:
}
\ExplSyntaxOff

\begin{document}
\begin{tikzpicture}
\RandMatrix[matrix of nodes, draw, row 1 column 1/.style=red](a){15}{10}
\RandMatrix[matrix of nodes, right=of a, row 1 column 3/.style=red](b){15}{10}[1][10]
\node [above=1em of a] {$p=0.5$};
\node [above=1em of b] {$p=0.1$};
\draw [->] (a-1-1) edge [bend left=20] (b-1-3);
\end{tikzpicture}
\end{document}


• That's nice. Is there a way to make it work as \documentclass{standalone}? Jul 3, 2020 at 20:09
• @monkey-dart Now you have a tikz command. Jul 4, 2020 at 13:19

Here's a sagetex solution.

\documentclass{article}
\usepackage{sagetex,amsmath,amssymb}
\begin{document}
\begin{sagesilent}
import numpy as np
def randbin(M,N,P):
return np.random.choice([0, 1], size=(M,N), p=[P, 1-P])

matrixA = latex(matrix(randbin(15,10,.5)))
A = matrixA[6:-7]
\end{sagesilent}
\noindent
$\sagestr{A}$
\end{document}


I found the code to construct the numpy array in the accepted answer here and fixed it up. The function randbin(M,N,P) will create a numpy array of order m by n where the probability of an entry being 0 is P. Printing that result would look ugly as it would be in a form like [[0,1,0],[0,1,1]...]. I take that numpy array and create the latex code for its matrix with the line matrixA = latex(matrix(randbin(15,10,.5))). From the documentation here I know that the matrix will start with \left( and end with \right), so I remove that from the string with A = matrixA[6:-7]. This gives me the numbers in an array. The result running in Cocalc is shown below:

Notice from the picture that, under the array of zeros and ones is a button to Build and a button to Force Build. Using the Force Build button will recompile and change the numbers, while 'Build will recompile without changing the numbers. By changing the values of M, N, and P to 25, 25, and .25 you can quickly create another array:

The final observation to make is in the second picture. It says Build Control and Log where the buttons to Build and Force Build were. Clicking on Build Control and Log will get the 2 buttons back.

I just noticed your comment about making the code work with standalone. That's easily done, too. Here is the output:

EDIT: I need to add that Sage, the computer algebra system that makes things run, can either be downloaded and installed on your computer or accessed with a free Cocalc account. It's simple and you can be up and running in a couple of minutes. Installing Sage on your computer is more problematic. Documentation on the sagetex` package is here.