Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quantum-kittens
GitHub Repository: quantum-kittens/platypus
Path: blob/main/translations/ja/ch-algorithms/quantum-phase-estimation.ipynb
3855 views
Kernel: Python 3 (ipykernel)

量子位相推定

量子位相推定は、量子計算における最も重要なサブルーチンの1つです。 多くの量子アルゴリズムの中心的な構成要素として機能します。このアルゴリズムの目的は次のとおりです。

ユニタリ演算子UUが、 Uψ=e2πiθψU\vert\psi \rangle =e^{\boldsymbol{2\pi i} \theta }|\psi \rangleのように与えられた場合に、θ\thetaを推定します。 ここで、ψ|\psi\rangle は固有ベクトルであり、e2πiθe^{\boldsymbol{2\pi i}\theta}は対応する固有値です。UU はユニタリーなので、すべての固有値のノルムは1です。

1. 概要

位相推定の一般的な量子回路を以下に示します。 上側のレジスターにはtt個の「カウント」量子ビットがあり、下のレジスターにはψ|\psi\rangleの状態の量子ビットがあります: image1

1.1 直感的解釈

量子位相推定アルゴリズムは、位相キックバックを使用して、UUの(フーリエ基底における)位相をカウントレジスターのtt 量子ビットに書き込みます。次に、逆QFTを使用して、フーリエ基底から計算基底に変換し、測定します。

(QFTの章から)フーリエ基底では、 00から数えて2t2^t回で最上位の量子ビットが1回転したことを覚えているでしょう。 00から2t2^tの間の数であるxxを数えるには、この量子ビットをz軸を中心にx2t\tfrac{x}{2^t} 回転させます。 次の量子ビットでは2x2t\tfrac{2x}{2^t}回転し、3番目の量子ビットでは4x2t\tfrac{4x}{2^t}回転します。

image2

制御UUゲートを使うと、量子ビットは(キックバックにより)位相 e2iπθe^{2i\pi\theta}に比例して回転します。 連続してCUCUゲートを使用して、フーリエ基底で002t2^tの数値として位相θ\thetaをエンコードできるところまで、この回転を適切な回数繰り返します。

次に、QFTQFT^\daggerを使用してこれを計算基底に変換します。

1.2 基礎となる数学

上記のように、この回路はユニタリー演算子UUの位相を推定します。Uψ=e2πiθψU\vert\psi \rangle =e^{\boldsymbol{2\pi i} \theta }|\psi \rangleにおいて、ψ|\psi\rangleは固有ベクトル、e2πiθe^{\boldsymbol{2\pi i}\theta}は対応する固有値で、θ\thetaを推定します。回路は次の手順です。

i. 準備ψ\vert\psi\rangleを1量子ビットレジスターにセットします。 別のnn個の量子ビットのセットは、値2nθ2^n\thetaを格納するカウントレジスターです。

ψ0=0nψ\psi_0 = \lvert 0 \rangle^{\otimes n} \lvert \psi \rangle

ii. 重ね合わせnnビットのアダマールゲート操作HnH^{\otimes n}をカウントレジスターに適用します。

ψ1=12n2(0+1)nψ\psi_1 = {\frac {1}{2^{\frac {n}{2}}}}\left(|0\rangle +|1\rangle \right)^{\otimes n} \lvert \psi \rangle

iii. 制御ユニタリー演算:制御ビットが1|1\rangleの場合にのみ、ターゲットレジスターにユニタリー演算子 UU を適用する、制御ユニタリー演算CUC-Uを導入する必要があります。UUは、Uψ=e2πiθψU|\psi \rangle =e^{\boldsymbol{2\pi i} \theta }|\psi \rangleとなる固有ベクトルψ|\psi\rangle のユニタリー演算子であるため、次のようになります。

U2jψ=U2j1Uψ=U2j1e2πiθψ==e2πi2jθψU^{2^{j}}|\psi \rangle =U^{2^{j}-1}U|\psi \rangle =U^{2^{j}-1}e^{2\pi i\theta }|\psi \rangle =\cdots =e^{2\pi i2^{j}\theta }|\psi \rangle

