# Making a macro for transition probability matrices (a la Pinsky & Karlin's "Introduction to Stochastic Modeling")

In An Introduction to Stochastic Modeling by Mark Pinsky and Samuel Karlin, transition probability matrices for finite-state Markov chains take a particular formatting style:

Particular items of note:

• The sides of the matrix (where we normally see brackets, parentheses, or single vertical bars) are double vertical bars here.
• The rows and the columns are numbered, starting from zero.

A past post here on TeX.SE discusses how to make these, and the end result is a good one.

However, using the code there is somewhat cumbersome if you need to type many such matrices, rather than just doing it as a one-off thing, especially as the size of said matrices may vary.

Of course, then, this suggests the creation of some sort of macro to handle it. But I'm not sure how to go about doing so, being rather new to LaTeX.

Ideally, such a macro would just take in the contents of the matrix itself. So I might have, say,

\tpm{
0.3 & 0.2 & 0.5 \\
0.5 & 0.1 & 0.4 \\
0.5 & 0.2 & 0.3
}


or

\tpm{
0.4 & 0.3 & 0.2 & 0.1 \\
0.1 & 0.4 & 0.3 & 0.2 \\
0.3 & 0.2 & 0.1 & 0.4 \\
0.2 & 0.1 & 0.4 & 0.3
}


(to generate the sample matrices above) and the rest would be done for me: regardless of the size, the columns and rows would be numbered accordingly, the double bars produced, and so on.

Can someone make such a macro? Any help would be appreciated!

It is done using the package nicematrix and defining a new environment.

It has the advantage that it mainly keeps the content of the array separate from the style that will be applied to it.

Thus allowing, as in this case, to have the raw matrix as the only input of an environment, and on the other hand, to adjust the style without interfering with the content.

Note that the array to be generated needs a first empty row, and all rows must start with &, to make room for column and row numbers, which are automatically filled.

The last four lines, following \CodeAfter redraws the four vertical lines, --replacing the separators inserted by VNiceMatrix (now hidedn)--, to put them a little further to the left of the row numbers.

\documentclass{article}

\usepackage{nicematrix} % needed <<<<<<<<<<<<<<<<<
\usepackage{tikz}% needed <<<<<<<<<<<<<<<<<

\newcounter{nrow}
\newcounter{ncol}

\newenvironment{probability-matrices}
{\setcounter{nrow}{0}\setcounter{ncol}{0}%
\NiceMatrixOptions{delimiters/color=white}
$\begin{VNiceMatrix}% [cell-space-limits = 4pt, first-row, first-col, code-for-first-row =\arabic{ncol}\addtocounter{ncol}{1}, code-for-first-col = \arabic{nrow}\addtocounter{nrow}{1}, margin=4pt, ] } { \CodeAfter \tikz \draw [transform canvas={xshift=-1.0pt}] (1-|1) --(last-|1) ; \tikz \draw [transform canvas={xshift=1.0pt}] (1-|1) --(last-|1) ; \tikz \draw [transform canvas={xshift=1.0pt}] (1-|last) -- (last-|last) ; \tikz \draw [transform canvas={xshift=-1.0pt}] (1-|last) -- (last-|last) ; \end{VNiceMatrix}$}

\begin{document}

$\mathbf{P} =$
\begin{probability-matrices}
&    &     &    \\ % needed  <<<
&0.3 & 0.2 & 0.5 \\
&0.5 & 0.1 & 0.4 \\
&0.5 & 0.2 & 0.3
\end{probability-matrices}
$\mathbf{T} =$
\begin{probability-matrices}
&    &     &     &     \\ % needed <<<
&0.4 & 0.3 & 0.2 & 0.1 \\
&0.1 & 0.4 & 0.3 & 0.2 \\
&0.3 & 0.2 & 0.1 & 0.4 \\
&0.2 & 0.1 & 0.4 & 0.3
\end{probability-matrices}

\end{document}


Another solution with nicematrix.

\documentclass{article}
\usepackage{nicematrix,tikz}

\ExplSyntaxOn

\NewDocumentCommand { \PreValue } { m }
{ \int_eval:n { \int_use:c { c@#1 } - 1 } }

\NewDocumentEnvironment { MyMatrix } { }
{
\begin { VNiceMatrix }%
[
first-row, code-for-first-row = \PreValue{jCol} ,
first-col, code-for-first-col = \PreValue{iRow} ,
]
}
{ \end { VNiceMatrix } }

\ExplSyntaxOff

\begin{document}

$\mathbf{T} = \begin{MyMatrix} & & & & \\ & 0.4 & 0.3 & 0.2 & 0.1 \\ & 0.1 & 0.4 & 0.3 & 0.2 \\ & 0.3 & 0.2 & 0.1 & 0.4 \\ & 0.2 & 0.1 & 0.4 & 0.3 \end{MyMatrix}$

\end{document}


You need several compilations (because nicematrix uses PGF/Tikz nodes under the hood).

Here is an environment {MyMatrix} which does the job. You have to end the rows with the command \ER.

\documentclass{article}
\usepackage{nicematrix}

\ExplSyntaxOn

\NewDocumentCommand { \PreValue } { m }
{ \int_eval:n { \int_use:c { c@#1 } - 1 } }

\newcounter{NbColumns}

\NewDocumentEnvironment { MyMatrix } { }
{
\cs_set_protected:Npn \ER { \\ & }
\begin { VNiceMatrix }%
[
first-row, code-for-first-row = { \PreValue{jCol} },
first-col, code-for-first-col = { \PreValue{iRow} },
]
\CodeBefore
\setcounter{NbColumns}{\value{jCol}}
\Body
\prg_replicate:nn { \value{NbColumns} } { & } \ER
}
{ \end { VNiceMatrix } }

\ExplSyntaxOff

\begin{document}

$\mathbf{T} = \begin{MyMatrix} 0.4 & 0.3 & 0.2 & 0.1 \ER 0.1 & 0.4 & 0.3 & 0.2 \ER 0.3 & 0.2 & 0.1 & 0.4 \ER 0.2 & 0.1 & 0.4 & 0.3 \end{MyMatrix}$

\end{document}


You need several compilations (because nicematrix uses PGF/Tikz nodes under the hood).