【LaTeX】自由に添字が変えられる白抜きの0と1を零行列・単位行列の記号として使う！〜bbm.sty, xparse.sty〜

# 0. はじめに


## 0.1 実行環境

Macbook Pro 2018, macOS Catalina 10.15.4
Visual Studio Code, Version: 1.55.0
LaTeX Workshop 8.16.1

`\documentclass[uplatex,fleqn]{jsarticle}`

## 0.2 目標

LaTeX マクロ，零行列 \zero (\zero[ ][ ]), 単位行列 \eins (\eins[ ][ ])を作ることを目指します．記号は白抜き文字（黒板太字）で，添字の有無を自由にするまでが目標です．

# 1. \mathbb

## 1.1 amsfonts

<font color="Red">`\mathbb{1}, \mathbb{0}`は用意されていません．</font> 

<font color="DeepSkyBlue">`\mathbb{N}, \mathbb{C}`はきれいです．据え置きで使いましょう．
</font>

## 1.2 bbold

bbold パッケージには`\mathbb{1}, \mathbb{0}` が用意されています．1 の見た目がそれほど良くありません．0 の見た目もそんなに良くはないです．そしてまずいことに，usepackage が他の黒板太字記号全てに影響を及ぼします (Fig. 1)．影響が部分的になるような pseudocode も書こうとはしましたが，どれもうまくいきませんでした．

<img width= 20%  alt="スクリーンショット 2021-04-08 1.43.51.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844184/0d529d4a-c900-bfff-ba73-0cc750ad701e.jpeg">
Fig. 1 bbold font の 0 と 1. 

`\usepackage{amsfonts}` (個人的には`\usepackage{amsmath,amssymb,amsthm}`を使用)と`\usepackage{bbold}`の順序を入れ替えてもこの状況は改善しません．

見た目の問題で，$\mathbb{N}, \mathbb{C}$ などは使いたくありません．どうすればよいでしょうか．


# 2. 準備

## 2.1 \mathbbm


```latex
\usepackage{bbm}
```

で使えます．

`\mathbbm{1}, \mathbbm{2}` が用意されています．しかし，<font color="Red">`\mathbbm{0}`は用意されていません．</font> 

<font color="DeepSkyBlue">`\mathbbm{1}`はきれいなのでそのまま使います．</font>

1 については，bbold font を使わなくてよいですが，まだ 0 が残っています．




## 2.2 xparse

