Source code for qdk_chemistry.plugins.qiskit.regular_isometry

"""Regular isometry module for quantum state preparation."""
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See LICENSE.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

from qiskit import QuantumCircuit, qasm3
from qiskit.circuit.library import StatePreparation as QiskitStatePreparation
from qiskit.compiler import transpile
from qiskit.quantum_info import Statevector
from qiskit.transpiler import PassManager

from qdk_chemistry.algorithms.state_preparation import StatePreparation, StatePreparationSettings
from qdk_chemistry.data import Circuit, Wavefunction
from qdk_chemistry.plugins.qiskit._interop.transpiler import (
    MergeZBasisRotations,
    RemoveZBasisOnZeroState,
    SubstituteCliffordRz,
)
from qdk_chemistry.plugins.qiskit.conversion import create_statevector_from_wavefunction
from qdk_chemistry.utils import Logger

__all__ = ["RegularIsometryStatePreparation"]


[docs] class RegularIsometryStatePreparation(StatePreparation): """State preparation using a regular isometry approach. This class implements the isometry-based state preparation proposed by Matthias Christandl in arXiv:1501.06911 :cite:`Christandl2016`. """
[docs] def __init__(self): """Initialize the RegularIsometryStatePreparation.""" Logger.trace_entering() super().__init__() self._settings = StatePreparationSettings()
def _run_impl(self, wavefunction: Wavefunction) -> Circuit: """Create a quantum circuit that prepares the state using regular isometry. Args: wavefunction: Wavefunction to prepare state from Returns: A Circuit object containing a QASM string representation of the quantum circuit. """ Logger.trace_entering() # Active Space Consistency Check alpha_indices, beta_indices = wavefunction.get_orbitals().get_active_space_indices() if alpha_indices != beta_indices: raise ValueError( f"Active space contains {len(alpha_indices)} alpha orbitals and " f"{len(beta_indices)} beta orbitals. Asymmetric active spaces for " "alpha and beta orbitals are not supported for state preparation." ) num_orbitals = len(alpha_indices) n_qubits = num_orbitals * 2 num_dets = wavefunction.size() Logger.debug(f"Using {num_dets} determinants for state preparation") # Create statevector using Python conversion function statevector_data = create_statevector_from_wavefunction(wavefunction, normalize=True) # Create the circuit circuit = QuantumCircuit(n_qubits, name=f"regular_isometry_{num_dets}_det") # Use the StatePreparation class which implements efficient decomposition state_prep = QiskitStatePreparation(Statevector(statevector_data), normalize=True) circuit.append(state_prep, range(n_qubits)) # Transpile the circuit if needed basis_gates = self._settings.get("basis_gates") do_transpile = self._settings.get("transpile") if do_transpile and basis_gates: opt_level = self._settings.get("transpile_optimization_level") circuit = transpile(circuit, basis_gates=basis_gates, optimization_level=opt_level) pass_manager = PassManager( [ MergeZBasisRotations(), RemoveZBasisOnZeroState(), SubstituteCliffordRz(), ] ) circuit = pass_manager.run(circuit) return Circuit(qasm=qasm3.dumps(circuit))
[docs] def name(self) -> str: """Return the name of the state preparation method.""" Logger.trace_entering() return "regular_isometry"