行列と配列

「行列(matrix)」という語を数学に持ち込んだのはジェームズ・ジョセフ・シルヴェスターで 1850 年、その代数を築いたのは友人のアーサー・ケイリーが 1858 年に王立協会紀要 148 巻へ寄せた「A Memoir on the Theory of Matrices」でした。LaTeX ではこの行列、じつは特別な構造ではありません。amsmath の pmatrix の中身は \array{*10 c}、つまり「中央そろえの列を 10 個持つ array」に括弧を付け、左右の余白を 5pt ずつ削っただけのものです。この一行が、よく聞かれる二つの疑問——「行列の列が足りない(11 列目でエラーになる)」「列の間隔をどう変えるのか」——の答えをそのまま与えてくれます。このページでは pmatrixbmatrixvmatrixsmallmatrix の一式、MaxMatrixColsarray 環境と \arraycolsep\arraystretch、拡大係数行列、そして \cdots\vdots\ddots を扱います。

amsmath が定義する行列環境は 7 つだけ

matrixpmatrixbmatrixBmatrixvmatrixVmatrixsmallmatrix の 7 つです。\usepackage{amsmath} を書けば使えます。いずれも数式モードの中で使い、要素は 横方向を &(アンパサンド)、行の終わりを \\(バックスラッシュ 2 個) で区切ります。中身の書き方はまったく同じで、違うのは 囲む区切り記号だけ です。名前の付け方も規則的で、先頭の文字が括弧の種類を表します——p は丸括弧(parenthesis)、b は角括弧(bracket)、v は縦棒(vertical bar)。大文字始まりの BmatrixVmatrix は「強い」方、つまり波括弧と二重縦棒になります。素の matrix は何も付けません。

環境付く区切り記号主な用途
matrixなし自分で区切り記号を付けたいときの土台
pmatrix丸括弧 ( )もっとも一般的な行列・列ベクトル
bmatrix角括弧 [ ]角括弧の流儀で書く行列
Bmatrix波括弧 { }波括弧で囲みたいとき
vmatrix縦棒 | |行列式
Vmatrix二重縦棒 ‖ ‖ノルム
smallmatrixなし(小型)本文の行のなかに埋め込む小さな行列
latex
% 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}
\]

この 7 つの中身は 常に中央そろえ で、右寄せや左寄せは指定できません。列の揃えを自分で決めたいときは、後述の array 環境を使うか、mathtools パッケージ星付き版 を使います。mathtools は matrix*pmatrix*bmatrix*Bmatrix*vmatrix*Vmatrix*smallmatrix* を定義しており、いずれも省略可能引数 [r][c][l] を取って全列をその向きにそろえます(既定は c)。星付き版は amsmath ではなく mathtools のもの で、\usepackage{mathtools} が要ります。mathtools 自身が amsmath を読み込むので、両方書く必要はありません。区切り記号を手で伸縮させる \left\right\big\Big の話は別ページ「区切り記号」の担当です。

行列の列が足りない — MaxMatrixCols と 11 列目のエラー

既定の上限は 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 列を並べても何のエラーも出ませんでした。列指定に必要なだけ書けばよいからです。

latex
% 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列指定を必須の引数として受け取る 汎用の格子で、文字を 1 列につき 1 つ書きます——l が左そろえ、c が中央、r が右そろえ。文字と文字のあいだに | を置くと、その位置に 縦罫線 が引かれます。{l|c|r} なら「左・罫線・中央・罫線・右」の 3 列です。本文の表を組む 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)2 つ分にあたります。amsmath の行列環境は始まりと終わりに \hskip -\arraycolsep を入れてこの余白を打ち消しているのです。裏返せば、\arraycolsep を変えれば行列の列間隔も変わります。実測でも、2pt に縮めると pmatrix の幅は 29.21304pt に、10pt に広げると 45.21304pt になりました。行の高さを一律に伸ばしたいときは \renewcommand{\arraystretch}{1.5}——1.5 にすると 2×2 の総高が 24pt から 36pt へ、ちょうど 1.5 倍になりました(幅は変わりません)。

latex
% 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 には、この種の拡大行列をもっと素直に書く仕組みも用意されています。

latex
\[
  \left[\begin{array}{cc|c}
    1 & 2 & 5 \\
    3 & 4 & 6
  \end{array}\right]
\]

一般の n×n 行列を書く — \cdots\vdots\ddots

省略を表す点々を、行列の一つの要素として置きます。方向の違う 4 種類があり、行列のどこに落ちるかで選び分けます。いずれも数式モードの命令で、追加パッケージは要りません。

  • \cdots中央の高さ の水平の点(⋯)。行に沿った省略に使います。+= と同じ高さに並ぶので、横方向の連なりによく合います。
  • \vdots の点(⋮)。列に沿った省略に使います。
  • \ddots — 右下がりの 斜め の点(⋱)。主対角線に沿った省略に使います。
  • \ldots(および文脈で判断する \dots)— ベースライン の水平の点(…)。数の並びや添字の列に使います。行列の中では \cdots のほうが収まりが良いのがふつうです。
latex
\[
  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 行列の定石の書き方です。第 1・2・最終行では 3 列目の \cdotsa_{12}a_{1n} のあいだの省略を埋め、第 3 行では各列の \vdots が縦の省略を、対角の位置の \ddots が右下がりの省略を示します——行も列も同様に続く、という意味です。1 行まるごとを点で埋めたいときは、amsmath の \hdotsfor{n} が指定した n 列ぶんを水平の点でまたぎます。

本文の行に行列を埋める — smallmatrix はちょうど 1 行分

本文の $ … $pmatrix を落とすと行の高さが膨れ、周囲の行送りが乱れます。数字で見ると理由がはっきりします。10pt 組版で \bigl( … \bigr) に入れた 2×2 行列は、高さ 14.5pt・深さ 9.5pt で合計 24.0pt——\baselineskip の 12pt ちょうど 2 行分を占めてしまうのです。amsmath の smallmatrix 環境 は要素を小さく詰めて組み、同じ括弧に入れた同じ内容が高さ 8.5pt・深さ 3.5pt の合計 12.0pt、つまり ちょうど 1 行分 に収まります。smallmatrix は区切り記号を付けないので、必要なら \bigl( … \bigr) のように手で囲みます(\left( \right) でも囲めますが、本文中では固定サイズの \bigl\bigr のほうが行送りを乱しにくいです)。mathtools を読み込んでいれば、列の揃えを選べる smallmatrix* も使えます。

latex
% preamble: \usepackage{amsmath}
Consider the rotation matrix
$\bigl(\begin{smallmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{smallmatrix}\bigr)$
in the plane.