この記事に関して
ここでは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 が出力されるのがわかります。
実装
上の回路を実装してみます。
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 が出力されるのがわかります。
実装
上の回路を実装してみます。
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桁目の部分です。
実装
上の回路を実装してみます。
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
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
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
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パターンを作っています。
実装
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で実装してみます。