Quantum Phase Estimation
Quantum Phase Esitmation is one of the most fundamental algorithms in quantum computing. Its purpose is to estimate the eigenvalue of a given unitary operator and its eigenstate , s.t. .
In other words, QPE converts the information encoded in the phase of a quantum state into measurable binary data.
QPE is proceeded through the following steps:
-
Initialization: Prepare two registers - Ancilla register of m qubits initialized in , System register eigenstate of .
-
Hadamard gates operation: Apply Hadamard gate to each ancilla qubit:
This step is prepared for parallel phase encoding, as it creates a uniform superposition over all computational basis states of the ancilla register.
-
Controlled Unitary Operations - Phase kickback: For each ancilla qubit, apply a controlled operation :
This process is known as phase kickback, the eigenphase of is transferred into the phase of the ancilla register. The resulting state becomes:
-
Inverse Quantum Fourier Transformation: Apply the inverse QFT to the ancilla register:
where encodes the binary digits of the best -bits approximation to . This step converts phase information into an amplitude distribution peaked around that binary value.
-
Measurement Measure the ancilla register to obtain the binary representation of , which approximates the true phase with the precision .
Define a Hamiltonian for QPE
First, we create a Hamiltonian using Pauli operators. This Hamiltonian represents the quantum system whose eigenvalues we want to estimate using the Quantum Phase Estimation algorithm. The Hamiltonian contains X, Y, and Z Pauli terms acting on two qubits.
from quri_parts.core import Operator, pauli_label
from quri_algo.problem import QubitHamiltonian
hamiltonian = Operator(
{
pauli_label("X0 X1"): 1.0,
pauli_label("Y0 Y1"): 2.0,
pauli_label("Z0 Z1"): 3.0,
}
)
qubit_hamiltonian = QubitHamiltonian(2, hamiltonian)
Visualize the QPE Circuit
Here we construct and visualize the Quantum Phase Estimation circuit. We use Trotter time evolution to approximate the unitary operator exp(-iHt), where H is our Hamiltonian and t is the evolution time. The QPE circuit uses m=3 ancilla qubits to estimate the phase with sufficient precision.
from quri_parts.qsub.lib import qpe
from quri_parts.qsub.visualize import draw
from quri_algo.qsub.time_evolution.trotter_time_evo import TrotterTimeEvo
t = 1/3
n_trotter = 1
trotter_order = 1
time_evo_op = TrotterTimeEvo(qubit_hamiltonian, t, n_trotter, trotter_order)
m = 3
draw(qpe.QPE(m, time_evo_op ))

Run the QPE Algorithm
In this section, we execute the Quantum Phase Estimation algorithm to estimate the eigenvalues of our Hamiltonian. We first calculate the exact eigenvalues using classical diagonalization for comparison. Then we prepare an initial quantum state and run QPE with m=9 ancilla qubits for high precision. The algorithm uses 1 million shots to gather sufficient statistics for accurate phase estimation.
Build a state which is a uniform superposition of all the eigenstates of the Hamiltonian
import numpy as np
from quri_algo.algo.phase_estimation.qpe.qpe import TimeEvolutionQPE
from quri_parts.qsub.primitive import SimulatorBasicSet
from quri_parts.qulacs.sampler import create_qulacs_general_vector_sampler
from quri_parts.core import get_sparse_matrix, quantum_state
from quri_parts.circuit import QuantumCircuit
vals, vecs = np.linalg.eigh(get_sparse_matrix(hamiltonian).toarray())
gs_val = vals[0]
circuit = QuantumCircuit(2)
circuit.add_H_gate(1)
circuit.add_Z_gate(1)
gs_vec = quantum_state(qubit_hamiltonian.n_qubit, circuit=circuit)
sampler = create_qulacs_general_vector_sampler()
n_shots = int(1e6)
m = 10
evolution_time = 1/16
qpe_algo = TimeEvolutionQPE(TrotterTimeEvo, sampler)
qpe_result = qpe_algo.run(gs_vec, n_shots, m, qubit_hamiltonian, evolution_time, primitives=SimulatorBasicSet)