はじめに
量子もつれを理解するためにベル状態を見てみたいと思います。あまり新しいことなはいです、、、wikipediaにあるような基本的なことです。
ベル状態を作るための回路
こちらは量子もつれ回路です、
|0> ---H---*---
|
|0> -------X---
量子状態の変遷を見ると、
からスタートします。この時点ではもつれていません。アダマールゲートHを適用すると、上の量子ビットが重ね合わせ状態になります。
そして、これにCXゲートを適用すると、0番目の量子ビットが1のときに1番目の量子ビットが反転し、
の状態が得られます。blueqatでやると、重ね合わせは、
from blueqat import Circuit
Circuit(2).h[0].run()
#array([0.70710678+0.j, 0.70710678+0.j, 0. +0.j, 0. +0.j])
array([0.70710678+0.j, 0.70710678+0.j, 0. +0.j, 0. +0.j])
は00と01の重ね合わせになります。
これにCXを適用すると、
Circuit().h[0].cx[0,1].run()
#array([0.70710678+0.j, 0. +0.j, 0. +0.j, 0.70710678+0.j])
array([0.70710678+0.j, 0. +0.j, 0. +0.j, 0.70710678+0.j])
00と11のもつれに変化しました。量子ビットの値によって、
は今確認しました。
blueqatでは、
Circuit(2).x[1].h[0].cx[0,1].run()
#array([0. +0.j, 0.70710678+0.j, 0.70710678+0.j, 0. +0.j])
array([0. +0.j, 0.70710678+0.j, 0.70710678+0.j, 0. +0.j])
無事出ました。次に
blueqatでは、
Circuit(2).x[0].h[0].cx[0,1].run()
#array([ 0.70710678+0.j, 0. +0.j, 0. +0.j, -0.70710678+0.j])
array([ 0.70710678+0.j, 0. +0.j, 0. +0.j, -0.70710678+0.j])
最後に、
blueqatでは、
Circuit(2).x[:].h[0].cx[0,1].run()
#array([ 0. -0.j, 0.70710678+0.j, -0.70710678-0.j, 0. -0.j])
array([ 0. +0.j, -0.70710678+0.j, 0.70710678+0.j, 0. +0.j])
これら4つの状態は正規直交基底となり、「ベル基底」と呼ばれます。
可逆回路を確認
手計算は省きますが、blueqatで00,01,10,11に対応するベル基底から可逆回路で再度CXとHを適用することで元に戻ることを確認します。
|0> ---H--*--*--H--
| |
|0> ------X--X-----
#00
Circuit(2).h[0].cx[0,1].cx[0,1].h[0].m[:].run(shots=100)
#Counter({'00': 100})
Counter({'00': 100})
#01
Circuit(2).x[1].h[0].cx[0,1].cx[0,1].h[0].m[:].run(shots=100)
#Counter({'01': 100})
Counter({'01': 100})
#10
Circuit(2).x[0].h[0].cx[0,1].cx[0,1].h[0].m[:].run(shots=100)
#Counter({'10': 100})
Counter({'10': 100})
#11
Circuit(2).x[:].h[0].cx[0,1].cx[0,1].h[0].m[:].run(shots=100)
#Counter({'11': 100})
Counter({'11': 100})