整理一下LaTeX关于数学公式/定理与证明以及相关的内容。

AMS宏包

AMS提供了一系列最常用的LaTeX数学宏包:

  1. amsmath 宏包:
    • 提供了一套增强的数学排版命令和环境,使得数学公式的编辑和排版更加灵活和方便。
    • 引入了一些新的数学环境,例如 aligngather,以便更好地控制多行公式的排版。
    • 提供了诸如 \text, \DeclareMathOperator 等命令,用于在数学模式中插入文本或定义新的运算符。
  2. amssymb 宏包:扩展了 amsmath,提供了额外的数学符号,如各种箭头、关系符号、集合符号等。
  3. amsfonts 宏包:提供了一些额外的字体,例如 \mathbb 命令用于黑板粗体字母。
  4. amsthm 宏包:提供了 theorem, lemma, proof 等定理或证明环境,方便用户在文档中定义和使用定理。

下面的数学公式绝大部分都需要这些宏包,默认已经被导入

1
\usepackage{amsmath,amssymb,amsfonts,amsthm}

这些宏包在实际使用时似乎要注意一下导入的先后顺序,例如最好先调用 amsmath 再调用 amsthm,参考LaTeX 宏包介绍(一)—— amsthm 阅读笔记

数学公式排版

行内公式直接使用$...$包裹即可,也可以使用\(...\)包裹,关于哪一种更好并没有统一的结论,chktex建议使用后者,但是大部分教程都建议使用前者。

本文主要关注的是行间公式,\(\TeX{}\) 默认的行间公式环境为$$...$$,这也是Markdown支持的行间公式,但是在\(\LaTex{}\)中并不推荐使用它,虽然在大多数情况下是没有问题的,但是在某些情况下和\[\]以及其它行间公式环境的表现并不一样。

这里只关注了编号和多行公式的问题,略去了很多数学符号的处理。

基本使用

基本的行间公式环境为equation,例如

1
2
3
\begin{equation}
a^2 + b^2 = c^2
\end{equation}

公式自动带有编号并在右侧呈现,编号可能形如:1, 2, 3, 也可能是形如1.1, 1.2等基于章节的编号, 默认行为取决于当前文档是atricle这类小型文本或book这类大型文本,当然也可以使用命令手动更改,例如

1
2
\numberwithin{equation}{section}
\numberwithin{equation}{subsection}

可以使用\label{}结合\ref{}\eqref{}来形成交叉引用(后者是宏包提供的,区别在于引用时自动给公式编号加了括号)

1
2
3
4
5
\begin{equation}
a^2 + b^2 = c^2 \label{eq:1}
\end{equation}

Equation \eqref{eq:1} is called `Gougu theorem' in Chinese.

效果如下

还可以使用hyperref 宏包提供的 \autoref{} 命令来替代普通的 \ref{},它会自动在前面加上引用对应的计数器名称,例如 Figure XSection X 等,并且将整体作为链接。但是不建议使用它引用公式,因为它呈现的是 Equation X,看着很奇怪。

可以在行尾使用\tag{xxx}来手动修改编号,例如一个具有特殊意义的文本标记,此时行尾的编号和交叉引用都会替换为自定义的标记

1
2
3
4
5
\begin{equation}
a^2 + b^2 = c^2 \tag{aaa}\label{eq:2}
\end{equation}

Equation \eqref{eq:2} is called `Gougu theorem' in Chinese.

效果如下

注意\tag{xxx}的内部属于文本模式,如果需要在标记中使用数学公式,还需要$$包裹。还有一个与\tag非常类似的\tag*命令,区别在于后者生成的标记不会被括号包裹。

可以在行尾使用\notag来抑制当前行的公式生成编号。(这个命令更常见的情景是在多行带编号的公式中选择性关闭某些行的编号)

1
2
3
\begin{equation}
1 + 1 \neq 3 \notag
\end{equation}

有时需要使用完全不带编号的公式,可以使用equation*环境,更常见的选择是\[\],它也提供了不带编号的行间公式环境,它实际上是displaymath环境的等价形式。

