量子回路をLaTeXで描いてみよう！(Quantikz)



$$
\def\bra#1{\mathinner{\left\langle{#1}\right|}}
\def\ket#1{\mathinner{\left|{#1}\right\rangle}}
\def\braket#1#2{\mathinner{\left\langle{#1}\middle|#2\right\rangle}}
$$
# はじめに
どうも，物理学科3年のKokiといいます．弊学物理学科学生有志による五月祭企画「Physics Lab. 2023」の量子物理学班の班長をしております．人によっては，趣味や生活に関することを語っていますが今回はだいぶ真面目寄りのトピックを書き連ねていきます．
新聞やニュースでも，たびたびトピックになる量子コンピュータ．その回路図の作成方法を紹介します．ただ，[LaTeXで量子回路を描く](https://qiita.com/squary/items/fb80583e341b9ba5fa3e) で紹介されているqcircuitではなく，**quantikz**について紹介していきます．パッケージのダウンロード先は[Quantikz CTAN](https://ctan.org/pkg/quantikz)から飛ぶことができます．

# どんな回路図が描けるか？
例としては，次のようなコードで下図が書けます！（最初だけ，documentclassなどの情報を入れてます．）
```LaTeX
\documentclass[12pt,border={25pt 5pt 5pt 5pt}]{standalone}

\usepackage[dvipdfmx]{graphicx}
\usepackage{physics}
\usepackage{quantikz}
\begin{document}

\begin{quantikz}[thin lines]
  \lstick{{$\ket{0}$}} & \gate{H} & \ctrl{1} &\gate{U} 
  & \ctrl{1} &\swap{2} & \ctrl{1} &\qw \\
  \lstick{{$\ket{0}$}} & \gate{H} & \targ{} &\octrl{-1} 
  & \control{} &\qw & \octrl{1} &\qw \\
  &&&&& \targX{} & \gate{U} & \qw
\end{quantikz}

\begin{document}

```
![qiita_ex1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004131/e3df95d0-ad82-99b0-a209-e8222f38d830.jpeg)

```LaTeX
\begin{quantikz}[row sep = 0.7em, thin lines]
  \lstick{$\ket{\psi}$} & \qw 
  & \qw & \ctrl{1} & \gate{H} 
  & \meter{} & \cwbend{2} & \\
  \lstick{$\ket{0}$} & \qw 
  & \targ{} & \targ{} & \qw 
  & \meter{} \vcw{1} & &\\
  \lstick{$\ket{0}$} & \gate{H} 
  & \ctrl{-1} & \qw & \qw 
  & \gate{X} & \gate{Z} & \rstick{$\ket{\psi}$} \qw 
\end{quantikz}
```
![qiita_ex2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004131/ff07e8ea-3fd5-f53b-e881-2c1aa7278112.jpeg)
さらに複雑な回路だと，この様な回路も書くことができます（コードは長いんで省略しました．量子回路の内容が気になる方は参考文献を見てみてください）．

![monster_cir.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004131/113a3686-f196-2033-9118-89ef00833a64.jpeg)


# 環境条件
qcircuitでは，Xy-picパッケージ，Ifpdfパッケージに依存していましたが，**quantikzパッケージのみ有れば使えるもの**となっています．
それでなおかつ，qcircuitとかなり共通点の多いパッケージとなっており，それでいて自由度の高いものとなっています！


# 実際に描いてみよう！
この節の内容はほとんど，[LaTeXで量子回路を描く](https://qiita.com/squary/items/fb80583e341b9ba5fa3e) とほとんど同じ内容を含んでおります．参考としてそちらもご覧ください[^1]．殊にテーブルを使って説明されている部分はこちらの記事に準拠した内容となっています．

[^1]:但し，QuantikzとQ-circuitでは微妙な部分で差異があるのでその点は気を付けてください．

## コードの見方
quantikzでも，行列テーブルのようにコマンド要素について行と列で区切って，量子回路を表現します．先達に倣って，解りやすくするために区切り線とコマンドを記載した量子回路図を用意しました[^6]．
![qiita_ex3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004131/0e3363ab-0766-1055-9fa4-941a5b0c5128.jpeg)

```LaTeX
\begin{quantikz}[row sep = 0.7em, thin lines]
  \lstick{$\ket{0}$} & \gate{H} & \ctrl{1} & \qw          & \qw              & \meter{} \\
  \lstick{$\ket{0}$} & \qw      & \targ{}  & \ctrl{1}     & \qw              & \meter{} \\
  \lstick{$\ket{0}$} & \qw      & \gate{Z} & \control \qw & \gate{T^\dagger} & \meter{1}
\end{quantikz}
```
quantikzにおいても，LaTeXの行列のように**列区切りには`&`，行区切りには`\\`を使います**．ここで，量子回路ダイアグラムの見易さのために，設定を`[row sep =0.7em, thin lines]`として引数として入れていますが，細かい設定については下で説明していきます．

ここで注意としては量子状態の表現で$\ket{0}$を使っていますが，これは**physicsパッケージやbraketパッケージを用いない**と使えないので，気を付けてください[^3]．

[^3]: `physics`パッケージの説明は[LaTeX で物理学徒が最低限知っておくべきこと・私が気を付けていること](https://event.phys.s.u-tokyo.ac.jp/physlab2022/posts/19/) などを参照すると良いと思います．

[^6]: `\slice`というコマンドによって，回路要素に区切ることが簡単になっているのでこの様な回路図でも非常に作りやすくなっています．

## 基本コマンド
上で使っている基本コマンドを説明していきます．これだけでも覚えれば基本的な量子回路は描くことができます．ここで数式を表す引数は`#1`を，テキストを表す引数は`#2`で書きます．単なる数字を表す場合には`#3`とします．

| コマンド | 効果 | 備考 |
| :-- | :-- | :-- |
| `\lstick{#2}` | このコマンド位置のテーブル位置の右側に`#2`を出力 | あまり拘らない場合は，`#2`で表した量子状態を配置する程度の理解で問題ないです |
| `\qw` | 何もしない量子結線(quantum wire)を出力 | `\qw`がない場合には横線が無くなります |
| `\gate{#1}` | `#1`で表される量子ゲートを出力 | `#1`は標準で数式環境ですので`$H$`等とすると怒られます[^4] |
| `\ctrl{#3}` | 制御ビットを表す黒点と`#3`個下への線を出力 | `#3`は負の値も利用できます |
| `\targ{}` | XORの意味を含む，対象ビットをXフリップさせるゲート記号の出力 | `{}`の中の引数はあまり意味をなさない．．．？ |
| `\control` | CZゲート等の対象として利用される点を出力 | このコマンドは点のみを出力するため通常は`\qw`と一緒に利用されます |
| `\meter{#2}` | 測定を表す記号を出力 | `#2`は入れなくても問題ないが，入れると記号の上に`#2`が出力される　|


# 個人的に思うQuantikzの優れた点
Q-circuitはかなり前に作られたもので，おそらく今なお業界標準のパッケージではあります．しかしながら，非常に巨大な回路図を作ることを考えた時に各行`&`の数を統一する必要があり，一つ数え間違えるとエラーが出てしまうため，体裁を整えるのに微調整が非常に面倒でした．
しかしながら，tikzの特徴上，**各行`&`の数は任意**なので微妙な位置にオブジェクトを置きたいと思った時に，簡易的にできる点で優れていると思います．
さらに，Xypicsの特徴上，量子回路向きではない記法の使い方があったところを改善したことによって，使いやすくなっているところも良いと思います．（例えば，Q-circuitの公式documentで挙げられていた良くあるエラーが構造上起こらない．）

更に以下で挙げるような詳細で挙げますが，tikzの自由度を利用してやれることが増えました．


# 詳細
ここまでの内容でバラエティに富んだ量子回路を作れるのですけど，細部を究めたい人向けに，詳細を連ねていきます．自分にとっては以下の内容が重要な本文だと思っています．

## 回路の設定
`\begin{quantikz}`の後に`[]`の中に入れる設定を紹介していきます．それなりに多い要素を含むので区分分けして紹介します．以下，ここで数式を表す引数は#1を，テキストを表す引数は#2で書きます．単なる数字を表す場合には#3とします

### テーブル間隔設定

| 引数 | 効果 | 備考　|
| :-- | :-- | :-- |
| `row sep = #3` | 行(row)間隔を`#3`に合わせる  |但し，回路オブジェクトのサイズが`#3`を上回る場合は，回路オブジェクトのサイズに合うようにしてくれる|
| `column sep = #3`[^5] | 列(column)間隔を`#3`に合わせる．  |上と同様|
| `row sep = {#3,between origins}` | 全ての列間隔をに`#3`に合わせる．  |オブジェクトが重なるのを無視して合わせる．ちなみに`#3,`と`between`の間にスペースを入れるとエラーとなる．|
| `column sep = {#3,between origins}` | 全ての行間隔をに`#3`に合わせる．  |上と同様|

### 結線，オブジェクト描画設定
| 引数 | 効果 | 備考　|
| :-- | :-- | :-- |
| `\line thins` | 結線，回路オブジェクトの枠線を細くする ||
|`\transparent`| 回路オブジェクトの配色を白から透明にする||

`\transparent`は`\linethrough`と併用することによって例に示したように擬立体的な回路を作成できる便利な機能です．

#### 適用例
この様な回路を作る場合には，元々`\qw`が入る位置に`\linethrough`を入力すると良いです．

![trans.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004131/fc758466-ee61-99a6-c70c-087d5a526de8.jpeg)


[^5]:公式ドキュメントにこれに関する一部誤植あり．`col sep = #3`とするとエラーとなる．


### 回路，文字のスケール設定
| 引数 | 効果 | 備考　|
| :-- | :-- | :-- |
| `scale=#3` | 回路全体の大きさを`#3`倍にする ||
|`width=#3\textwidth`| 回路全体の幅を`#3`倍にする||


## 量子状態の配置
基本コマンドで`\lstick{#1}`を使って$\ket{\psi}$などの，状態を最初に配置したと思いますが，この`\lstick`の意味について説明していきます．
はじめに，`\lstick{#1}`とは**L**eft **Stick** outから来ており，テーブル要素の配置位置の中心から`#1`を左(Left)方向へはみだす(Stick out)という操作を表しています．そのため，stick out方向として左，右，~~上，下~~（left, right, ~~up, down~~)を指定してあげれば，

上図のようにテーブル要素中心の各方向に好きなオブジェクトを配置することができます．（qcircuitには`\ustick,\dstick`がありましたが，quantikzにはない様です．）

`stick`に関するコマンドを以下の表にまとめました．
| コマンド | 効果 |
| :-- | :-- |
| `\lstick{#1}` | `#1`をコマンドの記入したテーブル要素の左側に配置する．  |
| `\rstick{#1}` | `#1`をコマンドの記入したテーブル要素の右側に配置する．  |



## 結線，１量子ゲート，測定器，位相因子など
| コマンド | 効果 | 備考　|
| :-- | :-- | :-- |
| `\gate{#1}` | 1量子ゲートを配置する． ||
|`\phase{#1}` | 結線とともに位相因子を表す記号を配置する． ||
|`\push{#1}`| 結線とともに数式を配置する||
|`\meter{#1}`| 測定器を配置する|`#2`に入れた文字が，測定器記号の**上部**に配置される|
|`\meterD{#2}`| D字型の測定器を配置する|`#1`に入れた数式が，測定器記号の**内部**に配置される|
|`\measuretab{#1}`| 特殊な形状の測定器を配置する|`#1`に入れた数式が，測定器記号の**内部**に配置される|
|`\metesure{#1}`| 円盤型の測定器を配置する|`#1`に入れた数式が，測定器記号の**内部**に配置される|
|`\qw`| 何も要素のない結線を配置する||
|`\vqw{#3}`| 垂直方向の結線を配置する（例は次節を参照．）|`#3`に対応する長さの結線を下方向に伸ばします|
|`\cw`| 古典的結線を配置する||
|`\vcw{#3}`| 垂直方向の結線を配置する（例は次節を参照．）|`#3`に対応する長さの結線をした方向に伸ばします|

![gates.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004131/d695d13c-0a33-dad3-220b-91224c1936f8.jpeg)
![measures.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004131/829d5eb7-0560-54a4-97fa-aacbe7c5d63e.jpeg)
![cw.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004131/fdbeb855-83a2-f8e1-f503-c1031934d218.jpeg)


## 2量子ゲート

| コマンド | 効果 | 備考　|
| :-- | :-- | :-- |
| `\ctrl{#3}` | 制御ビットを表す黒点の出力と`#3`の長さの結線を下方向に伸ばす |`\control{}`というコマンドもありますが，これは結線を伸ばすことはしません|
|`\octrl{#3}` |  制御ビットを表す白点の出力と`#3`の長さの結線を下方向に伸ばす |白点の意味は文脈依存であると思います|
|`\swap{#3}`| SWAPゲートを表す×の出力と`#3`の長さの結線を下方向に伸ばす|微妙に`\ctrl`の結線と種類が異なります|
|`\targ{}`|Xフリップを表す記号の出力 |引数を入力しても変化は現れません|
|`\targX{}`|SWAPゲートを表す×のみ出力 |`\swap{#3}`と併用するのがほとんどのケースかと思います|


![2gates.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004131/bc5b6b76-fce8-c024-6cc2-1268d3b168a1.jpeg)

## 結線，量子ゲートに関するオプション
`\gate{}`等とは，`\gate{},\meter{},\push{},\phase{}`を指します．



| コマンド | 効果 | 備考|
| :-- | :-- | :-- | 
| `\hphantom{wide}` | `\gate{}`等の後に入力することで，そのオブジェクトの幅を大きくする| `very wide`とすることもできます|
| `&[#3]` | 区切り文字`&`について，この様に入力することでオブジェクト間の長さを`#3`にする| |
| `\qwbundle{#1}` | `\gate{}`等の後に入力することで，結線の束を表す記号を出力する．  | `#1`はその記号の横に出力される|
|  `\qwbundle[akternate]` | `\gate{}`の後に入力することで，直前の結線を束状（3本線）に出力する  |　|

![wide.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004131/7341c078-6e62-dac8-6983-fe6bac19fd1c.jpeg)
 ２番目の`&[#3]`に関して大きく間隔をとった回路です．
![betww.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004131/88632277-15ef-1167-058a-9761b044fb81.jpeg)
![bundle1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004131/2778af96-5fee-ea6d-08e5-a5664adb920e.jpeg)
![bundle2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004131/38ccd501-08c5-c476-e012-b3240078cafb.jpeg)


## 多量子ビット操作関連
| コマンド | 効果 | 備考|
| :-- | :-- | :-- | 
| `\gate[wires = #3][#4]{#1}` | `#3`に対応するの数の多量子ビットゲートを出力する．`#4`を入力でゲートの長さが決まる |`wires=#3`とする代わりに`#3`だけでも問題ない|
| ` \lstick[#3]{#1}` | `#3`に対応するの数の量子ビットにかかって，左カッコ{ を出力する，  |例の入力部の$\ket{000}$のカッコに対応している|
| ` \rstick[#3]{#1}` | `#3`に対応するの数の量子ビットにかかって，左カッコ{ を出力する，  |例の出力部の$\ket{10}$のカッコに対応している|
| ` \gateinput[#3]{#1}` | `#3`に対応するの数の量子ビットにかかって，左カッコ{ を出力するとともに，ゲート入力部に`#1`を出力する．  | |
| ` \gateoutput[#3]{#1}` | `#3`に対応するの数の量子ビットにかかって，右カッコ} を出力するとともに，ゲート出力部に`#1`を出力する．  | ` \gateinput`の直後に入力するのが一番良い |
| ` \gate[#3,disable auto height]{#1}` | 上で説明した`\gate`と内容は変わらないが，この様に入力することで`#1`の出力の高さ調整を無効化する  | ゲートの自由度の高いラベル付（**縦方向や２段**）が可能となる |


#### 例1
![multi1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004131/460fbe55-2d2d-4c35-9ab4-312c75af8ceb.jpeg)
```LaTeX
\begin{quantikz}[transparent]
  \lstick[wires = 3]{$\ket{000}$} & \gate{X} \vqw{1} & \meterD{} \\
  & \gate[wires=2][1.5cm]{U} & \qw \rstick[wires = 2]{$\ket{10}$} \\
  & \qw & \qw
\end{quantikz}
```
#### 例2
![multi2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004131/b4b5ae92-5e29-b9ea-ee0e-f277948de8d6.jpeg)
```LaTeX
\begin{quantikz}[transparent]
  \lstick[wires = 3]{$\ket{\psi}$} 
  & \gate[wires=3][1.9cm]{\mathcal{O}} \gateinput[2]{$x$}
  \gateoutput[2]{$x$} 
  & \meterD{} \\
  & \qw
  & \qw \\
  & \qw \gateinput{$y$}\gateoutput{$y \oplus f(x) $} & \qw
\end{quantikz}

```
#### 例3
右側が`disable auto height`を追加したものです．

![multi3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004131/4fe3c02b-bde6-ef96-21dd-776a43bc7a72.jpeg)
```LaTeX
\begin{quantikz}[transparent]
  \lstick[wires = 3]{$\ket{\psi}$} & \gate[wires=3, disable auto height][2.5cm]{\begin{array}{c} Quantum \\ Oracle \end{array}{c} } 
  \gateinput[2]{$x$} \gateoutput[2]{$x$} 
  & \meterD{} \\
  & \qw
  & \qw \\
  & \qw \gateinput{$y$}\gateoutput{$y \oplus f(x) $} & \qw
\end{quantikz}
```


# 締め
 いかがでしたでしょうか？ここまで読んできて，quantikzの最低限の知識を身に付けられたと思いますので，皆さんも量子回路を描きたくなったことでしょう．参考文献に載っている公式ドキュメントを読むと，さらにできることが増えると思います（Gate Grouping，波線の活用，量子回路の色付け，など暇ができたら追加していこうかと思います）．
未だに量子計算機が抱える問題は数多くありますが，地道な技術発展によって10,20年前では不可能と考えられた問題でも少しずつ解消して，新しい技術が生み出されているのが現状況だと考えています．近い将来ではないですが，いつの日か量子計算機が我々の知見を深める機械として活躍してくれる日々が来るのを気長に待ちましょう．

# 参考文献

1. [Quantikz CTAN](https://ctan.org/pkg/quantikz)
1. [LaTeXで量子回路を描く](https://qiita.com/squary/items/fb80583e341b9ba5fa3e)
1. [公式ドキュメント](https://ftp.jaist.ac.jp/pub/CTAN/graphics/pgf/contrib/quantikz/quantikz.pdf)
1. [どんな回路図が描けるか？で挙げている量子回路が描かれた元論文](https://arxiv.org/abs/2210.14109)