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
from qdk_chemistry.data import Circuit, Settings, 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", "RegularIsometryStatePreparationSettings"]


[docs] class RegularIsometryStatePreparationSettings(Settings): """Settings for RegularIsometryStatePreparation."""
[docs] def __init__(self): """Initialize the RegularIsometryStatePreparationSettings.""" super().__init__() self._set_default("basis_gates", "vector<string>", ["x", "y", "z", "cx", "cz", "id", "h", "s", "sdg", "rz"]) self._set_default("transpile", "bool", True) self._set_default("transpile_optimization_level", "int", 0)
[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 = RegularIsometryStatePreparationSettings()
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() num_dets = wavefunction.size() Logger.debug(f"Using {num_dets} determinants for state preparation") # Create statevector from wavefunction statevector_data = create_statevector_from_wavefunction(wavefunction, normalize=True) n_qubits = int(statevector_data.shape[0]).bit_length() - 1 # 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), encoding="jordan-wigner")
[docs] def name(self) -> str: """Return the name of the state preparation method.""" Logger.trace_entering() return "qiskit_regular_isometry"