使い方についてはCTANと参考記事 [xparse パッケージでスゴイ LaTeX マクロを作ろう！ - Qiita](https://qiita.com/zr_tex8r/items/50168ad7087516c3e139#パッケージの読込) を参照してください．xparse.sty は

```latex
\usepackage{xparse}
```
（または個人的には，それを含んでいると思われる

```latex
\usepackage{xpatch}
```

を利用．詳しくお知りになりたい方は [CTAN: Package xpatch](https://ctan.org/pkg/xpatch?lang=en) ）で利用できます．

`\NewDocumentCommand` というものを使いますが，ここでは，オプション変数や条件分岐などが使える， `\newcommand`を拡張したものと思ってください．行列の記号に添字をつけたりつけなかったりするのを可能にするために使います．



# 3 作成

## 3.1 "\mathbbm{0}" を作る

どうやら`\mathbbm{0}` については用意してくれているパッケージがないようです．そこで，`\mathbbm{0}` を`\mathbbm{1}`と同じように自作しようと思いソースコードを見てみました．

```java:blbordsp.mf
cmchar "The numeral 1";
beginchar("1",9u#,fig_height#,0);
italcorr fig_height#*slant-.5u#;
adjust_fit(0,0);
numeric light_stem; light_stem=hround .4[stem',cap_stem'];
pickup tiny.nib; pen_duplicate(1,2);
pos1(.5light_stem,0); pos2(.5light_stem,0);
lft x.G1l=lft x.G2l=hround(.5(w+.5u)-.5cap_stem'-.5interspace); top y1=h+o; bot y2=0;
Delta_x = hround(interspace+.5light_stem);
double filldraw stroke z1e--z2e;  % double stem
if not serifs: save slab; slab=bar; fi
dish_biserif(2,1,a,1/3,min(2.25u,lft x2l-1.5u),
  ab,1/3,
  b,1/3,min(2.25u,w-1.25u-rt x2r)); % serif
pickup crisp.nib; pos3(slab,-90); pos4(bar,-90);
top y3l=h+o; top y4l=if monospace: .8 else: .9 fi\\ h+o;
lft x4=max(1.25u,tiny.lft x.G1l-2.35u);
tiny.rt x.D1r=lft x3+.25[tiny,hair];
erase fill z3l{x4l-x3l,3(y4l-y3l)}...z4l{left}
 --(x4l,h+o+1)--(x3l,h+o+1)--cycle; % erase excess at top
filldraw stroke z3e{x4e-x3e,3(y4e-y3e)}..z4e{left};  % point
penlabels(G1,D1,G2,D2,3,4); endchar;
```

一瞬で挫折しました．というわけで発想の転換をしました．自分でゼロから作るのはやめて（0だけに），普段紛らわしいとされて敬遠されている`0`と`o`ですが，似ている文字ということで，`o`をゼロの作成に利用することにしました．ここで，`o`は小文字のオーです．

数式環境を前提に，手で調節しながら書いた` "\mathbbm{0}"` が以下です（これを実践で使うわけではないので名前は適当です．）．

```latex
\newcommand{\aaaa}{\scalebox{0.8}[1.5]{\kern .1mm$\mathbbm{o}$}}
```

## 3.2 零行列 \zero, 単位行列 \eins

ここまで来たら<font color="DeepSkyBlue">使いやすいように If 文で組み上げて完成</font>です．

```latex
\NewDocumentCommand\zero{o o}{
    \scalebox{0.8}[1.5]{\kern .1mm$\mathbbm{o}$}%
    \IfValueT{#1}{%
        \IfNoValueT{#2}{_{#1}}
        \IfValueT{#2}{_{#1\times#2}}
    }%must use [] for option args
}
\NewDocumentCommand\eins{o o}{
    \mathbbm{1}%
    \IfValueT{#1}{%
        \IfNoValueT{#2}{_{#1}}
        \IfValueT{#2}{_{#1\times#2}}
    }%must use [] for option args
}
```
<font color="DeepSkyBlue">eins とはドイツ語で 1 という意味です．</font>単位行列のことは <font color="DeepSkyBlue">Einheitsmatrix</font> といいます．

`\ein`でも良いのですが，もう`\newcommand{\ein}[1]{\mathbbm{1}_{#1}}`としてしまっていたので今回は`\eins`としました．`\ein` の方は，行列のサイズを示してなるべく誤解のないようにすることを意図したコマンドです．
今回はそれを改良した格好です．

ゼロ行列のことは<font color="DeepSkyBlue"> Nullmatrix </font> といいますが，`\null`コマンドはすでに存在している上にゼロ行列に $N$ の文字を当てることはないので，英語の`\zero` でよいでしょう．

`{o o}`は既定値 (default values) のない，オプション変数が2つあるという意味で，`\IfValueT{arg}{code}`は引数`arg`が存在する時，`code`を実行し，存在しない場合何もしない，という意味です．
<font color="DeepSkyBlue">これで，添字を自由に省略したり，追加したりできるようになりました．</font>

特性上オプション引数の括弧は { } でなく [ ] を用います．何もしないと，自動補完のときに { }{ } で補完されてしまいますので，後で VSCode の機能を使ってスニペットを作成しましょう．

## 3.3 使用例！

なかなか便利なコマンドができました．一般化や応用も効くと思いますので，ぜひ試してみてください．

具体的に使ってみましょう．

```latex:test.tex
\documentclass[uplatex,fleqn]{jsarticle}
\usepackage{bbm}
%\usepackage{amsmath,amssymb,amsthm}
\usepackage{amsfonts}
\usepackage{color}
\usepackage[dvipdfmx]{graphicx}
\usepackage{xparse}

\pagecolor{black}
\color{white}
\begin{document}
\NewDocumentCommand\zero{o o}{
    \scalebox{0.8}[1.5]{\kern .1mm$\mathbbm{o}$}%
    \IfValueT{#1}{%
        \IfNoValueT{#2}{_{#1}}
        \IfValueT{#2}{_{#1\times#2}}
    }%must use [] for option args
}
\NewDocumentCommand\eins{o o}{
    \mathbbm{1}%
    \IfValueT{#1}{%
        \IfNoValueT{#2}{_{#1}}
        \IfValueT{#2}{_{#1\times#2}}
    }%must use [] for option args
}
\newcommand{\N}{\mathbb{N}}
\newcommand{\Z}{\mathbb{Z}}
\newcommand{\R}{\mathbb{R}}
\newcommand{\C}{\mathbb{C}}
\newcommand{\by}{\times}
\(\exists M\in\R^{m\by m}\setminus\{\zero\},\,\exists n\in\N ,\, M^n=\zero[m][m].\)

\(\forall n\in\Z_{>0},\,\exists U\in\C^{n \by n},\, U^\dagger U = UU^\dagger = \eins[n].\)

\end{document}
```

`\newcommand{\N}{\mathbb{N}}`などはインターネットでも多くの場面で紹介されている標準的な置き方です．
`\newcommand{\by}{\times}`は行列の読み方に合わせるとともにコマンドをやや短くしたものです．

出力結果がこちらです．この数式自体にあまり深い意味はありません．
また，`[fleqn]`がたしてあるのは自分が普段使うオプションだからというだけです．今回は出力には影響しません．

<img width= 75%  alt="スクリーンショット 2021-04-07 21.58.40.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844184/7ebc9858-3391-1cec-c65c-8afec3c9e787.jpeg">


0 の左側の囲まれた部分が若干広いので，改良の余地はありますが，<font color="DeepSkyBlue">見た目の美しさ，コードの美しさ共に納得の行く出力になりました．</font>



#まとめ

<font color="DeepSkyBlue">LaTeX で行列に白抜き文字の 0 と 1 を使うことができるようになりました．</font>`0` の作成には`o`を借用しましたが，ひとまずはこれで十分でしょう．


また，添字の自由性も大幅に向上してコード（pseudocode）が書きやすくなりました．こちらについては https://webdemo.myscript.com の手書き変換を利用するのも手だとは思いますが，まだ白抜き文字の 0 や 1 には対応していないのが実情だと思います．`\mathbb{N}`や`\mathbb{C}`には対応していますので，技術の進歩が待たれるところです．

<font color="DeepSkyBlue">`\usepackage{bbm}` と`\usepackage{xparse}`で LaTeX ライフを豊かなものにしましょう．
</font>

# 補足

## 表記

ゼロ行列や単位行列の notation は一般に定まったものではありません．大きさは適当に取ると，ざっと以下のようなものがあります[^1] [^2]．今は $\mathbb{0},\mathbb{1}$ には仮に`\mathbb{0}, \mathbb{1}`を用いています．

<dl>
  <dt>ゼロ行列</dt>
  <dd>$O_n,\, O_{n,n},\,O_{n\times n},\,O_{m,n},\,O_{m\times n},\,O.$ 文字を $0$ に変えたもの．文字を $\mathbb{0}$ に変えたもの．</dd>
  <dt>単位行列</dt>
  <dd>$I_{n},\, I_{n,n},\, I_{n\times n},\,I.$ 文字を $E$ に変えたもの．文字を $1$ に変えたもの．文字を $\mathbb{1}$ に変えたもの．</dd>
</dl>

[^1]: 物理学ではエネルギーと混同しやすいので $E$ を用いた表記はほとんど用いられません．
[^2]: $0_{n},\,\mathbb{0}_{n}$ はゼロベクトルを表す場合もあります．

白抜き文字を使うのは，活字よりも手書きの場合の方が多いと思われます．個人的には，混同の危険もなくなりますし，加法及び乗法の単位元であることがはっきり分かってよいと思います．

## VSCode 用スニペット

VSCode をお使いの場合は，Code -> Preferences -> User snippets -> latex.json に以下を加えておくと便利です．

```json:latex.json
	"zero matrix": {
		"prefix": ["\\zero", "zero"],
		"body": [
			"\\zero[${1}][${2}]"
			//"\\zero[][]"
			//"\\zero[${1}]"
			//"\\zero"
		],
		"description": "zero matrix"
		},
	"identity matrix": {
		"prefix": ["\\eins", "eins"],
		"body": [
			"\\eins[${1}]"
			//"\\eins[${1}][${2}]" 
			//"\\eins[][]"
			//"\\eins"
		],
		"description": "identity matrix"
	},
```

添字がデフォルトでリーズナブルな数になるように設定してあります．
省略してよい文脈なら，添字の補完をデフォルトでなしにすることもあるかもしれません．

# 参考記事


- [x] CTAN: Package bbm
https://ctan.org/pkg/bbm

- [x] CTAN: Package xparse
https://ctan.org/pkg/xparse?lang=en

math mode - How do you get \mathbb{1} to work (characteristic function of a set)? - TeX - LaTeX Stack Exchange
https://tex.stackexchange.com/questions/26637/how-do-you-get-mathbb1-to-work-characteristic-function-of-a-set

math mode - \mathds{0} and \mathbbm{0} not working - TeX - LaTeX Stack Exchange
https://tex.stackexchange.com/questions/250975/mathds0-and-mathbbm0-not-working

xparse パッケージでスゴイ LaTeX マクロを作ろう！ - Qiita
https://qiita.com/zr_tex8r/items/50168ad7087516c3e139#パッケージの読込

CTAN: Package xpatch
https://ctan.org/pkg/xpatch?lang=en

黒板太字 - Wikipedia
https://ja.wikipedia.org/wiki/黒板太字

Blackboard bold - Wikipedia
https://en.wikipedia.org/wiki/Blackboard_bold

\NewDocumentCommand versus \newcommand versus ...
https://www.texdev.net/2020/08/20/newdocumentcommand-versus-newcommand-versus

Visual Studio Code/LaTeX - TeX Wiki
https://texwiki.texjp.org/?Visual%20Studio%20Code%2FLaTeX