この記事に関して
ここではpythonライブラリのblueqatを用いて量子プログラミングを行っていこうと思います。
内容は公式のチュートリアルを元に作成しています。
今回は量子テレポーテーションを実装していきます。
量子テレポーテーション
量子テレポーテーションは量子もつれを用いて作られます。
その名の通り情報を瞬間移動のように相手に送ることができます。
量子もつれを用いるためにまずは Bell基底について説明します。
Bell 基底
2量子ビットのもつれ状態は、以下の4種類で表せます。
\left|\Phi^+\right> = \frac{1}{\sqrt2}(\left|00\right>+\left|11\right>),\
\left|\Phi^-\right> = \frac{1}{\sqrt2}(\left|00\right>-\left|11\right>) \\
\left|\Psi^+\right> = \frac{1}{\sqrt2}(\left|01\right>+\left|10\right>),\
\left|\Psi^-\right> = \frac{1}{\sqrt2}(\left|01\right>-\left|10\right>)
これらをBell基底と言います。
量子テレポーテーションはこの基底を使って計算します。
回路の作成
まずは送る情報ともつれの生成・復元に関して、
送る情報は自由なのでbloch球上の純粋状態を考えて $\left|\psi\right>$ と置きます。
$\left|\psi\right> = a\left|0\right>+b\left|1\right>$ とします。 $(|a|^2+|b|^2 = 1)$
2量子ビットのもつれの生成は前回説明した通り、片方に Hゲートを施してその後 CXゲートを施します。
すなわち 00 の場合
\left|00\right> \xrightarrow{H\ \& \ CX} \left|\Phi^+\right>
逆にもつれ状態から戻すのには上と逆の操作をすればいいので
Bell 状態は
\left|\Phi^+\right> \xrightarrow{CX\ \& \ H} \left|00\right>,
\left|\Phi^-\right> \xrightarrow{CX\ \& \ H} \left|10\right> \\
\left|\Psi^+\right> \xrightarrow{CX\ \& \ H} \left|01\right>,
\left|\Psi^-\right> \xrightarrow{CX\ \& \ H} \left|11\right>
となります。
量子テレポーテーションは $\left|\psi\right> \otimes \left|\Phi^+\right>$ と上記のことを考えます。
回路は以下のようになります。
\begin{array}{ccccccccc}
\left|\psi\right> &-&-&-&-&*&H&-&-&*&-&H&- \\
&&&&&|&&&&|& \\
\left|0\right> &-&H&*&-&X&-&-&*&|&-&H&- \\
&&&|&&&&&|&|&& \\
\left|0\right> &-&-&X&-&-&-&-&X&Z&-&-&-&←出力 \\
&&&&↑&&&↑&&&↑&&↑\\
&&&&\left|\psi_1\right>&&&\left|\psi_2\right>&&&\left|\psi_3\right>&&\left|\psi_4\right>
\end{array}
$\left|\psi_1\right>$ について
$\left|\psi_1\right> = \left|\psi\right> \otimes \left|\Phi^+\right>$ となるが、この 0, 1番目のビットを Bell 基底で書き直すと以下のようになります。
\begin{align}
\left|\psi_1\right> = \left|\psi\right> \otimes \left|\Phi^+\right> = &\frac{1}{2}\left|\Phi^+\right> \otimes (a\left|0\right>+b\left|1\right>) +
\frac{1}{2}\left|\Phi^-\right> \otimes (a\left|0\right>-b\left|1\right>) \\
+&\frac{1}{2}\left|\Psi^+\right> \otimes (b\left|0\right>+a\left|1\right>) +
\frac{1}{2}\left|\Psi^-\right> \otimes (b\left|0\right>-a\left|1\right>)
\end{align}
Bell 基底が4つ表示されたことがわかります。
また 3ビット目に $\left|\psi\right>$ らしきものが見えるので情報が移動してるのがわかります。
このように一瞬で情報が移動しているのでテレポーテーションと呼ばれています。
次に $\left|\psi_2\right>$ に関して
上のもつれを戻す操作から $\left|\psi_2\right>$ は以下のように考えられます。
\begin{align}
\left|\psi_2\right> =
&\frac{1}{2}\left|00\right> \otimes (a\left|0\right>+b\left|1\right>) +
\frac{1}{2}\left|10\right> \otimes (a\left|0\right>-b\left|1\right>) \\
+&\frac{1}{2}\left|01\right> \otimes (b\left|0\right>+a\left|1\right>) +
\frac{1}{2}\left|11\right> \otimes (b\left|0\right>-a\left|1\right>)
\end{align}
以上から $\left|\psi_3\right>, \left|\psi_4\right>$ は
\left|\psi_3\right> = H\left|0\right> \otimes H\left|0\right> \otimes \left|\psi\right> \\
\left|\psi_4\right> = \left|0\right> \otimes \left|0\right> \otimes \left|\psi\right>
となります。
実装 1
以上の内容を実装します。
今回は簡単に送りたい情報を $\left|\psi\right> = \left|1\right>$ とします。
これをテレポートさせます。
from blueqat import Circuit
c = Circuit().x[0]
c.h[1].cx[1,2].cx[0,1].h[0].cx[1,2].cz[0,2].h[0,1]
c.m[:].run(shots=1000)
出力
Counter({'001': 1000})
0番目が1だったはずが2番目にテレポートしてます。
実装 2
次は一般の状態を考えます。
今回は送りたい情報を $\left|\psi\right> = U_3(\pi/2,\pi/3,\pi)\left|0\right>$ とします。
from blueqat import Circuit
import math
c = Circuit().u3(math.pi/2,math.pi/3,math.pi)[0]
c.run()
出力
array([0.70710678+0.j , 0.35355339+0.61237244j])
$\left|\psi\right>$ は上の状態ベクトルとなります。
この $\left|\psi\right>$ を上の回路でテレポートさせます。
from blueqat import Circuit
import math
c = Circuit().u3(math.pi/2,math.pi/3,math.pi)[0]
c.h[1].cx[1,2].cx[0,1].h[0].cx[1,2].cz[0,2].h[0,1]
c_array = c.run()
# 要素が0の部分を削除
print(c_array[c_array != 0])
出力
[0.70710678+0.j 0.35355339+0.61237244j]
実際の出力は3ビットの状態なので上のコードではいらない部分を落としています。
きちんと出力されたことがわかります。
まとめ
今回はblueqatを用いて量子テレポーテーションを実装しました。
次回は量子フーリエ変換(QFT)をblueqatで実装してみます。