LaTeX で増減表を書きたい

<!-- # LaTeX で増減表を書きたい -->

LaTeX による増減表の書き方はさまざまあります。LaTeX 標準では tabular 環境を利用しますが、以下のような点が面倒になります。

- 表内を数式環境に変更する
- 各列幅を等幅する
- 表のコンテンツと表のスタイルを分離する

これらの面倒さは tabularray パッケージから提供される tblr 環境を利用すれば解消されます。
そこで今回は、[tabularray][] パッケージを利用した増減表の書き方を紹介します。

[tabularray]: https://ctan.org/pkg/tabularray " tabularray- CTAN"

## 増減表のための矢印

増減表を作成する前に、増減表のための矢印を用意します。

増減表には、単調増加・単調減少を表す真っ直ぐな斜め向き矢印 2 種類と、凸の向きの表現が加わった曲がった矢印 4 種類が使われます。

真っ直ぐな斜め向き矢印は Unicode にも存在し、簡単に利用することが出来ますが、曲がった矢印のすべては Unicode に存在しません。
フォントによって矢じりの形状が違ったりするため、今回これらすべての矢印を TikZ を利用して描きました。

TikZ とそのライブラリ arrows.meta を利用して、以下のように作成しました。

```latex
\usepackage{tikz}
\usetikzlibrary{arrows.meta}
\tikzset{
  arrowStyle/.style={ -Straight Barb[], semithick },
  straightArrow/.style={ arrowStyle, scale=0.35 },
  roundedArrow/.style={ arrowStyle, scale=0.4, rounded corners=2pt },
  bentArrow/.style={ arrowStyle, scale=0.4 }
}

\newcommand{\diagonalArrowNE}{\tikz[ baseline={([yshift=-0.6ex]current bounding box.center)} ] \draw[ straightArrow ] (0,0) to (1,1);}
\newcommand{\diagonalArrowSE}{\tikz[ baseline={([yshift=-0.6ex]current bounding box.center)} ] \draw[ straightArrow ] (0,1) to (1,0);}

\newcommand{\roundedArrowRU}{\tikz[ baseline={([yshift=-0.6ex]current bounding box.center)} ] \draw[ roundedArrow ] (0,0) .. controls(1,0) .. (1,1);}
\newcommand{\roundedArrowRD}{\tikz[ baseline={([yshift=-0.6ex]current bounding box.center)} ] \draw[ roundedArrow ] (0,1) .. controls(1,1) .. (1,0);}
\newcommand{\roundedArrowDR}{\tikz[ baseline={([yshift=-0.6ex]current bounding box.center)} ] \draw[ roundedArrow ] (0,1) .. controls(0,0) .. (1,0);}
\newcommand{\roundedArrowUR}{\tikz[ baseline={([yshift=-0.6ex]current bounding box.center)} ] \draw[ roundedArrow ] (0,0) .. controls(0,1) .. (1,1);}

\newcommand{\bentArrowRU}{\tikz[ baseline={([yshift=-0.6ex]current bounding box.center)} ] \draw[ bentArrow ] (0,0) to [bend right] (1.3,0.8);}
\newcommand{\bentArrowDR}{\tikz[ baseline={([yshift=-0.6ex]current bounding box.center)} ] \draw[ bentArrow ] (0,0.8) to [bend right] (1.3,0);}
\newcommand{\bentArrowRD}{\tikz[ baseline={([yshift=-0.6ex]current bounding box.center)} ] \draw[ bentArrow ] (0,0.8) to [bend left] (1.3,0);}
\newcommand{\bentArrowUR}{\tikz[ baseline={([yshift=-0.6ex]current bounding box.center)} ] \draw[ bentArrow ] (0,0) to [bend left] (1.3,0.8);}
```

![zougen-image-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/4fc33713-58cb-b1b4-82d2-f78e01a1dbf1.png)

`NE` は **N**orth-**E**ast、`SE` は **S**outh-**E**ast の方向を意味します。
また、`R` は **R**ight、`U` は **U**p、`D` は **D**own を意味し、`RU` は右に向かってから上に向かう矢印を意味します。

命名が若干冗長的なので、適当に改名した方が良いかもしれません。

## 増減表の作成例

2 次関数の増減表は次のように作成します。

```latex
\begin{tblr}{
    width = {0.5\linewidth},
    hline{1,Z} = {0.08em},
    hline{2,Y},
    vlines,
    columns = { mode = dmath, halign = c, co = 1 },
  }
  x    & \cdots           & -2 & \cdots           & 4  & \cdots           \\
  f'   & +                & 0  & -                & 0  & +                \\
  f(x) & \diagonalArrowNE & 5  & \diagonalArrowSE & -2 & \diagonalArrowNE \\
\end{tblr}
```

![zougen-image-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/e6a6af97-8948-514e-1bcd-03dc7192c483.png)

3 次関数の増減表は次のように作成します。

