数式アルファベット(\mathbf・\mathbb・\mathcal)

LaTeX の数式モードには、本文のように「フォントを切り替える」という考え方がありません。あるのは 数式アルファベット——\mathbf\mathbb\mathcal のように、囲んだ範囲の字を丸ごと別の書体に割り当てる仕組みです。ところがこの枠は無限ではなく、古典的なエンジンでは 一つの数式に 16 個まで。1978 年に決まったこの上限は 40 年以上たったいまも生きていて、! LaTeX Error: Too many math alphabets used in version normal. という形で突然顔を出します。このページでは、標準で使える七つの命令から、amssymb が要る黒板太字 \mathbbmathrsfs\mathscr、数式の太字 \bm、そして unicode-math\sym… までを、この 16 枠をどう配るかという一本の筋で並べます。

数式アルファベットは書体ではなく「族」

数式モードに入った英字は、一文字ずつが変数とみなされ 数式イタリック で組まれます。これが既定の数式アルファベットです。\mathbf{v} のように命令で囲むと、その範囲だけが別の族——TeX の用語では family(\fam)——に切り替わります。ここが本文の書体命令との決定的な違いです。TeX は数式の一文字ごとに「どの族の何番目の文字か」という番号を持っており、書体はテキストのように連続した流れではなく、記号ひとつずつに貼られたラベルなのです。だから \mathbf{fit} は単語 “fit” ではなく、f・i・t という三つの太字記号の積として組まれ、fi のあいだには変数どうしの空きが入ります。数式の中に本物の単語を立体で置きたいときは、amsmath\text{…} を使います。

標準の LaTeX には七つの数式アルファベット命令が最初から入っています。名前はどれも \math… の形で、本文用の \textbf\textsf と対になるように付けられています。紛らわしいのは \mathnormal\mathit の違いです。\mathnormal(既定)は一字ずつを変数として組むため字間が広めで、\mathit は本文用のイタリック、つまり \mathit{diff} のように 多文字の語をひとまとまりの斜体 にしたいときのものです。\mathrm\mathbf は立体(ローマン体)で、後者は太字。\mathsf はテンソルや圏の名前に、\mathtt は数式の中にコードらしい記号を置くときに使われます。

命令見た目備考
\mathnormal既定の数式イタリック標準。変数の既定の書体。字間は変数どうしの空き
\mathrm立体(ローマン体)標準。立体の定数・演算子・略号に
\mathbf立体の太字標準。立体なので変数には不向き。ギリシャ文字には効かない
\mathsfサンセリフ体標準。テンソル・圏の名前などに
\mathtt等幅(タイプライタ体)標準。数式の中のコード片に
\mathit本文用イタリック体標準。\mathit{diff} のように多文字語をひとまとまりの斜体に
\mathcal花文字(カリグラフィック)。大文字のみ標準。集合族・圏・変換名に。字体は Computer Modern の cmsy

\mathbb\mathscr\mathfrak にはどのパッケージが要るか

黒板太字 \mathbb とフラクトゥール \mathfrak には amssymb(または軽い amsfonts)が、スクリプト \mathscr には mathrsfs が要ります。\mathcal だけは標準です。\mathbb は縦棒などを二重線にした太字で、黒板でボールドを表すために線を重ねて書いた習慣に由来し、実数 ℝ・複素数 ℂ・整数 ℤ・有理数 ℚ・自然数 ℕ といった数の集合に使うのがほぼ定着した用法です。収録は大文字 A–Z だけ で、小文字も数字もありません。

\mathcal\mathscr の使い分けは、由来を知ると迷わなくなります\mathscr が読み込む rsfs は「Ralph Smith’s Formal Script」の略で、1991 年 10 月に公開されました。作者自身が README で、これは 18 世紀のスペンサリアン/カッパープレート系の手書きに基づく formal な 書体で、活字設計者 R. Hunter Middleton の書体を手本にし、Springer Verlag の組版で見かけるものに近い、と書いています。対して \mathcal は Computer Modern の記号フォント cmsy に入っている、より informal な 装飾大文字です。つまり ℒ と 𝓛 は「格式ばった筆記体」と「くだけた飾り字」の対比であって、どちらが正しいという話ではありません。関数解析の定義域 𝒟 や場の理論のラグランジアン ℒ に rsfs が好まれるのは、この formal さゆえです。

