Source code for qdk_chemistry.algorithms.time_evolution.hamiltonian_simulation.euler_integrator

r"""Euler integrator for time-dependent Hamiltonian simulation.

This module implements a Hamiltonian simulation algorithm that uses an
:class:`~qdk_chemistry.algorithms.time_evolution.evolution_circuit_builder.euler_builder.EulerEvolutionCircuitBuilder`
to construct the evolution circuit and then executes it to measure
observable expectation values.

The circuit builder handles all time-stepping, propagation, Trotterization,
and circuit mapping.  This class adds circuit execution and observable
measurement on top.
"""

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

from __future__ import annotations

from typing import TYPE_CHECKING

from qdk_chemistry.utils import Logger

from .base import HamiltonianSimulation, HamiltonianSimulationSettings

if TYPE_CHECKING:
    from qdk_chemistry.data import (
        Circuit,
        EnergyExpectationResult,
        MeasurementData,
        QuantumErrorProfile,
        QubitOperator,
        TimeDependentQubitHamiltonian,
    )

__all__: list[str] = ["EulerIntegrator", "EulerIntegratorSettings"]


[docs] class EulerIntegratorSettings(HamiltonianSimulationSettings): """Settings for the Euler integrator."""
[docs] def __init__(self): """Initialize the settings for EulerIntegrator.""" super().__init__()
[docs] class EulerIntegrator(HamiltonianSimulation): r"""Euler integrator for time-dependent Hamiltonian simulation. Delegates circuit construction to the configured ``evolution_circuit_builder`` (default: ``EulerEvolutionCircuitBuilder``), then executes the circuit and measures observables. For resource estimation (without execution), use the ``evolution_circuit_builder`` directly via ``create("evolution_circuit_builder", "euler", ...)``. """
[docs] def __init__(self): """Initialize EulerIntegrator.""" Logger.trace_entering() super().__init__() self._settings = EulerIntegratorSettings()
def _run_impl( self, hamiltonian: TimeDependentQubitHamiltonian, observables: list[QubitOperator], state_prep: Circuit, shots: int = 1000, *, noise: QuantumErrorProfile | None = None, ) -> list[tuple[EnergyExpectationResult, MeasurementData]]: """Run the Euler-integrated Hamiltonian simulation. Args: hamiltonian: Time-dependent Hamiltonian. observables: List of observable Hamiltonians to measure after evolution. state_prep: Circuit that prepares the initial state before time evolution. shots: Number of measurement shots per observable. Defaults to 1000. noise: Optional noise profile. Returns: A list of tuples containing ``EnergyExpectationResult`` and ``MeasurementData`` objects. """ for observable in observables: if observable.num_qubits != hamiltonian.num_qubits: raise ValueError("All observables must have the same number of qubits as the Hamiltonian.") circuit = self._build_evolution_circuit(hamiltonian, state_prep) measurements = [] for observable in observables: measurements.append( self._measure_observable( circuit=circuit, observable=observable, shots=shots, noise=noise, ) ) return measurements
[docs] def name(self) -> str: """Return ``euler_integrator`` as the algorithm name.""" return "euler_integrator"