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

"""QDK/Chemistry Hadamard test circuit 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.algorithms.hadamard_test.hadamard_test import HadamardTestBasis
from qdk_chemistry.data import (
    AlgorithmRef,
    Circuit,
    Settings,
    UnitaryRepresentation,
)

__all__: list[str] = [
    "HadamardTestCircuitBuilder",
    "HadamardTestCircuitBuilderFactory",
    "HadamardTestCircuitBuilderSettings",
]


[docs] class HadamardTestCircuitBuilderSettings(Settings): """Settings for the Hadamard test circuit builder algorithm."""
[docs] def __init__(self): """Initialize the settings for the Hadamard test circuit builder.""" super().__init__() self._set_default( "controlled_circuit_mapper", "algorithm_ref", AlgorithmRef("controlled_circuit_mapper", "pauli_sequence"), ) self._set_default( "test_basis", "string", HadamardTestBasis.X.value, "Measurement basis for the control qubit ('X' or 'Y').", [basis.value for basis in HadamardTestBasis], )
[docs] class HadamardTestCircuitBuilder(Algorithm): """Abstract base class for Hadamard test circuit builders. A circuit builder turns a prepared state and a target unitary into a single backend-specific Hadamard test circuit. It owns the controlled circuit mapper used to synthesize the controlled evolution. """
[docs] def __init__( self, controlled_circuit_mapper: AlgorithmRef | None = None, test_basis: HadamardTestBasis = HadamardTestBasis.X, ): """Initialize the Hadamard test circuit builder. Args: controlled_circuit_mapper: Optional algorithm reference for the controlled circuit mapper. test_basis: Measurement basis for the control qubit (``HadamardTestBasis.X`` or ``HadamardTestBasis.Y``). """ super().__init__() self._settings = HadamardTestCircuitBuilderSettings() if controlled_circuit_mapper is not None: if not isinstance(controlled_circuit_mapper, AlgorithmRef): raise TypeError("controlled_circuit_mapper must be an instance of AlgorithmRef.") self._settings.set("controlled_circuit_mapper", controlled_circuit_mapper) if isinstance(test_basis, HadamardTestBasis): test_basis_value = test_basis.value elif isinstance(test_basis, str): try: test_basis_value = HadamardTestBasis(test_basis).value except ValueError as err: raise ValueError("test_basis must be one of {'X', 'Y'}.") from err else: raise TypeError("test_basis must be an instance of HadamardTestBasis or a string.") self._settings.set("test_basis", test_basis_value)
[docs] def type_name(self) -> str: """Return the algorithm type name as hadamard_test_circuit_builder.""" return "hadamard_test_circuit_builder"
@abstractmethod def _run_impl( self, state_preparation_circuit: Circuit, unitary: UnitaryRepresentation, ) -> Circuit: r"""Build the Hadamard test circuit for a given state and target unitary. The unitary is mapped into a controlled evolution circuit internally via :meth:`_create_controlled_circuit`. Args: state_preparation_circuit: Circuit that prepares the trial state on system qubits. unitary: Unitary representation :math:`U` (e.g. a time-evolution unitary built with the desired power). Returns: Circuit representing the Hadamard test workflow for the selected backend. """ def _create_controlled_circuit(self, unitary: UnitaryRepresentation) -> Circuit: r"""Map a target unitary into a controlled evolution circuit. Map ``unitary`` controlled on the Hadamard test control qubit (index 0) and runs the nested ``controlled_circuit_mapper`` to synthesize the controlled-:math:`U` circuit. Args: unitary: Unitary representation :math:`U` to map into a controlled circuit. Returns: The controlled circuit implementing controlled-:math:`U`. """ circuit_mapper_ref = self._settings.get("controlled_circuit_mapper") if circuit_mapper_ref.algorithm_type != "controlled_circuit_mapper": raise ValueError( "controlled_circuit_mapper must reference algorithm type 'controlled_circuit_mapper', " f"got '{circuit_mapper_ref.algorithm_type}'." ) circuit_mapper = self._create_nested("controlled_circuit_mapper") circuit_mapper.settings().update("control_indices", [0]) return circuit_mapper.run(unitary=unitary)
[docs] class HadamardTestCircuitBuilderFactory(AlgorithmFactory): """Factory class for creating Hadamard test circuit builder instances."""
[docs] def __init__(self): """Initialize the HadamardTestCircuitBuilderFactory.""" super().__init__()
[docs] def algorithm_type_name(self) -> str: """Return the algorithm type name as hadamard_test_circuit_builder.""" return "hadamard_test_circuit_builder"
[docs] def default_algorithm_name(self) -> str: """Return 'qdk' as the default algorithm name.""" return "qdk"