```latex
\begin{tblr}{
    width = {0.7\linewidth},
    hline{1,Z} = {0.08em},
    hline{2,Y} = {0.05em},
    vlines,
    columns = { mode = dmath, halign = c, co = 1 },
  }
  x    & \cdots          & -2  & \cdots          & 1           & \cdots          & 4  & \cdots          \\
  f'   & +               & 0   & -               & -           & -               & 0  & +               \\
  f''  & -               & -   & -               & 0           & +               & +  & +               \\
  f(x) & \roundedArrowUR & 5   & \roundedArrowRD & \frac{3}{4} & \roundedArrowDR & -2 & \roundedArrowRU \\
\end{tblr}
```

![zougen-image-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/49749786-4e45-8a51-df82-2c27ebfcf4b8.png)

----------

この増減表作成の肝は `width` と `columns` です。

`width` は表全体の幅を指定しており、`columns` の `co = 1` によって、それぞれの列が `X` 指定子で指定された状態になっています。
このとき、表全体の列数は気にする必要はありません。

加えて、`columns` の `mode = dmath` によって、すべてのセルが数式環境になっています。

## 極値・変曲点

増減表内に極値や変曲点を書きたい場合、次のようなコマンドを作成して 1 つのセル内で改行できるようにします。
極小値は `\localMin`、極大値は `\localMax`、変曲点は `\inflexion` と定義しています。

```latex
\newcommand{\chartFont}{ \sffamily \scriptsize }
\newcommand{\cellStack}[2]{$\displaystyle #1$ \\ {\chartFont #2}}
\newcommand{\localMin}[1]{\cellStack{#1}{極小値}}
\newcommand{\localMax}[1]{\cellStack{#1}{極大値}}
\newcommand{\inflexion}[1]{\cellStack{#1}{変曲点}}
```

また、セル内でこれらのコマンドを利用するよりも `cell{Z}{}` の `cmd` から指定すると、表の内容と構造を分離することが出来て見通しが良くなります。
このとき、これらのセルは `text` モードを指定しておきます。

```latex
\begin{tblr}{
    width = {0.7\linewidth},
    hline{1,Z} = {0.08em},
    hline{2,Y},
    vline{2},
    columns = { mode = dmath, halign = c, co = 1 },
    %
    % 最終行の配置調整
    row{Z} = { valign = t, abovesep = 4pt, belowsep = -2pt },
    %
    % 極値や変曲点を書き込むセルを指定
    cell{Z}{3} = { mode = text, cmd = {\localMax} },
    cell{Z}{5} = { mode = text, cmd = {\inflexion} },
    cell{Z}{7} = { mode = text, cmd = {\localMin} },
  }
  x    & \cdots          & -2 & \cdots          & 1           & \cdots          & 4  & \cdots          \\
  f'   & +               & 0  & -               & -           & -               & 0  & +               \\
  f''  & -               & -  & -               & 0           & +               & +  & +               \\
  f(x) & \roundedArrowUR & 5  & \roundedArrowRD & \frac{3}{4} & \roundedArrowDR & -2 & \roundedArrowRU \\
\end{tblr}
```

![zougen-image-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/41282f5b-1da5-b7a6-d0ce-86a5abe506d5.png)

関数に区間が指定されていれば、次のように最大値・最小値に関するコマンドを作成しておいても良いでしょう。

```latex
\newcommand{\funcMax}[1]{\cellStack{#1}{最大値}}
\newcommand{\funcMin}[1]{\cellStack{#1}{最小値}}
```

## 収束・発散に対応するセル

増減表で収束・発散に対応する列の微分の行はスラッシュで消しておくことが多いです。

tabularray には diagbox ライブラリがあるので、これを利用してセルにスラッシュを引きます。このライブラリは [diagbox][] パッケージを tblr 環境で利用できるようにします。

[diagbox]: https://ctan.org/pkg/diagbox " diagbox- CTAN"

<!-- tabularray パッケージでスラッシュを引く方法は次の 2 つの方法があります。

1. `\diagbox`（diagbox ライブラリ）を利用する

    スラッシュが中途半端な感じになります。