\mathfrak の中身にも名前があります。amssymb\DeclareMathAlphabet{\mathfrak}{U}{euf}{m}{n} と書いており、eufEuler Fraktur——AMSFonts の README によれば、Euler 系の書体は ヘルマン・ツァップ の設計で 1990 年代に公開されました。同 README はさらに、ツァップ自身が多くの字形を作り直した Euler 3.0 が 2008 年 1 月 10 日、クヌースの誕生日に本人へ贈られた ことも記しています。Lie 環 𝔤 やイデアル 𝔭 に使うあの角ばった書体は、20 世紀を代表するタイプデザイナーの手によるもので、しかも \mathbb\mathcal と違って 大文字・小文字の両方 が揃っています。euscript パッケージが提供する Euler Script(eus)も同じ一族です。

document.tex
\usepackage{amssymb}   % \mathbb and \mathfrak
\usepackage{mathrsfs}  % \mathscr (Ralph Smith's Formal Script)
% ...
\[
  \mathbb{R} \subset \mathbb{C}, \qquad
  \mathcal{F}(f) = \hat{f}, \qquad
  \mathscr{L}(f) = F, \qquad
  \mathfrak{g} = \operatorname{Lie}(G).
\]
命令必要なパッケージ対応範囲と典型的な用途
\mathbbamssymb(または amsfonts)大文字 A–Z のみ。数の集合 ℝ ℂ ℤ ℚ ℕ
\mathcal標準(不要)大文字のみ。集合族・圏・変換名。字体は cmsy
\mathscrmathrsfs(または euscript)大文字のみ。より格式ばった筆記体。字体は rsfs10
\mathfrakamssymb / amsfonts(euf)大文字・小文字。Lie 環・イデアル。Euler Fraktur

\mathbb{2} はエラーにならず、別の記号になる

黒板太字の 1 や 2 を出そうとして \mathbb{1}\mathbb{2} と書くと、警告もエラーも出ないまま、まったく別の記号が出ます。TeX Live 2024 の amssymb$\mathbb{2}$ を組んで PDF から文字を取り出すと、返ってくるのは U+22AD(⊭、not true) でした。理由は数式アルファベットの仕組みそのものにあります。\mathbb は「msbm フォントの、いま渡された文字と同じ位置」を引くだけなので、msbm10 の 2 の位置に入っている記号——それが ⊭——がそのまま出るのです。文字の存在を確認する仕組みはありません。指示関数 𝟙 が要るときは、dsfont\mathds{1}(Type 1 の dsrom10)か、mathalpha パッケージで黒板太字そのものを差し替えます。bbm\mathbbm{1} も有名ですが、TeX Live 同梱版には Type 1 版がなく Type 3 のビットマップ として PDF に埋め込まれる(pdffonts で確認できます)ので、投稿規程がビットマップフォントを嫌う場では避けたほうが安全です。

document.tex
% A blackboard-bold digit is NOT available from amssymb:
%   $\mathbb{2}$  ->  U+22AD, silently. Use one of these instead.
\usepackage{dsfont}                              % \mathds{1}, Type 1 outlines
\usepackage[bb=dsserif,scr=rsfs]{mathalpha}      % replace the whole \mathbb alphabet
% ...
\[ \mathds{1}_{A}(x), \qquad \mathbb{1}_{A}(x) \]

数式アルファベットは 16 個まで — Too many math alphabets

アルファベットを足していくと、いつか ! LaTeX Error: Too many math alphabets used in version normal. に当たります。上限は 16。TeX の数式文字コードは「族番号」に 4 ビットしか割いていないので、族は 0 から 15 までしか存在できないのです。latex.ltx には \chardef\e@mathgroup@top=16 と書かれており、\Umathcode を持つエンジン(XeTeX・LuaTeX)ではこれが 256 に引き上げられます。素の article は起動時点で 4 族(operators・letters・symbols・largesymbols)を使っており、amssymbmathrsfs を足すと 7 族。残りは 9 枠ほどで、そこへ \mathbf\mathsf\mathtt\mathit\mathcal\mathbb\mathfrak\mathscr が順に入っていきます。この計算は「数式ごと」ではなく「文書ごと」に近い——枠は使った順に埋まり、返ってきません。

同じ 16 枠に、二つ目の門番があります。\DeclareSymbolFont(記号フォントの登録)は latex.ltx の中で \ifnum\count18<15 という ハードコードされた条件 で守られていて、これを超えると ! LaTeX Error: Too many symbol fonts declared. になります。ここが重要な落とし穴で、この 15 という数字はエンジンに関係なく効きます——LuaLaTeX でアルファベットは 256 個使えるのに、記号フォントは 16 個までのままです。実際に 17 個目の \DeclareSymbolFont を書くと pdfLaTeX でも LuaLaTeX でも同じエラーが出ます。低水準の \newfam を直接呼んで上限を越えた場合だけは、TeX 側の ! No room for a new \mathgroup. が出ます(\fam ではありません。LaTeX2e は \newfam\new@mathgroup の別名にしているためです)。

救いもあります。近年の LaTeX カーネルは、16 枠のうち 末尾 2 枠を「使い回し用」に予約 しています(\c@localmathalphabets の既定値が 2)。本文中で 15 個目・16 個目のアルファベットが必要になると、カーネルはその枠を式ごとに貸し出し、式が終われば回収します。だから「一つの数式に登場する追加アルファベットが 2 個までなら、文書全体では 14 個を超えても止まらない」——実測でも、カウンタは 14 で固まったままエラーが出ませんでした。逆に言えば、同じ一つの数式に三つ以上の新しいアルファベットを詰め込むと、そこで折れます。エラーが「なぜかこの式だけ」で出るときは、まずこれを疑ってください。なお isomath パッケージのドキュメントは、この 16 という上限を理由に自身の \mathsfit をオプション扱いにしていると明記しています。上限を気にせず済ませたいなら、XeLaTeX・LuaLaTeX に移って unicode-math を使うのが根本的な解決です。

自分でアルファベットを足す — \DeclareMathAlphabet

新しい数式アルファベットは \DeclareMathAlphabet{命令}{符号化}{ファミリ}{シリーズ}{シェイプ} の一行で作れます。プリアンブル専用で、たとえばテンソル用にサンセリフの斜体が欲しければ \DeclareMathAlphabet{\mathsfsl}{OT1}{cmss}{m}{sl} と書くだけ。太字の数式(後述の \mathversion{bold})でも自然に太くしたいなら、\SetMathAlphabet{\mathsfsl}{bold}{OT1}{cmss}{bx}{sl} を続けます。すでに記号フォントとして登録済みのものへ別名を付けたいだけなら、枠を消費しない \DeclareSymbolFontAlphabet が使えます——mathrsfs.sty の中身は実質この二行だけです。なお \DeclareMathAlphabet は枠を 宣言した時点では消費せず、最初に使われたときに確保します。「読み込んだだけのパッケージ」が枠を食い潰すことはない、という点は覚えておくと切り分けが楽になります。

document.tex
% preamble only
\DeclareMathAlphabet{\mathsfsl}{OT1}{cmss}{m}{sl}
\SetMathAlphabet{\mathsfsl}{bold}{OT1}{cmss}{bx}{sl}

% costs no slot: just another name for a symbol font already declared
\DeclareSymbolFont{rsfs}{U}{rsfs}{m}{n}
\DeclareSymbolFontAlphabet{\mathscr}{rsfs}
% ...
\[ \mathsfsl{T}_{ij} \]

数式を太字にする — \mathbf\boldsymbol\bm の違い

\mathbf立体の太字 なので、斜体であるべき変数やベクトルには向かず、しかも ギリシャ文字にはまったく効きません。実測ではっきりします——$\mathbf{\alpha}$ だけを含む文書を pdfLaTeX で組んで pdffonts にかけると、埋め込まれているのは CMMI10 一つだけ。つまり α は太字用の CMMIB10 ではなく、ふつうの数式イタリックのまま出ています。これは仕様どおりで、\mathbf は「族を切り替える」命令であり、α は族を切り替えても字形が変わらない位置にいるからです。エラーも警告も出ないので、気づかずに提出されがち な事故です。

斜体を保ったまま太字にしたいときの第一候補が amsmath(内部の amsbsy)の \boldsymbol、そして実務でいちばん頑健なのが bm パッケージの \bm です。bm は LaTeX の必須ツール集 latex-tools に含まれるので、標準的な TeX 配布版なら追加インストールは要りません。\bm{…} は「与えられたものに 太さだけを足し、斜体などその他の見た目と前後の空きを保つ」よう設計されていて、変数・ギリシャ文字・記号のどれでも、複雑な入力でもほぼそのまま太字化できます。bm\boldsymbol\bm の別名として定義し直します。ただし \bm はただではありません——bm.sty\bmmax(既定 4)という上限を持ち、太字用に確保する族の数をここで抑えています。太字の数式アルファベットもまた 16 枠から取られる ので、前節の予算表に載るわけです。足りなくなったら \chardef\bmmax=6 のように増やせますが、そのぶん通常のアルファベットが減ります。

数式ぜんぶを太字にしたい場面——見出しや図の中の式など——では、命令ではなく 数式バージョン を切り替えます。\boldmath\mathversion{bold} がそれで、標準 LaTeX には normalbold の二つのバージョンが最初から用意されています。自分で第三のバージョンを作ることもでき、\DeclareMathVersion{heavy} と宣言してから \SetMathAlphabet{…}{heavy}{…} を並べれば、\mathversion{heavy} で丸ごと切り替わります。bm\hm(別名 \heavysymbol)はこの heavy バージョン向けの命令で、\hmmax は既定 3。ただし heavy バージョンを自分で定義していなければ \hm はただの \bm になるので、\hm を書けば \bm より太くなる」わけではない 点に注意してください。

document.tex
\usepackage{amsmath}   % \boldsymbol
\usepackage{bm}        % \bm -- recommended
% \chardef\bmmax=6     % raise bm's family budget if it runs out
% ...
\[
  \mathbf{v} \neq \bm{v}, \qquad
  \bm{\beta} = (\beta_1, \dots, \beta_n), \qquad
  \nabla \bm{F} = \bm{0}.
\]
\section{\boldmath A whole heading in bold maths: $E = mc^2$}
  • \mathbf — 立体の太字。標準で使えるが、斜体であるべき変数には不向きで、ギリシャ文字には効かない(実測で確認済み)。
  • \boldsymbol — amsmath(amsbsy)。斜体を保ち、ギリシャ文字・記号も太字にできる。
  • \bm — bm パッケージ。推奨。太さだけを足し、字形と前後の空きを保つ。族の消費は \bmmax(既定 4)で制限される。
  • \boldmath / \mathversion{bold} — 命令ではなく数式バージョンごと切り替える。見出しや図中の式に。

unicode-math の \sym… — アルファベットが Unicode に写る

XeLaTeX・LuaLaTeX で unicode-math を読み込むと、アルファベット命令は \sym… 系に置き換わります。\symbf(太字)・\symbb(黒板太字)・\symcal(花文字)・\symscr(スクリプト)・\symfrak(フラクトゥール)・\symup(立体)・\symit(斜体)・\symsf(サンセリフ)。従来の名前も残りますが、実際には \mathbb\symbb の、\mathcal\symcal の別名に置き換えられています。決定的な違いは、\sym…族の切り替えではなく Unicode の数学英数記号への写像 である点です。LuaLaTeX で $\symbb{2}\ \symbb{r}\ \symcal{L}$ を STIX Two Math で組み、PDF から文字を取り出すと、返ってくるのは U+1D7DA(𝟚)・U+1D563(𝕣)・U+2112(ℒ)。前節で ⊭ になった \mathbb{2} が、ここでは本物の黒板太字の 2 になり、しかも小文字まで揃っています。PDF からコピーした文字が意味を保つ のは、この写像のおかげです。

その写像には一つ、知らないと確実にはまる帰結があります。\symcal\symscr は同じ Unicode 文字に写ります。Unicode の数学英数記号にはスクリプト体が一系統しかないため、\symcal{L}\symscr{L} も U+2112 になるのです。両者を見た目で分けたいときは、フォント側の OpenType 機能(スタイルセット)range= で当てます。STIX Two Math なら \setmathfont{STIX Two Math}[range=\symscr,StylisticSet=1] を主フォントの指定に続けて書けばよく、実測ではこの一行で \symcal{L} の幅 6.99pt に対し \symscr{L} が 8.63pt——別の字形が選ばれていることが数字で確認できます。在来方式で \mathcal\mathscr を二枠使って区別していた話が、unicode-math では フォント機能の指定 に置き換わるわけです。

document.tex
% compile with xelatex or lualatex
\usepackage{amsmath}
\usepackage{unicode-math}
\setmathfont{STIX Two Math}
\setmathfont{STIX Two Math}[range=\symscr,StylisticSet=1]  % a second script shape
% ...
\[
  \symbb{R} \subset \symbb{C}, \qquad \symbb{2}, \qquad
  \symcal{F} \neq \symscr{F}, \qquad \symfrak{g}, \qquad
  \symbfit{v} = \symbf{0}.
\]

最後に、unicode-math 環境で \symbf を書くときの注意を一つ。既定の設定(bold-style=TeX)では \symbf{v} は太字の「立体」 になります。実測では \symbf{v} が U+1D42F(太字ローマン体の v)、\symbfit{v} が U+1D497(太字斜体の v)でした。ベクトルを太字斜体で書く流儀なら、\symbfit を使うか、bold-style=ISO を指定します。なお、文書全体の数式フォントをどう選ぶか——\setmathfont に何を渡すか、本文の書体とどう合わせるか——は別ページの主題です。