LoginSignup
2
1

More than 3 years have passed since last update.

blueqatで加算器の実装

Last updated at Posted at 2019-12-10

この記事に関して

ここではpythonライブラリのblueqatを用いて量子プログラミングを行っていこうと思います。
内容は公式のチュートリアルを元に作成しています。
今回は加算器を実装していきます。

加算器

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

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ゲートと同じことがわかります。
(CCXは入力の頭2つのビットが1ならば3番目のビットを反転させる)

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

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

上から2ビットを入力、残りの1ビットを出力だと考えると上の回路から 1 が出力されるのがわかります。

実装

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

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ゲートと同じことがわかります。
(左辺がCXの入力で右辺が出力の2番目のビット)

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

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

上から2ビットを入力、残りの1ビットを出力だと考えると上の回路から 1 が出力されるのがわかります。

実装

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

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 としてまとめた回路を以下に示します。

\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桁目の部分です。

実装

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

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
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
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
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>$ を考えます。

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パターンが出てきました。
この性質を用いて実装します。

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

\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パターンを作っています。

実装

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で実装してみます。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1