1
2
3
4
5
6
7
8
9
10
11
\begin{equation*}
a^2 + b^2 = c^2
\end{equation*}
For short:
\[
a^2 + b^2 = c^2
\]
Or if you like the long one:
\begin{displaymath}
a^2 + b^2 = c^2
\end{displaymath}

多行公式

一个常见的使用情景为罗列一组公式,按照中间的等号对齐,常用的环境为align,基于&定位,通常将&放在等号左侧,在多行公式中使用\\换行

1
2
3
4
\begin{align}
a & = b + c \\
& = d + e
\end{align}

默认情形下align环境的每一行都会产生一个编号,可以使用\notag去掉某行的编号,例如出现长公式换行时不需要两个编号。

有时也可能将&放在等号右侧,因为右侧有长公式需要换行,不能让加号和等号对齐,例如

1
2
3
4
5
6
\begin{align}
a ={} & b + c \\
={} & d + e + f + g + h + i + j + k + l \notag \\
& + m + n + o \\
={} & p + q + r + s
\end{align}

这里的使用={} &是为了产生更合适的间距。

对于多组公式的对齐,例如两行三列的公式可以如下表示,其中公式之间和等号旁都要加上&

1
2
3
4
\begin{align}
a &=1 & b &=2 & c &=3 \\
d &=-1 & e &=-2 & f &=-5
\end{align}

除了默认的多行公式环境align,还有几个常见的需求以及对应的变体,例如完全不使用编号的环境align*,还有一个情景是多行公式被打包为一个整体进行编号,此时需要使用aligned环境,例如

1
2
3
4
5
6
7
8
\begin{equation}
\begin{aligned}
a &= b + c \\
d &= e + f + g \\
h + i &= j + k \\
l + m &= n
\end{aligned}
\end{equation}

公式细节

  • \(\ell\)\ell)是一个手写体的小写字母,通常用于数学公式中替代l(L小写)来使用,防止与1(数字1)和I(大写i)的混淆。
  • 可以使用 \(A^\top\)A^\top)而非 \(A^T\)A^T)来表示矩阵转置记号。
  • 在本身就是斜体的定理环境的公式环境里,可能\text{xxx}无法起到正体的效果,可以改成使用\mathrm{xxx}
  • 使用\dots而非连续的...,也可以具体指定\ldots\cdots\cdots会自动调整显示效果。
  • 使用\mid而非直接的|,它提供更合适的间距,例如在集合的定义中使用。
  • 对于行内公式,尽量不要包括标点符号,把标点符号放在行内公式的外面;对于行间公式,则需要包括标点符号。
  • 使用\times\cdot表示乘法,不要直接使用x*
  • 对于小于等于号有很多写法,例如\le,\leq,\leqslant,最后一个不等号的横线是倾斜的。
  • 在等号上面加一点符号(例如问号):\overset{?}{=}
  • 在长等式的一部分下面使用长括号(例如标记为(A)):\underbrace{......}_{(A)}

定理与证明

amsthm宏包提供了定理类和证明类环境,但是并不是开箱即用的,这里记录一下。

定理类环境

基于amsthm包可以创造定理类环境,语法包括如下几类

1
2
3
4
5
6
\newtheorem{name}{text}                     % 独自使用计数器
\newtheorem{name}{text}[section-level] % 基于section层级设置计数器
\newtheorem{name}{text}[counter] % 基于计数器层级设置下一层的计数器
\newtheorem{name}[counter]{text} % 共享其它环境的计数器

\newtheorem*{name}{text} % 不使用计数器

其中

  • name:必选的定理类环境的标识符(名称)
  • text:必选的显示环境名称(引导词)
  • 可选项的位置和名称有不同含义:
    • counter 在前面:共享前者的计数器,例如前者为1.1,后者则为1.2;
    • counter 在后面:继承前者的计数器,例如前者为1.1,后者则为1.1.1;
    • section-level 在后面:编号计数器依赖于某个章节层次,例如section 1的编号从1.1开始。

