physics / braket / tensor

排版物理或量子力学公式时,同样的形状会反复出现:导数 d/dx、偏导 ∂/∂x、绝对值或范数的竖线、bra 与 ket,以及张量上下叠放的指标。每次都用 \frac\left| 手写这些结构很费力。本页介绍三个把这些记号封装成易记命令的宏包:提供导数和自动伸缩定界符工具箱的 physics,专用于 Dirac bra-ket 记法的 braket,以及能整齐对齐上下指标的 tensor。它们很方便,但 physics 尤其有一些陷阱,例如会静默重定义某些标准命令,因此我们会同时看它的优点和注意事项。

physics 宏包是什么

physics 是 Sergio C. de la Barrera 编写的宏包,用来快速、清晰地排版物理数学。在导言区写一行 \usepackage{physics} 即可启用。它内部需要 xparseamsmath;physics 会自动加载 amsmath,所以不必另写。它的目标很明确:让命令名一看就知道用途,并用短命令替代 \frac{\mathrm{d}}{\mathrm{d}x} 这样的长模板。

latex
\usepackage{physics}

它提供的命令大致分为几类:自动伸缩定界符(\qty\abs\norm\eval)、向量分析(\grad\div\curl\laplacian)、导数与微分(\dv\pdv\dd)、Dirac 记法(\bra\ket\braket),以及一组矩阵宏。下面依次看实际公式排版中最常用的部分。这个宏包还有一些设计上的怪癖,最后会集中说明。

physics 中的导数和微分

physics 的招牌功能是导数。\dv 表示常微分,形状随参数个数变化。像 \dv{x} 只给一个参数时,它排出算子 d/dx;像 \dv{f}{x} 给两个参数时,它排出 df/dx。高阶微分用可选参数指定:\dv[2]{f}{x} 是 d²f/dx²,\dv[n]{f}{x} 是 dⁿf/dxⁿ。默认情况下,分子和分母中的 d 都以直立体(罗马体)排版;使用 \usepackage[italicdiff]{physics} 可切换为斜体 d。

偏导数用 \pdv,写法与 \dv 相同。\pdv{f}{x} 排出 ∂f/∂x,\pdv[2]{f}{x} 排出 ∂²f/∂x²。混合偏导数给三个参数:\pdv{f}{x}{y} 得到 ∂²f/∂x∂y。微分元本身用 \dd\dd{x} 会排出 dx,并根据前后文给出合适间距;\dd[3]{x} 排出 d³x(在积分中写作 \int f(x) \dd{x})。

latex
\[
  \dv{f}{x}, \qquad \dv[2]{f}{x}, \qquad
  \pdv{f}{x}{y}, \qquad \int_0^1 f(x) \dd{x}
\]

这个例子从左到右排出 df/dx、二阶导数 d²f/dx²、混合偏导 ∂²f/∂x∂y,以及从 0 到 1 的积分(被积函数后接微分元 dx)。如果行内需要斜线形式的分数,可用带星号的 \dv*{f}{x},它会以并排的 \flatfrac 形式输出 df/dx。

physics 中的自动定界符和 bra-ket

physics 还提供会根据内容高度自动伸缩的定界符。\abs{a} 排出绝对值 |a|,\norm{a} 排出范数 ‖a‖,大小都随内容调整(内部完成相当于 \left\right 的工作)。若想手动固定大小,可像 \abs\Big{a} 那样插入 \big\Big 等;若想保持原大小,则使用带星号的 \abs*{a}。求值竖线是 \eval\eval{x}_0^\infty 得到带上下限的竖线)。通用定界符是 \qty(...),其中 \qty(...)\qty[...]\qty{...} 分别对应圆括号、方括号和花括号。

latex
\[
  \abs{\frac{a}{b}}, \qquad \norm{\vb{v}}, \qquad
  \eval{x^2}_0^\infty, \qquad \qty( \frac{1}{2} )
\]

在这个例子中,绝对值竖线会伸到分数 a/b 的高度,范数的双竖线包住向量 v,求值竖线立在右侧并带有 0 和 ∞,最后的圆括号也会放大到分数 1/2 的高度。

在 Dirac 记法中,基本的一对是 \bra{\phi}\ket{\psi}。按照 physics 的设计,写 \bra{\phi}\ket{\psi}(中间不加空格)时,bra 和 ket 会“收缩”为一个内积 ⟨φ|ψ⟩。还可直接用 \braket{a}{b} 表示内积(→ ⟨a|b⟩),用单参数 \braket{a} 表示 ⟨a|a⟩(范数),以及用 \ketbra{a}{b} 表示外积(→ |a⟩⟨b|,即 \dyad 的别名)。它们都会随内容自动调整大小,带星号则关闭自动伸缩。

向量分析算子也包括在内。\grad 是梯度 ∇,\div 是散度 ∇·,\curl 是旋度 ∇×,\laplacian 是拉普拉斯算子 ∇²。它们以函数作为参数,因此 \grad{\Psi} 会排成 ∇Ψ。不过 \div 的重定义需要注意,下一节会说明。

physics 的注意事项与替代方案

physics 很方便,但因为它会静默重定义标准命令,使用时需要小心。典型例子是 \div。在标准 LaTeX 中,\div 是除号 ÷;physics 会把它替换为散度 ∇·,并把原来的 ÷ 移到 \divisionsymbol。三角函数也同样被重定义,使 \sin 等命令自动加括号(可用 \usepackage[notrig]{physics} 关闭,原定义保存在 \sine 等较长名称下)。\Re\Im 也会被替换。如果不了解这些变化,就会因为“常用符号没有出现”而困惑。

