HHL Algorithm
Overview
Objective of the HHL algorithm: Given a Hermitian matrix
Let
Assume the spectral decomposition of
Then,
Express
Using Quantum Phase Estimation (QPE), where
Here,
It is easy to see that the solution to the equation is:
Therefore, we only need to extract the information from the quantum state
Steps of the HHL Algorithm
Below, we provide a detailed explanation of the steps involved in the HHL algorithm, including the mathematical derivations.
Data Preprocessing
As mentioned earlier,
Then, we solve the equation:
It can be easily verified that the solution to this equation,
where
For
Preparation of Operator
The efficient preparation of the operator
The preparation of this time evolution operator
In the original paper, a sparsity constraint was imposed on the matrix
Here, we won’t go into the proof of the correctness of QPE. Readers only need to know that the input of QPE is a unitary operator
Specifically, using
Here,
To better understand, let’s take an example: Take
Then
The two phases are
If we use
The estimated values of the two phases are
Through simple quantitative calculations, we obtain the following mapping relationship:
Here,
Conditional Rotation
After QPE, the overall quantum state is as follows:
To extract the information of
In simple terms, the rotation operation is only applied to the subsequent qubits when
Since we don’t know the correct
The effect of the rotation is straightforward:
After applying inverse QPE once again, the overall quantum state is as follows:
Measurement
Measure the last qubit. When the measurement result is
After the measurement, the quantum state becomes
Clearly, there is no entanglement between the three quantum registers at this point. If we only look at the first quantum register, it is already in the state
It should be noted that there is a parameter
Implementation with MindQuantum
Here, we use MindQuantum to implement a simple example to illustrate the process and correctness of the HHL algorithm.
For convenience, we choose a simple matrix
[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]
Here, we import various required functions:
[2]:
from mindquantum.core.gates import H, X, RY, RZ, Measure, Power, BARRIER
from mindquantum.core.circuit import Circuit
from mindquantum.simulator import Simulator
For the preparation of the quantum state
The following code prepares the state
[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]:
The following is the step-by-step construction of the complete quantum circuit, with
First is QPE.
Then comes
, .Next is inverse QPE.
Finally, measurement is performed.
[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]:
How do we verify the correctness of our results? Through measurement. Since the result is a quantum state
[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.3612780010344965
By statistically analyzing the measurement results of q5
when q0
is 1, we observe that the proportion of q5 = 0
is 0.36
, which is consistent with the expected answer.
However, this method only provides information about the magnitude of the amplitudes. To obtain more information, such as phase, adjustments to the measurement would be required, but we won’t discuss that here.
[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 | Sat Dec 30 23:19:52 2023 |