Phase estimation circuit builder

The QpeCircuitBuilder is an abstract base class that defines the interface for constructing phase estimation circuits. It serves as the central component that orchestrates circuit synthesis by composing a HamiltonianUnitaryBuilder (to construct the target unitary) with a ControlledCircuitMapper (to convert it to a controlled circuit).

The QpeCircuitBuilder is the primary algorithm reference configured in the PhaseEstimation class via the qpe_circuit_builder setting. It encapsulates all details about circuit composition, allowing the high-level phase estimation interface to remain agnostic to the specific phase estimation variant (iterative or standard).

Overview

Phase estimation circuit builders are responsible for:

  1. Composing circuits from state preparation, controlled unitaries, and measurement/QFT operations

  2. Generating variant-specific circuits (iterative uses adaptive feedback; standard uses QFT)

The QpeCircuitBuilder abstract class provides the common interface, while concrete implementations handle variant-specific details. All variants delegate to the same nested algorithm interfaces, enabling flexible composition of different circuit synthesis strategies.

Use QpeCircuitBuilder

Note

This algorithm is currently available only in the Python API.

This section demonstrates how to create, configure, and run a phase estimation circuit builder. The run method returns a list of Circuit containing the constructed phase estimation circuits.

Input requirements

The QpeCircuitBuilder requires the following inputs:

State preparation circuit

A Circuit that prepares the target quantum state on the system register. This is typically generated by the StatePreparation algorithm from a Wavefunction, but can also be any user-constructed circuit (e.g., a custom initial state for a model Hamiltonian).

QubitOperator

A QubitOperator containing the Pauli-string representation of the Hamiltonian. This can be obtained from the QubitMapper algorithm, constructed from a model Hamiltonian, or built directly by the user.

The QpeCircuitBuilderSettings class defines the general configuration parameters shared by all QPE circuit builders.

Setting

Type

Description

num_bits

int

Number of phase bits to estimate. Must be a positive integer. Default: -1 (invalid; user must set).

unitary_builder

AlgorithmRef

Reference to the algorithm that constructs the target unitary \(U\). Default: AlgorithmRef to "hamiltonian_unitary_builder" with method "trotter".

controlled_circuit_mapper

AlgorithmRef

Reference to the algorithm that converts unitaries to controlled circuits. Default: AlgorithmRef to "controlled_circuit_mapper" with method "pauli_sequence".

Once configured, the QpeCircuitBuilder can be executed with all required dependencies:

import numpy as np
from qdk_chemistry.algorithms import create
from qdk_chemistry.data import Structure

# 1. Setup molecule
coords = np.array([[0.0, 0.0, 0.0], [0.0, 0.0, 1.4]])
symbols = ["H", "H"]
structure = Structure(coords, symbols=symbols)

# 2. SCF
scf_solver = create("scf_solver")
E_scf, wfn_scf = scf_solver.run(
    structure, charge=0, spin_multiplicity=1, basis_or_guess="sto-3g"
)

# 3. Hamiltonian construction
hamiltonian_constructor = create("hamiltonian_constructor")
hamiltonian = hamiltonian_constructor.run(wfn_scf.get_orbitals())

# 4. Multi-configuration calculation (reference state)
cas_solver = create("multi_configuration_calculator")
E_cas, wfn_cas = cas_solver.run(hamiltonian, 1, 1)

# 5. Qubit mapping
from qdk_chemistry.data import MajoranaMapping

n_spin_orbitals = 2 * hamiltonian.get_orbitals().get_num_molecular_orbitals()
qubit_mapper = create("qubit_mapper")
qubit_ham = qubit_mapper.run(
    hamiltonian, MajoranaMapping.jordan_wigner(n_spin_orbitals)
)

# 6. State preparation
state_prep = create("state_prep", "sparse_isometry_gf2x")
circuit = state_prep.run(wfn_cas)

# 7. Create and run IQPE circuit builder with nested algorithm settings
from qdk_chemistry.data import AlgorithmRef

controlled_circuit_mapper = AlgorithmRef("controlled_circuit_mapper", "pauli_sequence")
unitary_builder = AlgorithmRef("hamiltonian_unitary_builder", "trotter", time=0.1)
iqpe_circuit_builder = create("qpe_circuit_builder", "qdk_iterative", num_bits=4)
iqpe_circuit_builder.settings().set(
    "controlled_circuit_mapper", controlled_circuit_mapper
)
iqpe_circuit_builder.settings().set("unitary_builder", unitary_builder)

iqpe_circuits = iqpe_circuit_builder.run(
    state_preparation=circuit,
    qubit_hamiltonian=qubit_ham,
)

# 8. Print the generated circuits for each bit (iterative)
for idx, circ in enumerate(iqpe_circuits):
    print(f"Bit {idx}:")
    print(circ.get_qsharp_circuit())

