量子位相推定(Quantum Phase Estimation: QPE)
pip install blueqat qiskit pylatexenc &>/dev/null
from blueqat import Circuit
import math
位相キックバックの分解能を上げる
前回に利用した位相キックバックアルゴリズム
を改良していきます。
位相キックバックは、位相シフト操作
これを
\theta=0 or \pi を検出する位相キックバック
(再掲) Circuit().h[0].x[1].cu1(math.pi)[0,1].h[0].m[0].run_with_ibmq(returns='draw', output='mpl')
<Figure size 327.252x204.68 with 1 Axes>
具体的に
このとき、位相角を
位相が
つまり、位相シフト操作
得られた位相を後で(古典的に)
同様に、位相角が
位相シフト操作
問題は、位相角が半端な値で
この場合、少し工夫してやると
- まず、
の部分を取り出すために、位相シフト操作1/8 をe^{i\theta} 回数行います。2^2
すると、
- 次に
の部分を取り出します。1/4
位相シフト操作
再び
取り出したい
しかし、要らない
だめじゃないか! と思うわけですが、
なので、先程の推定結果が
先程の推定結果が
- 最後に
の部分を取り出します。1/2
位相シフト操作
やはり
検出結果に応じて
このように、先に確定した桁の情報を使って古典的なif処理を行い、不要な部分を打ち消しながら順繰り1桁ずつ推定し、確定させていきます。
この操作により、位相は
反復量子位相推定(Iterative QPE: IQPE)
上記のような方法で、決めた精度で位相の推定が可能となります。
応用例として、ユニタリ行列の固有値の位相推定に使うことが出来ます。
これを反復量子位相推定と言います。
量子位相推定
反復量子位相推定の場合、量子ビットは制御用に1bit,標的用に1bitの合計2bitあればよく、代わりにこの回路と測定を
量子ビット数が一度に
これを 量子位相推定 と呼びます。
量子位相推定の回路
blueqatで量子位相推定の回路を作ってみます。
この回路を覚える必要はなく、上述のような””考え方”がわかっていれば良いかと思います。
def qft_dagger(circ, n):
"""n-qubit QFTdagger the first n qubits in circ"""
# Don't forget the Swaps!
for qubit in range(n//2):
circ.swap[qubit, n-qubit-1]
for j in range(n):
for m in range(j):
circ.cu1(-math.pi/float(2**(j-m)))[m,j]
circ.h[j]
def qpe(circ, n_iqft, theta):
circ.h[0:n_iqft]
repetitions = 1
for counting_qubit in range(n_iqft):
for i in range(repetitions):
circ.cu1(theta)[counting_qubit, n_iqft] # This is Controlled-U
repetitions *= 2
qft_dagger(circ, n_iqft)
circ_QPE = Circuit(4)
circ_QPE.x[3]
qpe(circ_QPE, 3, math.pi/4)
circ_QPE.m[:]
circ_QPE.run_with_ibmq(returns='draw', output='mpl', fold=30)
<Figure size 1772.2x325.08 with 1 Axes>
circ_QPE.run(shots=1024)
Counter({'1001': 1024})
'Counter({'1001': 1024})' と出ます。
'1001'のうち、右端の量子ビット'1'は、固有ベクトル入力
読み出し結果としては'100'で、左端の量子ビットが
その隣は、
つまり
少し
circ_QPE = Circuit(4)
circ_QPE.x[3]
qpe(circ_QPE, 3, math.pi/2)
circ_QPE.m[:]
circ_QPE.run(shots=1024)
Counter({'0101': 1024})
Counter({'0101': 1024}) となります。つまり読み出し結果は010で、
以上、量子位相推定アルゴリズムの紹介でした。