1
Copy pip install blueqat qiskit pylatexenc &>/dev/null
Copy from blueqat import Circuit import math
前回に利用した位相キックバックアルゴリズム を改良していきます。
位相キックバックは、位相シフト操作(ただし or )が与えられた時、それを別の1量子ビットの と の位相差として移し取り、ゲートの作用によりそれがなのかなのか検出する1量子ビットのアルゴリズムでした。
これを or よりも高い分解能となるように拡張します。
Copy 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>
具体的に の場合を考えます。
このとき、位相角を倍すると、 となります。 位相がに変換されていますので、位相キックバックができる形です。
つまり、位相シフト操作を4回行ったものに対して位相キックバックを行い、 得られた位相を後で(古典的に)倍すればよいことになります。
同様に、位相角がのときは、 位相シフト操作を回行えばよいです。
問題は、位相角が半端な値で のような時です。
この場合、少し工夫してやると,,の部分を順繰り推定することができます。
すると、 となります。
ですから、元の,の部分が何であったとしても、無視され、の部分(つまり)が位相に移されており、位相キックバックができる形です。
位相シフト操作を回数行います。
となります。
再びより、元のの部分は無視できています。
取り出したいの部分は位相に移されますので位相キックバックができる形です。
しかし、要らないの部分がという形で残ってしまっています。
だめじゃないか! と思うわけですが、
の部分というのは先程推定した位相なので、実は既知です。
なので、先程の推定結果が、即ち[rad]だった場合はなので何もする必要がなく、
先程の推定結果が、即ち[rad]だった場合は、今はという形で残っているはずですのでを(量子ゲートとして)掛けることでキャンセルします。
位相シフト操作を回数行います。
となります。
やはり およびの部分というのは先程推定した位相なので、既知です。
検出結果に応じておよびの項を相殺します。
このように、先に確定した桁の情報を使って古典的なif処理を行い、不要な部分を打ち消しながら順繰り1桁ずつ推定し、確定させていきます。
この操作により、位相はの精度で推定できます。
上記のような方法で、決めた精度で位相の推定が可能となります。 応用例として、ユニタリ行列の固有値の位相推定に使うことが出来ます。
これを反復量子位相推定と言います。
反復量子位相推定の場合、量子ビットは制御用に1bit,標的用に1bitの合計2bitあればよく、代わりにこの回路と測定を度繰り返しています。
量子ビット数が一度に個用意できる場合は、この操作を同時に(並列に)行うができ、たった1つの回路で終了します。
これを 量子位相推定 と呼びます。
blueqatで量子位相推定の回路を作ってみます。 この回路を覚える必要はなく、上述のような””考え方”がわかっていれば良いかと思います。
とし、入力する固有ベクトルは, 対応する固有値の位相を読み出してみます
Copy 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)
Copy 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>
Copy circ_QPE.run(shots=1024)
Counter({'1001': 1024})
'Counter({'1001': 1024})' と出ます。
'1001'のうち、右端の量子ビット'1'は、固有ベクトル入力がそのまま出てきているだけです。
読み出し結果としては'100'で、左端の量子ビットがの存在を意味しています。
その隣は、、その隣はの存在に相当します。
つまり ということです。
少しをかえて、 とし、入力する固有ベクトルは, 対応する固有値の位相を読み出してみます。
Copy 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で、 を意味しています。
以上、量子位相推定アルゴリズムの紹介でした。
© 2024, blueqat Inc. All rights reserved