Source code for qdk_chemistry.algorithms.controlled_circuit_mapper.base

"""QDK/Chemistry circuit mapper for controlled-unitary 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 Circuit, Settings
from qdk_chemistry.data.unitary_representation.base import UnitaryRepresentation

__all__: list[str] = ["ControlledCircuitMapper", "ControlledCircuitMapperFactory", "ControlledCircuitMapperSettings"]


[docs] class ControlledCircuitMapperSettings(Settings): """Settings for the ControlledCircuitMapper. Attributes: control_indices: The control qubit indices. Defaults to ``[0]``. target_indices: The target qubit indices. An empty list means auto-fill based on the unitary's qubit count and control indices. """
[docs] def __init__(self): """Initialize the settings for ControlledCircuitMapper.""" super().__init__() self._set_default( "control_indices", "vector<int>", [0], "The control qubit indices.", ) self._set_default( "target_indices", "vector<int>", [], "The target qubit indices. Empty means auto-fill.", )
[docs] class ControlledCircuitMapper(Algorithm): """Base class for circuit mapper for controlled-unitary in QDK/Chemistry algorithms."""
[docs] def __init__(self): """Initialize the ControlledCircuitMapper.""" super().__init__() self._settings = ControlledCircuitMapperSettings()
@abstractmethod def _run_impl(self, unitary: UnitaryRepresentation) -> Circuit: """Construct a Circuit representing the controlled unitary. Args: unitary: The unitary representation to be controlled. Control and target indices are read from settings. Returns: Circuit: A Circuit representing the controlled unitary. """ def _get_control_indices(self) -> list[int]: """Get control indices from settings. Returns: The control qubit indices. """ control_indices = self._settings.get("control_indices") if len(control_indices) != len(set(control_indices)): raise ValueError("control_indices must not contain duplicates.") return control_indices def _get_target_indices(self, unitary: UnitaryRepresentation) -> list[int]: """Get target indices from settings, auto-filling if empty. Args: unitary: The unitary representation, used for auto-fill. Returns: The resolved target qubit indices. """ target_indices = self._settings.get("target_indices") if target_indices: if len(target_indices) != len(set(target_indices)): raise ValueError("target_indices must not contain duplicates.") if len(target_indices) != unitary.get_num_qubits(): raise ValueError( f"target_indices length ({len(target_indices)}) " f"must match unitary qubit count ({unitary.get_num_qubits()})." ) if any(idx in self._get_control_indices() for idx in target_indices): raise ValueError("target_indices must not overlap with control_indices.") return target_indices control_indices = self._get_control_indices() control_set = set(control_indices) num_target = unitary.get_num_qubits() targets: list[int] = [] i = 0 while len(targets) < num_target: if i not in control_set: targets.append(i) i += 1 return targets
[docs] class ControlledCircuitMapperFactory(AlgorithmFactory): """Factory class for creating ControlledCircuitMapper instances."""
[docs] def algorithm_type_name(self) -> str: """Return controlled_circuit_mapper as the algorithm type name.""" return "controlled_circuit_mapper"
[docs] def default_algorithm_name(self) -> str: """Return pauli_sequence as the default algorithm name.""" return "pauli_sequence"