Learn to Quantum Algorithm with Qamomile: Iterative QPE
この記事はJij Advent Calendar 2024の24日目の記事です.
Introduction
The Iterative Quantum Phase Estimation (IQPE) algorithm is a cornerstone of quantum computing, used to estimate the eigenphase of a unitary operator corresponding to an eigenstate. It is a more resource-efficient variant of the Quantum Phase Estimation (QPE) algorithm, requiring only one ancillary qubit.
This tutorial explains the algorithm's key steps, its implementation in Qamomile and quri-parts.
Prerequisites
Before running the code, ensure the required libraries are installed:
pip install qamomile
pip install quri-parts-qulacs==0.19.0
pip install quri-parts-circuit==0.19.0
pip install quri-parts-core==0.19.0
Algorithm Overview
The IQPE algorithm iteratively refines the estimate of the eigenphase using the following steps:
-
Initialization: Prepare a quantum state
, an eigenstate of a unitary operator| \psi \rangle .U - Hadamard Gate: Apply a Hadamard gate to the ancillary qubit.
-
Controlled-U Operations: Implement the
-controlledk operation to amplify phase information.U^{2^{k-1}} - Kickback Phase: Introduce a kickback phase to refine the estimate iteratively.
-
Final Measurement: Measure the ancillary qubit to determine the
-th binary digit of the eigenphase.k
IQPE Circuit Construction
The IQPE circuit consists of one ancillary qubit and a system qubit. Controlled operations and phase shifts are applied iteratively to extract the phase. Here's the implementation in Qamomile:
def iqpe_circuit(target_angle, kickback_phase, k):
"""Constructs the Iterative Quantum Phase Estimation (IQPE) circuit."""
n_qubits = 2 # 1 system qubit, 1 ancilla qubit
ancilla_idx = 1
circuit = QuantumCircuit(n_qubits)
circuit.h(ancilla_idx) # Apply Hadamard to ancilla
circuit.rz(kickback_phase, ancilla_idx) # Apply kickback phase rotation
# Controlled time evolution for 2^(k-1) times
for _ in range(2 ** (k - 1)):
circuit.rz(target_angle, 0)
circuit.cnot(ancilla_idx, 0)
circuit.h(ancilla_idx) # Final Hadamard gate
return circuit
Iterative Phase Estimation
The Iterative Phase Estimation algorithm uses controlled quantum gates and classical post-processing to iteratively determine the eigenphase of a unitary operator
Mathematical Foundation
-
Problem Setup:
Given a unitary operator and its eigenstateU , the eigenvalue equation is:| \psi \rangle U | \psi \rangle = e^{2\pi i \phi} | \psi \rangle where
is the eigenphase we aim to estimate.\phi -
Controlled Unitary Evolution:
To extract , we use a controlled application of\phi . If the ancilla qubit is in stateU^{2^k} , the operator|1 \rangle is applied toU^{2^k} . The combined state evolves as| \psi \rangle |0\rangle | \psi \rangle + e^{2\pi i (2^k \phi)} |1 \rangle | \psi \rangle -
Interference via Hadamard:
A Hadamard gate on the ancilla qubit creates interference, allowing the phase information to modulate the probability amplitudes of measuring or|0\rangle . After the Hadamard, the state becomes:|1\rangle
Measuring the ancilla qubit yields probabilities:
-
Binary Phase Digits:
By iteratively adjusting a kickback phase , the algorithm determines the binary digits of\gamma_k . At each iteration\phi , the phase is updated:k \phi_k = \frac{\gamma_k}{2} + \frac{\pi}{2} b_k where
is determined by the measured probabilities.b_k \in \{0, 1\} -
Recursive Phase Refinement:
The new is derived from the previous phase estimate:\phi \gamma_k = 0.5 \cdot \gamma_{k+1} + \pi \cdot b_k
Iterative Process
At each step
- Constructs the quantum circuit to apply
.U^{2^{k-1}} - Updates the kickback phase
to refine the phase estimate.\gamma_k - Measures the ancilla qubit and determines the
-th binary digitk .b_k - Combines
withb_k to produce the new estimate\gamma_k .\phi_k
In summary, IQPE leverages interference, controlled unitary evolution, and iterative refinement to estimate
Iterative Phase Estimation code
The first function maps parameter names to values and the core logic of IQPE refines the phase estimation iteratively.
def generate_params_dict(qp_circuit, param_value_mapping):
"""Generates a parameter mapping dictionary."""
params_dict = {}
for param in qp_circuit.param_mapping.in_params:
param_name = param.name
if param_name in param_value_mapping:
params_dict[param] = param_value_mapping[param_name]
else:
raise ValueError(f"Unknown parameter: {param_name}")
return params_dict
def iterative_phase_estimation(target_angle, n_iterations, kickback_phase=0.0):
"""Performs iterative phase estimation to estimate the phase."""
kth_digit_list = []
for k in reversed(range(1, n_iterations + 1)):
param_target_angle = Parameter("theta")
param_kickback_phase = Parameter("gamma")
circuit = iqpe_circuit(param_target_angle, param_kickback_phase, k)
qp_transpiler = QuriPartsTranspiler()
qp_circuit = qp_transpiler.transpile_circuit(circuit)
param_value_mapping = {
'gamma': -kickback_phase,
'theta': 2 * target_angle
}
params_dict = generate_params_dict(qp_circuit, param_value_mapping)
qp_mapped = qp_circuit.bind_parameters_by_dict(params_dict)
circuit_state = quantum_state(2, bits=0b00)
psi = evaluate_state_to_vector(
circuit_state.with_gates_applied(qp_mapped.gates)
).vector
# Calculate probabilities
p0 = get_marginal_probability(psi, {1: 0})
p1 = get_marginal_probability(psi, {1: 1})
kth_digit = 1 if (p0 < p1) else 0
kickback_phase = 0.5 * kickback_phase + np.pi * 0.5 * kth_digit
kth_digit_list.append(kth_digit)
return 2 * kickback_phase
Example Simulation
The main function demonstrates the use of IQPE to estimate a target angle with increasing iterations.
A simple setting with iterative 12 times. we can see the e_iqpe
is close to the target angle
target_angle = 1
iterative_times = 12
result_list = []
time_list = []
for n_itter in range(1, iterative_times + 1):
start_time = time.time()
iqpe_phase = iterative_phase_estimation(target_angle, n_itter, kickback_phase=-1)
error = np.abs(iqpe_phase - target_angle)
print(f"n_itter={n_itter:2d}, e_iqpe={iqpe_phase:.6f}, error={error:.5e}")
result_list.append([n_itter, iqpe_phase])
time_list.append([n_itter, time.time() - start_time])
Here shows the process of iterations.
n_itter= 1, e_iqpe=-1.000000, error=2.00000e+00
n_itter= 2, e_iqpe=1.070796, error=7.07963e-02
n_itter= 3, e_iqpe=1.320796, error=3.20796e-01
n_itter= 4, e_iqpe=1.053097, error=5.30972e-02
n_itter= 5, e_iqpe=0.919248, error=8.07523e-02
n_itter= 6, e_iqpe=1.048672, error=4.86725e-02
n_itter= 7, e_iqpe=1.015210, error=1.52101e-02
n_itter= 8, e_iqpe=0.998479, error=1.52110e-03
n_itter= 9, e_iqpe=1.002385, error=2.38515e-03
n_itter=10, e_iqpe=0.998202, error=1.79765e-03
n_itter=11, e_iqpe=0.999179, error=8.21089e-04
n_itter=12, e_iqpe=0.999667, error=3.32808e-04
Last we can plot the result for the visualizations.
# Plotting results
result_array = np.array(result_list)
plt.xlabel("n_itter", fontsize=15)
plt.ylabel("Gap", fontsize=15)
plt.yscale("log")
plt.plot(result_array[:, 0], np.abs(result_array[:, 1] - target_angle), "bo-")
plt.xlim(0, iterative_times)
plt.fill_between([0, iterative_times], 1.6e-3, color="lightgrey")
# Chemical accuracy region
plt.show()
Conclusion
The IQPE algorithm is a powerful quantum tool for precise eigenphase estimation, with applications in quantum chemistry, material science, and beyond. Understanding its principles and implementation is fundamental to advancing quantum computing research.
募集
Jijでは数理最適化・量子コンピュータに関連するソフトウェア開発を行っています。
OSSも複数開発、提供しています。Discordのコミュニティへぜひ参加してください!
また,Jijでは各ポジションを絶賛採用中です!
ご興味ございましたらカジュアル面談からでもぜひ!ご連絡お待ちしております。
数理最適化エンジニア(採用情報)
量子コンピューティングソフトウェアエンジニア(採用情報)
Rustエンジニア(アルゴリズムエンジニア)(採用情報)
研究チームPMO(採用情報)
オープンポジション等その他の採用情報はこちら
Discussion