mathtools

amsmath は 1990 年代からほとんど変わっていません。安定は美徳ですが、代わりに「直したいのに直せない小さな不満」が積み上がりました——:= の見た目、絶対値の縦棒が中身の高さに追随しないこと、総和の下に長い条件を書くと式全体が横に広がること。mathtools はその不満を置く場所として 2002 年に生まれた LaTeX パッケージで、amsmath を置き換えるのではなく amsmath を読み込んだうえに積み増します。このページでは \DeclarePairedDelimiter\coloneqq\mathclap\prescriptmatrix*dcasesshowonlyrefs を、実際に測った寸法つきで見ていきます。どれも「amsmath だけでは届かなかった一歩」です。

amsmath と mathtools はどちらを \usepackage するか

mathtools だけを書けば足ります。 mathtools は内部で amsmath を読み込むので、\usepackage{amsmath} を別に書く必要はありません。しかも amsmath 宛てのオプションはそのまま素通りします——\usepackage[fleqn,tbtags]{mathtools} は、\usepackage[fleqn,tbtags]{amsmath} に続けて \usepackage{mathtools} と書いたのと同じです。順序を気にして両方書く、という手間は要りません。

latex
% one line is enough: mathtools loads amsmath itself
\usepackage{mathtools}

% options aimed at amsmath are passed straight through
\usepackage[fleqn,tbtags]{mathtools}

この「amsmath の上に積む」という設計は、担い手が三代替わっても変わりませんでした。mathtools.sty の著作権表示は、2002〜2011 年が Morten Høgholm、2012〜2019 年が Lars Madsen、2020 年以降が Lars Madsen と LaTeX3 プロジェクト と読めます。つまり mathtools は個人の便利ツールから、LaTeX 本体の開発チームが面倒を見る準標準へ昇格したわけです。実際、数式を含む文書のプリアンブルで最初に書かれるのは、いまや amsmath ではなく mathtools であることが多くなりました。なお mathtools は補助パッケージ mhsetup にも依存しますが、TeX Live などには同梱されているので意識する必要はありません。

絶対値やノルムの大きさを自動で合わせる — \DeclarePairedDelimiter