すべての𝑛制御演算子 CU2jC − U^{2^j}0jn10\leq j\leq n-1において適用し、0ψ+1e2πiθψ=(0+e2πiθ1)ψ|0\rangle \otimes |\psi \rangle +|1\rangle \otimes e^{2\pi i\theta }|\psi \rangle =\left(|0\rangle +e^{2\pi i\theta }|1\rangle \right)\otimes |\psi \rangleを使用すると以下のようになります。

ψ2=12n2(0+e2πiθ2n11)(0+e2πiθ211)(0+e2πiθ201)ψ=12n2k=02n1e2πiθkkψ\begin{aligned} \psi_{2} & =\frac {1}{2^{\frac {n}{2}}} \left(|0\rangle+{e^{\boldsymbol{2\pi i} \theta 2^{n-1}}}|1\rangle \right) \otimes \cdots \otimes \left(|0\rangle+{e^{\boldsymbol{2\pi i} \theta 2^{1}}}\vert1\rangle \right) \otimes \left(|0\rangle+{e^{\boldsymbol{2\pi i} \theta 2^{0}}}\vert1\rangle \right) \otimes |\psi\rangle\\\\ & = \frac{1}{2^{\frac {n}{2}}}\sum _{k=0}^{2^{n}-1}e^{\boldsymbol{2\pi i} \theta k}|k\rangle \otimes \vert\psi\rangle \end{aligned}

ここで、kk はnビットの2進数の整数表現です。

iv. 逆フーリエ変換:上の式は、量子フーリエ変換とそのQiskit実装のnotebookで導出したように、量子フーリエ変換を適用した結果であることに注意してください。 QFTがn量子ビットの入力状態x\vert x\rangleを出力として以下のようにマップすることを思い出してください。

QFTx=12n2(0+e2πi2x1)(0+e2πi22x1)(0+e2πi2n1x1)(0+e2πi2nx1)QFT\vert x \rangle = \frac{1}{2^\frac{n}{2}} \left(\vert0\rangle + e^{\frac{2\pi i}{2}x} \vert1\rangle\right) \otimes \left(\vert0\rangle + e^{\frac{2\pi i}{2^2}x} \vert1\rangle\right) \otimes \ldots \otimes \left(\vert0\rangle + e^{\frac{2\pi i}{2^{n-1}}x} \vert1\rangle\right) \otimes \left(\vert0\rangle + e^{\frac{2\pi i}{2^n}x} \vert1\rangle\right)

上の式でxx2nθ2^n\theta に置き換えると、上記のステップ2で導出された式が正確に得られます。したがって、状態2nθ\vert2^n\theta\rangleを復元するには、補助レジスターに逆フーリエ変換を適用します。そうすることで、以下を得られます。 ψ3=12n2k=02n1e2πiθkkψQFTn112nx=02n1k=02n1e2πik2n(x2nθ)xψ \vert\psi_3\rangle = \frac {1}{2^{\frac {n}{2}}}\sum _{k=0}^{2^{n}-1}e^{\boldsymbol{2\pi i} \theta k}|k\rangle \otimes | \psi \rangle \xrightarrow{\mathcal{QFT}_n^{-1}} \frac {1}{2^n}\sum _{x=0}^{2^{n}-1}\sum _{k=0}^{2^{n}-1} e^{-\frac{2\pi i k}{2^n}(x - 2^n \theta)} |x\rangle \otimes |\psi\rangle

v. 測定:上記の式はx=2nθx = 2^n\theta付近でピークになります。2nθ2^n\thetaが整数の場合、計算基底で測定すると、高い確率で補助レジスターに位相が得られます。

ψ4=2nθψ|\psi_4\rangle = | 2^n \theta \rangle \otimes | \psi \rangle

2nθ2^n\thetaが整数でない場合、上記の式は x=2nθx = 2^n\theta の近くでピークに達し、その確率は4/π240%4/\pi^2 \approx 40\%よりも高いものになります[1]。

2. 例:Tゲート

みなさんがよく知っているTTゲートを例として取り上げ、量子位相推定を使用してその位相を推定します。TTゲートは状態1|1\rangleに位相eiπ4e^\frac{i\pi}{4} を追加することを思い出してください。

T1=[100eiπ4][01]=eiπ41T|1\rangle = \begin{bmatrix} 1 & 0\\ 0 & e^\frac{i\pi}{4}\\ \end{bmatrix} \begin{bmatrix} 0\\ 1\\ \end{bmatrix} = e^\frac{i\pi}{4}|1\rangle

