27

I just learned in eqnarray vs align that eqnarray should be avoided in general. Ok, so I started looking at my documents to get rid of it and (as suggested) use some environment of the amsmath package instead. However, I encountered two situations where this change yields a worse output (IMHO) than with eqnarray. This may be due to my lack of knowledge how to do it right, but first I will show the two situations:

The first one is a sequence of (in-)equalities used to prove a bound (as common in, e.g., runtime complexity analysis). This one here is used to show that 2^n does not grow faster than n!.

\documentclass{article}

\usepackage{amsmath}

\begin{document}

\begin{eqnarray*}
2^n & =                      & \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n \text{ times}}\\
    & \stackrel{n > 3}{=}    & 2 \cdot 2 \cdot 2 \cdot 2 \cdot \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n - 4 \text{ times}}\\
    & =                      & 16 \cdot \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n - 4 \text{ times}}\\
    & <                      & 24 \cdot \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n - 4 \text{ times}}\\
    & =                      & 1 \cdot 2 \cdot 3 \cdot 4 \cdot \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n - 4 \text{ times}}\\
    & \stackrel{n > 3}{\leq} & 1 \cdot 2 \cdot 3 \cdot 4 \cdot 5 \cdot \ldots \cdot n\\
    & =                      & n!
\end{eqnarray*}

\end{document}

It yields the following output:

enter image description here

These are my attempts to use some environment of the amsmath package instead:

\documentclass{article}

\usepackage{amsmath}

\begin{document}

\begin{align*}
2^n & =                      \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n \text{ times}}\\
    & \stackrel{n > 3}{=}    2 \cdot 2 \cdot 2 \cdot 2 \cdot \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n - 4 \text{ times}}\\
    & =                      16 \cdot \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n - 4 \text{ times}}\\
    & <                      24 \cdot \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n - 4 \text{ times}}\\
    & =                      1 \cdot 2 \cdot 3 \cdot 4 \cdot \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n - 4 \text{ times}}\\
    & \stackrel{n > 3}{\leq} 1 \cdot 2 \cdot 3 \cdot 4 \cdot 5 \cdot \ldots \cdot n\\
    & =                      n!
\end{align*}

\[
\begin{aligned}
2^n & =                      && \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n \text{ times}}\\
    & \stackrel{n > 3}{=}    && 2 \cdot 2 \cdot 2 \cdot 2 \cdot \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n - 4 \text{ times}}\\
    & =                      && 16 \cdot \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n - 4 \text{ times}}\\
    & <                      && 24 \cdot \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n - 4 \text{ times}}\\
    & =                      && 1 \cdot 2 \cdot 3 \cdot 4 \cdot \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n - 4 \text{ times}}\\
    & \stackrel{n > 3}{\leq} && 1 \cdot 2 \cdot 3 \cdot 4 \cdot 5 \cdot \ldots \cdot n\\
    & =                      && n!
\end{aligned}
\]

\begin{alignat*}{2}
2^n & =                      && \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n \text{ times}}\\
    & \stackrel{n > 3}{=}    && 2 \cdot 2 \cdot 2 \cdot 2 \cdot \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n - 4 \text{ times}}\\
    & =                      && 16 \cdot \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n - 4 \text{ times}}\\
    & <                      && 24 \cdot \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n - 4 \text{ times}}\\
    & =                      && 1 \cdot 2 \cdot 3 \cdot 4 \cdot \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n - 4 \text{ times}}\\
    & \stackrel{n > 3}{\leq} && 1 \cdot 2 \cdot 3 \cdot 4 \cdot 5 \cdot \ldots \cdot n\\
    & =                      && n!
\end{alignat*}

\end{document}

The corresponding outputs have the following flaws:

  • align:

enter image description here

The reduced space between the relation symbols and the terms they connect makes it harder to recognize the steps in this proof. While one can argue whether more space is a good thing here (I read "consistency over all" in one of the documents advocating the avoidance of eqnarray and I do not entirely agree on this - I think readability is more important than consistency while consistency supports readability in most cases but possibly not always), I think it is definitely not the best thing that the relations built with \stackrel are not aligned in a centered way below the other relation symbols. The latter point is also a flaw of all the other attempts to use an environment of the amsmath package (which is to be expected as these environments only offer columns being left- or right-aligned but not centered - at least I did not find a similar environment offering a centered column).

  • aligned:

enter image description here

While we do have more space on the right of the relation symbols, we have less space on the left of them.

  • alignat:

enter image description here

This is even worse than aligned since now the spacing is not only different between left and right of the relation symbols but we also have almost no space between the relation symbols built with \stackrel and the next term.

The second situation is the definition of substitutions as comma-separated lists of replacements in square brackets (a notation quite common in, e.g., term rewriting or logic programming). If these definitions are too long such that we need to break them, the environments of the amsmath package do not succeed in aligning the second line correctly while keeping the same amount of space left and right of the = symbol:

\documentclass{article}

\usepackage{amsmath}

\begin{document}

