Quantum Computing in Python: Introductionを自分の言葉でまとめてみた

#この記事を書こうと思ったきっかけ
先日，以下のLT大会にて量子コンピュータのお話をしました．
https://fun.connpass.com/event/127784/

https://drive.google.com/file/d/1aD_ClqlCud5oKNgCpMrnQiN5AAnVhlWL/view

IBM Q Experienceを使うのではなく，自分でプログラミングが出来ないか色々と資料を探しました．
・Quantum Computing in Python: Introduction
http://dkopczyk.quantee.co.uk/quantum-computing-in-python-introduction/
という文献を見つけたので，自分の言葉でまとめてみました．
自分のためのまとめ的な感じですが，何か1つでも多くの人に有益なことが書ければと思います．

今回だけでは全部書けなかったので，複数回に分けてまとめる予定です．


#前提知識
・線形代数(特に抽象的な線形空間の議論)
・量子力学(特にj.j.sakurai上巻に書いてあるような内容)
はある程度前提とします．
~~この記事に目をつけたということは、多少の知識はあるのではと思います．~~

#用いた環境
・windows 10
・Python3
・jupyter notebook

#numpy
今回は科学技術計算でよく使うnumpy というパッケージを使用します．


numpy以外の方法で調べたところ，SymPyをpipでインストールして量子計算する方法もあるみたいですね．

・SymPy で量子プログラミングを体験してみましょう
https://qiita.com/openql/items/e5b98bcd13fb4f0b6d59

・Welcome to SymPy’s documentation!
https://docs.sympy.org/latest/modules/physics/quantum/gate.html


#ライブラリのインポート
以下のコードをjupyter notebookにとりあえず打ち込んでnumpyをインポートします．

```
import numpy as np
```

#古典的ビット
ここから本題です．古典ビットの状態はブラケット表記を用いると，以下のように記述できます．これが古典的ビットの定義であることを思い出しましょう．

```math
\begin{aligned}|0\rangle &=\left[\begin{array}{l}{1} \\ {0}\end{array}\right] \\|1\rangle &=\left[\begin{array}{l}{0} \\ {1}\end{array}\right] \end{aligned}

```

これをpythonで記述すると，

```
state_0 = np.array([[1.0],[0.0]])
state_1 = np.array([[0.0],[1.0]])
```

と記述できます．Qubitではこの2つの状態を重ね合わせることができるので，パラメータc1，c2，という確率振幅(複素数)を用いると

```math
c_{1}\left[\begin{array}{l}{1} \\ {0}\end{array}\right]+c_{2}\left[\begin{array}{l}{0} \\ {1}\end{array}\right]=\left[\begin{array}{l}{c_{1}} \\ {c_{2}}\end{array}\right]
```
となりますね．ここで測定確率は，c1，c2のノルムの2乗である$\left|c_{1}\right|^{2} \text { , }\left|c_{2}\right|^{2}$でそれぞれの終状態$|0\rangle \text { , }|1\rangle$が測定されることが知られています．もちろんこれは，$\left|c_{1}\right|^{2}+\left|c_{2}\right|^{2}=1$であることが前提です．

重ね合わせの状態である，$|\psi\rangle=\frac{1}{\sqrt{2}}(|0\rangle+|1\rangle)$はpythonだと以下のように書けます．


```
c1 = 1.0/(2**0.5)
c2 = 1.0/(2**0.5)
state_psi = c1 * state_0 + c2 * state_1
```

#Hadamardゲート
量子ゲートには色々な種類がありますが，今回はHadamardゲートを使ってみます．Hadamardゲートは行列の形式(雑な言い方ですいません)だと，

```math
H=\frac{1}{\sqrt{2}}\left[\begin{array}{cc}{1} & {1} \\ {1} & {-1}\end{array}\right]
```
と表されます．この特徴の1つには，２×２行列の場合は単一量子ビット状態に作用します．また，４×４行列の場合は２量子ビット状態に作用することが挙げられます(この言い方で良いのか？)．

これで何ができるのかというと，LT大会のスライドでも説明したように，Hadamardゲートの役割は状態の重ね合わせを作成することです．

状態の重ね合わせを行列表示で表現すると，

```math
\left[\frac{\frac{1}{\sqrt{2}}}{\frac{1}{\sqrt{2}}}\right]=\frac{1}{\sqrt{2}}\left(\left[\begin{array}{l}{1} \\ {0}\end{array}\right]+\left[\begin{array}{l}{0} \\ {1}\end{array}\right]\right)=\frac{1}{\sqrt{2}}(|0\rangle+|1\rangle)
```
となります．これはpythonだと，

```
gate_H = 1.0/(2**0.5) * np.array([[1, 1],[1, -1]])
state_new = np.dot(gate_H, state_0)
```

となります．したがって，上のコードのstate_newというものは重ね合わせであるstate_psiであるということである．
これでアダマールゲートの役割が確認できます．


#まとめと今後の予定
全部書けなかったので，複数回に分けて書くことにし，今回はブラケット表記や量子ゲートの1つであるHadamardゲートに着目しました．
次回以降はいつになるかわかりませんが，扱いきれなかったテンソル積の概念を用いて正確に多粒子量子状態を記述することを書きたいと思います．

#参考文献
再掲ですが，
・SymPyで量子プログラミングを体験してみましょう
https://qiita.com/openql/items/e5b98bcd13fb4f0b6d59

・Welcome to SymPy’s documentation!
https://docs.sympy.org/latest/modules/physics/quantum/gate.html

・Quantum Computing in Python: Introduction
http://dkopczyk.quantee.co.uk/quantum-computing-in-python-introduction/

これ以外には，
・石坂・他，量子情報科学入門，共立出版(2015).
https://www.amazon.co.jp/%E9%87%8F%E5%AD%90%E6%83%85%E5%A0%B1%E7%A7%91%E5%AD%A6%E5%85%A5%E9%96%80-%E7%9F%B3%E5%9D%82-%E6%99%BA/dp/4320122992

を参考にしました．