行间、对齐与编号公式

陈列数学往往不只需要一行。你会把长公式拆成多行,对齐等号,给每一行分配连续编号,并在后文引用;这些多行公式的排版机制几乎都由 amsmath 包提供。本页依次介绍带编号的 equation,用于对齐的 aligngathermultlinesplit,分段定义的 cases,以及编号控制(\notag\tagsubequations)。行内数学和陈列数学的入口在“Math mode basics”中已经说明,这里进一步进入多行与编号。

先加载 amsmath

本页除 equation 之外的所有环境都由 amsmath package 提供。只需在导言区加一行。对于任何会使用数学内容的新文档,加载 amsmath 已经是事实标准:它把陈列公式环境、对齐和编号控制集中到一起。

latex
\usepackage{amsmath}

amsmath 在基本 LaTeX 之上大幅扩展了陈列公式结构。除了普通 LaTeX 中已有的 equation 环境,它还加入 alignalign*gathergather*multlinemultline*alignatalignat*flalignflalign*,以及 split。注意,在这些环境内部 不能留下空行,因为空行会被读作段落分隔并导致错误。要把公式编号放在左侧,使用 \usepackage[leqno]{amsmath};放在右侧(横排默认)用 [reqno];要让陈列公式左对齐,则使用 [fleqn] 选项。

带编号的一行 — equation

陈列数学的起点是 equation environment。它把内容排成独立的一行,并在右边距(横排默认)自动添加连续编号。编号由 equation 计数器管理;加上 \label{…} 后,就可以在正文中用 \ref{…}\eqref{…} 引用(引用细节见后文)。如果只是不要编号,使用带星号的 equation*;它等同于基本 LaTeX 的 displaymath\[\]),即无编号陈列公式。

latex
\begin{equation}
  \label{eq:euler}
  e^{i\pi} + 1 = 0
\end{equation}

输出中,欧拉恒等式会居中放在自己的行上,并在该行右端带有类似 (1) 的编号(编号是文档中的连续编号,不一定是 1)。equation 是给 一行公式一个编号 的环境。如果公式放不下一行,或需要对齐多条公式,请使用下面的对齐环境。\[\] 和无编号陈列公式的基础在姊妹页“Math mode basics”中介绍。

对齐多行 — align 和 gather

要把多条公式竖直排列,最常用的是 align 环境。用 \\ 分隔各行,并在要对齐的位置放一个 &。按惯例,& 放在等号或不等号等 关系符号的正前方,这样关系符号会在竖直方向对齐。关键是把 & 放在关系符号 之前(后面讨论的旧 eqnarray 把它放在之后,因此会破坏间距)。align 会给每一行编号;带星号的 align* 不加编号。

latex
\begin{align}
  (x + y)^2 &= x^2 + 2xy + y^2 \\
  (x - y)^2 &= x^2 - 2xy + y^2
\end{align}

输出中,两条公式竖直排列,两个等号精确位于同一水平位置,每一行右端都有编号。& 左侧(左边)右对齐,右侧(右边)左对齐,因此两边会在等号处整齐相接。不要在最后一行后面加 \\,否则会产生多余空白。

align 也可以 把多条公式横向并排放置& 同时用作对齐标记和列分隔符:交替写“关系符号前的 &”和“下一条公式前的 &”。换句话说,每组公式写成“右对齐部分 & 带关系符号的左对齐部分”,再用另一个 & 与下一组公式分开。

latex
\begin{align}
  x  &= y      & X  &= Y      & a &= b + c \\
  x' &= y'     & X' &= Y'     & a' &= b      \\
  x + x' &= y + y' & X + X' &= Y + Y' & a'b &= c'b
\end{align}

输出中,三组公式横向排成三列,每一列内的等号分别对齐,并且每一行有一个编号。amsmath 会在列与列之间自动插入固定间距。