\begin{eqnarray*}
\sigma & = & [x_1/t_1,x_2/t_2,\\
       &   & x_3/t_3,x_4/t_4]
\end{eqnarray*}

\begin{align*}
\sigma & = [x_1/t_1,x_2/t_2,\\
       &   x_3/t_3,x_4/t_4]
\end{align*}

\begin{align*}
\begin{split}
\sigma & = [x_1/t_1,x_2/t_2,\\
       &   x_3/t_3,x_4/t_4]
\end{split}
\end{align*}

\[
\begin{aligned}
\sigma & = && [x_1/t_1,x_2/t_2,\\
       &   && x_3/t_3,x_4/t_4]
\end{aligned}
\]

\begin{alignat*}{2}
\sigma & = && [x_1/t_1,x_2/t_2,\\
       &   && x_3/t_3,x_4/t_4]
\end{alignat*}

\end{document}
  • eqnarray:

enter image description here

  • align:

enter image description here

Here, the two versions with and without the use of split yield the same output. The spacing around = is consistent but the alignment of the second line is wrong.

  • aligned:

enter image description here

Here, the alignment is ok, but the spacing is inconsistent.

  • alignat:

enter image description here

Again, the alignment is ok but the spacing is inconsistent.

So my question is: How can these two situations be handled without using eqnarray yielding an output which is at least as readable as the versions using it and with a similar (or less) amount of code?

Of course, one can use array and customize it accordingly, but what would be the point of doing so in preference of using the existing eqnarray? Also, in Aligning a split up equation not at equal sign (which is similar to my second situation) the only answer suggests to use \phantom in combination with align to fix the alignment. While this is of course possible, it is definitely more tedious than using eqnarray in such a situation as described above.

cryingshadow
  • 2,350
  • 9
    “Solving” the bad alignment with eqnarray is wrong anyway, because eqnarray must *never* be used: its output is bad and it doesn't cooperate well with some packages (notably hyperref and cleveref). – egreg Dec 30 '15 at 14:43
  • 4
    @egreg Well, here I show a case where I consider the output with eqnarray better than that of align (at least in the form I tried to use it). My question is not to improve the output of the versions using eqnarray but to come up with alternatives that do not use it and yield an output which is at least as good. I understand that there are many problems with eqnarray but avoiding it just for the sake of avoiding it does not make sense to me. In these situations described here, I do not have any problems with hyperref or cleveref or whatsoever. – cryingshadow Dec 30 '15 at 14:48

2 Answers2

21

The output of eqnarray is wrong anyway and there's little to do about it. Consider also that it doesn't work with cross-references if hyperref or cleveref are involved.

No, there's no reason for using it.

The first example can be dealt with using array:

\documentclass{article}

\usepackage{amsmath,array}

\begin{document}

\begin{equation*}
\renewcommand{\arraystretch}{1.5}
\begin{array}{@{} r @{} >{{}} c <{{}} @{} l @{} }
2^n
 & =                   & \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n \text{ times}}\\
 & \overset{n>3}{=}    & 2 \cdot 2 \cdot 2 \cdot 2 \cdot \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n - 4 \text{ times}}\\
 & =                   & 16 \cdot \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n - 4 \text{ times}}\\
 & <                   & 24 \cdot \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n - 4 \text{ times}}\\
 & =                   & 1 \cdot 2 \cdot 3 \cdot 4 \cdot \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n - 4 \text{ times}}\\
 & \overset{n>3}{\leq} & 1 \cdot 2 \cdot 3 \cdot 4 \cdot 5 \cdot \ldots \cdot n\\
 & =                   & n!
\end{array}
\end{equation*}

A better proof, by induction, is
\begin{alignat*}{2}
2^4     &= 16 < 4! = 24  \\
2^{n+1} &= 2\cdot 2^n    &\quad&\text{for $n>3$} \\
        &< 2\cdot n!     &\quad&\text{induction hypothesis}\\
        &< (n+1)\cdot n! \\
        &= (n+1)!
\end{alignat*}
\end{document}

enter image description here

The second example is even easier: use a good alignment point:

\documentclass{article}

\usepackage{amsmath}

\begin{document}

\begin{align*}
\sigma =[ &x_1/t_1,x_2/t_2,\\
          & x_3/t_3,x_4/t_4]
\end{align*}

\end{document}

enter image description here

More lines can be accommodated:

\documentclass{article}

\usepackage{amsmath}

\begin{document}

\begin{align*}
\sigma = [ &x_1/t_1,x_2/t_2, \\
           & x_3/t_3,x_4/t_4] \\
\tau   = [ &y_1/t_1] \\
\psi   = [ &x_1/t_1,x_2/t_2,\\
           & x_3/t_3,x_4/t_4]
\end{align*}

\end{document}

enter image description here