以下の式で与えられる θ\theta についてQPEを使って、

T1=e2iπθ1T|1\rangle = e^{2i\pi\theta}|1\rangle

θ\thetaを見つけることができます:

θ=18\theta = \frac{1}{8}

この例では、3量子ビットを使用して、 正確な 結果(推定ではありません!)を得ます。

2.1 回路の作成

まず、環境を準備しましょう。

#initialization import matplotlib.pyplot as plt import numpy as np import math # importing Qiskit from qiskit import IBMQ, Aer, transpile, assemble from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister # import basic plot tools from qiskit.visualization import plot_histogram

次に、量子回路を設定します。 4量子ビットを使用します。qubit 0〜2はカウント量子ビットとして、qubit 3はユニタリー演算子(TT)の固有状態として使用します。

XX ゲートを適用して、ψ=1\vert\psi\rangle = \vert1\rangleと初期化します。

qpe = QuantumCircuit(4, 3) qpe.x(3) qpe.draw()
Image in a Jupyter notebook

カウント量子ビットにアダマールゲートをかけます:

for qubit in range(3): qpe.h(qubit) qpe.draw()
Image in a Jupyter notebook

次に、制御ユニタリー演算を実行します。注意:Qiskitでは量子ビットが上の画像とは逆のむきに並びます。

repetitions = 1 for counting_qubit in range(3): for i in range(repetitions): qpe.cp(math.pi/4, counting_qubit, 3); # This is C-U repetitions *= 2 qpe.draw()
Image in a Jupyter notebook

逆量子フーリエ変換を適用して、カウントレジスターの状態を変換します。 ここでは、QFTQFT^\daggerのコードを以下のように与えます。

def qft_dagger(qc, n): """n-qubit QFTdagger the first n qubits in circ""" # Don't forget the Swaps! for qubit in range(n//2): qc.swap(qubit, n-qubit-1) for j in range(n): for m in range(j): qc.cp(-math.pi/float(2**(j-m)), m, j) qc.h(j)

次に、カウントレジスターを測定します。

qpe.barrier() # Apply inverse QFT qft_dagger(qpe, 3) # Measure qpe.barrier() for n in range(3): qpe.measure(n,n)
qpe.draw()
Image in a Jupyter notebook

2.2 結果

aer_sim = Aer.get_backend('aer_simulator') shots = 2048 t_qpe = transpile(qpe, aer_sim) qobj = assemble(t_qpe, shots=shots) results = aer_sim.run(qobj).result() answer = results.get_counts() plot_histogram(answer)
Image in a Jupyter notebook

結果(001)のみが得られ、これは10進数に変換されると 1となります。θ\thetaの結果を得るには、結果(1)を2n2^nで割る必要があります。

θ=123=18\theta = \frac{1}{2^3} = \frac{1}{8}

これはまさに私たちが期待した結果です!

3. 例:より精度を高める

3.1 問題

TTゲートの代わりに、θ=13\theta = \frac{1}{3}のゲートを使用してみましょう。上の例のように回路を準備しました。

# Create and set up circuit qpe2 = QuantumCircuit(4, 3) # Apply H-Gates to counting qubits: for qubit in range(3): qpe2.h(qubit) # Prepare our eigenstate |psi>: qpe2.x(3) # Do the controlled-U operations: angle = 2*math.pi/3 repetitions = 1 for counting_qubit in range(3): for i in range(repetitions): qpe2.cp(angle, counting_qubit, 3); repetitions *= 2 # Do the inverse QFT: qft_dagger(qpe2, 3) # Measure of course! for n in range(3): qpe2.measure(n,n) qpe2.draw()
Image in a Jupyter notebook
# Let's see the results! aer_sim = Aer.get_backend('aer_simulator') shots = 4096 t_qpe2 = transpile(qpe2, aer_sim) qobj = assemble(t_qpe2, shots=shots) results = aer_sim.run(qobj).result() answer = results.get_counts() plot_histogram(answer)
Image in a Jupyter notebook

