Horizontal alignment of matrix in an array by using \llap and \phantom

It's best to view the output of certain combinations of \phantoms and \*lapping. Below are all possible overlaps (either \phantom first, followed by \*laps, or \*laps first, followed by \phantom. Column 1 denotes the broad usage, while column 2 shows the actual output. Column 3 shows the \phantom text using a light gray colour, just for clarity. A left rule (in red) is inserted before the construction; a centre rule (green) is inserted in the middle of the construction; a right rule (blue) is inserted after the construction.

enter image description here

\documentclass{article}

\usepackage{xcolor}

\newcommand{\lrule}{\textcolor{red}{\rule[-.3\normalbaselineskip]{.4pt}{1.3\normalbaselineskip}}\hspace*{-.4pt}}
\newcommand{\crule}{\textcolor{green}{\rule[-.3\normalbaselineskip]{.4pt}{1.3\normalbaselineskip}}\hspace*{-.4pt}}
\newcommand{\rrule}{\textcolor{blue}{\rule[-.3\normalbaselineskip]{.4pt}{1.3\normalbaselineskip}}\hspace*{-.4pt}}
\newcommand{\abcd}{\textcolor{black!50}{abcd}}

\begin{document}

\begin{tabular}{ l @{\hspace{4em}} l @{\hspace{4em}} l }
  \verb|\phantom\llap| & \lrule\phantom{abcd}\crule\llap{efgh}\rrule & \lrule \abcd \crule \llap{efgh}\rrule \\
  \verb|\phantom\clap| & \lrule\phantom{abcd}\crule\clap{efgh}\rrule & \lrule \abcd \crule \clap{efgh}\rrule \\
  \verb|\phantom\rlap| & \lrule\phantom{abcd}\crule\rlap{efgh}\rrule & \lrule \abcd \crule \rlap{efgh}\rrule \\
  \verb|\llap\phantom| & \lrule\llap{efgh}\crule\phantom{abcd}\rrule & \lrule \llap{efgh}\crule \abcd \rrule \\
  \verb|\clap\phantom| & \lrule\clap{efgh}\crule\phantom{abcd}\rrule & \lrule \clap{efgh}\crule \abcd \rrule \\
  \verb|\rlap\phantom| & \lrule\rlap{efgh}\crule\phantom{abcd}\rrule & \lrule \rlap{efgh}\crule \abcd \rrule
\end{tabular}

\end{document}

None of the available options show that efgh is set exactly in the middle of abcd. So, there's no way to do what you want using the above methods. You'll have to resort to other box manipulations. Bernard already mentioned eqparbox (which calculates the maximum width of <stuff> automatically for all similar <tag>s within \eqmakebox[<tag>][<align>]{<stuff>}; an optional <align>ment can be specified, with the default being centre).

You can use \makebox[\widthof{<other stuff>}]{<stuff>} which sets <stuff> is a box that matches the width of <other stuff>. Or, you can measure the widths yourself using boxes or the like (for example, \newlength{\inftylen} \settowidth{\inftylen}{$\infty$} and then use \makebox[\inftylen]{<stuff>}).

You could also just set the \infty in a zero-width box (make a thin \infty, or \thinfty command):

enter image description here

\documentclass{article}

\usepackage{mathtools}

\newcommand{\thinfty}{\makebox[0pt]{$\infty$}}

\begin{document}

\begin{align*}
  D_0 &= \left[
    \begin{array}{ *{4}{c} }
          0    &     7    &     1    &     6    \\
      \thinfty &     0    &     9    & \thinfty \\
          4    &     4    &     0    &     2    \\
          1    & \thinfty & \thinfty &     0 
    \end{array}
  \right] \\
  D_1 &= \left[
    \begin{array}{ *{4}{c} }
          0    &     7    &     1    &     6    \\
      \thinfty &     0    &     9    & \thinfty \\
          4    &     4    &     0    &     2    \\
          1    &     8    &     2    &     0 
    \end{array}
  \right]
\end{align*}

\end{document}

The \fixTABwidth feature of tabstackengine forces all columns to an equal width. While this will not necessarily match matrices generated from another (align* or array) technique, by doing them both in tabstackengine, perfect alignment can be achieved, in this case, without the mess of \phantoms and \llaps.

\documentclass{article}
\usepackage{amsmath}
\usepackage{mathtools}
\usepackage{calc}
\usepackage{tabstackengine}
\fixTABwidth{T}
\setstacktabbedgap{2ex}
\begin{document}
\[
D_0 = 
\bracketMatrixstack{
    0 & 7 & 1 & 6 \\
    \infty & 0 & 9 & \infty \\
    4   & 4 & 0 & 2 \\
    1 & \infty & \infty & 0 
}
\]
\[
D_1 = 
\bracketMatrixstack{
    0 & 7  & 1 & 6 \\
    \infty & 0 & 9 & \infty \\
    4   & 4 & 0 & 2 \\
    1 & 8 & 2 & 0 
}
\]
\end{document}

enter image description here


A simple solution with eqparbox. Two observations, the bmatrix environment already defines matrices with extensible brackets, and you don't have to load amsmath when you load mathtools: the latter does it for you, and furthermore, it defines \clap and \mathclap commands.

\documentclass{article}

\usepackage{mathtools}
\usepackage{calc}
\usepackage{eqparbox, booktabs}
\newcommand*{\eqmathbox}[2][2]{\eqmakebox[#1]{$\displaystyle#2$}}

\begin{document}

\begin{align*}
D_0 &=\begin{bmatrix}
    0 & 7 & 1 & 6 \\
    \infty & 0 & 9 & \infty \\
    4 & 4 & 0 & 2 \\
    1 & \eqmathbox{\infty} & \infty & 0
    \end{bmatrix}\\
\addlinespace
D_1 &=
\begin{bmatrix}
    0 & \phantom{\infty}\llap{7} & 1 & 6 \\
    \infty & 0 & 9 & \infty \\
    4 & 4 & 0 & 2 \\
    1 & \eqmathbox{8} & \eqmathbox{2} & 0
\end{bmatrix}
\end{align*}

\end{document} 

enter image description here