merlin.measurement.detectors module

class merlin.measurement.detectors.Combinadics(scheme, n, m)

Bases: object

Rank/unrank Fock states in descending lexicographic order.

Parameters

schemestr

Enumeration strategy. Supported values are "fock", "unbunched", and "dual_rail".

nint

Number of photons. Must be non-negative.

mint

Number of modes. Must be at least one.

Raises

ValueError

If an unsupported scheme is provided or the parameters violate the constraints of the selected scheme.

compute_space_size()

Return the number of admissible Fock states for this configuration.

Return type:

int

Returns

int

Cardinality of the state space.

enumerate_states()

Return all admissible states in descending lexicographic order.

Return type:

list[tuple[int, ...]]

Returns

list[Tuple[int, …]]

State list matching iter_states().

fock_to_index(counts)

Map a Fock state to its index under the configured scheme.

Return type:

int

Parameters

countsIterable[int]

Photon counts per mode.

Returns

int

Rank of the Fock state in descending lexicographic order.

Raises

ValueError

If counts violates the scheme-specific constraints.

index_to_fock(index)

Map an index to its corresponding Fock state.

Return type:

tuple[int, ...]

Parameters

indexint

Rank to decode.

Returns

Tuple[int, …]

Photon counts per mode.

Raises

ValueError

If index is outside the valid range for the configured scheme.

iter_states()

Yield admissible states in descending lexicographic order.

Return type:

Iterator[tuple[int, ...]]

Returns

Iterator[Tuple[int, …]]

Generator over states matching the configured scheme.

class merlin.measurement.detectors.DetectorTransform(simulation_keys, detectors, *, dtype=None, device=None, partial_measurement=False)

Bases: Module

Linear map applying per-mode detector rules to a Fock probability vector.

Args:
simulation_keys: Iterable describing the raw Fock states produced by the

simulator (as tuples or lists of integers).

detectors: One detector per optical mode. Each detector must expose the

detect() method from perceval.Detector.

dtype: Optional torch dtype for the transform matrix. Defaults to

torch.float32.

device: Optional device used to stage the transform matrix. partial_measurement: When True, only the modes whose detector entry is

not None are measured. The transform then operates on complex amplitudes and returns per-outcome dictionaries (see forward()).

forward(tensor)

Apply the detector transform.

Return type:

Tensor | list[dict[tuple[int, ...], list[tuple[Tensor, Tensor]]]]

Args:
tensor: Probability distribution (complete mode) or amplitudes

(partial measurement). The last dimension must match the simulator basis.

Returns:
  • Complete mode: real probability tensor expressed in the detector basis.

  • Partial mode: list indexed by remaining photon count. Each entry is a dictionary whose keys are full-length mode tuples (unmeasured modes set to None) and whose values are lists of (probability, normalized remaining-mode amplitudes) pairs – one per perfect measurement branch.

property is_identity: bool

Whether the transform reduces to the identity (ideal PNR detectors).

property output_keys: list[tuple[int, ...]]

Return the classical detection outcome keys.

property output_size: int

Number of classical outcomes produced by the detectors.

property partial_measurement: bool

Return True when the transform runs in partial measurement mode.

remaining_basis(remaining_n=None)

Return the ordered Fock-state basis for the unmeasured modes.

Return type:

list[tuple[int, ...]]

Args:
remaining_n: Optional photon count used to select a specific block.

When omitted, the method returns the concatenation of every remaining-mode basis enumerated during detector initialisation.

Returns:

List of tuples describing the photon distribution over the unmeasured modes.

row(index, *, dtype=None, device=None)

Return a single detector transform row as a dense tensor.

Return type:

Tensor

class merlin.measurement.detectors.Iterable

Bases: object

class merlin.measurement.detectors.Sequence

Bases: Reversible, Collection

All the operations on a read-only sequence.

Concrete subclasses must override __new__ or __init__, __getitem__, and __len__.

count(value) integer -- return number of occurrences of value
index(value[, start[, stop]]) integer -- return first index of value.

Raises ValueError if the value is not present.

Supporting start and stop arguments is optional, but recommended.

merlin.measurement.detectors.cast(typ, val)

Cast a value to a type.

This returns the value unchanged. To the type checker this signals that the return value has the designated type, but at runtime we intentionally don’t check anything (we want this to be as fast as possible).

merlin.measurement.detectors.resolve_detectors(experiment, n_modes)

Build a per-mode detector list from a Perceval experiment.

Return type:

tuple[list[Detector], bool]

Args:

experiment: Perceval experiment carrying detector configuration. n_modes: Number of photonic modes to cover.

Returns:
normalized: list[pcvl.Detector]

List of detectors (defaulting to ideal PNR where unspecified),

empty_detectors: bool

If True, no Detector was defined in experiment. If False, at least one Detector was defined in experiement.