merlin.pcvl_pytorch.noisy_slos module

Noisy SLOS probability graphs for source-indistinguishability models.

This module implements a probability-only simulation backend for source noise in Merlin’s SLOS pipeline. The main entry point, NoisySLOSComputeGraph, caches one noisy subgraph per input Fock state in _slos_graph_per_input and reuses those cached subgraphs across repeated evaluations.

The implementation follows the Orthogonal Bad Bits model: each input state is expanded into partitions of fully indistinguishable and distinguishable photon subsets, and the corresponding probability distributions are convolved back together to obtain the final noisy output distribution.

class merlin.pcvl_pytorch.noisy_slos.NoisyG2SLOSComputeGraph(noise_groups, m, n_photons, computation_space=ComputationSpace.FOCK, device=None, dtype=torch.float32)

Bases: object

compute_probs(unitary, input_state)
Return type:

SectoredDistribution

save(path)

Save the noisy g2 SLOS graph configuration to disk.

Parameters:

path (str | os.PathLike[str]) – Destination path for the serialized graph metadata.

Return type:

None

to(device)

Move cached tensors and subgraphs to a specific device.

Parameters:

device (str | torch.device) – Target device.

Returns:

The graph instance moved to device.

Return type:

NoisyG2SLOSComputeGraph

Raises:

TypeError – If device is neither a string nor a torch.device.

class merlin.pcvl_pytorch.noisy_slos.NoisySLOSComputeGraph(noise_groups, m, n_photons, computation_space=ComputationSpace.FOCK, keep_keys=True, device=None, dtype=torch.float32, _slos_graphs=None)

Bases: object

Probability-only SLOS graph with source noise.

The graph caches one _InputStateNoisySLOSComputeGraph per input Fock state and one shared list of noiseless SLOS subgraphs in _slos_graphs indexed by photon number. Each cached input-state helper expands its input according to the Orthogonal Bad Bits model and uses the shared subgraphs to produce the final noisy distribution in Fock space.

Parameters:
  • noise_groups (NoiseGroups | None) – Noise configuration extracted from the layer or experiment. Source noise must be present.

  • m (int) – Number of optical modes.

  • n_photons (int) – Total photon number represented by the graph.

  • computation_space (ComputationSpace) – Requested computation space. Source-noise simulations currently operate in Fock space only. Default is ComputationSpace.FOCK.

  • keep_keys (bool) – If True, return output basis keys together with probabilities. Default is True.

  • device (str | torch.device | None) – Target device for cached tensors and subgraphs. Default is None.

  • dtype (torch.dtype) – Real dtype used by the probability graph. Default is torch.float.

Raises:

RuntimeError – If noise_groups is missing or does not contain source noise.

compute_probs(unitary, input_state)

Compute noisy output probabilities for one input Fock state.

Parameters:
  • unitary (torch.Tensor) – Circuit unitary with shape [m, m] or batched shape [batch_size, m, m]. Its dtype must match the complex dtype associated with self.dtype.

  • input_state (list[int] | tuple[int, ...]) – Input Fock occupation numbers.

Returns:

If keep_keys is True, returns the Fock output keys and a tensor of probabilities with shape [batch_size, n_output_states]. Otherwise returns the probability tensor directly.

Return type:

tuple[list[tuple[int, …]], torch.Tensor] | torch.Tensor

Raises:

ValueError – If the unitary shape is invalid, the dtype is incompatible, or the input state contains negative occupations or no photons.

save(path)

Save the noisy SLOS graph configuration to disk.

Parameters:

path (str | os.PathLike[str]) – Destination path for the serialized graph metadata.

Return type:

None

to(device)

Move cached tensors and subgraphs to a specific device.

Parameters:

device (str | torch.device) – Target device.

Returns:

The graph instance moved to device.

Return type:

NoisySLOSComputeGraph

Raises:

TypeError – If device is neither a string nor a torch.device.

merlin.pcvl_pytorch.noisy_slos.convolve_distributions(keys, *probs)

Convolve one or more probability distributions over Fock states.

This helper performs the same mode-merging tensor product used by Perceval when combining independent distributions over mode occupations.

Parameters:
  • keys (list[torch.Tensor | list[tuple[int, ...]]]) – Sequence of state lists matching the input distributions.

  • *probs (torch.Tensor) – Input probability distributions. Each tensor is either one-dimensional or batched on its leading axis.

Returns:

Combined keys and the corresponding convolved probabilities.

Return type:

tuple[torch.Tensor | list[tuple[int, …]], torch.Tensor]

Raises:

ValueError – If the number of key sets does not match the number of probability tensors.