1. TikZ を利用する (https://zrbabbler.hatenablog.com/entry/20150630/1435621044)

      綺麗な結果を得ますが、結果を見ながら調整する必要があり面倒です。

ここでは、`\diagbox` を利用してスラッシュを引く例を紹介します。
-->

----------

`\diagbox` には適当にオプションを課す必要があるので、実際に利用する際には適当なコマンドを定義しておくと簡単に扱うことが出来ます。

```latex
\usepackage{tabularray}
\UseTblrLibrary{diagbox}
\newcommand{\none}{%
  \diagbox[%
    dir = SW,%
    height = 2\line+2\abovesep+2\belowsep,%
    width = \linewidth+\leftsep+\rightsep,%
  ]{}{}%
}
```

`\none` は 2 行 1 列分のセルに斜線が入るように調整しています。このため、tblr 環境内では斜線のセルを結合しています。

```latex
\begin{tblr}{
    width = {0.7\linewidth},
    hline{1,Z} = {0.08em},
    hline{2,Y} = {0.05em},
    vlines,
    columns = { mode = dmath, halign = c, co = 1 },
    %
    % \none のあるセルを結合
    cell{2}{2,Z} = { r = 2, c = 1 }{},
  }
  x    & 0         & \cdots          & 2            & \cdots          & 3            & \cdots          & +\infty \\
  f'   & \none     & -               & 0            & +               & +            & +               & \none   \\
  f''  & \none     & +               & +            & +               & 0            & -               & \none   \\
  f(x) & (+\infty) & \roundedArrowDR & -\frac{1}{4} & \roundedArrowRU & -\frac{2}{9} & \roundedArrowUR & (-0)    \\
\end{tblr}
```

![zougen-image-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/f3cc3bc7-b896-db80-d1e3-8578e81471fe.png)

セルに何も入れずに `cell` キーに `cmd = \none` としても問題なくタイプセットされますが、`cmd` キーはセルの内容を引数とすることを前提としたキーのようなので、控えた方が良いかもしれません。

これに加えて、TikZ を利用してスラッシュを引く方法もあります。`\diagbox` で上手くスラッシュを引けなかった場合には TikZ で対応してください。（[参考][zr-slash]）
ただし、この方法は結果を見ながら調整する必要があるため少々面倒です。

[zr-slash]: https://zrbabbler.hatenablog.com/entry/20150630/1435621044 "tabular のセルに斜線を入れる話 - マクロツイーター"

# 余談

LaTeX で増減表を書くにも、tabularray パッケージを使えば簡単！

functional ライブラリを利用すれば、セルの内容を評価して矢印を自動的に判定させることも出来る気がします。
頻繁に増減表を書く人は、矢印を自動的に判定させるようにしてもおもしろいかもしれません。

と言うことで、functional ライブラリで矢印を自動判定させるコードを書いてみました。

https://qiita.com/Yarakashi_Kikohshi/items/39a95a9a8c2665dc4b69

----------

tabularray パッケージの使い方を紹介する記事ではないので詳しく紹介していませんでしたが、1 列目と 2 列目の間の縦罫線を 2 重罫線にしたい場合には、`vline{2}` を指定します。

```latex
\begin{tblr}{
  width = {0.5\linewidth},
    hline{1,Z} = {0.08em},
    hline{2,Y},
    vlines,
    % ↓ これを追加する
    vline{2} = {2}{-}{},
    columns = { mode = dmath, halign = c, co = 1 },
  }
  x    & \cdots           & -2 & \cdots           & 4  & \cdots           \\
  f'   & +                & 0  & -                & 0  & +                \\
  f(x) & \diagonalArrowNE & 5  & \diagonalArrowSE & -2 & \diagonalArrowNE \\
\end{tblr}
```

![zougen-image-7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/df7c8469-bf59-cddd-aec7-639c69bf7d1a.png)

この他、使い方の詳細に関しては以下の記事を参照してください。

https://qiita.com/Yarakashi_Kikohshi/items/b645de659cbfe8c12b36

----------

国は変わってフランスでも、日本における増減表に似た表 (tableau de variation) が作成されるらしいです。（[参考][les-tableaux]）

[les-tableaux]: https://www.mathematiques-lycee.com/2nde-02-tableau-variations.html "Les tableaux de variations - Cours de mathématique lycée - Maths pour 2nde / 1ère / Terminale - Apprendre les mathématiques"

これに付随して [tablvar][] パッケージでは、このフランス式の増減表を書くための環境やコマンドが提供されています。

[tablvar]: https://ctan.org/pkg/tablvar "CTAN: Package tablvar"

書き方がかなり異なっていて面白いですね。ただ、フランス式だと単純な表に落とし込むことは難しいので面倒そうです。

## プラスとマイナス

数式のプラス・マイナスが表内にあるとすこし貧弱に見える気がします。そのため、これも TikZ で描いても良いでしょう。

```latex
\newcommand{\tikzPlus}{\tikz[baseline={([yshift=-1ex]current bounding box.center)}] \draw[scale=0.15, semithick] (-1,0) to (1,0) (0,-1) to (0,1);}
\newcommand{\tikzMinus}{\tikz[baseline={([yshift=-1ex]current bounding box.center)}] \draw[scale=0.15, semithick] (-1,0) to (1,0);}
```

これを利用して増減表を書くと次のようになります。

```latex
\begin{tblr}{
    width = {0.7\linewidth},
    hline{1,Z} = {0.08em},
    hline{2,Y} = {0.05em},
    vlines,
    columns = { mode = dmath, halign = c, co = 1 },
  }
  x    & \cdots          & -2         & \cdots          & 1           & \cdots          & 4         & \cdots          \\
  f'   & \tikzPlus       & 0          & \tikzMinus      & \tikzMinus  & \tikzMinus      & 0         & \tikzPlus       \\
  f''  & \tikzMinus      & \tikzMinus & \tikzMinus      & 0           & \tikzPlus       & \tikzPlus & \tikzPlus       \\
  f(x) & \roundedArrowUR & 5          & \roundedArrowRD & \frac{3}{4} & \roundedArrowDR & -2        & \roundedArrowRU \\
\end{tblr}
```

![zougen-image-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590705/cc621548-4323-2c14-e6ad-5b48aa073299.png)