下面的常用环境都可以基于定理环境创建:(按照字体风格进行了分类)

  • plain风格
    • 定理 theorem
    • 推论 corollary
    • 引理 lemma
    • 命题 proposition
  • definition风格
    • 定义 definition
    • 例子 example
    • 问题 problem
  • remark风格
    • 注记 remark(remark*)
    • 笔记 note(note*)

使用时例如

1
2
3
\begin{theorem}
...
\end{theorem}

或者可以加上额外名称,会在引导词后加上括号显示

1
2
3
\begin{theorem}[xxx]
...
\end{theorem}

关于下面三个写法有必要辨析一下

1
2
3
\newtheorem{theorem}{Theorem}[section]
\newtheorem{corollary}{Corollary}[theorem]
\newtheorem{lemma}[theorem]{Lemma}

三者的区别为:

  • 对于theorem,根据当前section创建子编号;
  • 对于corollary,根据最近一次的theorem创建子编号,例如theorem 1.1之后的corollary采用编号1.1.1;
  • 对于lemma,与theorem共享计数器,例如theorem 1.1之后的lemma则采用编号1.2。

可以使用 \theoremstyle{style} 命令修改定理环境的样式,内置样式有三种:

  • plain(默认样式):引导词是正体,内容是斜体,通常用于定理/推论/引理/命题等
  • definition:引导词和内容都是正体,通常用于定义/条件/示例/问题等
  • remark:引导词是斜体,内容是正体,通常用于remark/note/断言/结论等

注意只有remark的引导词不会加粗显示。

完整的定义语法如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
\theoremstyle{plain}
\newtheorem{theorem}{Theorem}[section] % 定理,基于section计数器
\newtheorem{corollary}{Corollary}[theorem] % 推论,继承定理的计数器(定理1.1,推论1.1.1)
\newtheorem{lemma}[theorem]{Lemma} % 引理,共享定理的计数器
\newtheorem{proposition}[theorem]{Proposition} % 命题,共享定理的计数器

\theoremstyle{definition}
\newtheorem{definition}{Definition}[section] % 定义,基于section计数器
\newtheorem{example}{Example}[section] % 示例,基于section计数器
\newtheorem{problem}{Problem}[section] % 问题,基于section计数器

\theoremstyle{remark}
\newtheorem{remark}{Remark}[section] % remark,基于section计数器
\newtheorem{note}{Note}[section] % note,基于section计数器
\newtheorem*{remark*}{Remark} % remark*,无编号
\newtheorem*{note*}{Note} % note*,无编号

我们还可以使用thmtools宏包更简单直观地实现上述定理的设置,与上面几乎等价的一组配置命令如下 (与上文不完全相等,这里进行了简化,直接将推论和命题等视作一类,共享定理的计数器)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
\usepackage{thmtools}

\declaretheorem[style=plain, numbered=yes, name=Theorem, numberwithin=section]{theorem}
\declaretheorem[style=plain, name=Corollary, sibling=theorem]{corollary}
\declaretheorem[style=plain, name=Lemma, sibling=theorem]{lemma}
\declaretheorem[style=plain, name=Proposition, sibling=theorem]{proposition}

\declaretheorem[style=definition, numbered=yes, name=Definition, numberwithin=section]{definition}
\declaretheorem[style=definition, name=Example, numberwithin=section]{example}
\declaretheorem[style=definition, name=Problem, numberwithin=section]{problem}

\declaretheorem[style=remark, numbered=yes, name=Remark, numberwithin=section]{remark}
\declaretheorem[style=remark, name=Note, numberwithin=section]{note}
\declaretheorem[style=remark, name=Remark, numbered=no]{remark*}
\declaretheorem[style=remark, name=Note, numbered=no]{note*}

证明类环境

amsthm也提供了用于写证明/解答的proof环境,不含有编号,默认样式包括:引导词Proof为斜体,内容是正体,结尾会自动添加证毕的方框符号。 可以直接使用,并不需要手动定义

1
2
3
\begin{proof}
...
\end{proof}

注意proofname默认是proof,但是会被ctex修改为中文的证明,这里改回来