egreg
  • 1,121,712
  • 1
    What is the advantage of using array instead of eqnarray? Which problems are solved/avoided doing so? Concerning the second situation: What if I have several substitutions and would like to align these on the = symbol, but only some must be broken? – cryingshadow Dec 30 '15 at 15:10
  • 2
    @cryingshadow Look closely at the output, you'll see that the spacing is much better with array. About the second problem, I see no issue, I'll add the example. – egreg Dec 30 '15 at 15:23
  • 1
    I see that there is less space around the relation symbols but why is that better? Is it more consistent in any place (then please point me to the details)? Moreover, the settings for array seem much more complicated than just taking the existing eqnarray environment. Just for the sake of having less space around the relation symbols, I would not consider this a good trade-off. Is there any additional benefit? – cryingshadow Dec 30 '15 at 15:31
  • Ah, I agree on the second situation, but for the first I would still like to know what the actual advantage of array over eqnarray is. – cryingshadow Dec 30 '15 at 16:03
  • 2
    @cryingshadow I see no advantage whatsoever in using eqnarray. Do as you like. – egreg Dec 30 '15 at 16:06
  • 5
    Compare the amount of code. There is definitely less code in the version using eqnarray compared to yours with array. I would consider the output in both versions more or less equally good. Don't get me wrong: I do not want to use eqnarray if there is an actual advantage in not doing so. But just changing a document to avoid the use of eqnarray if there is no advantage would mean work for nothing. So I'm asking what the advantage in avoiding eqnarray in favor of array is such that this change is justified. – cryingshadow Dec 30 '15 at 16:16
  • 2
    @cryingshadow Don't get me wrong. I think that egreg already give you the best answer "Do as you like" so if you like eqnarray just use it and if you change your mind later, just change your code. – touhami Dec 30 '15 at 17:16
  • @touhami No worries - this is no flamewar and I don't see a reason why it should become one. ;) The thing is that "as you like" sounds very opinion-based while I would like to know if there is an objective reason in the situation above not to use eqnarray apart from "Thou shalt not use eqnarray!" ;) – cryingshadow Dec 30 '15 at 17:21
  • 6
    @cryingshadow I tried to explain that eqnarray provides bad output, is buggy and incompatible with useful packages. If these are insufficient reasons for you, I don't know what else to say. – egreg Dec 30 '15 at 17:23
  • @cryingshadow may be here https://tug.org/pracjourn/2006-4/madsen/madsen.pdf – touhami Dec 30 '15 at 17:28
  • 2
    @egreg These three points are certainly true in many cases. But in the particular situation here I see none of them. The output is fine as it is, I do not get any errors and there are no incompatibilities in this particular situation (I'm using both hyperref and and cleveref in the same document where such a sequence of transformations is contained). Apart from that I see the (small) advantage of slightly less code. So could this situation be seen as the exception to the rule or is even in this situation an objective reason to change the code and use array instead of eqnarray? – cryingshadow Dec 30 '15 at 17:28
  • @touhami I read this article (it's actually the one where it is said "Consistency above all" (p. 5)). It definitely explains well why eqnarray should be avoided in many cases. However, for my particular situation I still do not see a convincing argument there as equations are usually seen as stand-alone objects in this article and not as proof steps. I think it is ok that "real equations" and "proof steps" are distinguishable by different spacing. This does not automatically mean inconsistency IMHO. – cryingshadow Dec 30 '15 at 17:33
  • @egreg To overcome the "amount of code" problem, one might add a command like \newcommand{\inarray}[1]{{\renewcommand{\arraystretch}{1.5}\[\begin{array}{@{} r @{\;} >{{}} c <{{}} @{\;} l @{}}#1\end{array}\]\renewcommand{\arraystretch}{1}}}. Could you add something similar to your answer? – cryingshadow Jan 15 '16 at 17:56
7

Use \mathclap:

\documentclass{article}    
\usepackage{mathtools}    
\begin{document}
\begingroup 
\advance\thickmuskip by 5mu  % 5mu = 5/18 em
\begin{align*}
    2^n &=                      \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n \text{ 
    times}}\\
    & \stackrel{\mathclap{n > 3}}{=}    2 \cdot 2 \cdot 2 \cdot 2 \cdot \underbrace{2 
    \cdot 2 \cdot 
    \ldots \cdot 2}_{n - 4 \text{ times}}\\
    & =                      16 \cdot \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n - 4 
    \text{ times}}\\
    & <                      24 \cdot \underbrace{2 \cdot 2 \cdot \ldots \cdot 2}_{n - 4 
    \text{ times}}\\
    & =                      1 \cdot 2 \cdot 3 \cdot 4 \cdot \underbrace{2 \cdot 2 \cdot 
    \ldots \cdot 2}_{n - 4 \text{ times}}\\
    & \stackrel{\mathclap{n > 3}}{\leq} 1 \cdot 2 \cdot 3 \cdot 4 \cdot 5 \cdot \ldots 
    \cdot n\\
    & =                      n!
\end{align*}
\endgroup

\end{document}

enter image description here

  • 1
    What is the part \advance\thickmuskip by 5mu about? Is this generally applicable or tailored to the content above the relation symbols? – cryingshadow Dec 30 '15 at 16:20
  • 2
    It is in mathmode the space left and right from the relation symbol =. 1mu=1/18 em –  Dec 30 '15 at 16:42