予測される結果はθ=0.3333\theta = 0.3333\dotsです。実行の結果、最も可能性の高い結果は010(bin) = 2(dec)011(bin) = 3(dec)であることが見てわかります。 これらの2つの結果から、それぞれθ=0.25\theta = 0.25 (off by 25%) とθ=0.375\theta = 0.375 (off by 13%)が得られます。θ\theta の真の値は、カウントビットから取得できる値の間にあり、この回路は、不確実であり不正確であることがわかります。

3.2 解決策

より精度を上げるには、カウント量子ビットを追加するだけです。 さらに2つのカウント量子ビットを追加しましょう。

# Create and set up circuit qpe3 = QuantumCircuit(6, 5) # Apply H-Gates to counting qubits: for qubit in range(5): qpe3.h(qubit) # Prepare our eigenstate |psi>: qpe3.x(5) # Do the controlled-U operations: angle = 2*math.pi/3 repetitions = 1 for counting_qubit in range(5): for i in range(repetitions): qpe3.cp(angle, counting_qubit, 5); repetitions *= 2 # Do the inverse QFT: qft_dagger(qpe3, 5) # Measure of course! qpe3.barrier() for n in range(5): qpe3.measure(n,n) qpe3.draw()
Image in a Jupyter notebook
### Let's see the results! aer_sim = Aer.get_backend('aer_simulator') shots = 4096 t_qpe3 = transpile(qpe3, aer_sim) qobj = assemble(t_qpe3, shots=shots) results = aer_sim.run(qobj).result() answer = results.get_counts() plot_histogram(answer)
Image in a Jupyter notebook

最も可能性の高い2つの測定結果は、01011(10進数の11)と01010 (10進数の10)です。 これらから、次のようにθ\thetaが求められます。

θ=1125=0.344,   or     θ=1025=0.313\theta = \frac{11}{2^5} = 0.344,\;\text{ or }\;\; \theta = \frac{10}{2^5} = 0.313

この2つの結果の13\frac{1}{3} との誤差は、それぞれ3%と6%です。さきほどよりずっと優れた精度の結果が得られました!

4. 実デバイスでの実験

4.1 2.1の回路で

2.1節の回路は実際のデバイスで実行できます。回路を思い出してみましょう。

qpe.draw()
Image in a Jupyter notebook
IBMQ.load_account() from qiskit.tools.monitor import job_monitor provider = IBMQ.get_provider(hub='ibm-q') santiago = provider.get_backend('ibmq_santiago') # Run with 2048 shots shots = 2048 t_qpe = transpile(qpe, santiago, optimization_level=3) job = santiago.run(t_qpe, shots=shots) job_monitor(job)
Job Status: job has successfully run
# get the results from the computation results = job.result() answer = results.get_counts(qpe) plot_histogram(answer)
Image in a Jupyter notebook

うまくいけば、最も可能性の高い結果は、シミュレーターから期待される結果である 001 になることがわかります。 シミュレーターとは異なり、 001以外も測定される可能性があります。これは、量子コンピューターにおけるノイズとゲートエラーによるものです。

5. 練習問題

  1. 異なるゲート(CNOT\text{CNOT}, 制御SS, 制御TT^\dagger)で上記の実験を試してください。どのような結果が期待できますか? どのような結果が得られますか?

  2. 制御YYゲートを使って実験してみてください。正しい結果が得られますか? (ヒント:ψ|\psi\rangleYYの固有状態であることを確認してください!)

6. 今後の展望

制御UU演算を実行するには θ\theta を知っている必要があったため、量子位相推定アルゴリズムは無意味に見えるかもしれません。後の章で、θ\theta が不明な状態で回路を作る方法を学び、このθ\theta について学習することで、非常に有用な情報が得られることが分かります(最も有名なのは、数を因数分解する方法です!)。

7. 参考文献

[1] Michael A. Nielsen and Isaac L. Chuang. 2011. Quantum Computation and Quantum Information: 10th Anniversary Edition (10th ed.). Cambridge University Press, New York, NY, USA.

8. 寄稿者

03/20/2020 — Hwajung Kang (@HwajungKang) — Fixed inconsistencies with qubit ordering

import qiskit.tools.jupyter %qiskit_version_table
{'qiskit-terra': '0.14.2', 'qiskit-aer': '0.5.2', 'qiskit-ignis': '0.3.3', 'qiskit-ibmq-provider': '0.7.2', 'qiskit-aqua': '0.7.3', 'qiskit': '0.19.6'}