プリアンブルに \DeclarePairedDelimiter\abs{\lvert}{\rvert} と一行書けば、大きさを三段階に切り替えられる自前の \abs が手に入ります。誰もが最初に思いつく \newcommand{\abs}[1]{\lvert#1\rvert} は、横方向の空きこそ正しくなりますが、\abs{\frac{a}{b}} のように背の高い中身を入れると縦棒が伸びず、はみ出した分数の脇に取り残されます。\DeclarePairedDelimiter が引き受けるのはまさにそこです。命令名を波括弧で囲む \DeclarePairedDelimiter{\abs}{\lvert}{\rvert} も同じように通ります。

latex
% in the preamble; braces around the command name are optional
\DeclarePairedDelimiter\abs{\lvert}{\rvert}
\DeclarePairedDelimiter\norm{\lVert}{\rVert}

% three ways to call it
\[
  \abs{x} = \abs{-x}
  \qquad
  \abs*{\frac{a}{b}} = \frac{\abs{a}}{\abs{b}}
  \qquad
  \norm[\big]{v}
\]

違いは目分量ではなく寸法で確かめられます。TeX Live 2024 で \sbox0{$\abs{\frac ab}$} の高さを測ると 7.5pt、星付きの \abs*{\frac ab}8.50006pt になりました。星は中身を \left … \right で包むので、分数の高さぶんだけ縦棒が伸びたわけです。[\big] [\Big] [\bigg] [\Bigg] を渡す第三の形は手動で段を選ぶもので、この例では [\big] が 8.50006pt と、たまたま自動と同じ段に落ち着きました。星は「伸ばす」、角括弧は「この段に固定する」 と覚えれば取り違えません。区切り記号の内側にさらに区切りが要る \Set{x}{x>0} のような記法には \DeclarePairedDelimiterX を使います。

書き方大きさ使いどころ
\abs{x}固定(測定値 7.5pt)中身が背の低い変数や数のとき
\abs*{x}自動(測定値 8.50006pt)分数・根号・総和など背の高い中身
\abs[\big]{x}手動で段を指定並んだ式で高さをそろえたいとき
\DeclarePairedDelimiterX同上(引数を複数取れる)\Set{x}{x>0} のように内側に区切りがある記法

:= の見た目がおかしい理由と \coloneqq

直す点は二つ、コロンの高さコロンと等号のあいだの空きです。よく「: は関係子ではないから間隔が崩れる」と説明されますが、これは誤りです。LaTeX に : の math code を表示させると 12346、十六進で "303A ——先頭の 3 が 関係子(class 3) を意味します。だから $a\mathrel{:=}b$ と囲っても何も変わりません。実測でも $a:=b$$a\mathrel{:=}b$ はどちらも 25.68855pt で完全に一致しました。

では \coloneqq は何をしているのか。定義を開くと \vcentcolon\mathrel{\mkern-1.2mu}= です。第一に、通常の : の代わりに 数式軸の高さに中央寄せしたコロン \vcentcolon を使います(実測で $:$ の高さ 4.30554pt に対し $\vcentcolon$ は 4.65277pt——0.34723pt だけ持ち上がっています)。第二に、-1.2mu の負の空きでコロンを等号に引き寄せます。関係子が二つ並ぶと TeX はそのあいだにも関係子の空きを入れてしまい、:= が別々の記号に見えるからです。結果、$a\coloneqq b$25.02191pt——生の := より 0.66664pt だけ狭く、これは 10pt 環境での 1.2mu にちょうど一致します。

latex
\[
  f(x) \coloneqq x^2 + 1, \qquad y \eqqcolon g(x), \qquad
  A \Coloneqq B
\]

一つ落とし穴があります。mathtools は \coloneq意味そのものを変えました。現在の既定では \coloneq\coloneqq と同じ「:=」を出しますが、古い定義では コロンと横棒「:−」 でした。\eqcolon も同様で、いまは \eqqcolon と同じ「=:」です。古い字形が要る文書には \usepackage[legacycolonsymbols]{mathtools} が用意されています。逆に言えば \coloneqq\eqqcolon は廃止されておらず、どちらの設定でも同じものを出します——迷ったら q が二つある方を書けば安全 です。仲間には \dblcolon(::)、\Coloneqq(::=)、\Eqqcolon\colonapprox\colonsim、そして新しく加わった \approxcolon\simcolon があります。

総和の下の長い条件で式が横に広がる — \mathclap\smashoperator

条件を 幅ゼロの箱 に入れてしまえば解決します。\sum_{1 \le i \le j \le n} a_{ij} を測ると全体で 48.21771pt ありますが、条件を \mathclap{…} で包んだ \sum_{\mathclap{1 \le i \le j \le n}} a_{ij}28.43983pt——19.78pt も縮みます。条件の文字は消えず、そのまま総和記号の下に見えたままです。ただ、その幅が式全体の幅に 数えられなくなる だけです。\mathclap は中央に、\mathllap は左に、\mathrlap は右にはみ出させます。本文で使う \clap も同じ発想です。

latex
% the wide condition stretches the whole formula
\[ \sum_{1 \le i \le j \le n} a_{ij} \]

% zero-width box: same look, width of the operator only
\[ \sum_{\mathclap{1 \le i \le j \le n}} a_{ij} \]

% same result, but this one can flatten a single side
\[ \smashoperator{\sum_{1 \le i \le j \le n}} a_{ij} \]
\[ \smashoperator[r]{\sum_{1 \le i \le j \le n}} a_{ij} \]

mathtools はもう一つ \smashoperator を用意しています。\smashoperator{\sum_{1 \le i \le j \le n}} の測定値は 28.43983pt で、\mathclap の結果とぴたり同じでした。違いは融通の利き方です。\smashoperator は演算子と添字をまとめて受け取り、[l] [r] [lr](既定)で どちら側をつぶすかを選べます。総和記号が行頭にあって左へはみ出させたくない、という場面では [r] が効きます——実測 38.32878pt と、両側つぶしと元の中間になりました。\mathclap は式の中の一点を狙う道具、\smashoperator は行頭の演算子ごと面倒を見る道具、と使い分けます。

記号の左に添字を置く — \prescript\adjustlimits

\prescript{上}{下}{本体} の三引数で、記号の 左肩と左足 に添字が付きます。同位体表記がいちばん分かりやすい例で、\prescript{238}{92}{\mathbf{U}} はウラン 238 を、質量数 238 を左上に、原子番号 92 を左下に置いて組みます。素朴に {}^{238}_{92}\mathbf{U} と書く手もありますが、そちらは空の添字を土台にするため位置と大きさが安定しません。左下が要らないときは第二引数を空の {} にします。添字の書体は \mathtoolssetprescript-sub-formatprescript-sup-format で差し替えられます。

latex
\[
  \prescript{238}{92}{\mathbf{U}}, \qquad
  \prescript{n}{}{C}_{k}
\]

% limits of two nested operators lined up
\[ \adjustlimits \sum_{i} \sum_{j} a_{ij} \]

同じ節にもう一つ、地味ですが効く道具を置きます。\adjustlimits入れ子になった二つの演算子の下限をそろえます\sum_i \sum_j のように大きさの違う添字が続くと、二つ目の下限がわずかに浮いて見えることがあり、\adjustlimits がその段差を吸収します。実測では \sum_i\sum_j が 30.55557pt、\adjustlimits\sum_i\sum_j が 32.2222pt——差は 1.66663pt、ちょうど 3mu ぶんの調整です。\lim_{n\to\infty}\sup_{x} のように語幅の違う演算子が続く場面でも効きます。

行列の列をそろえる — pmatrix*[r] [l] [c]

amsmath の pmatrix は列を必ず中央揃えにします。 負の数が混じるとこれが困りもので、-12 が縦に並ぶとマイナス記号の幅のぶんだけ数字がずれて見えます。mathtools は各環境に星付き版——matrix*pmatrix*bmatrix*Bmatrix*vmatrix*Vmatrix*smallmatrix*——を用意し、array と同じ列指定を 省略可能引数 で受け取ります。\begin{pmatrix*}[r] と書けば右揃えになり、マイナス記号が左へきれいに突き出ます。既定は c なので、星を付けただけでは見た目は変わりません。小行列の既定揃えは \mathtoolssetsmallmatrix-align で決められます。

latex
\[
  \begin{pmatrix*}[r]
    -1 &  3 \\
     2 & -4
  \end{pmatrix*}
  \qquad
  \begin{pmatrix}
    -1 &  3 \\
     2 & -4
  \end{pmatrix}
\]

場合分けと長すぎる一行 — dcasesrcasesmultlined

amsmath の cases は中身を 文中サイズ(text style) で組むので、分数を入れると \frac{1}{2} が小さく潰れます。mathtools の dcases は同じ書き方のまま中身を別行立てサイズにします——d は displaystyle の d です。中括弧を 右側 に置きたい、つまり複数の条件から一つの結論を導く形にしたいときは rcases を使い、\end{rcases} の直後に \Rightarrow などを続けます。両方まとめた drcases、そして最終列を文章として組む dcases*rcases* もあります。独自の場合分け環境が要るときは \newcases で作れます。

latex
\[
  f(x) =
  \begin{dcases}
    \frac{1}{2} & x > 0 \\
    0           & x \le 0
  \end{dcases}
  \qquad
  \begin{rcases}
    a \\ b
  \end{rcases} \Rightarrow c
\]

% [t] aligns on the first row; the second optional argument fixes the width
\[
  \begin{multlined}[t][0.6\textwidth]
    a + b + c + d \\ {} + e + f
  \end{multlined}
\]

multlined は amsmath の multline 環境を 一つの箱に閉じ込めた版 です。multline は別行立ての行全体を占有してしまうため、align の中や = の右側では使えません。multlined は環境なので式のどこにでも埋め込めて、長い右辺だけを内部で折り返せます。省略可能引数は二つ、一つ目が外側との縦の揃え位置(tb/既定は中央)、二つ目が幅です。幅を明示しない限り、必要なだけの幅を取ります。整列された式のあいだに矢印を差し込みたいときは \ArrowBetweenLines、整列全体の行間をゆるめたいときは spreadlines 環境が使えます。

参照した式にだけ番号を振る — showonlyrefs

\mathtoolsset{showonlyrefs} を書くと、本文から参照されている式にだけ番号が付き、残りの番号は消えます。書きかけの原稿では式番号がどんどん増えては減るもので、参照していない式にまで番号が振られていると、査読者は「(7) はどこで使うのか」と探しにいってしまいます。TeX Live 2024 で二式の align を組み、片方だけ \eqref で参照したところ、参照した式が (1)、参照していない式は無番号になりました。条件は一つ、参照に \ref ではなく \eqref を使うことです。\tag{} で手動で付けた番号まで消えては困るときは showmanualtags を足します。

latex
\mathtoolsset{
  showonlyrefs,        % number only what \eqref points at
  showmanualtags,      % but keep \tag{} numbers visible
  centercolon          % a bare : is set at axis height
}

その命令は amsmath と mathtools のどちらのものか

mathtools だけを読み込んでいると境界が見えなくなりますが、他人の文書を直すときや、amsmath しか許されない投稿規定に当たったときには効いてきます。境目は .sty を開けば分かります。伸縮矢印 \xrightarrow\xleftarrowamsmathamsmath.sty で定義)で、mathtools が足すのは残りの仲間——二重線の \xRightarrow\xLeftarrow\xLeftrightarrow、両向きの \xleftrightarrow、鈎つきの \xhookrightarrow\xhookleftarrow、写像の \xmapsto、より長い \xlongrightarrow、そしてハープーン——です。いずれも [下]{上} の同じ書き方で使えます。\intertext は amsmath、詰めた \shortintertext は mathtools。\overset\underset\substack は amsmath、角張った \overbracket\underbracket は mathtools です。

命令・環境出どころ役割
\xrightarrowamsmathラベルの幅まで伸びる矢印。[下]{上}
\xleftrightarrowmathtools伸縮矢印の仲間を大きく増やす。\xRightarrow\xmapsto など
\overbracketmathtools\overbrace\underbrace の角張った版。第一引数が線の太さ、第二引数が高さ(既定 0.7ex)
\intertextamsmath整列を保ったまま行間に文章を挟む
\shortintertextmathtools同じことを、上下の空きを詰めて行う
\substackamsmath添字を複数行に積む。横に詰める \mathclap と対になる
\MoveEqLeftmathtoolsalign の一行目を左へ吐き出して二行目以降と揃える
\splitfracmathtools分子や分母が長すぎるときに、そこだけ二行に折る