相反,如果 不需要对齐,只想把多条公式居中排列,使用 gather 环境。在 gather 中没有 & 对齐;每一行都 独立居中。行与行用 \\ 分隔,每行都会编号(无编号用 gather*)。如有需要,gather 的某一行本身也可以包含下面介绍的 split,把一条公式拆成多行。

latex
\begin{gather}
  a^2 + b^2 = c^2 \\
  e^x = \sum_{n=0}^{\infty} \frac{x^n}{n!}
\end{gather}

输出中,两条公式各自居中放在自己的行上(它们的符号位置不会相互对齐),每行右端都有编号。一个好记的对比是:align 是“按关系符号对齐”,而 gather 是“只把公式居中堆放”。

拆分一条长公式 — multline 和 split

有两个环境用于把一行放不下的 一条公式 拆成多行:multlinesplit。它们都与 align/gather 不同,因为它们是“公式是一条,编号也是一个”。

multline 不做对齐。它会把 第一行靠左、最后一行靠右,中间各行居中。行用 \\ 分隔。整条公式的编号出现在 最后一行(若使用 leqno 选项则在第一行)。因为 multline 给一条公式一个编号,所以 不要用 \notag 去取消单独某行的编号。如果要把中间行推到某一侧,可用 \shoveleft{…}\shoveright{…},把整行(不包括随后的 \\)作为参数传入。无编号形式是 multline*

latex
\begin{multline}
  a + b + c + d + e + f \\
  + g + h + i + j + k + l + m + n
\end{multline}

输出中,长和式被拆成两行,第一段 a + … + f 靠左,续行 + g + … + n 靠右,整条公式只有一个编号。如果有中间行,则会居中。multline 不使用对齐用的 &,只用 \\ 标出换行位置。

如果希望拆开的各行 相互对齐,使用 split。和 align 一样,split& 对齐,但它 只允许一个对齐列(每行一个 &),并且 自身不带编号。要把它放在 equation(或 align/gather)这样的带编号结构 内部 使用,由外层结构给整体提供一个编号。split 不能放在 multline 内部。

latex
\begin{equation}
  \label{eq:cosh}
  \begin{split}
    \cosh x &= \frac{e^x + e^{-x}}{2} \\
            &= 1 + \frac{x^2}{2!} + \frac{x^4}{4!} + \cdots
  \end{split}
\end{equation}

输出中,一条公式被拆成两行,两行的等号对齐,并带有由 equation 提供的 一个编号(默认在垂直方向居中)。split 是把一条拆行公式按等号对齐的标准工具,与不做对齐的 multline 相对应。split 的内容应占满外层结构的主体;只有像 \label 这样不产生输出的命令可以与它并列。

环境公式 / 编号对齐主要用途
equation一条 / 一个一行陈列公式
align多条 / 每行有,在 &按关系符号堆叠并对齐
gather多条 / 每行无(各行居中)居中堆叠,不对齐
multline一条 / 一个无(左到右)拆分长公式,不对齐
split一条 / 无(外层提供)一个 &对齐一条拆行公式的各行

分段定义 — cases

