6

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.

enter image description here

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 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 at 19:29
8

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}
  • nice answer! thanks – sun0727 Nov 21 at 20:12
5

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

3

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

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

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}

enter image description here

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\infty2$

$2\cenover{7}{\infty}2$

\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.