Source code for scikit_quri.backend.base_sampler

"""ABC for sampling backends.

Mirrors :class:`~scikit_quri.backend.BaseEstimator` so that the two execution
families (expectation values vs computational-basis sampling) share the same
class-based abstraction style.

A ``BaseSampler`` is also a quri-parts ``ConcurrentSampler`` (i.e. callable
with the same signature), so any existing API expecting a ``ConcurrentSampler``
accepts a ``BaseSampler`` instance unchanged. This is enforced by the
``__call__`` slot that delegates to :meth:`sample`.
"""

from abc import ABCMeta, abstractmethod
from typing import Iterable

from quri_parts.circuit import NonParametricQuantumCircuit
from quri_parts.core.sampling import MeasurementCounts


[docs]class BaseSampler(metaclass=ABCMeta): """Concurrent sampling abstraction. The required method :meth:`sample` takes an iterable of ``(circuit, n_shots)`` pairs and returns one ``MeasurementCounts`` per pair in input order. Single-circuit sampling is offered as a thin convenience via :meth:`sample_one`. """
[docs] @abstractmethod def sample( self, circuit_shots_tuples: Iterable[tuple[NonParametricQuantumCircuit, int]], ) -> Iterable[MeasurementCounts]: """Sample each ``(circuit, n_shots)`` pair and yield the resulting counts. Args: circuit_shots_tuples: Iterable of ``(circuit, n_shots)`` pairs. Returns: Iterable of measurement counts, one per input pair in the same order. """
[docs] def sample_one(self, circuit: NonParametricQuantumCircuit, n_shots: int) -> MeasurementCounts: """Sample a single circuit ``n_shots`` times. Default implementation forwards to :meth:`sample` with a one-element list. """ return next(iter(self.sample([(circuit, n_shots)])))
def __call__( self, circuit_shots_tuples: Iterable[tuple[NonParametricQuantumCircuit, int]], ) -> Iterable[MeasurementCounts]: """``ConcurrentSampler`` protocol compatibility — delegates to :meth:`sample`.""" return self.sample(circuit_shots_tuples)