HHL 算法
概述
HHL算法的目的: 给定一个 Hermitian
令
设
那么
将
使用量子相位估计 QPE(Quantum Phase Estimation),其中
其中
很容易看出方程的解就是
所以我们只需要将信息从量子态
HHL 算法步骤
下面详细介绍 HHL 算法的详细步骤,包含详细的数学推导。
数据预处理
前面提到
然后求解方程
很容易验证方程的解
其中
对于
制备算子
如何高效的制备算子
制备这个时间演化算子
在原论文中,对矩阵
这里不去展开证明 QPE 的正确性,读者只需要知道 QPE 的输入是一个酉算子
具体来说,使用
其中
为了更好的理解,这里举一个例子: 取
那么
两个相位分别是
如果我们使用
两个相位的估计值分别是
通过简单的定量计算,我们得到如下的映射关系:
其中
条件旋转
经过 QPE 后,整个量子态如下
想要将
简单来说,只有当
因为我们不知道正确的
旋转的效果是很简单的
再作用一次逆 QPE,整体的量子态如下
测量
对最后一个量子比特进行测量,当测量结果是
测量后的量子态变为
显然此时三个量子寄存器之间不存在纠缠,如果只看第一个量子寄存器,它已经是
需要指出的是,旋转操作里面有一个参数
MindQuantum 实现
这里使用 MindQuantum 实现一个简单的例子,仅说明 HHL 算法的过程和正确性。
为了计算方便,我们选取一个简单的
[1]:
import numpy as np
A = np.array([[1, 0], [0, -1]])
es, vs = np.linalg.eig(A)
print(f"eigenvalues of A:\n {es}")
print(f"eigenvectors of A:\n {vs}")
b = np.array([0.6, 0.8])
print(f"b: {b}")
print(f"Solution of Ax=b is: {np.linalg.solve(A, b)}")
eigenvalues of A:
[ 1. -1.]
eigenvectors of A:
[[1. 0.]
[0. 1.]]
b: [0.6 0.8]
Solution of Ax=b is: [ 0.6 -0.8]
这里导入所需要的各种函数:
[2]:
from mindquantum.core.gates import H, X, RY, RZ, Measure, Power, BARRIER
from mindquantum.core.circuit import Circuit
from mindquantum.simulator import Simulator
对于量子态
下面的代码制备了
[3]:
circ = Circuit()
circ += RY(2 * np.arcsin(0.8)).on(0)
circ += Measure().on(0)
sim = Simulator(backend="mqvector", n_qubits=1)
res = sim.sampling(circ, shots=10000)
res.svg()
[3]:
下面一步步构建出完整的量子线路,取
首先是 QPE
然后是
,接着是 逆QPE
最后测量
[4]:
from mindquantum.algorithm.library import qft
# q1 ~ q4 : for QPE
t = 4
qc = [4, 3, 2, 1]
# store |b> , and store the result |x>
qb = 5
# use for conditional rotation
qs = 0
# choose a time evolution
dt = np.pi / 4
# choose a small C
C = 0.5
circ = Circuit()
# prepare b
circ += RY(2 * np.arcsin(0.8)).on(qb)
# QPE
for i in qc:
circ += H.on(i)
for (i, q) in enumerate(qc):
circ += Power(RZ(-2 * dt), 2**i).on(qb, q)
# apply inverse QFT
circ += qft(list(reversed(qc))).hermitian()
# conditional rotate
circ += BARRIER
for k in range(1, 2**t):
for i in range(t):
if (k & (1 << i)) == 0:
circ += X.on(qc[i])
phi = k / (2**t)
if k > 2**(t-1):
phi -= 1.0
l = 2 * np.pi / dt * phi
circ += RY(2 * np.arcsin(C / l)).on(qs, qc)
for i in range(t):
if (k & (1 << i)) == 0:
circ += X.on(qc[i])
circ += BARRIER
# apply inverse QPE
circ += qft(list(reversed(qc)))
for (i, q) in enumerate(qc):
circ += Power(RZ(2 * dt), 2**i).on(qb, q)
for i in qc:
circ += H.on(i)
circ.svg()
[4]:
如何验证我们的结果的正确性?测量。因为结果是量子态
[5]:
sim = Simulator(backend="mqvector", n_qubits=2 + t)
sim.apply_circuit(circ)
circ_m = Circuit()
circ_m += Measure().on(qs)
circ_m += Measure().on(qb)
res = sim.sampling(circ_m, shots=100000)
res.svg()
[5]:
[6]:
res.data.get("01", 0) / (res.data.get("01", 0) + res.data.get("11", 0))
[6]:
0.3602052179446389
通过统计当 q0
是 1 时,q5
的测量结果,我们看到 q5 = 0
的占比是 0.36
,和答案的预期一致。
当然这种方法只能得到振幅大小,想要得到更多信息,例如相位,需要对测量进行调整,这里不去讨论。
[7]:
from mindquantum.utils.show_info import InfoTable
InfoTable('mindquantum', 'scipy', 'numpy')
[7]:
Software | Version |
---|---|
mindquantum | 0.9.11 |
scipy | 1.10.1 |
numpy | 1.23.5 |
System | Info |
Python | 3.9.16 |
OS | Linux x86_64 |
Memory | 8.3 GB |
CPU Max Thread | 8 |
Date | Fri Dec 29 23:43:57 2023 |