merlin.measurement.strategies module
Overview
The measurement API is now centered on MeasurementStrategy, an immutable object
that fully describes how quantum outputs are converted into classical outputs. The new
API uses explicit factory methods instead of enum-style access.
New API (recommended)
Factory methods (preferred):
from merlin.core.computation_space import ComputationSpace
from merlin.measurement.strategies import MeasurementStrategy
# Full measurement probabilities
strategy = MeasurementStrategy.probs(ComputationSpace.FOCK)
# Per-mode expectations
strategy = MeasurementStrategy.mode_expectations(ComputationSpace.UNBUNCHED)
# Raw amplitudes (no detectors, no sampling)
strategy = MeasurementStrategy.amplitudes(ComputationSpace.UNBUNCHED)
Partial measurement
Partial measurement is explicit and validated. It returns a
merlin.core.partial_measurement.PartialMeasurement.
from merlin.core.computation_space import ComputationSpace
from merlin.measurement.strategies import MeasurementStrategy
# Measure only modes 0 and 2
strategy = MeasurementStrategy.partial(
modes=[0, 2],
computation_space=ComputationSpace.FOCK,
)
Deprecations and Migration Guide
Enum-style access is deprecated and will be removed in v0.4:
MeasurementStrategy.PROBABILITIESMeasurementStrategy.MODE_EXPECTATIONSMeasurementStrategy.AMPLITUDESMeasurementStrategy.NONE(aliases amplitudes)
Passing measurement_strategy as a string is also deprecated (e.g. "PROBABILITIES").
Old to new mappings
Deprecated |
Recommended replacement |
|---|---|
|
|
|
|
|
|
|
|
|
|
Computation space now lives inside the strategy. If you already use the new factory
methods, do not also pass computation_space separately in constructors such as
QuantumLayer.
# Deprecated (legacy enum + separate computation_space)
# QuantumLayer(..., measurement_strategy=MeasurementStrategy.PROBABILITIES,
# computation_space=ComputationSpace.FOCK)
# Recommended
QuantumLayer(..., measurement_strategy=MeasurementStrategy.probs(ComputationSpace.FOCK))
Reference
Measurement strategy definitions for quantum-to-classical conversion.
- class merlin.measurement.strategies.AmplitudesStrategy
Bases:
BaseMeasurementStrategyNew API: return raw amplitudes (sampling is not supported).
- class merlin.measurement.strategies.BaseMeasurementStrategy
Bases:
objectNew API: internal strategy interface for post-processing implementations.
- process(*, distribution, amplitudes, apply_sampling, effective_shots, sample_fn, apply_photon_loss, apply_detectors, grouping=None)
Return the processed result for the selected measurement strategy.
- Return type:
- supports_sampling()
Return whether the strategy can apply sampling to distributions.
- Return type:
bool
- class merlin.measurement.strategies.Callable
Bases:
object
- enum merlin.measurement.strategies.ComputationSpace(value)
Bases:
str,EnumEnumeration of supported computational subspaces.
- Member Type:
str
Valid values are as follows:
- FOCK = <ComputationSpace.FOCK: 'fock'>
- UNBUNCHED = <ComputationSpace.UNBUNCHED: 'unbunched'>
- DUAL_RAIL = <ComputationSpace.DUAL_RAIL: 'dual_rail'>
The
Enumand its members also have the following methods:- classmethod default(*, no_bunching)
Derive the default computation space from the legacy no_bunching flag.
- Return type:
- classmethod coerce(value)
Normalize user-provided values (enum instances or case-insensitive strings).
- Return type:
- class merlin.measurement.strategies.DistributionStrategy
Bases:
BaseMeasurementStrategyNew API: shared logic for distribution-based strategies.
- process(*, distribution, amplitudes, apply_sampling, effective_shots, sample_fn, apply_photon_loss, apply_detectors, grouping=None)
Return the processed result for the selected measurement strategy.
- Return type:
- supports_sampling()
Return whether the strategy can apply sampling to distributions.
- Return type:
bool
- enum merlin.measurement.strategies.Enum(value)
Bases:
objectCreate a collection of name/value pairs.
Example enumeration:
>>> class Color(Enum): ... RED = 1 ... BLUE = 2 ... GREEN = 3
Access them by:
attribute access:
>>> Color.RED <Color.RED: 1>
value lookup:
>>> Color(1) <Color.RED: 1>
name lookup:
>>> Color['RED'] <Color.RED: 1>
Enumerations can be iterated over, and know how many members they have:
>>> len(Color) 3
>>> list(Color) [<Color.RED: 1>, <Color.BLUE: 2>, <Color.GREEN: 3>]
Methods can be added to enumerations, and members can have their own attributes – see the documentation for details.
The
Enumand its members have the following methods:- name
The name of the Enum member.
- value
The value of the Enum member.
- class merlin.measurement.strategies.LexGrouping(input_size, output_size)
Bases:
ModuleMaps tensor to a lexical grouping of its components.
This mapper groups consecutive elements of the input tensor into equal-sized buckets and sums them to produce the output. If the input size is not evenly divisible by the output size, padding is applied.
- forward(x)
Map the input tensor to the desired output_size utilizing lexical grouping.
- Args:
x: Input tensor of shape (n_batch, input_size) or (input_size,)
- Returns:
Grouped tensor of shape (batch_size, output_size) or (output_size,)
- enum merlin.measurement.strategies.MeasurementKind(value)
Bases:
EnumNew API: internal measurement kinds used by MeasurementStrategy.
Valid values are as follows:
- PROBABILITIES = <MeasurementKind.PROBABILITIES: 'PROBABILITIES'>
- MODE_EXPECTATIONS = <MeasurementKind.MODE_EXPECTATIONS: 'MODE_EXPECTATIONS'>
- AMPLITUDES = <MeasurementKind.AMPLITUDES: 'AMPLITUDES'>
- PARTIAL = <MeasurementKind.PARTIAL: 'PARTIAL'>
- class merlin.measurement.strategies.MeasurementStrategy(type, measured_modes=(), computation_space=None, grouping=None)
Bases:
objectNew API: immutable definition of a measurement strategy for output post-processing.
-
AMPLITUDES:
ClassVar[_LegacyMeasurementStrategy] = 'amplitudes'
-
MODE_EXPECTATIONS:
ClassVar[_LegacyMeasurementStrategy] = 'mode_expectations'
-
NONE:
ClassVar[MeasurementStrategy] = MeasurementStrategy(type=<MeasurementKind.AMPLITUDES: 'AMPLITUDES'>, measured_modes=(), computation_space=<ComputationSpace.UNBUNCHED: 'unbunched'>, grouping=None)
-
PROBABILITIES:
ClassVar[_LegacyMeasurementStrategy] = 'probabilities'
- static amplitudes(computation_space=ComputationSpace.UNBUNCHED)
- Return type:
-
computation_space:
Optional[ComputationSpace]
- get_unmeasured_modes(n_modes)
Return the complement of the measured modes after validation.
- Return type:
tuple[int,...]
-
grouping:
UnionType[LexGrouping,ModGrouping,None]
-
measured_modes:
tuple[int,...]
- static mode_expectations(computation_space=ComputationSpace.UNBUNCHED)
- Return type:
- static partial(modes, computation_space=ComputationSpace.UNBUNCHED, grouping=None)
Create a partial measurement on the given mode indices. Note that the specified grouping only applies on the resulting probabilities, not on the amplitudes.
- Return type:
- static probs(computation_space=ComputationSpace.UNBUNCHED, grouping=None)
- Return type:
-
type:
MeasurementKind
- validate_modes(n_modes)
Validate mode indices and warn when the selection covers all modes.
- Return type:
None
-
AMPLITUDES:
- class merlin.measurement.strategies.ModGrouping(input_size, output_size)
Bases:
ModuleMaps tensor to a modulo grouping of its components.
This mapper groups elements of the input tensor based on their index modulo the output size. Elements with the same modulo value are summed together to produce the output.
- forward(x)
Map the input tensor to the desired output_size utilizing modulo grouping.
- Args:
x: Input tensor of shape (n_batch, input_size) or (input_size,)
- Returns:
Grouped tensor of shape (batch_size, output_size) or (output_size,)
- class merlin.measurement.strategies.ModeExpectationsStrategy
Bases:
DistributionStrategyNew API: return per-mode expectations (optionally sampled).
- class merlin.measurement.strategies.PartialMeasurement(branches, measured_modes, unmeasured_modes, grouping=None)
Bases:
objectCollection of measurement branches along with measured/unmeasured mode metadata.
- Args:
branches: Tuple of branches, ordered lexicographically by outcome. measured_modes: Indices of measured modes in the full system. unmeasured_modes: Indices of unmeasured modes in the full system. grouping: Optional grouping callable to group probabilities.
- property amplitudes
- static from_detector_transform_output(detector_output, *, grouping=None)
Branch-based PartialMeasurement wrapper from DetectorTransform(partial_measurement=True) output.
- Return type:
- property n_measured_modes: int
- property n_unmeasured_modes: int
- property outcomes
- property probabilities: Tensor
Return the probabilities of all branches as a tensor of shape (batch, n_branches) unless a grouping was set in which case, the probabilities are grouped and the returned tensor has shape (batch, grouping_output_size).
Same property as self.tensor.
- property probability_tensor_shape: tuple[int, int]
Return the expected (batch, n_outcomes) shape for the probability tensor.
- reorder_branches()
Reorder branches lexicographically by their outcomes.
- Return type:
None
- set_grouping(grouping)
Set the grouping used to group probabilities.
Once the grouping is set, the properties probabilities and tensor return grouped probabilities.
- Return type:
None
- Args:
grouping: Grouping object used to group probabilities.
- property tensor: Tensor
Return the probabilities of all branches as a tensor of shape (batch, n_branches). unless a grouping was set in which case, the probabilities are grouped and the returned tensor has shape (batch, grouping_output_size).
This property assumes that all branches are ordered lexicographically by their outcomes so the stacking of probabilities follows the same order.
- verify_branches_order()
Verify that branches are ordered lexicographically by their outcomes.
- Return type:
None
- class merlin.measurement.strategies.PartialMeasurementStrategy(measured_modes)
Bases:
BaseMeasurementStrategyNew API: return a PartialMeasurement from detector partial-measurement output.
- process(*, distribution, amplitudes, apply_sampling, effective_shots, sample_fn, apply_photon_loss, apply_detectors, grouping=None)
Return the processed result for the selected measurement strategy.
- Return type:
- class merlin.measurement.strategies.ProbabilitiesStrategy
Bases:
DistributionStrategyNew API: return output probabilities (optionally sampled).
- merlin.measurement.strategies.dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False, weakref_slot=False)
Add dunder methods based on the fields defined in the class.
Examines PEP 526 __annotations__ to determine fields.
If init is true, an __init__() method is added to the class. If repr is true, a __repr__() method is added. If order is true, rich comparison dunder methods are added. If unsafe_hash is true, a __hash__() method is added. If frozen is true, fields may not be assigned to after instance creation. If match_args is true, the __match_args__ tuple is added. If kw_only is true, then by default all fields are keyword-only. If slots is true, a new class with a __slots__ attribute is returned.
- merlin.measurement.strategies.partial_measurement(detector_output, *, grouping=None)
Build a PartialMeasurement from DetectorTransform(partial_measurement=True) output.
- Return type:
- merlin.measurement.strategies.resolve_measurement_strategy(measurement_strategy)
Return the concrete strategy implementation for the enum value.
- Return type:
- merlin.measurement.strategies.warn_deprecated_enum_access(owner, name)
Warn on deprecated enum-style attribute access and return True if handled.
- Return type:
bool