量子相位估计算法
概述
量子相位估计算法(Quantum Phase Estimation Algorithm,简称QPE),是很多量子算法的关键。假设一个幺正算符
算法解析
量子相位估计算法的实现需要两个寄存器(register),第一寄存器包含
对第一寄存器的所有量子比特进行
Hadamard
门操作,对第二寄存器连续进行控制U
门操作,其中 门的幂次依次为 ,控制比特依次为 。这时第一寄存器中的态就会变为
其中
对第一寄存器的进行量子傅里叶变换的逆变换(Inverse Quantum Fourier Transform),在线路中表示成
, 对 进行逆量子傅里叶变换可得
其中
为本征基矢
对第一寄存器的量子比特进行测量,得到第一寄存器的末态
, ,从中找到最大的振幅 ,其对应的本征基矢 中的 再除以 即为相位的估计值。
QPE代码实现
下面用一个实例来演示如何在MindQuantum实现量子相位估计算法,选择 T
门作为进行估计的幺正算符,由定义
可知需要估计的相位角为
现在假设我们不知道 T
门的相位信息,只知道幺正算符 T
门且本征态为
首先导入相关依赖。
[1]:
from mindquantum.core import Circuit, UN, T, H, X, Power, BARRIER
from mindquantum.simulator import Simulator
from mindquantum.algorithm import qft
import numpy as np
UN
可以指定量子门,目标比特和控制比特,从而在线路中搭建门操作; Power
可以得到指定量子门的指数形式。因为我们已知 T
门的本征态为
因此我们需要搭建5比特线路,
利用 UN
对 Hadamard
门操作, 用 X
门对 T
门的本征态
[2]:
# pylint: disable=W0104
n = 4
circ = Circuit()
circ += UN(H, n) # 对前4个比特作用力H门
circ += X.on(n) # 对q4作用X门
circ
[2]:
q0: ──H── q1: ──H── q2: ──H── q3: ──H── q4: ──X──
以
[3]:
# pylint: disable=W0104
for i in range(n):
circ += Power(T, 2**i).on(n, n - i - 1) # 添加T^2^i门,其中q4为目标比特,n-i-1为控制比特
circ
[3]:
q0: ──H──────────────────────────●─── │ q1: ──H───────────────────●──────┼─── │ │ q2: ──H────────────●──────┼──────┼─── │ │ │ q3: ──H─────●──────┼──────┼──────┼─── │ │ │ │ q4: ──X────T^1────T^2────T^4────T^8──
对第一寄存器中的比特进行逆量子傅里叶变换。
[4]:
# pylint: disable=W0104
circ += BARRIER
circ += qft(range(n)).hermitian() # 对前4个比特作用量子傅立叶变换的逆变换
circ
[4]:
q0: ──H──────────────────────────●──────────@───────────────────────────────────────────────────────PS(-π/8)────PS(-π/4)────PS(-π/2)────H── │ │ │ │ │ q1: ──H───────────────────●──────┼─────@────┼──────────────────────────PS(-π/4)────PS(-π/2)────H───────┼───────────┼───────────●─────────── │ │ │ │ │ │ │ │ q2: ──H────────────●──────┼──────┼─────@────┼─────────PS(-π/2)────H───────┼───────────●────────────────┼───────────●─────────────────────── │ │ │ │ │ │ │ q3: ──H─────●──────┼──────┼──────┼──────────@────H───────●────────────────●────────────────────────────●─────────────────────────────────── │ │ │ │ q4: ──X────T^1────T^2────T^4────T^8────────────────────────────────────────────────────────────────────────────────────────────────────────
选择后端、传入总比特数创建模拟器,对量子线路进行演化,得到末态。
[5]:
# pylint: disable=W0104
from mindquantum import Measure
sim = Simulator('projectq', circ.n_qubits) # 创建模拟器
sim.apply_circuit(circ) # 用模拟器演化线路
qs = sim.get_qs() # 获得演化得到的量子态
res = sim.sampling(UN(Measure(), circ.n_qubits - 1), shots=100) # 在寄存器1中加入测量门并对线路进行100次采样,获得统计结果
res
[5]:
shots: 100 Keys: q3 q2 q1 q0│0.00 0.2 0.4 0.6 0.8 1.0 ─────────────────┼───────────┴───────────┴───────────┴───────────┴───────────┴ 0100│▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ │ {'0100': 100}
需要注意的是,测量结果作为二进制串的读取顺序应为0010
,概率幅为1,该末态可以精准地反映相位0010
是二进制结果,因此我们将它转回十进制后再除以
我们也可以通过线路演化得到的量子态 qs
找出第一寄存器中振幅最大值
[6]:
index = np.argmax(np.abs(qs))
print(bin(index)[2:])
10100
需要注意的是,qs
对应的是整个量子线路的末态,因此得到的 index
也包含第二寄存器中的比特,不能直接得到第一寄存器末态中 index
转成二进制后将
[7]:
bit_string = bin(index)[2:].zfill(circ.n_qubits)[1:] # 将index转换成01串并剔除q4
bit_string = bit_string[::-1] # 将比特串顺序调整为q0q1q2q3
print(bit_string)
0010
再将二进制转回十进制,得到我们最终的估计值。
[8]:
# pylint: disable=W0104
theta_exp = int(bit_string, 2) / 2**n
theta_exp
[8]:
0.125
可见得到的估计相位和
参考文献
[1] Michael A. Nielsen and Isaac L. Chuang. Quantum computation and quantum information