数式の折り返し前後で高さが自動調整される括弧を利用する
amsmath パッケージから、長い数式を折り返す数式環境として split 環境や multline 環境が提供されている。しかし、これらの環境内で高さが自動調整される括弧を利用する場合、少しだけ (?!) 不便になることがある。これを解決してみたい。
また、# 中間区切りの手動調整と自動調整 では \middle
の取り扱いに関しても触れてみた。
○ 前提
amsmath パッケージと mathtools パッケージを利用することを前提とします。
また、それぞれの括弧については以下のようなコマンドを利用する。
括弧の種類 | コマンド |
---|---|
丸括弧 ( , ) (Parenthesis) |
( , ) or \lparen , \rparen
|
波括弧 { , } (Brace) |
\lbrace , \rbrace
|
角括弧 [ , ] (Bracket) |
\lbrack , \rbrack
|
山括弧 < , > (Angle bracket) |
\langle , \rangle
|
垂直棒 (Vertical bar) |
\lvert , \rvert
|
2 本の垂直棒 |
\lVert , rVert
|
■ 基本的な使用方法例
multline(d) 環境や split 環境の基本的な使い方は以下の記事を参照のこと。
\frac
や \sum
などの背の高い数学記号に対して高さを自動調整する括弧を具体的な使い方は以下のようになる。
\begin{equation}
% Example of automatic
\left\lparen
\frac{\partial T}{\partial P}
\right\rparen_S
=
% Example of manual
\biggl\lparen
\frac{\partial V}{\partial S}
\biggr\rparen_P
\end{equation}
これらの調整によって調整される括弧スタイルの組み合わせは任意に採ることが出来る。したがって、\left\lparen <contents> \right\rbrace
などが可能である。また、開き括弧と閉じ括弧を揃える必要もない。
また、一方に括弧を挿入したくない場合には .
を用いて \left. <contents> \right\rvert
などとすれば、右側の垂直棒だけを高さを調節して出力することが出来る。
\begin{equation}
% Example of automatic
\left.
\frac{\partial T}{\partial P}
\right\rvert_{S=\mathrm{const}}
=
% Example of manual
% Do not need \biggl
\frac{\partial V}{\partial S}
\biggr\rvert_{P=\mathrm{const}}
\end{equation}
囲うコンテンツは数式に留まらず、aligned 環境などの非独立な数式環境も囲うことが出来る。(split 環境を除く)
また、行列を作成する場合には array 環境や matrix 環境を括弧で囲わずに、amsmath パッケージから提供される pmatrix 環境などを利用することをお薦めする。
○ 発生する問題
折り返し(改行 \\
)の前後で \left
~ \right
で括弧を対応させることが出来ない。
すなわち、以下のような式を出力することが出来ない。これは、対応する \left
~ \right
の中に \\
や &
が含まれているためである。
\begin{equation}
\begin{split}
<left_hand_side>
= {} &
\left(
<wrapped_equation_1> \\
& + <wrapped_equation_2>
\right)
\end{split}
\end{equation}
これを回避する方法として、それぞれの行で \left
~ \right
を対応させることがよく知られている。
\begin{equation}
\begin{split}
<left_hand_side>
= {} &
\left(
<wrapped_equation_1>
\right.
\\
& \left.
+ <wrapped_equation_2>
\right)
\end{split}
\end{equation}
ただし、このようにした場合、<wrapped_equation>
の高さはそれぞれ同じである必要がある。
たとえば、以下のような場合では自動調整の恩恵を得られない。
\begin{equation}
\begin{split}
<left_hand_side>
= {} &
\left\lbrace
<TALL_wrapped_equation_1>
\right.
\\
& \left.
+ <short_wrapped_equation_2>
\right\rbrace
\end{split}
\end{equation}
この場合、開き括弧だけが高くなり閉じ括弧はそのままの高さになっている。本来、開き括弧と閉じ括弧の高さは揃っているべきなので、これは好ましくない。また、開き括弧と折り返された式の行頭がそろっていない方が良いように思われる。少しだけ右へずらすようにしたい。
したがって、以下の点を解決する必要がある。
- 改行
\\
の前後で括弧を対応させる- 対応する括弧の高さを揃える
- 行列環境の場合
- 折り返された後の式を少しだけインデントする
これらを解決させよう。
ちなみに、これらを解決させたコマンドを提供するパッケージは存在しないようだ。
○ 手動で調整する
折り返しの前後で自動調整を利用したいのに、手動での調整を考えるのは本末転倒とも言えそうだが、まずは手動での方法を確認しておきたい。
手動で調整する場合には括弧の高さを調整するコマンドを利用する。これらのコマンドは左と右で別のコマンドが用意されている。
括弧の高さ | 左側 | 右側 |
---|---|---|
big | \bigl |
\bigr |
Big | \Bigl |
\Bigr |
bigg | \biggl |
\biggr |
Bigg | \Biggl |
\Biggr |
また、\left
~ \right
で対応している場合、どの高さに調整されているのかは気になるだろう。以下のような主要な高さの高い数式について確認してみた。
数式の例 | 自動調整される括弧の高さ |
---|---|
分数 | bigg |
分数と根号 | Bigg |
積分記号 (nolimits 型) |
Bigg |
積分記号 (limits 型) |
Bigg より大きい |
総和記号 (limits 型) |
Bigg |
場合によっては上手くないが、Bigg で調節しておくことが定石になりそうである。これに固定して括弧で囲うとするならば自動調整の必要はないため、\\
や &
を含む数式を囲むことのできるコマンドを作成しておくことも出来るだろう。
\newcommand{\BiggParen}[1]{\Biggl(#1\Biggr)}
\begin{equation}
\begin{split}
<left_hand_side>
= {} &
\BiggParen{
<wrapped_equation_1> \\
& + <wrapped_equation_2>
}
\end{split}
\end{equation}
括弧コマンドを拡張する(折りたたみ)
mathtools パッケージから提供されている \DeclarePairedDelimiter
コマンドを利用して括弧コマンドを作成し、ifthen と xparse からオプションで括弧のスタイルを指定するように作成した。デフォルトの括弧の高さを Bigg
にした。
\manualDelimiter(delimiter_size)[delimiter_style]{formula_body}
を定義した。
\usepackage{ifthen}
\usepackage{xparse}
\usepackage{mathtools}
\DeclarePairedDelimiter{\pairedParen}{\lparen}{\rparen}
\DeclarePairedDelimiter{\pairedBrace}{\lbrace}{\rbrace}
\DeclarePairedDelimiter{\pairedBrack}{\lbrack}{\rbrack}
\newcommand{\wrongOptionName}{\text{Warning! Wrong option.}}
\NewDocumentCommand{\maualDelimiter}{ D(){Bigg} O{p} m }{
\ifthenelse{\equal{p}{#2} \OR \equal{paren}{#2}}{
\ifthenelse{\equal{big}{#1}}{\pairedParen[\big]{#3}}{
\ifthenelse{\equal{Big}{#1}}{\pairedParen[\Big]{#3}}{
\ifthenelse{\equal{bigg}{#1}}{\pairedParen[\bigg]{#3}}{
\ifthenelse{\equal{Bigg}{#1}}{\pairedParen[\Bigg]{#3}}{
\wrongOptionName
} } } }
}{
\ifthenelse{\equal{b}{#2} \OR \equal{brace}{#2}}{
\ifthenelse{\equal{big}{#1}}{\pairedBrace[\big]{#3}}{
\ifthenelse{\equal{Big}{#1}}{\pairedBrace[\Big]{#3}}{
\ifthenelse{\equal{bigg}{#1}}{\pairedBrace[\bigg]{#3}}{
\ifthenelse{\equal{Bigg}{#1}}{\pairedBrace[\Bigg]{#3}}{
\wrongOptionName
} } } }
}{
\ifthenelse{\equal{B}{#2} \OR \equal{brack}{#2}}{
\ifthenelse{\equal{big}{#1}}{\pairedBrack[\big]{#3}}{
\ifthenelse{\equal{Big}{#1}}{\pairedBrack[\Big]{#3}}{
\ifthenelse{\equal{bigg}{#1}}{\pairedBrack[\bigg]{#3}}{
\ifthenelse{\equal{Bigg}{#1}}{\pairedBrack[\Bigg]{#3}}{
\wrongOptionName
} } } }
}{\wrongOptionName}
}
}
}
delimiter_style |
括弧のスタイル |
---|---|
p , paren (デフォルト) |
丸括弧 |
b , brace
|
波括弧 |
B , brack
|
角括弧 |
○ コマンドを作成する
何かしらのパッケージからコマンドを提供されているか探してみたが、どうやらないらしい。
ユーザ側で作ってみよう。2 パターンのコマンド例を見てみよう。
■ 簡単なコマンド例
次のようにコマンドを作成すれば、\left
~ \right
が対応する括弧を作成することが出来る。開き括弧と閉じ括弧のそれぞれの内部で、囲む数式の全体の高さを処理して自動調整させるようにしている。
\newcommand{\autoParen}[2]{%
\mathopen{%
\left(%
\vphantom{#1#2}%
\right.%
}%
#1%
\\ &%
#2%
\mathclose{%
\left.%
\vphantom{#1#2}%
\right)%
}%
}
以下のように利用することが出来る。ただし、1 回の折り返ししか使うことが出来ない。また、コマンド内部で &
や \\
を利用しない。
\begin{equation}
\begin{split}
<left_hand_side>
= {} &
\autoParen{ <TALL_wrapped_equation_1> }
{+ <short_wrapped_equation_2> }
\end{split}
\end{equation}
もちろん、折り返しの回数を 2 回、3 回と増やしたコマンドを作成することも出来るが、特定の回数しか利用できなくなるため少々面倒くさい。
■ エキスパートな例
mathtools パッケージから提供されているコマンドと TeX にプリミティブなコマンドを利用して折り返しの前後でも対応が取れる括弧を作成してみる。
cf. The mathtools Package, §3.6.1 Expert use
Sebastien Gouezel (2014/05/14) から例として挙げられているコマンドを少し変更したものを紹介する。(垂直棒では変化が分かりづらかったので、波括弧に変更した)
\usepackage{mathtools}
\newcommand{\MTkillspecial}[1]{% helper macro
\bgroup%
\catcode`\&=9%
\let\\\relax%
\scantokens{#1}%
\egroup%
}
\DeclarePairedDelimiter{\autoBrace}{\lbrace}{\rbrace}
\reDeclarePairedDelimiterInnerWrapper{\autoBrace}{star}{%
\mathopen{%
#1% `\left <left_delimiter>'
\vphantom{\MTkillspecial{#2}}%
\kern-\nulldelimiterspace%
\right.%
}%
#2% Formula in bracket
\mathclose{%
\left.%
\kern-\nulldelimiterspace%
\vphantom{\MTkillspecial{#2}}%
#3% `\right <right_delimiter>'
}%
}
-
\MTkillspecial
では、\catcode`\&=9
で&
を無視するカテゴリコードに変更 -
\let\\\relax
で\\
を無視 -
\DeclarePairedDelimiter
では、波括弧で囲むコマンドを定義 -
\reDeclarePairedDelimiterInnerWrapper
では、\DeclarePairedDelimiter
で定義されているコマンドを再定義
したがって、このビックリ ブラックボックスコマンドを利用すれば、次のように途中で折り返しを含むような数式も上手く括弧の高さを自動調整できる。
\begin{equation}
\begin{split}
<left_hand_side>
= {} &
\autoBrace*{
<short_wrapped_equation_1> \\
& + <TALL_wrapped_equation_2> \\
& + <short_wrapped_equation_3>
}
\end{split}
\end{equation}
このコマンドの大きなメリットは、折り返しの回数が制限されない点である。また、このコマンドも手動で調整するコマンドを拡張したときと同じように、ifthen パッケージと xparse パッケージを利用してオプションから括弧のスタイルを使い分けるように新たなコマンドを作成することも出来るだろう。
ただし、このコマンドを管理する際には、TeX にプリミティブなコマンドが含まれているため、それなりの知識が必要になる可能性がある。
なお、mathtools パッケージから提供される \DeclarePairedDelimiter
などのコマンドは定義したコマンドの *
付きが高さを自動調整された括弧となる。
○ 行列環境を折り返す
基本的な攻略法は、分割した行列をそれぞれ matrix 環境で書き、それぞれを \left(
~ \right.
と \left.
~ \right)
などして括弧を書くようにする方法となる。もちろん、# エキスパートな例 で紹介しているコマンドを利用していても良いが、基本的に行列の高さは折り返しの前後で変わらないので、これで十分だと思われる。
問題は、どのように折り返すかのみになるが、multlin(d) 環境か split 環境を利用すれば良いだろう。
これらには以下のようなメリットとデメリットがあると思われる。
環境 | メリット | デメリット |
---|---|---|
multline | 自動インデント(& 不要) |
行列がある程度大きい必要がある |
multlined | 自動インデント(& 不要) |
align 環境などで整列が上手くない |
split | どの環境でも利用可能 | インデントを手動でする必要がある |
■ multline(d) 環境を利用する場合
かなり大きめの行列に関しては multline 環境を利用すると良いだろう。
\begin{multline}
M
=
\left(
\begin{matrix}
<BIG_matrix_contents>
\end{matrix}
\right.
\\
\left.
\begin{matrix}
<BIG_matrix_contents>
\end{matrix}
\right)
\end{multline}
あまり大きな行列ではない場合には、multlined 環境を使って最大幅をユーザ側で与えて使うことにしよう。
改行ごとに適当なインデントが与えられるので、split 環境よりも平易に書くことが出来る。ただし、align 環境などで &
を用いて整列する場合には上手く整列できないので注意が必要。
\begin{equation}
\begin{multlined}[0.5\linewidth]
M
=
\left(
\begin{matrix}
<matrix_contents>
\end{matrix}
\right.
\\
\left.
\begin{matrix}
<matrix_contents>
\end{matrix}
\right)
\end{multlined}
\end{equation}
■ split 環境を利用する場合
split 環境で折り返すだけでは折り返した後の行列をある程度インデントしておくと良いだろう。ただし、どこまでインデントすべきかの一般的な回答はないと思われる。気持ちのいいところまでインデントしよう。
\newcommand{\matrixindent}{\qquad}
\NewDocumentCommand{\mtxind}{ o }{%
\IfNoValueF{#1}{\hphantom{#1}}%
\matrixindent%
}
例として、=
右側から \mtxind
(\qquad
) でインデントしてみた。
\begin{equation}
\begin{split}
M
= {} &
\left(
\begin{matrix}
<matrix_contents>
\end{matrix}
\right.
& \mtxind
\left.
\begin{matrix}
<matrix_contents>
\end{matrix}
\right)
\end{split}
\end{equation}
&
が split 環境外でも整列として適用されるので、align 環境などでも利用できる。
○ 2 行目以降を開き括弧の後ろまでインデントする
以降では、改行に伴うインデントを簡便にするコマンドを考えたい。
折り返しの前後を括弧で囲む場合、折り返し後の数式は開き括弧の右端から始めた方がきれいにも思われる。次のようなコマンドを定義しておいても良いだろう。
\newcommand{\delimind}{\hphantom{\Biggl\lparen}}
この空白は、開き括弧と同じくらいの水平幅になっている。
以下のように折り返したあとの &
に続けて利用する。
\begin{equation}
\begin{split}
<left_hand_side>
= {} &
\Biggl(
<wrapped_equation_1> \\
& \delimind + <wrapped_equation_2>
\Biggr)
\end{split}
\end{equation}
また、xparse パッケージを利用して括弧の前にある係数などを含めてインデントさせるオプションを付与したコマンドを作成しておいても良いだろう。
\newcommand{\delimiterindent}{\hphantom{\Biggl\lparen}}
\NewDocumentCommand{\delimind}{ o }{%
\IfNoValueF{#1}{\hphantom{#1}}%
\delimiterindent%
}
たとえば、以下のような括弧の全体に係数がかかっている場合にインデントする。
\begin{equation}
\begin{split}
<left_hand_side>
= {} &
<coefficient>
\Biggl(
<wrapped_equation_1> \\
& \delimind[<coefficient>] + <wrapped_equation_2>
\Biggr)
\end{split}
\end{equation}
○ 高さが自動調整される括弧の周りの空白
\left
~ \right
で対応させた高さが自動調整される括弧を利用しているとき、括弧の左右で通常よりも大きい空白を作ってしまう。
これは以下のような例を見ると分かりやすい。
-
\sin
などの作用素の後 -
\sum
などの大型演算子の後 - 連続する高さが自動調整される括弧の間
-
,
などの前
上を見ればわかるように、mleftright パッケージを利用すると良い。
このパッケージでは、\left
~ \right
で対応させる括弧を通常の括弧と同じような空白に調節するように設計されているようだ。これを実現する \left
~ \right
の代わりの \mleft
~ \mright
が提供されている。
しかしながら、これらをすべて置き換えるのは面倒である。\mleftright
を利用することで、再定義させることも出来る。したがって、以下のようにプリアンブルに追加すれば良いだろう。
\usepackage{mleftright}
\mleftright
これで、\left
は \mleft
、\right
は \mright
としてふるまうようになる。
○ 中間区切りの手動調整と自動調整
集合論の内包的記法や Dirac の bra-ket 記法などでは (X|Y)
のような構造の数式を書くことになる。このとき、中間にある区切りの |
も高さを揃える必要がある。
Dirac の bra-ket 記法では braket や physics パッケージなどの適当なパッケージを利用すれば良い が、内包的記法のパッケージは存在しないようだ。ユーザ側で事前に定義しておくことになるだろう。
基本的な使い方を確認し、適当なコマンドを作成してみよう。
■ 基本的な使用方法
中間区切りの自動調整コマンドにも手動調整と自動調整の 2 つがある。左右の調整コマンドと合わせて表にしておこう。
括弧の高さ | 左側 | 中間 | 右側 |
---|---|---|---|
big | \bigl |
\bigm |
\bigr |
Big | \Bigl |
\Bigm |
\Bigr |
bigg | \biggl |
\biggm |
\biggr |
Bigg | \Biggl |
\Biggm |
\Biggr |
auto | \left |
\middle |
\right |
手動調整して利用する場合には、以下のように記述する。
\begin{equation}
\Biggl\lbrace
x \in X
\Biggm\vert
\frac{\sqrt{x}}{x^2+1} > 1
\Biggr\rbrace
\end{equation}
これと同じように自動調整する際に注意しておきたいのは以下の点である。
-
\middle
は必ず\left
~\right
の間に置く-
\middle
の数は複数でも良い
-
-
\mid
は高さを変更することが出来ない (\middle\mid
は不可) -
\vert
は自動調整 (\middle\vert
) すると左右の間隔が詰まりすぎる- これは改善したい
\middle\vert
によって高さを調節するには、以下のように別コマンドを定義して間隔を空けるようにしておくと良い。どうやら、二項演算子 (\mathrel
) として扱えるようにしておくと良いようだ。
\newcommand{\relmiddle}[1]{\mathrel{}\middle#1\mathrel{}}
ここでは再定義していないが、\middle
として再定義しておいても良いだろう。
\relmiddle
は次のように利用する。
\begin{equation}
\left\lbrace
y \in Y
\relmiddle\vert
\frac{\sqrt{y}}{y^2+1} > 1
\right\rbrace
\end{equation}
これを簡易的にコマンドとして定義しておくことは容易だろう。
■ コマンドを作成する
mathtools パッケージから提供される \DeclarePairedDelimiterX
と \delimsize
を利用して、以下のように定義しておいても良いだろう。(\delimsize
は \middle
と同じような役割を担っている。と言っても、内部では \middle
を使って \delimsize
を作成しているようだ)
cf. The mathtools package §3.6 Paired delimiters
\providecommand\given{}
\newcommand{\SetSymbol}[1]{%
\nonscript\:#1\vert%
\allowbreak%
\nonscript\:%
\mathopen{}%
}
\DeclarePairedDelimiterX{\Set}[1]{\lbrace}{\rbrace}{%
\renewcommand{\given}{\SetSymbol{\delimsize}}%
#1%
}
これを用いて、次のように利用することが出来る。\given
で |
が呼び出されるようになっている。
\begin{equation}
\Set*{ z \in Z \given \frac{\sqrt{z}}{z^2+1} > 1 }
\end{equation}
なお、ここで作成したような \DeclarePairedDelimiterX
で定義されたコマンドは \reDeclarePairedDelimiterInnerWrapper
を利用して再定義することが出来ない。
ここではこれ以上考えないが、これらの途中で改行を含みたい場合は何かしらの方策を考える必要がある。(そもそもどこで折り返すべきなのかが不明)
参考
- User’s Guide for the amsmath Package (Version 2.1) [PDF]
- The mathtools package [PDF]
- \left & \right (LaTeX2e unofficial reference manual (July 2021))
- \bigl & \bigr etc. (LaTeX2e unofficial reference manual (July 2021))
- \middle であり \mid であるもの - マクロツイーター
- math mode - How to get a \mid binary relation that grows - TeX - LaTeX Stack Exchange
余談
今回で実現した折り返しの前後で対応する括弧を利用することはままあると思われるが、意外にもこれに対するパッケージが提供されていなかった。だれか作っておいてよ〜のお気持ち。
また、なぜかエキスパートな例で紹介した自動調整される括弧のコマンドは誰もネット上で紹介していないようであった。もしかして、誰も mathtools のパッケージガイド読んでない?
少しだけ記事の話題から反れているが、\middle
も扱ってみている。しかしながら、これによって括弧の高さを調節する方法を網羅的に説明できているような気がする。
追記
- 2022/07/16 :「行列環境を折り返す」を追記。軽微修正。