1
2
3
4
% proof是默认存在的证明环境
% proofname默认是斜体英文proof,但是会被ctex修改为中文证明,这里改回来
\renewcommand{\proofname}{\bf Proof}
\newenvironment{solution}{\begin{proof}[\bf Solution]}{\end{proof}} % 解答

即使在英文环境下,因为proof默认是斜体,显得非常不正式,可以改成加粗的正体

1
\renewcommand*{\proofname}{\normalfont\bfseries Proof}

注:这里并没有对证明的引导词采用缩进,可以加入\indent实现。要求中文排版时,上述所有的引导词可以直接替换为相应的中文。

数学字体

下面几个命令是LaTeX默认支持的数学环境中的字体:

  • \mathnormal{}:数学环境的默认字体
  • \mathrm{}:罗马体
  • \mathit{}:意大利体(italic),通常是斜体
  • \mathbf{}:粗体(bold),通常是直立的粗体
  • \mathsf{}:无衬线体
  • \mathtt{}:打字机体
  • \mathcal{}:手写体(花体),注意默认情形仅支持大写英文字母,某些大写希腊字母不支持
  • \mathbb{}:(需要amssymb宏包或amsfonts)黑板粗体(blackboard bold),注意仅支持大写字母

\mathnormal{}是数学环境的默认字体,与正文中相比,字母之间的间距更大一些,其它几个字体的间距则于正文基本一致(但没有连字),例如 $xyz$$\mathit{xyz}$ 的间距不同。

默认的\mathbf{}命令提供的是加粗直立的大写字母,还可以使用bm宏包提供的\bm{}命令来获得加粗的斜体字母。

英文字母

英文大小写字母的常见字体效果如图

\mathcal{} 是 LaTeX 直接提供的花体命令,而 mathrsfs 宏包提供了一套略微不同的花体,使用\mathscr{}命令即可,它提供的花体更花哨复杂一些。

除此之外,还有一种可读性最差的哥特体(mathfrak),并不需要额外的宏包,直接使用\mathfrak{}命令即可

希腊字母

LaTeX对希腊字母的默认支持特别奇怪,有的字母有大小写,有的字母只有小写,有的甚至完全不支持(omicron), 有的还有var开头的变体,如下表。希腊字母通常不会使用花体之类的变形。如果使用额外的字体宏包,则可能支持的范围更大一些。

omicron在LaTeX中没有对应的符号\omicron,可能是因为它的大小写和英文字母Oo完全一样。

快捷命令

可以用自定义命令定义不同字体的字符,使得数学公式的编写更加简洁,例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
\newcommand{\cA}{\mathcal{A}}
\newcommand{\cB}{\mathcal{B}}
\newcommand{\cC}{\mathcal{C}}
\newcommand{\cD}{\mathcal{D}}
\newcommand{\cE}{\mathcal{E}}
\newcommand{\cF}{\mathcal{F}}
\newcommand{\cG}{\mathcal{G}}
\newcommand{\cH}{\mathcal{H}}
\newcommand{\cI}{\mathcal{I}}
\newcommand{\cJ}{\mathcal{J}}
\newcommand{\cK}{\mathcal{K}}
\newcommand{\cL}{\mathcal{L}}
\newcommand{\cM}{\mathcal{M}}
\newcommand{\cN}{\mathcal{N}}
\newcommand{\cO}{\mathcal{O}}
\newcommand{\cP}{\mathcal{P}}
\newcommand{\cQ}{\mathcal{Q}}
\newcommand{\cR}{\mathcal{R}}
\newcommand{\cS}{\mathcal{S}}
\newcommand{\cT}{\mathcal{T}}
\newcommand{\cU}{\mathcal{U}}
\newcommand{\cV}{\mathcal{V}}
\newcommand{\cW}{\mathcal{W}}
\newcommand{\cX}{\mathcal{X}}
\newcommand{\cY}{\mathcal{Y}}
\newcommand{\cZ}{\mathcal{Z}}