另一个著名陷阱是导数会把紧跟其后的圆括号组当作参数吞掉。在 physics 中,导数后接圆括号,例如 \dv{x}(\Psi),被定义为“长形式”,表示 d/dx 作用在括号内容上。因此写 \dv{f}{x}(g) 时,(g) 会被吸收为 \dv 的参数,而不是一个独立因子,输出就会偏离预期。这个行为在 tex.stackexchange 上反复被讨论,甚至有改良用的 physics-patch 宏包。避免方法包括在后续因子前放一个空格、插入 {},或用 \qty() 以外的方式写括号。

宏包之间也可能冲突。尤其是单位排版的标准宏包 siunitx 在新版本中引入了表示 quantity 的命令 \qty,会与 physics 的 \qty 重名(行为取决于加载顺序)。因此近年来,不再整套采用 physics,而是按目的选择专用宏包的做法也逐渐流行。导数可考虑擅长高阶和多变量情形的 derivative;漂亮的微分算子可用 fixdif;Zhang Tingxuan 的 physics2(2022 年首次发布)则把同一领域拆成按功能划分的模块,如 ab(自动括号)、ab.braketdiagmatxmat 等,只用 \usephysicsmodule{...} 加载所需部分。

对于自动伸缩定界符,也有一种不依赖 physics、而是自己定义具名定界符的做法。使用 mathtools\DeclarePairedDelimiter,只需声明一次 \DeclarePairedDelimiter{\abs}{\lvert}{\rvert},就能得到自己的 \abs,并在 \abs{x}(默认大小)和 \abs*{x}(用 \left\right 自动伸缩)之间选择。由于它不会覆盖标准命令,行为也更可预测,在重视稳健性的文档中更常被采用(详见 mathtools 页面)。

braket 宏包

如果只想轻量使用 Dirac 记法,Donald Arseneau 的 braket 宏包很合适。它不像 physics 那样是大型工具箱,而是一个只专注于 bra-ket 和集合记法的小宏包,用 \usepackage{braket} 加载。它提供两组命令:固定大小的小写版本 \bra{ }\ket{ }\braket{ }\set{ }(无论内容如何大小恒定),以及自动伸缩的大写版本 \Bra{ }\Ket{ }\Braket{ }\Set{ }(内部用 \left\right 包住内容)。

大写版本的方便之处在于,直接写在参数中的竖线 | 也会随外侧定界符一起伸缩。在 \Braket 中,内部所有 | 都会伸到参数高度;在 \Set 中,第一根 | 会伸缩。需要双竖线时,使用 \| 或它的局部别名 ||

latex
\Braket{ \phi | \frac{\partial^2}{\partial t^2} | \psi }

\Set{ x \in \mathbf{R}^2 | 0 < {|x|} < 5 }

这个例子的第一行排出夹着二阶偏微分算子的矩阵元 ⟨φ| ∂²/∂t² |ψ⟩,外侧尖括号和内部两根竖线都伸到算子的高度。第二行排出集合 { x ∈ R² | 0 < |x| < 5 },外侧花括号和分隔竖线会伸缩;内部的 |x|{|x|} 包住,是为了保持固定大小。注意,与 physics 不同,braket 没有定义外积命令 \ketbra;作者建议写成 \ket{ }\bra{ }

tensor 宏包

在上下指标混合的张量中,指标的水平位置和间距具有意义。例如 Γ^μ_{νρ} 或 R^μ_{ν}{}^ρ_σ 中,上指标和下指标必须从左到右按正确顺序排列。若朴素地连续写 ^_,上下指标会堆在同一位置,无法看出哪个指标在前。解决这个问题的是 Philip G. Ratcliffe 的 tensor 宏包(对 Mike Piff 原版的全面修订,v2.2)。它不需要外部宏包,用 \usepackage{tensor} 加载即可。

核心命令有两个。轻量的 \indices 放在张量主体之后,只接收指标串。例如写 M\indices{^a_b^{cd}_e},会在 M 后依次排出上指标 a、下指标 b、上指标 cd、下指标 e,并保持正确的水平位置。指标串中直接使用 ^(上标)和 _(下标),多字符指标用 ^{cd} 这样的花括号分组(\sp\sb 也起同样作用)。

另一个命令 \tensor 与 Mike Piff 的原版保持向后兼容,把张量主体和指标串作为两个单独参数。\tensor{M}{^a_b^{cd}_e} 与上面的 \indices 示例输出完全相同。\tensor 的优点是可以把指标放在张量前面:在可选第一参数中传入前置指标串,就能像 \tensor[^a_b^c_d]{M}{^e_f^g_h} 那样,在主体 M 前后都对齐指标。

latex
\[
  M\indices{^a_b^{cd}_e}, \qquad
  \tensor{M}{^a_b^{cd}_e}, \qquad
  \tensor[^a_b^c_d]{M}{^e_f^g_h}
\]

这三种写法都会让上下指标不重叠,而是从左到右按正确顺序错开排列;只有最后一个例子在 M 前面也带有一组指标。\indices\tensor 都有带星号形式:\indices*\tensor* 会压缩指标之间的间距,使外观更接近标准排版。此外,在指标串开头放一个 *,会让后续上下指标对左对齐(当你想抑制位置漂移时很有用)。

附带地,\nuclide 也被定义为可在文本和数学模式中使用。\nuclide[14][6]{C} 会排出 ¹⁴₆C,把质量数 14 和原子序数 6 放在元素符号 C 的左上和左下(两者都可省略)。多记号指标必须用花括号分组,\mathrm 这类结构也要整体包住,例如 \indices{_{\mathrm{H}}^x}