量子ゲートの操作を直感的に理解しながら進めたかったので、基本的な操作を行うコードと、それに付随する量子回路図を並べてみました。
コードの内容は Blueqat日本語チュートリアル を参考に、回路図は Quirk からスクショを撮りました。
前提知識
個人的には、「量子ビットはブロッホ球で表現できる」ことが分かっていればコーディングを始められると思っています。
Try Bloch! で X, Y, Z, H あたりを押して見ると、イメージが早いと思います。
量子ビット内を指す点を操作して、北極に近づけるほど0の確率が高くなり、南極に近づけるほど1の確率が高くなります。
初期ゲート
便宜上、2量子ビットを初期値とします。
from blueqat import Circuit
Circuit(2).m[:].run(shots=100) # Counter({'00': 100})
Circuit(2)
で2個の量子ビットを宣言、 m[:]
で現在の状態を計測、 run(shots=100)
で実行回数を指定し実行します。
これを実行すると、 00
が 100 となりました。
1つ目の量子ビット -> 0
2つ目の量子ビット -> 0
上記の状態が100回計測されたということになります。
量子ビットは、何も操作をしないと北極地点(0)を指すということがわかりました。
量子回路図は以下のようになります。
( 上記のツールでは ...
は何もしないゲートという意味だそうです。 これを入れないとヒントが出てきて邪魔だったのと、1つだけの量子回路の作り方がわからなかったので2つにした。 )
Xゲートの操作
ブロッホ球のx軸の周りを 180°回転をさせるものを「Pauli-X ゲート」または「ビット反転演算子」1と呼びます。
Circuit(2).x[0].m[:].run(shots=100) # Counter({'10': 100})
x[0]
で、配列0番目の量子ビットにXゲートを適用させました。
それにより、以下の状態が100回観測されました。
1つ目の量子ビット -> 1
2つ目の量子ビット -> 0
量子回路は以下になります。
※Blueqatでは量子ビットを左から順に 10
と並べて表しますが、Quirkの数式(ケットベクトル)では右から順に |01⟩
と表現されるので注意。右端の水色の円にカーソルを乗せると表示されます。
Yゲートの操作
同様にy軸の周りに 180°回転をさせるものを「Pauli-Y ゲート」または「位相・ビット反転演算子」2と呼びます。
Circuit(2).y[0].m[:].run(shots=100) # Counter({'10': 100})
xゲートと同様に、 y[0]
がそれです。
量子回路図は以下になります。
Quirk / Circuit Link
Zゲートの操作
同様にz軸の周りに 180°回転をさせるものを「Pauli-Z ゲート」または「位相反転演算子」3と呼びます。
0の時は何も変化させず、1の時に位相を反転させます。
Circuit(2).z[0].m[:].run(shots=100) # Counter({'00': 100})
量子回路図は以下になります。
上記の北極地点では、結果に何も影響を与えないので、後続のアダマールゲートで加えて説明します。
アダマールゲートの操作
これはちょっと特殊で、z軸からx軸へと向かう中間の 45°を軸として 180°の回転をさせるもので、「アダマール変換」4とも呼びます。
( Try Block で H を押して見たほうがイメージしやすいかと思います )
Circuit(2).h[0].m[:].run(shots=100) # Counter({'00': 47, '10': 53})
h[0]
がそれです。
1つ目の量子ビットが赤道に位置することで重ね合わせ状態となり、0である確率が50%, 1である確率が50% となりました。
100回実行時の確認で、 00
が 47回, 10
が 53回と、大体50%前後に収まってることが確認できるかと思います。
また、赤道はぐるりと回っているので、どの地点にいるかを判別する方法があります。
Circuit(2).h[0].run() # array([0.70710678+0.j, 0.70710678+0.j, 0. +0.j, 0. +0.j])
m[:]
を外して状態を確定させる測定を止め、 shots=100
の実行回数指定を外すと、状態を取得できます。
(この実行はシミュレーターでのみ使える機能5のようです)
実行すると、状態を以下の複素ベクトル6で取得できました。
結果の1つ目は 00
-> 0.70710678+0.j
結果の2つ目は 10
-> 0.70710678+0.j
結果の3つ目は 01
-> 0. +0.j
結果の4つ目は 11
-> 0. +0.j
結果の配列は、上記の量子ビットに対応していることを確認しました。
アダマールゲートを適用した直後の赤道では、複素ベクトルは 0.70710678+0.j
となるようです。
(この複素ベクトルは絶対値を2乗することで確率を取得できます6)
赤道上を移動するにはZゲートが使えます。
Circuit(2).h[0].z[0].run() # array([ 0.70710678+0.j, -0.70710678+0.j, 0. +0.j, -0. +0.j])
結果の1つ目は 00
-> 0.70710678+0.j
結果の2つ目は 10
-> -0.70710678+0.j
結果の3つ目は 01
-> 0. +0.j
結果の4つ目は 11
-> 0. +0.j
Zゲートは 1
の時に作用するので、1つ目の量子ビットが 1 である 10
の結果が、負になっていることを確認できたかと思います。
アダマールゲート適用直後の手前の赤道が + の最大値となり、そこから半周(180°)回した地点では - の最大値になります。
その性質により、位置(位相)を計算できるようです。
位相シフトゲートの操作
z軸の周りに角度θ 回転させるもので、「位相シフト演算子」とも呼ばれます。回転方向は手前の球面から右方向になります。
Circuit(2).h[0].rz(math.pi/4)[0].run() # array([0.70710678+0.j , 0.5 +0.5j, 0. +0.j , 0. +0.j ])
rz(math.pi/4)[0]
がそれです。
Zゲートは180度回転なので、 math.pi/4
でその4分の1、45度の回転を行います。
結果の1つ目は 00
-> 0.70710678+0.j
結果の2つ目は 10
-> 0.5 +0.5j
結果の3つ目は 01
-> 0. +0.j
結果の4つ目は 11
-> 0. +0.j
1つ目の量子ビットが1である10
の時に、結果が変わっていることを確認できたかと思います。
メモ帳 📝
-
rz(math.pi/4)
は手前の球面から右方向に回転します。 -
rz(-math.pi/4)
だと左方向に回転します。 -
rz(math.pi/2)
は Sゲートと呼ばれることもあります。 -
rz(-math.pi/4)
は T†ゲートと呼ばれることもあります。
CNOTゲートの操作
2つの量子をもつれさせるゲートです。「制御NOTゲート」7とも呼ばれます。
片方の量子ビット(制御量子ビット)が1の時だけ、もう片方の量子ビット(標的量子ビット)にXゲートを適用させます。
Circuit(2).x[0].cx[0,1].m[:].run(shots=100) # Counter({'11': 100})
cx[0,1]
で指定します。
左側の0が制御量子ビットを指定していて、右側の1が標的量子ビットを指定しています。
1つ目の量子ビットが x[0]
で1になっているため、2つ目の量子ビットがCNOTゲートにより1になり、結果は 11
が100%となります。
やっと2個の量子ビットを使う例を出せました。
基本的なゲート操作は以上になります。
最後に
量子力学やその関連数式も学んではいますが、大抵は「なるほどわからん」という感じです。
ただ、わからなくても辛くはなく、逆にどうしてその謎の数式が出てくるんだろうといった興味が沸いてくるので、そのうちわかっていくだろうと楽観的に思っています。内容はとても面白いので、参考URLを乗せておきます。
- 予備校のノリで学ぶ - 【大学物理】量子力学入門シリーズ / 1-7
- 量子計算(量子回路)の考え方を理解するために最低限必要な量子力学の知識を(それなりに納得感のある形で)うまいこと導入する方法について考えてみた(目次) / 全7記事
自分への戒め
- 強化学習のコード等を量子コンピューターにうつせる力が無ければ実利を出せない。触って楽しいで終わるのではなく、生活をより豊かにすることを前提に行動を選択していく。
-
http://lyncs.hateblo.jp/entry/2017/12/16/000103#%E3%83%91%E3%82%A6%E3%83%AAX ↩
-
http://lyncs.hateblo.jp/entry/2017/12/16/000103#%E3%83%91%E3%82%A6%E3%83%AAY ↩
-
http://lyncs.hateblo.jp/entry/2017/12/16/000103#%E3%83%91%E3%82%A6%E3%83%AAZ ↩
-
https://github.com/mdrft/Blueqat_tutorials_ja/blob/master/docs/003_basic_superposition.ipynb > (応用)マイナス状態で重ね合わせを作ってみる ↩
-
http://enakai00.hatenablog.com/entry/2018/05/20/170047 > 純粋状態と混合状態の違いについて ↩
-
http://lyncs.hateblo.jp/entry/2017/12/16/000103#CNOT%E3%82%B2%E3%83%BC%E3%83%88 ↩