Source code for qdk_chemistry.algorithms.phase_estimation.circuit_builder.base

"""QDK/Chemistry phase estimation builder abstractions."""

# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See LICENSE.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

from abc import abstractmethod

from qdk_chemistry.algorithms.base import Algorithm, AlgorithmFactory
from qdk_chemistry.data import (
    AlgorithmRef,
    Circuit,
    QubitOperator,
    Settings,
)

__all__: list[str] = [
    "IterativeQpeCircuitBuilder",
    "QpeCircuitBuilder",
    "QpeCircuitBuilderFactory",
    "QpeCircuitBuilderSettings",
    "StandardQpeCircuitBuilder",
]


[docs] class QpeCircuitBuilderSettings(Settings): """Settings for the Phase Estimation Builder algorithm."""
[docs] def __init__(self): """Initialize the settings for the Phase Estimation Builder. Includes nested algorithm references for the evolution builder and the circuit mapper used to construct phase estimation circuits. """ super().__init__() self._set_default("num_bits", "int", -1, "The number of phase bits to estimate.") self._set_default( "unitary_builder", "algorithm_ref", AlgorithmRef("hamiltonian_unitary_builder", "trotter"), ) self._set_default( "controlled_circuit_mapper", "algorithm_ref", AlgorithmRef("controlled_circuit_mapper", "pauli_sequence"), )
[docs] class QpeCircuitBuilder(Algorithm): """Abstract base class for phase estimation circuit builders."""
[docs] def __init__( self, num_bits: int = -1, unitary_builder: AlgorithmRef | None = None, controlled_circuit_mapper: AlgorithmRef | None = None, ): """Initialize the QpeCircuitBuilder with default settings. Args: num_bits: The number of phase bits to estimate. Default to -1; user needs to set a valid value. unitary_builder: Optional algorithm reference for the unitary builder. controlled_circuit_mapper: Optional algorithm reference for the controlled circuit mapper. """ super().__init__() self._settings = QpeCircuitBuilderSettings() self._settings.set("num_bits", num_bits) if unitary_builder is not None: self._settings.set("unitary_builder", unitary_builder) if controlled_circuit_mapper is not None: self._settings.set("controlled_circuit_mapper", controlled_circuit_mapper)
[docs] def type_name(self) -> str: """Return the algorithm type name as qpe_circuit_builder.""" return "qpe_circuit_builder"
@abstractmethod def _run_impl( self, state_preparation: Circuit, qubit_hamiltonian: QubitOperator, ) -> list[Circuit]: """Build phase estimation circuits. Args: state_preparation: The circuit that prepares the initial state. qubit_hamiltonian: The qubit Hamiltonian for which to build circuits. Returns: A list of quantum circuits for phase estimation. """ def _create_controlled_circuit( self, qubit_hamiltonian: QubitOperator, power: int, ) -> tuple[Circuit, int]: r"""Create the controlled circuit for the given Hamiltonian and power. Sets the ``power`` on the unitary builder so it produces :math:`U^{\\text{power}}` according to its ``power_strategy``, then maps the result to a controlled circuit. Args: qubit_hamiltonian: The qubit Hamiltonian to evolve under. power: The power to which the unitary should be raised. Returns: A tuple of (circuit, num_ancilla_qubits) where circuit implements controlled-:math:`U^{\\text{power}}` and num_ancilla_qubits is the number of ancilla qubits used by the unitary beyond the system qubits. """ unitary_builder = self._create_nested("unitary_builder") unitary_builder.settings().update("power", power) unitary_rep = unitary_builder.run(qubit_hamiltonian) num_ancilla_qubits = unitary_rep.get_num_qubits() - qubit_hamiltonian.num_qubits circuit_mapper = self._create_nested("controlled_circuit_mapper") circuit_mapper.settings().update("control_indices", [0]) circuit = circuit_mapper.run(unitary_rep) return circuit, num_ancilla_qubits
[docs] class QpeCircuitBuilderFactory(AlgorithmFactory): """Factory class for creating QpeCircuitBuilder instances."""
[docs] def __init__(self): """Initialize the QpeCircuitBuilderFactory.""" super().__init__()
[docs] def algorithm_type_name(self) -> str: """Return the algorithm type name as qpe_circuit_builder.""" return "qpe_circuit_builder"
[docs] def default_algorithm_name(self) -> str: """Return qdk_iterative as default algorithm name.""" return "qdk_iterative"
[docs] class IterativeQpeCircuitBuilder(QpeCircuitBuilder): """Abstract base class for iterative phase estimation circuit builders. Serves as a type-checking abstraction for implementations of the iterative (Kitaev-style) quantum phase estimation algorithm. """
[docs] class StandardQpeCircuitBuilder(QpeCircuitBuilder): """Abstract base class for standard (QFT-based) phase estimation circuit builders. Serves as a type-checking abstraction for implementations of the standard (non-iterative) quantum phase estimation algorithm using QFT. """