在量子傅里叶变换的基础上,我们可以实现量子相位估计算法。量子相位估计算法也是量子计算算法中的最重要的子算法之一。
1 相位估计 假设有一个幺正算符U(其本征值的模应为1),它有一个本征态 ,相应的本征值为 , 是未知的。相位估计算法的目的就是估计出 。接下来我们用 表示真实的相位,用 表示我们估计得到的相位。
1.1 量子傅里叶变换 在量子相位估计算法流程中,我们需要用到量子傅里叶逆变换,因此我们先回顾下量子傅里叶变换与逆变换的作用。
在上一篇笔记中,我们详细介绍了量子傅里叶变换,并给出推导:
量子傅里叶变换可以表示为
1.2 量子相位估计的流程 量子相位估计的流程
图中,位于上方的寄存器暂称为辅助寄存器,它包括t个量子比特,t的选择取决于两个因素:我们希望得到的估计相位 的精度的位数;我们以多大概率希望相位估计过程成功。我们将在后续的分析中认识到这两点。
位于下方的寄存器存储着态 ,它的量子比特数量应刚好可以表示 。
直观的理解量子相位估计的流程:首先将U的相位(在傅里叶基下)写入到辅助寄存器中,然后我们利用量子傅里叶逆变换将它从傅里叶基变换到计算基下,而计算基下我们是可以进行测量的。
1.3 数学推导 相位估计的任务是:估计幺正算符U的相位。 ,其中 为U的本征态, 是相应的本征值。
相位估计电路执行步骤如下:
初态 : 叠加 :在辅助寄存器上执行t-bit H门, 受控幺正算符 :U是我们要估计的算符,用CU来表示受控的U,CU的行为为:仅当控制比特为 时,对目标比特应用U,否则保持不变。 应用t个受控门 , ,且根据关系式 。有 这里的k表示n-bit二进制数的整数表示。量子傅里叶逆变换 :由于量子傅里叶变换可以记为: 我们将x取为 ,则刚好得到 ,即 。因此要恢复态 ,只需要在辅助寄存器上应用量子傅里叶逆变换。测量 :此时寄存器的状态为: 。考虑到 中的应该是一个小数( ,n为整数,则只有小数部分有意义), 假设二进制小数 ( ),如果 ,我们可以精确到得到 。而如果 ,我们依旧得到了一个足够精确的近似解。可以证明:如果想要以至少 的概率获得 精确到n位的估计,需要t满足: ,(这里[x]表示向下取整)。详细证明可以参考《Quantum Computation and Quantum Information》第五章。
1.4 本征态问题 在上述流程中,我们需要使用到算符U的一个本征态。如果我们不知道如何制备它的本征态,此时算法如何运行?假设我们制备了一个态 ,而U的本征态为 ,对应本征值为 。将 按照U的本征态展开 。直观地分析,现在运行相位估计算法,应当会输出一个接近于 的态, 是 的一个很好的估计。对这个态进行测量我们以 , ( )的概率得到 。也就是说即便我们不特意制备U的本征态依旧可以得到其本征值的信息。
1.5 算法流程 算法:量子相位估计
输入 :1. 一个产生受控门 的黑盒
2. U的一个本征值为 的 本征态
3. ([x]表示向下取整)个初始态为 的量子比特
输出 : 一个n比特的估计
运行时间 : 操作和 黑盒的各一次调用。成功的概率至少为
流程 :
1. 初始态
2. 制备叠加态
3. 通过黑盒
4. 执行量子傅里叶逆变换
5. 测量辅助寄存器
2 Qiskit中实现量子相位估计算法 我们尝试在Qiskit中实现并验证一下相位估计算法。
2.1 T-Gate T门的矩阵表示为: ,则 ,
我们可以知道 。
我们将用三个量子比特计算出其精确值。
创建电路
import matplotlib.pylab as plt
import numpy as np
import math
from qiskit import Aer,transpile,assemble
from qiskit import QuantumCircuit
from qiskit.visualization import plot_histogram
qpe = QuantumCircuit(4,3)
qpe.x(3) # 态|1>
qpe.draw('mpl')
添加H门
for qubit in range(3):
qpe.h(qubit)
qpe.draw('mpl')
执行受控T门
repetitions = 1
for help_qubit in range(3):
for i in range(repetitions):
qpe.cp(math.pi/4,help_qubit,3) # 这是CU 也就是 受控的T门
repetitions *= 2
qpe.draw('mpl')
定义量子傅里叶逆变换 ,这个电路的分析我们在上一篇中介绍过。
def qft_dagger(qc,n):
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()
qft_dagger(qpe,3)
qpe.barrier()
for n in range(3):
qpe.measure(n,n)
qpe.draw('mpl')
模拟电路
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)
输出的结果十进制中为:1。根据我们上面的分析即 ,这里n=3,故 。
2.2 精度问题 2.2.1 三比特模拟 上述实验中, 是可以被精确估计出来的。现在我们考虑无法精确估计的情况。
我们取 。
执行电路,
qpe2 = QuantumCircuit(4,3)
for qubit in range(3):
qpe2.h(qubit)
qpe2.x(3)
angle = 2*math.pi / 3
repetition = 1
for help_qubit in range(3):
for i in range(repetition):
qpe2.cp(angle,help_qubit,3)
repetition *= 2
qft_dagger(qpe2,3)
for n in range(3):
qpe2.measure(n,n)
qpe2.draw('mpl')
模拟
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)
我们期待的结果是 ,此时
观测模拟结果,我们得知最有可能的结果是010(bin) = 2(dec) 和011(bin)=3(dec),他们分别对应着 和 。真实的结果在这两个值之间,这给我们带来了不确定性及不精确性。
根据之前的理论分析,我们想要获得更精确到结果就需要用到更多辅助比特。
2.2.2 五比特模拟 这次我们使用五个辅助量子比特进行计算,并观测结果。
qpe3 = QuantumCircuit(6,5)
for qubit in range(5):
qpe3.h(qubit)
qpe3.x(5)
angle = 2*math.pi / 3
repetition = 1
for help_qubit in range(5):
for i in range(repetition):
qpe3.cp(angle,help_qubit,5)
repetition *= 2
qft_dagger(qpe3,5)
for n in range(5):
qpe3.measure(n,n)
aer_sim = Aer.get_backend('aer_simulator')
shots = 40960
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)
这次最有可能的测量结果是01001(decimal 11) 和 01010(decimal 10)。对应计算得到的 为: 和 。这两个结果与理论值的差距仅为 3%和6%了。
参考资料:《Quantum Computation and Quantum Information》
Qiskit