長い数式を手動で折り返す

# 長い数式を手動で折り返す

amsmath とmathtools を利用して長い数式を折り返す具体的な方法を考えたい．
この目的に沿った環境は以下の3通りである．

- [multline 環境](#-multline-環境)
- [multlined 環境](#-multlined-環境)
- [split 環境](#-split-環境)

まずは，これらのざっくりとした特徴を表にしておきたい．

|   環境    | 式の整列 | 説明                            |
| :-------: | :------: | :------------------------------ |
| multline  |   自動   | 折り返しに対応したequation 環境 |
| multlined |   自動   | multline 環境の非独立な数式環境 |
|   split   |   手動   | 整列しながら長い数式を折り返す  |

ただし，数式を折り返す位置(改行`\\` する位置) はどれも明示する必要がある．

以降，本記事では具体的にこれらの環境の利用方法を確認したい．

## ○ multline とmultlined 環境

比較的簡単な仕様の2つの環境．

### ■ multline 環境

整列は出来ず，基本的に数式は自動的に配置される．

```latex
\begin{multline}
  <left_hand_side>
    = <wrapped_equation_1> \\
    + <wrapped_equation_2> \\
    + <wrapped_equation_3>
\end{multline}
```

![multline](https://i.gyazo.com/86002b00cc6328b05cc37aa398d6db24.png)

1行目は左揃え，最終行は右揃え，それ以外の間の行は中央揃えになっている．

また，式番号はもっとも下の式に調整されている．これを合理的に式の垂直中央に調整する方法はないようだ．

同じ文書内でmultline 環境とsplit 環境の両方を利用する場合には，amsmath から提供されている`tbtags` オプションを利用すると良いだろう．
このオプションはsplit 環境で折り返された数式の式番号をmultline 環境と同じようにもっとも下に調整される．

### ■ multlined 環境

基本的な仕様はmultline 環境と同じ．
ただし，`<width>` オプションで数式の幅を指定することも出来る．

```latex
\begin{<ind_math_env>}
    \begin{multlined}[<vertical_position>][<width>]
      <wrapped_equation_1> \\
      <wrapped_equation_2> \\
      <wrapped_equation_3>
    \end{multlined}
\end{<ind_math_env>}
```

垂直位置の調整オプションは以下の通りになっている．

| `<vertical_position>`  | 説明          |
| :--------------------: | :------------ |
| `[c]` <br>(デフォルト) | 中央 (center) |
|         `[t]`          | 上部 (top)    |
|         `[b]`          | 下部 (bottom) |

multlined 環境はsplit 環境のように式を`&` で整列させながら数式を折り返すことにはあまり向かないと思われる．
これは，`<vertical_position>` オプションが式番号まで影響してしまうためである．

> e.g. あまりmultlined 環境が向かない例

split 環境のように使ってみる．

```latex
\begin{align}
  <left_hand_side>
    &
    \begin{multlined}[t][7cm]
      = <wrapped_equation_1> \\
      + <wrapped_equation_2> \\
      + <wrapped_equation_3> \\
      + <wrapped_equation_4>
    \end{multlined}
    \\
  % <left_hand_side>
    & =
    <right_hand_side>
\end{align}
```

式番号`(1)` が上に上がっている．split 環境であれば式番号はデフォルトで中央になる．

![multlined fail](https://i.gyazo.com/3c5011497861b281a3c9fe909ab0ea4c.png)

`<position>` を`[c]` にすると式番号は期待する位置に配置されるが，`<left_hand_side>` も垂直中央になってしまう．
これを上手く解消させる方法はあるにはあるが，非常に煩雑であり，上のようなsplit 環境に似た使い方を積極的にmultlined 環境でする理由にはならないと思われる．

### ■ 位置調整

multline(d) 環境で使用可能な右寄せ，左寄せのコマンドがある．

|           コマンド            | 説明   |
| :---------------------------: | :----- |
| `\shoveleft[arg]{<formula>}`  | 左寄せ |
| `\shoveright[arg]{<formula>}` | 右寄せ |

`[arg]` によるオプションはmultlined 環境のみで利用できるようだ．

> e.g. Sample

```latex
\begin{equation}
  \begin{multlined}[c][12cm]
    <First line> \\
    <Second line> \\
    \shoveleft{<shoveleft>} \\
    \shoveleft[1cm]{<shoveleft> \\
    \shoveright[1cm]{<shoveright>} \\
    \shoveright{<shoveright>} \\
    <Second to last line> \\
    <Last line>
  \end{multlined}
\end{equation}
```

![shove left and right](https://i.gyazo.com/0bcb1861840094753f84004af5c179f6.png)

## ○ split 環境

アンパサンド`&` で整列を取りながら長い数式を折り返したい場合に利用される．

split 環境では以下のようなことが要請されるだろう．

- 関係演算子と折り返した後の数式は頭を揃えずに右にずらす (インデント)
  - 折り返す区切りは`+` などの二項演算子の前で行うことが一般的
- 外部に整列のための`&` がある場合，これと揃える

これを実現するためには，2つの方策がある．

- [\# 非明示的にインデントする](#-非明示的にインデントする)
  - 整列位置を`=` などの関係演算子の右側で行う
  - インデントの大きさを調整できない
- [\# 明示的にインデントする](#-明示的にインデントする)
  - 折り返された数式を空白コマンドで右にずらす
  - インデントの大きさを調整できる

非明示的にインデントする方法をよく見る印象がある．が，好みで選択して良いだろう．

また，アンパサンドによる整列が実行できる環境内での使用と，整列が実行できない環境内での使用では少しだけ勝手が異なる．
まずはこれを確認しておきたい．

### ■ 環境ごとの注意点

環境ごとに注意する点がいくつかある．これらを明らかにしておきたい．

もちろん，これらの注意点を無視することも出来るが，多くの場合ではこれらを無視すると期待した式表示にならないと思われる．

#### ▶ アンパサンドを使用できない環境 + split 環境

アンパサンドが使用できない環境は以下の2つである．
ここで，multline 環境内でsplit 環境は利用できないことに注意しておきたい．

- equation
- gather

このような環境内でsplit 環境を利用する場合は，次のようなことに気を付ける必要がある．

- split 環境の内外で右辺と左辺を分けない
  - split 環境外に数式を書かない

#### ▶ アンパサンドを使用できる環境 + split 環境

アンパサンドが使用できる環境は以下の3つである．

- align
- alignat
- flalign

このような環境内でsplit 環境を利用する場合は，次のようなことに気を付ける必要がある．

- split 環境内では各行に`&` を1回のみしか利用できない
  - `\text` などを挿入したい場合にはsplit 環境外で行う
- split 環境内では基本的に1行の数式のみ
  - 折り返された数式が複数行ある場合はsplit 環境を分ける
- split 環境の内外で右辺と左辺を分けない
  - 数式1行目にsplit 環境を利用する場合には注意が必要
- 折り返された数式のあとに改行する場合は，split 環境のあとに改行`\\` を忘れないようにする

#### ▶ 推奨されない例

split 環境は1つの長い式を折り返すことに向いている．
そのため，split 環境内で複数の式を配置することは向いていない．したがって，次のような例は向いていないと言える．

```latex
\begin{equation}
  \begin{split}
    <Eq1_left_hand_side>
      & = <Eq1_right_hand_side> \\
    <Eq2_left_hand_side>
      & = <Eq2_right_hand_side>
  \end{split}
\end{equation}
```

このような例では次のようにaligned(at) 環境に置き換えると良いと思われる．

```latex
\begin{equation}
  \begin{aligned}
    <Eq1_left_hand_side>
      & = <Eq1_right_hand_side> \\
      % && \text{Description of equation 1}
    <Eq2_left_hand_side>
      & = <Eq2_right_hand_side>
      % && \text{Description of equation 2}
  \end{aligned}
\end{equation}
```

実はこの例では出力の見た目上，大きく異なる点はない．
しかし，以下の表に示すような違いがある．これを思うと積極的にsplit 環境を上のように利用する理由にはならないと思われる．

|                   特徴                   |                        split 環境                        |                    aligned(at) 環境                     |
| :--------------------------------------: | :------------------------------------------------------: | :-----------------------------------------------------: |
|              1行の`&` の数               |                         1つのみ                          |                        制限なし                         |
|              `&` による影響              |                      環境外にも影響                      |                     環境内で留まる                      |
| 環境全体を <br>`\left` \~`\right` で囲む |                           不可                           |                          可能                           |
|                  式番号                  |                           1つ                            |                           1つ                           |
|               式番号の位置               | デフォルトでは垂直中央 <br>`tbtags` 有効で右下または左上 | `<vertical_position>` に依存 <br>デフォルトでは垂直中央 |

あくまでsplit 環境では1つの式を折り返すことのみに利用する方が良い．

### ■ 非明示的にインデントする

非明示的に折り返された数式をインデントする方法を見る．
次のようにすることでインデントされる．しかしながら，明示的ではない．

- 関係演算子のあとに整列させる
  - 関係演算子ある行の整列は`= {} &` とする
  - 折り返された数式のある行は`&` から開始することで右にずれる

`= &` の間に`{}` がない場合，関係演算子の周囲の空白が適切に作られないので気を付けておく必要がある．

equaiton 環境と組み合わせる場合の具体例．

> e.g. equation 環境内でsplit 環境を利用する

```latex
\begin{equation}
  \begin{split}
    <left_hand_side>
      = {} & <wrapped_equation_1> \\
           & + <wrapped_equation_2> \\
           & + <wrapped_equation_3>
  \end{split}
\end{equation}
```

![equation+split](https://i.gyazo.com/30e8d42c4c93474c9a33a75309ab8177.png)

align 環境と組み合わせる場合の具体例3つ．

> e.g.1 数式1行目にsplit 環境を必要とする場合

```latex
\begin{align}
  \begin{split}
    <left_hand_side>
      = {} & <wrapped_equation_1> \\
           & + <wrapped_equation_2> \\
           & + <wrapped_equation_3>
  \end{split}
    \\
  % <left_hand_side>
    = {} & <right_hand_side>
\end{align}
```

![align+split+first](https://i.gyazo.com/8938cea93ce6fd1e1d214600d21a2518.png)

> e.g.2 数式2行目以降にsplit 環境を必要とする場合

```latex
\begin{align}
  <left_hand_side>
    = {} & <right_hand_side> \\
    \begin{split}
      % <left_hand_side>
        = {} & <wrapped_equation_1> \\
             & + <wrapped_equation_2> \\
             & + <wrapped_equation_3>
    \end{split}
    \\
  % <left_hand_side>
    = {} & <right_hand_side>
\end{align}
```

![align+split](https://i.gyazo.com/9c23ecffa6a52c1403b069197889b448.png)

> e.g.3 複数回split 環境を必要とする場合

```latex
\begin{align}
  <left_hand_side>
    = {} & <right_hand_side> \\
    \begin{split}
      % <left_hand_side>
        = {} & <wrapped_equation_1-1> \\
             & + <wrapped_equation_1-2> \\
             & + <wrapped_equation_1-3>
    \end{split}
    \\
    \begin{split}
      % <left_hand_side>
        = {} & <wrapped_equation_2-1> \\
             & + <wrapped_equation_2-2> \\
             & + <wrapped_equation_2-3>
    \end{split}
\end{align}
```

![align+split+split](https://i.gyazo.com/d3525e26692b1a7cc9735ffe13c04cbc.png)

### ■ 明示的にインデントする

前述のように`= {} &` とせずに，折り返された数式と`&` の間に空白コマンドを挿入して関係演算子のレベルからずらすことも出来る．

`\quad` 一つ分でも十分だが，もう少しだけレベルをずらしたいようにも感じる．
新たに空白のコマンドを作成しておいて，これを利用してインデントを行うことにしたい．

```latex
\newcommand{\spind}{\phantom{{}={}}}
```

上で紹介した2つの例を元に書き変えてみると，以下のようになる．
もちろん，`\quad` で十分な場合には，`\phantom{}={}` を`\quad` に置き換えれば良い．

> e.g.1 equation 環境内でsplit 環境を利用する

```latex
\begin{equation}
  \begin{split}
    <left_hand_side>
      & = <wrapped_equation_1> \\
      & \spind + <wrapped_equation_2> \\
      & \spind + <wrapped_equation_3>
  \end{split}
\end{equation}
```

![equation+split](https://i.gyazo.com/30e8d42c4c93474c9a33a75309ab8177.png)

> e.g.2 数式2行目以降にsplit 環境を必要とする場合

```latex
\begin{align}
  <left_hand_side>
    & = <right_hand_side> \\
    \begin{split}
      % <left_hand_side>
        & = <wrapped_equation_1> \\
        & \spind + <wrapped_equation_2> \\
        & \spind + <wrapped_equation_3>
    \end{split}
    \\
    & = <right_hand_side>
\end{align}
```

![align+split](https://i.gyazo.com/9c23ecffa6a52c1403b069197889b448.png)

align 環境などのsplit 環境外部との整列を利用する場合には，このようにする方が平易なようにも思われる．

#### ▶ インデントの数を増やす

繰り返して空白コマンドを続ければインデントの数を増やすことは容易である．しかしながら，何度も同じコマンドを打つのは面倒である．
たとえば，xparse パッケージを利用して以下のようなコマンドを作成すれば，各インデント幅を変更することが出来る．

```latex
\usepackage{xparse}
\newcommand{\splitindent}{\phantom{{}={}}}
\newcounter{CSplitIndent}
\NewDocumentCommand{\spind}{ O{1} }{
  \setcounter{CSplitIndent}{0}
  \whiledo{\value{CSplitIndent}<#1}{
    \splitindent
    \addtocounter{CSplitIndent}{1}
  }
}
```

ここで作成したコマンドの使い方は`\spind[arg]` とすれば良いだけ．
引数の数だけインデントを繰り返すようになっている．引数なしでは`[1]` と同じ．

> e.g.3 折り返すごとにインデントを増やす

```latex
\begin{align}
  <left_hand_side>
    & = <right_hand_side_1> \\
    \begin{split}
      % <left_hand_side>
        & = <wrapped_equation_2-1> \\
        & \spind + <wrapped_equation_2-2> \\
        & \spind[2] + <wrapped_equation_2-3> \\
        & \spind[3] + <wrapped_equation_2-4>
    \end{split}
    \\
  % <left_hand_side>
    & = <right_hand_side_3>
\end{align}
```

![split indent](https://i.gyazo.com/c0585a52b75df517a097bc65133816a1.png)

式を折り返すたびにインデントを増やしていく場合，式が右に飛び出ないように気を付ける必要がある．

### ■ 自動的に折り返す

split 環境では折り返す位置を手動で決める必要がある．
適当に決めれば良いのだが，これを自動化させることも出来る．

autobreak パッケージを利用しよう．

> cf. [autobreak を使いこなす \- Qiita](https://qiita.com/Yarakashi_Kikohshi/items/098621ab4b4d4f5ce8cc)

## ○ 折り返し前後で高さが自動調整される括弧を利用する

split 環境において，折り返しの前後で`\left` \~`\right` で対応する高さが自動調整される括弧を利用する場合，少々面倒なことが生じる．
これをうまく解決させよう．

> *cf.* [数式の折り返し前後で高さが自動調整される括弧を利用する - Qiita](https://qiita.com/Yarakashi_Kikohshi/private/3be42ed1985892e03c95)

## ● 折り返された数式にそれぞれ式番号を付与する

折り返された数式のそれぞれの行に式番号を付けたいときもあるだろう．このような場合には`(1)`, `(2)` などと続けずにサブ番号を付与して`(1a)`, `(1b)` などとする方が良いだろう．

したがって，次のような式番号の付与の仕方をしてみたい．

> ![subeqn sample](https://i.gyazo.com/bcc73b4724121f5124c38e0779625a53.png)
> 親番号の`(1)` と子番号の`(1a)` の両方を相互参照できる．

一般的に，サブ番号を付与する方法としてsubequations 環境がある．
基本的なsubequations 環境については以下の記事を参照してほしい．任意の数式環境をsubequations 環境で囲うだけである．

> cf. [連立方程式をきれいに書く - Qiita](https://qiita.com/Yarakashi_Kikohshi/items/dc8f983d24698119bf71)

しかし，折り返された数式ではalign 環境内で複数行の数式の中に折り返された数式が含まれる場合があり，subequations 環境を数式環境内で使用することは出来ないため利用することが出来ない．

そこで，subequations 環境を利用せずに，プリアンブルで以下のようなコマンドを仕込むことでサブ番号を含めることが出来るようにしよう．
単純に`\tag` で式番号を変更しているだけである．

> cf. [Mixed (sub)equation numbering within an array - TeX - LaTeX Stack Exchange]((https://tex.stackexchange.com/questions/34566/mixed-subequation-numbering-within-an-array))

上記事から少し改変している．(上記事では親番号を相互参照出来ない)

```latex
% https://tex.stackexchange.com/questions/34566/mixed-subequation-numbering-within-an-array
\usepackage{xparse}
\newcounter{subeqn}
\renewcommand{\thesubeqn}{\theequation\alph{subeqn}}
\newcommand{\subeqn}{%
  \refstepcounter{subeqn}%
  \tag{\thesubeqn}%
}
\NewDocumentCommand{\beginsubeqn}{ o }{%
  \refstepcounter{equation}%
  \IfNoValueF{#1}{\setcounter{subeqn#1label}{\value{equation}}}%
  \setcounter{subeqn}{0}%
  \subeqn%
}
\newcommand{\parentEqLabel}[1]{\newcounter{subeqn#1label}}
\newcommand{\parentEqRef}[1]{(\textup{\arabic{subeqn#1label}})}
```

4つのコマンドを提供している．

|           コマンド           | 説明                                                                           |
| :--------------------------: | :----------------------------------------------------------------------------- |
|  `\beginsubeqn[label_name]`  | サブ番号の付与を開始する式番号に付ける <br>`[label_name]` は親の式番号のラベル |
|          `\subeqn`           | サブ番号を付与する式番号に付ける                                               |
| `\parentEqLabel{label_name}` | 親の式番号を参照したいときに利用 <br>上のコマンドを使用する環境より前で使用    |
|  `\parentEqRef{label_name}`  | 親の式番号を相互参照する                                                       |

親番号の相互参照には2つのコマンドで同じラベル名を表す必要があり，少々面倒になっている．
親番号を相互参照しない場合は`\parentEqLabel` と`\beginsubeqn` のオプションは不要．

なお，子番号は直接`\eqref` などで相互参照することが出来る．

> e.g. 折り返された数式にそれぞれ式番号を付与する

```latex
\parentEqLabel{parent}
\begin{align}
  <left_hand_side>
    & = <right_hand_side> \\
  % <left_hand_side>
    & = <wrapped_equation_1-1> \beginsubeqn[parent] \label{subeq1} \\
    & \spind + <wrapped_equation_1-2> \subequ \label{subeq2} \\
    & \spind[2] + <wrapped_equation_1-3> \subequ \label{subeq3}
    \\
  % <left_hand_side>
    & = <right_hand_side>
    \\
    \begin{split}
      % <left_hand_side>
        & = <wrapped_equation_2-1> \\
        & \spind + <wrapped_equation_2-2> \\
        & \spind[2] + <wrapped_equation_2-3>
     \end{split}
\end{align}
```

![subeqn](https://i.gyazo.com/df3245c47e010c541fb1489e9aacf58e.png)

上のようにした場合，`\parentEqRef{parent}` で折り返された数式の親番号`(2)` を取得し，`\eqref{subeq1}` などではサブ番号付きの`(2a)` を取得することが出来る．
もちろん，サブ番号のスタイルを変更したい場合は`\renewcommand{\thesubeqn}{...` を好きなように変更すれば良いだろう．

このような記述がいつ使われるのか分からないが，数学的な解説などで，折り返された数式の「式(hoge)の1行目」などとするよりかはまだ分かりやすいのかもしれない．

# 参考

- パッケージガイド
  - [User’s Guide for the amsmath Package (Version 2.1)](http://texdoc.net/texmf-dist/doc/latex-dev/amsmath/amsldoc.pdf) [pdf]
  - [amsmathパッケージユーザガイド ( Version 2.1 )](https://www.latex-project.org/help/documentation/amsldoc_jpn.pdf) [pdf]
  - [The mathtools package](https://ftp.kddilabs.jp/CTAN/macros/latex/contrib/mathtools/mathtools.pdf) [pdf]
- [Mixed (sub)equation numbering within an array - TeX - LaTeX Stack Exchange]((https://tex.stackexchange.com/questions/34566/mixed-subequation-numbering-within-an-array))
- [LaTeX の数式モードをまとめたよ - Qiita](https://qiita.com/Yarakashi_Kikohshi/items/ef693d7abb195c55af7a)


# 余談

split 環境の記法はたまに忘れてしまう．このようにまとめておけば見直しに使えるだろう．
書けば書くほど要請してくることが多いように感じる．とにかく慣れれば良いだけだろう．

multline(d) 環境についてはおまけ程度に書き記したつもり．

最後の節で紹介したサブ番号を付与するコマンドはstackoverflow から引用した．
この質問の回答では親番号の取得をしていなかったので，これを可能になるように仕込んでみたが，`\newcounter` が数式環境内で定義できないために少々面倒な設計となってしまった．

本当は，サブ番号を付与する非独立な数式環境を作成すれば良いのかもしれない．
subeqned 環境(仮称) が作れる方がいれば．

# 追記

- 2021/10/20 : 「[折り返し前後で高さが自動調整される括弧を利用する](#-折り返し前後で高さが自動調整される括弧を利用する)」を追加しました．