把「矩阵(matrix)」一词带进数学的是詹姆斯·约瑟夫·西尔维斯特,时在 1850 年;建立其代数的则是他的朋友阿瑟·凯莱,见于 1858 年《哲学汇刊》第 148 卷所载「A Memoir on the Theory of Matrices」。在 LaTeX 里,矩阵其实并不是什么特殊构造。amsmath 中 pmatrix 的内核就是 \array{*10 c}——一个含十个居中列的 array——外面套上圆括号,再把左右各削去 5pt。这一行代码,正好回答了人们最常带来的两个问题:为什么矩阵到第十一列就不够用了,以及怎样改变列间距。本页涵盖 pmatrix、bmatrix、vmatrix、smallmatrix 一族,计数器 MaxMatrixCols,array 环境与 \arraycolsep、\arraystretch,增广矩阵,以及 \cdots、\vdots、\ddots。
amsmath 只定义了七个矩阵环境
它们是 matrix、pmatrix、bmatrix、Bmatrix、vmatrix、Vmatrix 和 smallmatrix。写上 \usepackage{amsmath} 即可使用。它们都在数学模式中使用,元素横向用 &(和号)分隔,行末用 \\(两个反斜杠)结束。内容的写法完全一样,唯一的区别是外面包裹的定界符。命名也有规律:首字母表示定界符种类——p 是圆括号(parenthesis),b 是方括号(bracket),v 是竖线(vertical bar)。首字母大写的 Bmatrix 与 Vmatrix 给出「更强」的一对,即花括号和双竖线。而光秃的 matrix 什么都不加。
| 环境 | 自动添加的定界符 | 典型用途 |
|---|---|---|
matrix | 无 | 打算自行添加定界符时的基础 |
pmatrix | 圆括号 ( ) | 最常见的矩阵与列向量 |
bmatrix | 方括号 [ ] | 按方括号惯例书写的矩阵 |
Bmatrix | 花括号 { } | 需要花括号时 |
vmatrix | 单竖线 | | | 行列式 |
Vmatrix | 双竖线 ‖ ‖ | 范数 |
smallmatrix | 无(紧凑型) | 嵌入正文行内的小矩阵 |
% preamble: \usepackage{amsmath}
\[
\begin{pmatrix} a & b \\ c & d \end{pmatrix}
\quad
\begin{bmatrix} a & b \\ c & d \end{bmatrix}
\quad
\begin{vmatrix} a & b \\ c & d \end{vmatrix}
\]这七个环境的内容始终居中,无法指定右对齐或左对齐。若想自行决定列的对齐方式,可以使用下文的 array 环境,或者 mathtools 宏包的带星版本。mathtools 定义了 matrix*、pmatrix*、bmatrix*、Bmatrix*、vmatrix*、Vmatrix* 和 smallmatrix*,它们都接受可选参数 [r]/[c]/[l],把所有列按该方向对齐(默认为 c)。带星版本来自 mathtools 而非 amsmath,需要 \usepackage{mathtools};由于 mathtools 自身会加载 amsmath,两行不必都写。用 \left/\right 或 \big/\Big 手动伸缩定界符,则属于另一页「定界符」的范围。
矩阵的列不够用了——MaxMatrixCols 与第十一列的报错
默认上限是 10 列,写到第 11 列就会以 ! Extra alignment tab has been changed to \cr. 中断。TeX 接着解释:You have given more \span or & marks than there were in the preamble to the \halign or \valign now in progress. 读一读就明白:这根本不是「矩阵」的错误,而是 \halign 表格对齐的通用错误。如开头所说,pmatrix 的内核是 \array{*\c@MaxMatrixCols c},而 amsmath.sty 第 1077 行的 \newcount\c@MaxMatrixCols \c@MaxMatrixCols=10 就是列数上限的来源。并没有什么专门针对矩阵的检查在运行,只是把交给 array 的列声明用完了而已。
解决办法是用 \setcounter{MaxMatrixCols}{n} 提高上限。要允许到 20 列,就写 \setcounter{MaxMatrixCols}{20}。数值越大,交给 array 的列声明就越长,TeX 的工作量随之增加,但在 20 左右的量级上,现代环境几乎感觉不到影响。想恢复原状,把它设回 10 即可。另外,这个上限只针对 amsmath 的矩阵环境,对下一节的 array 无效。实测写下 \begin{array}{ccccccccccccccc} 共 15 列,没有任何报错——因为在 array 里,列声明写多少就有多少。
% without this line, an 11th column raises
% ! Extra alignment tab has been changed to \cr.
\setcounter{MaxMatrixCols}{20}
\[
\begin{pmatrix}
a_{1} & a_{2} & \cdots & a_{12}
\end{pmatrix}
\]array 环境——自行决定对齐与竖线
array 是一种通用格子,它把列声明作为必需参数接收,每列写一个字母——l 左对齐,c 居中,r 右对齐。在字母之间放一个 |,就会在该位置画出竖线,所以 {l|c|r} 表示三列:左、竖线、居中、竖线、右。它相当于排正文表格的 tabular 的数学版,而且只能在数学模式中使用。若在 \[ \] 或 equation 环境之外写 \begin{array},LaTeX 会试图替你进入数学模式,并报出 ! Missing $ inserted.。元素的分隔与 tabular 一样用 & 和 \\,但每个元素都按文本样式的数学排版。
array 自身不添加定界符,所以要把它当矩阵套上括号,就得手写 \left( … \right)(或 \left[ … \right])。这里可以用测量来验证开头说的「左右各削去 5pt」。把内容都取作 a & b \\ c & d 来量,\left(\begin{array}{cc} … \end{array}\right) 的盒子宽 45.21304pt,而 pmatrix 宽 35.21304pt,差恰好 10pt——正是 array 在列两端加的间距 \arraycolsep(默认 5pt)的两份。amsmath 的矩阵环境在开头和结尾各加一个 \hskip -\arraycolsep 把这份间距抵消掉了。反过来说,改动 \arraycolsep 也会改变矩阵的列间距:实测把它缩到 2pt,pmatrix 宽度变为 29.21304pt;放宽到 10pt,则为 45.21304pt。若想统一拉高行距,用 \renewcommand{\arraystretch}{1.5}——设为 1.5 后,2×2 的总高从 24pt 变成 36pt,正好一倍半(宽度不变)。
% array needs math mode; outside it LaTeX reports "! Missing $ inserted."
\[
\left(\begin{array}{rrr}
1 & -2 & 3 \\
0 & 5 & -1 \\
4 & 0 & 2
\end{array}\right)
\]这个例子的列声明是 {rrr},因此所有列都右对齐,-2、-1 这类负数元素在右端对齐,读起来清爽。这是 pmatrix(永远居中)做不到的事,也通常正是选用 array 的理由。
增广矩阵——在中间画一条竖线
在 array 的列声明里放一个 |,再把整体用 \left[ … \right] 括起来。在表示线性方程组的增广矩阵中,惯例是在系数列与常数列之间画一条竖线。bmatrix 之类的 amsmath 矩阵环境不接受列声明,因而画不出这条线——这正是 array 派上用场的地方。只需写一个在系数列与常数列之间带 | 的声明(例如 {cc|c})即可。想用圆括号就换成 \left( … \right),想用花括号则用 \left\{ … \right\}。由于 \left 与 \right 会按内容高度拉伸括号,增加行数也不会走形(拉伸机制本身归另一页「定界符」管)。另外,mathtools 也提供了更顺手的写法来处理这类增广矩阵。
\[
\left[\begin{array}{cc|c}
1 & 2 & 5 \\
3 & 4 & 6
\end{array}\right]
\]书写一般的 n×n 矩阵——\cdots、\vdots、\ddots
把表示省略的点号当作矩阵的一个元素放进去。方向不同的共有四种,按它们落在网格中的位置来选择。它们都是数学模式命令,不需要额外宏包。
\cdots— 居中高度的水平点(⋯),用于沿行的省略。它与+、=同高,很适合横向的排列。\vdots— 竖直的点(⋮),用于沿列的省略。\ddots— 向右下的斜向点(⋱),用于沿主对角线的省略。\ldots(以及随上下文判断的\dots)— 基线上的水平点(…),用于数字序列或下标序列。在矩阵内部,通常\cdots更合适。
\[
A =
\begin{pmatrix}
a_{11} & a_{12} & \cdots & a_{1n} \\
a_{21} & a_{22} & \cdots & a_{2n} \\
\vdots & \vdots & \ddots & \vdots \\
a_{m1} & a_{m2} & \cdots & a_{mn}
\end{pmatrix}
\]这就是书写一般 m×n 矩阵的标准写法。第一、二和最后一行中,第三列的 \cdots 填补了 a_{12} 与 a_{1n} 之间的省略;第三行中,各列的 \vdots 表示纵向省略,对角位置的 \ddots 表示向右下的省略——合起来就是说行与列都照此继续。若想让整整一行都是点,amsmath 的 \hdotsfor{n} 会用一排水平点跨过指定的 n 列。
把矩阵嵌进正文行——smallmatrix 恰好占一行
把 pmatrix 丢进正文的 $ … $ 里,会撑高行高并扰乱周围的行距。看数字就明白原因:在 10pt 排版下,放进 \bigl( … \bigr) 的一个 2×2 矩阵高 14.5pt、深 9.5pt,合计 24.0pt——正好是 12pt 的 \baselineskip 的两倍。amsmath 的 smallmatrix 环境把元素排得小而紧凑,同样的内容放进同样的括号,高 8.5pt、深 3.5pt,合计 12.0pt,也就是恰好一行。smallmatrix 不添加定界符,需要的话请手动包裹,例如 \bigl( … \bigr)。(用 \left( \right) 也可以,但在正文中,固定大小的 \bigl、\bigr 更不容易扰乱行距。)若已加载 mathtools,还可以使用能选择列对齐的 smallmatrix*。
% preamble: \usepackage{amsmath}
Consider the rotation matrix
$\bigl(\begin{smallmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{smallmatrix}\bigr)$
in the plane.