# 9. Create and run standard QPE circuit builder
standard_builder = create("qpe_circuit_builder", "qdk_standard", num_bits=4)
standard_builder.settings().set("controlled_circuit_mapper", controlled_circuit_mapper)
standard_builder.settings().set("unitary_builder", unitary_builder)

standard_circuits = standard_builder.run(
    state_preparation=circuit,
    qubit_hamiltonian=qubit_ham,
)

# 10. Print the standard QPE circuit (single circuit with all ancillas)
print("Standard QPE circuit:")
print(standard_circuits[0].get_qsharp_circuit())

Available Implementations

QDK/Chemistry provides two primary implementations of QpeCircuitBuilder:

Iterative Phase Estimation Circuit Builder (IQPE)

Class: QdkIterativeQpeCircuitBuilder (QDK native) and QiskitIterativeQpeCircuitBuilder (Qiskit implementation)

Factory name: "qdk_iterative" (QDK native), "qiskit_iterative" (Qiskit implementation)

Constructs circuits for Kitaev’s iterative phase estimation algorithm, which extracts phase bits one at a time using single-ancilla feedback corrections.

Additional settings:

Setting

Type

Description

phase_correction

float

Accumulated phase feedback from prior iterations. Default: 0.0.

num_iteration

int

Specific iteration to build (0-based). If negative, builds all iterations. Default: -1.

Usage example:

from qdk_chemistry.algorithms import create
from qdk_chemistry.data import AlgorithmRef

# Create iterative QPE with circuit builder configuration
controlled_circuit_mapper = AlgorithmRef("controlled_circuit_mapper", "pauli_sequence")
unitary_builder = AlgorithmRef("hamiltonian_unitary_builder", "trotter", time=0.1)
iqpe_circuit_builder = create("qpe_circuit_builder", "qdk_iterative", num_bits=10)
iqpe_circuit_builder.settings().set(
    "controlled_circuit_mapper", controlled_circuit_mapper
)
iqpe_circuit_builder.settings().set("unitary_builder", unitary_builder)

Standard QFT-based Phase Estimation Circuit Builder

Class: QdkStandardQpeCircuitBuilder (QDK native) and QiskitStandardQpeCircuitBuilder (Qiskit implementation)

Factory name: "qdk_standard" (QDK native), "qiskit_standard" (Qiskit implementation)

Constructs the textbook multi-ancilla QPE circuit with inverse Quantum Fourier Transform. Extracts all phase bits simultaneously using num_bits ancilla qubits, applying controlled-\(U^{2^k}\) for each ancilla and finishing with the inverse QFT.

Additional settings (Qiskit implementation):

Setting

Type

Description

qft_do_swaps

bool

Whether to include swap gates in the inverse QFT decomposition. Default: True.

Usage example:

from qdk_chemistry.algorithms import create
from qdk_chemistry.data import AlgorithmRef

# Create standard QPE circuit builder
controlled_circuit_mapper = AlgorithmRef("controlled_circuit_mapper", "pauli_sequence")
unitary_builder = AlgorithmRef("hamiltonian_unitary_builder", "trotter", time=0.1)
qpe_circuit_builder = create("qpe_circuit_builder", "qdk_standard", num_bits=10)
qpe_circuit_builder.settings().set(
    "controlled_circuit_mapper", controlled_circuit_mapper
)
qpe_circuit_builder.settings().set("unitary_builder", unitary_builder)

Circuit Composition Details

The phase estimation circuit is built by composing:

  1. State Preparation — Prepares the initial quantum state on the system register

  2. Controlled Unitaries — Applies controlled powers of the unitary operator \(C\text{-}U^{2^k}\) to extract phase information

  3. Phase Feedback (IQPE only) — Applies adaptive phase corrections between iterations

  4. Measurement/QFT — For standard QPE, applies the inverse QFT before measurement

To accomplish this, the QpeCircuitBuilder maintains two key nested algorithm references:

Nested Algorithm 1: Unitary Builder

Reference setting: "unitary_builder"

Default: AlgorithmRef to "hamiltonian_unitary_builder" with method "trotter"

The unitary builder (typically HamiltonianUnitaryBuilder) produces a UnitaryRepresentation of the target operator from a QubitOperator. The builder is configured with the desired time-evolution strategy and time parameter (time setting).

Nested Algorithm 2: Controlled Circuit Mapper

Reference setting: "controlled_circuit_mapper"

Default: AlgorithmRef to "controlled_circuit_mapper" with method "pauli_sequence"

The controlled circuit mapper (see ControlledCircuitMapper) converts the UnitaryRepresentation into a controlled circuit, i.e., it synthesizes \(C\text{-}U\) as an executable Circuit.

Further Reading