量子相位估计算法

下载Notebook下载样例代码查看源文件

概述

量子相位估计算法(Quantum Phase Estimation Algorithm,简称QPE),是很多量子算法的关键。假设一个幺正算符 U,这个幺正算符作用在其本征态 |u 上会出现一个相位 e2πiφ,现在我们假设 U 算符的本征值未知,也就是 φ 未知,但是 U 算符和本征态 |u 已知,相位估计算法的作用就是对这个相位 φ 进行估计。

quantum phase estimation

算法解析

量子相位估计算法的实现需要两个寄存器(register),第一寄存器包含t个初始在 |0 的量子比特,比特数和最后相位估计的结果的精度和算法的成功概率相关;第二个寄存器初始化在幺正算符 U 的本征态 |u 上。相位估计算法主要分为三步:

步骤一

对第一寄存器的所有量子比特进行 Hadamard 门操作,对第二寄存器连续进行 控制U 门操作,其中 U 门的幂次依次为 20,21,...,2t1,控制比特依次为 qt1,qt2,...,q1,q0。这时第一寄存器中的态就会变为

|ψ1=12t/2(|0+ei2π2t1φ|1)(|0+ei2π2t2φ|1)...(|0+ei2π20φ|1)=12t/2k=02t1ei2πφk|k

其中k为直积态的十进制表示,比如 k=0 表示第一寄存器中t个比特全部在基态 |00...00k=2 表示 |00...10,以此类推。

步骤二

对第一寄存器的进行量子傅里叶变换的逆变换(Inverse Quantum Fourier Transform),在线路中表示成 QFT, 对 |ψ1 进行逆量子傅里叶变换可得 |ψ2

|ψ2=QFT|ψ1=12tx=02t1ax|x

其中

ax=k=02t1e2πik(φx/2t)

为本征基矢 |x (x=0.1,...,2t) 对应的概率幅。由上式可得,当 2tφ 为整数,且满足 x=2tφ 时,概率幅取最大值1,此时第一寄存器的末态可以精确反映 φ;当 2tφ 不是整数时,xφ 的估计,且t越大,估计精度越高。

步骤三

对第一寄存器的量子比特进行测量,得到第一寄存器的末态 f=x2t1ax|x, x=0,1,...,2t,从中找到最大的振幅 amax,其对应的本征基矢 |x 中的 x 再除以 2t 即为相位的估计值。

QPE代码实现

下面用一个实例来演示如何在MindSpore Quantum实现量子相位估计算法,选择 T 门作为进行估计的幺正算符,由定义

T|1=eiπ/4|1

可知需要估计的相位角为 φ=18

现在假设我们不知道 T 门的相位信息,只知道幺正算符 UT 门且本征态为 |1 ,接下来我们需要用量子相位估计算法求出其对应的本征值,即需要估计本征值指数上的相位角。

首先导入相关依赖。

[1]:
from mindquantum.core.gates import T, H, X, Power, BARRIER
from mindquantum.core.circuit import Circuit, UN
from mindquantum.simulator import Simulator
from mindquantum.algorithm.library import qft
import numpy as np

UN 可以指定量子门,目标比特和控制比特,从而在线路中搭建门操作; Power 可以得到指定量子门的指数形式。因为我们已知 T 门的本征态为 |1,所以第二寄存器只需1个比特,而在第一寄存器中的比特数越多,得到的结果就越准确,在这里我们使用4个比特。

因此我们需要搭建5比特线路, q0,q1,q2,q3 比特用于估计,属于第一寄存器, q4 属于第二寄存器用于传入 T 算符的本征态。

利用 UNq0,q1,q2,q3 进行 Hadamard 门操作,用 X 门对 q4 进行翻转,得到 T 门的本征态 |1

[2]:
# pylint: disable=W0104
n = 4
circ = Circuit()
circ += UN(H, n) # 对前4个比特作用力H门
circ += X.on(n)  # 对q4作用X门
circ.svg()
[2]:
../_images/case_library_quantum_phase_estimation_5_0.svg

q4 为目标比特,添加控制T2i门。

[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.svg()
[3]:
../_images/case_library_quantum_phase_estimation_7_0.svg

对第一寄存器中的比特进行逆量子傅里叶变换。

[4]:
# pylint: disable=W0104
circ += BARRIER
circ += qft(range(n)).hermitian() # 对前4个比特作用量子傅立叶变换的逆变换
circ.svg()
[4]:
../_images/case_library_quantum_phase_estimation_9_0.svg

选择后端、传入总比特数创建模拟器,对量子线路进行演化,得到末态。

[5]:
# pylint: disable=W0104
from mindquantum.core.gates import Measure
sim = Simulator('mqvector', 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.svg()
[5]:
../_images/case_library_quantum_phase_estimation_11_0.svg

需要注意的是,测量结果作为二进制串的读取顺序应为|q0q1q2q3,因此我们得到寄存器1的测量结果为0010,概率幅为1,该末态可以精准地反映相位φ。但0010是二进制结果,因此我们将它转回十进制后再除以2n,就得到了我们最终的估计值:φ=224=18

我们也可以通过线路演化得到的量子态 qs 找出第一寄存器中振幅最大值 amax 的位置,进而得到其对应的本征基矢 |x ,其中的 x 再除以 2t 即为相位的估计值。

[6]:
index = np.argmax(np.abs(qs))
print(bin(index)[2:])
10100

需要注意的是,qs 对应的是整个量子线路的末态,因此得到的 index 也包含第二寄存器中的比特,不能直接得到第一寄存器末态中 amax 对应的 |x ,需要将 index 转成二进制后将 q4 对应的比特位剔除,然后得到的才是第一寄存器的 |x

[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

可见得到的估计相位和 φ 近似相等。

[9]:
from mindquantum.utils.show_info import InfoTable

InfoTable('mindquantum', 'scipy', 'numpy')
[9]:
Software Version
mindquantum0.9.11
scipy1.10.1
numpy1.23.5
System Info
Python3.9.16
OSLinux x86_64
Memory8.3 GB
CPU Max Thread8
DateSun Dec 31 23:59:31 2023

参考文献

[1] Michael A. Nielsen and Isaac L. Chuang. Quantum computation and quantum information