按条件分段定义函数时,使用 cases 环境。左侧会自动加上一个大的左花括号 {;每一行中用 & 分隔“值”和“条件”,行与行用 \\ 分隔。条件中的文字(如“if …”等)如果保持在数学模式中会变成斜体并且字距过紧,因此要用 \text{…} 包起来,使其直立并具有正确间距。cases 自身没有编号,通常放在 equation 内部,让整个公式得到一个编号。

latex
\begin{equation}
  |x| =
  \begin{cases}
    x  & \text{if } x \ge 0, \\
    -x & \text{if } x < 0.
  \end{cases}
\end{equation}

输出中,左侧是一个大花括号,右侧有两行:x(条件“if x ≥ 0”)和 −x(条件“if x < 0”),并带有来自 equation 的一个编号。值列和条件列都左对齐。注意,cases 会以 text style(较紧凑的大小)排版内容;如果希望分数等显示得更大,请使用 mathtools 包中的 dcases 环境,它以 display style 排版。

控制编号 — \notag、\tag、subequations

aligngather 等带编号环境中,每一行都会自动编号。amsmath 提供了逐行调整编号的方法。

  • 只去掉某一行的编号:在该行的 \\ 前放 \notag(或同义的 \nonumber)。\notag 不能在陈列环境之外使用。
  • 自己设置或覆盖编号\tag{…} 会把你给出的内容作为编号排版,取代自动编号(括号会自动添加)。\tag*{…} 不加括号,按原样输出你的文本。
  • 把相关公式组成 1a, 1b, …:用 subequations 环境包住它们,内部公式会编号为 (1a)、(1b)、…,即父编号加字母。
latex
\begin{align}
  y &= (x + 1)^2           \notag \\
    &= x^2 + 2x + 1        \\
  E &= mc^2                \tag{$\star$}
\end{align}

在输出中,第一行因 \notag无编号,第二行照常带自动编号,第三行则用 (⋆) 取代自动编号。结合 \notag\tag,可以自然地让推导过程中的中间行不编号,只给结论行编号。

要把相关公式收在同一个编号之下,用 subequations 包住它们。如果前一个带编号公式是 (4),组内公式会变成 (4a)、(4b)、(4c)、…。紧跟在 \begin{subequations} 后面的 \label 指向 父编号 (4),而不是子编号 (4a)。

latex
\begin{subequations}
  \label{eq:max}
  \begin{align}
    \nabla \cdot \mathbf{E} &= \frac{\rho}{\varepsilon_0} \label{eq:gauss} \\
    \nabla \cdot \mathbf{B} &= 0
  \end{align}
\end{subequations}

输出中,两条公式按等号对齐,并编号为 (4a) 和 (4b),即父编号加字母(父编号是文档中的连续编号)。随后 \eqref{eq:gauss} 得到 (4a),而 \eqref{eq:max} 得到表示整组的 (4)。

回头引用 — \label 和 \eqref

给带编号的公式加上 \label{…},就可以在正文中按编号引用它。\ref{…} 返回编号本身(如 3.2),而 amsmath 的 \eqref{…}补上括号,返回 (3.2)\eqref 生成的括号不受周围字体影响,始终以直立体排版,因此引用公式时 \eqref 很方便。在多行环境中,要把 \label 放在你想引用编号的 那一行align 中每行各自放,subequations 中每个子公式行各自放)。

latex
式~\eqref{eq:euler} より $e^{i\pi} = -1$ が従う。

By~\eqref{eq:euler}, we have $e^{i\pi} = -1$.

输出会像“By equation (1), …”那样,把带有 \label{eq:euler} 的公式编号带括号插入正文。为了让引用解析完成,通常需要为交叉引用 编译两次\ref/\label 的一般机制在“Cross-references”页中说明。若要按章或节重置编号(得到 (1.1)、(2.1)、…),在导言区写 \numberwithin{equation}{section}。编号的外观由 \theequation 命令控制;在 article 中默认是 \arabic{equation},在 book/report 中默认是 \thechapter.\arabic{equation}(章号加连续编号)。若要直接改变格式,可用例如 \renewcommand{\theequation}{\thesection.\arabic{equation}} 重新定义。

避免使用 eqnarray

旧文档有时会用 eqnarray(以及 eqnarray*)排多行数学。这个环境早于 amsmath 出现,但现在 不应再使用。它最大的问题是 关系符号周围的间距eqnarray 会在等号两侧插入不自然的宽间距,而且这种间距与其他数学环境不一致。更糟的是,行太长时 公式编号可能叠印在正文上,定理包中的 \qedhere 也无法在其中工作。

amsmath 官方手册和 LaTeX 参考都建议避免 eqnarray,改用 align(对齐多条公式)或 equation + split(拆分一条公式)。还要注意 & 的位置差异:align 系列把 & 放在关系符号 之前,而 eqnarray 的设计是放在 之后,这正是其间距出错的原因之一。写新文档时,请直接选择 amsmath 的环境。