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

I want to vertical align two matrices by using a combination of \phantom and \llap. But neither \llap nor \clap gives the right spacing.

ps: when I use \makebox[\widthof{$\infty$}][c]{7}, it works. I can't explain the difference between them.

MWE

\documentclass{article}

\usepackage{amsmath}
\usepackage{mathtools}
\usepackage{calc}
%\def\clap#1{\hbox to 0pt{\hss#1\hss}}

\begin{document}

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

\end{document}

• You can't explain the difference between using \widthof and combinations of \phantom and \*lap commands? It's not entirely clear what you mean by the PS reference. – Werner Nov 21 '19 at 18:58
• @Werner I thought, they should have the same result. But in fact only \widthof works. I want to know the reason. Thanks – sun0727 Nov 21 '19 at 19:29
• – John Kormylo Nov 22 '19 at 1:58

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.

\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):

\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}

• nice answer! thanks – sun0727 Nov 21 '19 at 20:12

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}


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}\\
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}


• @Werner: Thanks for your edit. One never rereads oneself carefully enough! :) – Bernard Nov 21 '19 at 19:32

You can define a new column type which reserves the exact space for the infinity symbol.

\documentclass{article}

\usepackage{amsmath}
\usepackage{mathtools}
\usepackage{calc}
\usepackage{array}

\newcolumntype{i}{>{$}w{c}{\widthof{$\infty$}}<{$}}

\begin{document}

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

\end{document}


To answer your question about how to center something in a space at least as wide as another object?

You can use \ooalign, of course:

\documentclass{article}

\makeatletter
\newcommand{\cenover}[2]{%
\mathord{% force usage in math mode
\vphantom{#2}%
\ooalign{\hphantom{$\m@th#2$}$\cr\hfil$\m@th#1$\hfil\cr}% }% } \makeatother \begin{document}$2\infty22\cenover{7}{\infty}2\$

\end{document}