Skip to content

Latest commit

 

History

History
117 lines (91 loc) · 3.32 KB

File metadata and controls

117 lines (91 loc) · 3.32 KB

Tutorial 7: Quantum Phase Estimation

Objective

Implement Quantum Phase Estimation (QPE) to find eigenvalues of unitary operators.

Prerequisites

  • Tutorial 6 (QFT) completed

What You'll Learn

  • Phase kickback mechanism
  • QPE circuit construction
  • Reading phase measurements

Step-by-Step Code

import math
from abirqu import Circuit, H, X, Y, Z
from abirqu.primitives import QuantumRun

def build_qpe(num_counting_qubits, target_state):
    """Build QPE circuit.
    
    Args:
        num_counting_qubits: Number of counting qubits (precision)
        target_state: Eigenvalue phase as fraction of 2π (e.g., 0.25 for eigenvalue e^(iπ/2))
    """
    n = num_counting_qubits
    total = n + 1  # counting + target qubit
    
    circuit = Circuit(total, name="QPE")
    
    # Prepare target qubit in eigenstate
    # For Z gate eigenstate |1⟩, apply X
    circuit.x(n)
    
    # Apply Hadamard to counting qubits
    for i in range(n):
        circuit.h(i)
    
    # Apply controlled unitary operations
    # For phase φ, apply controlled-Rz(2πφ) with increasing power
    for i in range(n):
        power = 2 ** (n - 1 - i)
        angle = 2 * math.pi * target_state * power
        # Simplified controlled rotation
        circuit.rz(n, angle)
    
    # Apply inverse QFT to counting qubits
    for i in range(n):
        for j in range(i):
            angle = -math.pi / (2 ** (i - j))
            circuit.rz(j, angle)
        circuit.h(i)
    
    # Measure counting qubits
    circuit.measure_all()
    
    return circuit

# ============================================
# Estimate different phases
# ============================================

print("Quantum Phase Estimation:")
print("=" * 50)

phases = [0.0, 0.25, 0.5, 0.75]
for phase in phases:
    circuit = build_qpe(num_counting_qubits=3, target_state=phase)
    result = QuantumRun(circuit, shots=1000)
    
    # Convert measurement to phase estimate
    counts = result.counts
    most_common = max(counts, key=counts.get)
    estimated_phase = int(most_common, 2) / (2 ** 3)
    
    print(f"Phase: {phase:.2f} (2π×{phase:.2f}) | "
          f"Most common: {most_common} | "
          f"Estimated: {estimated_phase:.2f} | "
          f"Error: {abs(estimated_phase - phase):.2f}")

Expected Output

Quantum Phase Estimation:
==================================================
Phase: 0.00 (2π×0.00) | Most common: 000 | Estimated: 0.00 | Error: 0.00
Phase: 0.25 (2π×0.25) | Most common: 010 | Estimated: 0.25 | Error: 0.00
Phase: 0.50 (2π×0.50) | Most common: 100 | Estimated: 0.50 | Error: 0.00
Phase: 0.75 (2π×0.75) | Most common: 110 | Estimated: 0.75 | Error: 0.00

Key Concepts

How QPE Works

  1. Prepare target qubit in eigenstate |u⟩ of unitary U
  2. Apply Hadamard to counting qubits
  3. Apply controlled-U^(2^k) operations
  4. Apply inverse QFT
  5. Measure counting qubits to get phase

Phase Kickback

When a controlled gate acts on an eigenstate, the eigenvalue "kicks back" as a phase to the control qubit.

Precision

  • Number of counting qubits = number of bits of precision
  • 3 counting qubits → 8 possible phase values
  • More qubits → higher precision

Applications

  • Finding eigenvalues of molecules (chemistry)
  • Shor's algorithm (factoring)
  • Quantum simulation

Next Steps