\newcommand{\bA}{\mathbf{A}}
\newcommand{\bB}{\mathbf{B}}
\newcommand{\bC}{\mathbf{C}}
\newcommand{\bD}{\mathbf{D}}
\newcommand{\bE}{\mathbf{E}}
\newcommand{\bF}{\mathbf{F}}
\newcommand{\bG}{\mathbf{G}}
\newcommand{\bH}{\mathbf{H}}
\newcommand{\bI}{\mathbf{I}}
\newcommand{\bJ}{\mathbf{J}}
\newcommand{\bK}{\mathbf{K}}
\newcommand{\bL}{\mathbf{L}}
\newcommand{\bM}{\mathbf{M}}
\newcommand{\bN}{\mathbf{N}}
\newcommand{\bO}{\mathbf{O}}
\newcommand{\bP}{\mathbf{P}}
\newcommand{\bQ}{\mathbf{Q}}
\newcommand{\bR}{\mathbf{R}}
\newcommand{\bS}{\mathbf{S}}
\newcommand{\bT}{\mathbf{T}}
\newcommand{\bU}{\mathbf{U}}
\newcommand{\bV}{\mathbf{V}}
\newcommand{\bW}{\mathbf{W}}
\newcommand{\bX}{\mathbf{X}}
\newcommand{\bY}{\mathbf{Y}}
\newcommand{\bZ}{\mathbf{Z}}
\newcommand{\ba}{\mathbf{a}}
\newcommand{\bb}{\mathbf{b}}
\newcommand{\bc}{\mathbf{c}}
\newcommand{\bd}{\mathbf{d}}
\newcommand{\be}{\mathbf{e}}
\newcommand{\bff}{\mathbf{f}} % \bff
\newcommand{\bg}{\mathbf{g}}
\newcommand{\bh}{\mathbf{h}}
\newcommand{\bi}{\mathbf{i}}
\newcommand{\bj}{\mathbf{j}}
\newcommand{\bk}{\mathbf{k}}
\newcommand{\bl}{\mathbf{l}}
\newcommand{\bmm}{\mathbf{m}}
\newcommand{\bn}{\mathbf{n}}
\newcommand{\bo}{\mathbf{o}}
\newcommand{\bp}{\mathbf{p}}
\newcommand{\bq}{\mathbf{q}}
\newcommand{\br}{\mathbf{r}}
\newcommand{\bs}{\mathbf{s}}
\newcommand{\bt}{\mathbf{t}}
\newcommand{\mathbf{u}}{\mathbf{u}}
\newcommand{\bv}{\mathbf{v}}
\newcommand{\bw}{\mathbf{w}}
\newcommand{\bx}{\mathbf{x}}
\newcommand{\by}{\mathbf{y}}
\newcommand{\bz}{\mathbf{z}}

\newcommand{\RR}{\mathbb{R}}
\newcommand{\CC}{\mathbb{C}}
\newcommand{\QQ}{\mathbb{Q}}

自定义命令

在这里补充几个便于快速排版数学公式的命令。

快速定义和使用矩阵集合

1
2
\NewDocumentCommand{\mat}{>{\SplitArgument{1}{,}}m}{\mataux#1}
\NewDocumentCommand{\mataux}{mm}{\mathbb{R}^{#1 \times #2}}

\DeclareMathOperator命令可以个性化运算符以罗马字体而不是斜体显示,例如

1
2
3
4
5
\DeclareMathOperator{\re}{Re}
\DeclareMathOperator{\im}{Im}
\DeclareMathOperator{\rank}{rank}
\DeclareMathOperator*{\argmax}{argmax}
\DeclareMathOperator*{\argmin}{argmin}

这里第一个参数是命令名称,第二个参数是显示的文本,如果加上*则它的上下标会在运算符的正上方和正下方显示,否则会显示在右上角和右下角。

我们可以用自定义的实部虚部符号替换默认的花体的实部虚部符号\(\Re\)\(\Im\)

1
2
3
4
\DeclareMathOperator{\myRe}{Re}
\DeclareMathOperator{\myIm}{Im}
\let\Re\myRe
\let\Im\myIm

我们可以用倾斜的不等号 \(\leqslant\) 完全替换默认的不等号 \(\leq\)

1
2
\renewcommand{\le}{\leqslant}
\renewcommand{\ge}{\geqslant}