blueqatで加算器の実装

## この記事に関して
ここではpythonライブラリのblueqatを用いて量子プログラミングを行っていこうと思います。
内容は[公式のチュートリアル](https://github.com/Blueqat/Blueqat-tutorials/tree/master/tutorial-ja)を元に作成しています。
今回は加算器を実装していきます。

## 加算器
ビットは 0, 1 をとるので 2進数の足し算を考えます。
組み合わせは

``` math
0+0=00,\ \ 0+1=01,\ \ 1+0=01,\ \ 1+1=10
```
となります。
これを作成していきます。

### 回路の作成(1桁目)
まずは上の1桁目から作成します。
1桁目を見ると、0, 0, 0, 1 の順になっています。

表で表すと以下になります。

| X | Y |X+Yの2桁目|
|:-:|:-:|:-:|
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |

これを見ると [CCXゲート](https://qiita.com/KeiichiroHiga/items/f5117efcf6a96c9d10b8#ccx-%E3%82%B2%E3%83%BC%E3%83%88toffoli%E3%82%B2%E3%83%BC%E3%83%88)と同じことがわかります。
(CCXは入力の頭2つのビットが1ならば3番目のビットを反転させる)

このことから入力が 11 の場合は以下の回路を考えることができます。

``` math
\begin{array}{cccccc}
\left|1\right> &-&*&-&&\\
\left|1\right> &-&*&-&&\\
\left|0\right> &-&X&-&→&出力\\
\end{array}
```
上から2ビットを入力、残りの1ビットを出力だと考えると上の回路から 1 が出力されるのがわかります。

#### 実装
上の回路を実装してみます。

``` python:sample.ipynb
from blueqat import Circuit

c = Circuit().x[0].x[1].ccx[0,1,2]
c.m[:].run(shots=1000)

結果
Counter({'111': 1000})
```
結果の上2桁が入力で残りの1桁が出力です。
表と同じ結果になりました。

### 回路の作成(2桁目)
まずは上の1桁目から作成します。
次にもう一つのくらいを作成します。
2桁目を見ると、0, 1, 1, 0 の順になっています。

表で表すと以下になります。

| X | Y |X+Yの1桁目|
|:-:|:-:|:-:|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |

これを見ると [CXゲート](https://qiita.com/KeiichiroHiga/items/f5117efcf6a96c9d10b8#cxcyczcrxcrycrz-%E3%82%B2%E3%83%BC%E3%83%88)と同じことがわかります。
(左辺がCXの入力で右辺が出力の2番目のビット)

このことから入力が 10 の場合は以下の回路を考えることができます。

``` math
\begin{array}{cccccc}
\left|1\right> &-&*&-&-&&\\
\left|0\right> &-&|&*&-&&\\
\left|0\right> &-&X&X&-&→&出力\\
\end{array}
```
上から2ビットを入力、残りの1ビットを出力だと考えると上の回路から 1 が出力されるのがわかります。

#### 実装
上の回路を実装してみます。

``` python:sample.ipynb
from blueqat import Circuit

c = Circuit().x[0].cx[0,2].cx[1,2]
c.m[:].run(shots=1000)

結果
Counter({'101': 1000})
```
結果の上2桁が入力で残りの1桁が出力です。
表と同じ結果になりました。

### 回路の作成 (全体)

最後に上の二つの回路をまとめます。

入力を 00 としてまとめた回路を以下に示します。

``` math
\begin{array}{cccccc}
\left|0\right> &-&*&-&*&-&-&\\
\left|0\right> &-&*&-&|&*&-&\\
\left|0\right> &-&X&-&|&|&-&→&出力\\
\left|0\right> &-&-&-&X&X&-&→&出力
\end{array}
```

上2ビットを入力、残りの2ビットが出力です。
始めの CCX は1桁目の部分で残りの 2つの CX は2桁目の部分です。

#### 実装
上の回路を実装してみます。

``` python:sample.ipynb
from blueqat import Circuit

c = Circuit().ccx[0,1,2].cx[0,3].cx[1,3]
c.m[:].run(shots=1000)

結果
Counter({'0000': 1000})
```
きちんと結果が出力されました。

残りの3つも実装してみます。

###### 0 + 1

``` python:sample.ipynb
from blueqat import Circuit

c = Circuit().x[1].ccx[0,1,2].cx[0,3].cx[1,3]
c.m[:].run(shots=1000)

結果
Counter({'0101': 1000})
```

###### 1 + 0

``` python:sample.ipynb
from blueqat import Circuit

c = Circuit().x[0].ccx[0,1,2].cx[0,3].cx[1,3]
c.m[:].run(shots=1000)

結果
Counter({'1001': 1000})
```

###### 1 + 1

``` python:sample.ipynb
from blueqat import Circuit

c = Circuit().x[0].x[1].ccx[0,1,2].cx[0,3].cx[1,3]
c.m[:].run(shots=1000)

結果
Counter({'1110': 1000})
```
以上で加算器が実装できました。

## 重ね合わせを用いた加算器
先ほど4つのパターンを実装しましたがこれらは全て X ゲートで操作しています。
量子の重ね合わせを用いると4パターンを一気に操作することができます。
式としては $H\left|0\right> \otimes H\left|0\right>$ を考えます。

``` math
H\left|0\right> \otimes H\left|0\right> = \frac{1}{2}(\left|00\right>+\left|01\right>+\left|10\right>+\left|11\right>)
```
見てわかる通り右辺に入力の4パターンが出てきました。
この性質を用いて実装します。

回路は以下のようになります。

``` math
\begin{array}{cccccc}
\left|0\right> &H&-&*&-&*&-&-&\\
\left|0\right> &H&-&*&-&|&*&-&\\
\left|0\right> &-&-&X&-&|&|&-&→&出力\\
\left|0\right> &-&-&-&-&X&X&-&→&出力
\end{array}
```
今まで Xゲートを施していた部分を Hゲートにして 4パターンを作っています。

#### 実装

``` python:sample.ipynb
from blueqat import Circuit

c = Circuit().h[0,1].ccx[0,1,2].cx[0,3].cx[1,3]
c.m[:].run(shots=1000)

結果
Counter({'0000': 233, '1110': 260, '0101': 253, '1001': 254})
```
4つのパターンを同時に出力させることができました。

## まとめ
今回はblueqatを用いて2進数の和を実装しました。
次回は2進数の積をblueqatで実装してみます。