merlin.algorithms.feed_forward module

class merlin.algorithms.feed_forward.ACircuit(m, name=None)

Bases: AParametrizedComponent, ABC

Abstract linear optics circuit class. A circuit is defined by a dimension m, and by parameters. Parameters can be fixed (value) or variables.

property U

get the symbolic unitary matrix

add(port_range, component, merge=None)
Return type:

Circuit

compute_unitary(assign=None, use_symbolic=False, use_polarization=None)

Compute the unitary matrix corresponding to the current circuit

Parameters:
  • use_polarization (Optional[bool]) – ask for polarized circuit to double size unitary matrix

  • assign (dict) – optional mapping between parameter names and their corresponding values

  • use_symbolic (bool) – if the matrix should use symbolic calculation

Return type:

Matrix

Returns:

the unitary matrix, will be a MatrixS if symbolic, or a ~`MatrixN` if not.

definition()

Gives mathematical definition of the circuit

Only defined for elementary circuits

Return type:

Matrix

depths()
Returns:

the depth of the circuit for each mode

abstract describe()

Describe the component as the Python code that generates it.

Return type:

str

Returns:

code generating the component

identify(unitary_matrix, phases, precision=None, max_try=10, allow_error=False)

Identify an instance of the current circuit (should be parameterized) such as \(Q.C=U.P\) where \(Q\) and \(P\) are single-mode phase shifts (resp. \([q1, q2, ..., qn]\), and \([p1, p2, ...,pn]\)). This is solved through \(n^2\) equations: \(q_i * C_{i,j}(x,y, ...) = UP_{i,j} * p_j\)

Parameters:
  • unitary_matrix – the matrix to identify

  • phases – phase shift parameters

  • max_try – the resolution is using parameter search starting on a random points, it might fail, this parameter sets the maximal number of times to try

Return type:

None

inverse(v, h)
match(pattern, pos=None, pattern_pos=None, match=None, actual_pos=0, actual_pattern_pos=0)
Return type:

Optional[Match]

ncomponents()
Returns:

number of actual components in the circuit

property requires_polarization

Does the circuit require polarization?

Returns:

is True if the circuit has a polarization component

transfer_from(source, force=False)

Transfer parameters of a circuit to the current one

Parameters:
  • source (ACircuit) – the circuit to transfer the parameters from. The shape of the circuit to transfer from should be a subset of the current circuit.

  • force (bool) – force changing fixed parameter if necessary

class merlin.algorithms.feed_forward.BranchState(amplitudes, weight, remaining_n, measurement_key, basis_keys)

Bases: object

amplitudes: Tensor
basis_keys: tuple[tuple[int, ...], ...]
measurement_key: tuple[Optional[int], ...]
remaining_n: int
weight: Tensor
enum merlin.algorithms.feed_forward.ComputationSpace(value)

Bases: str, Enum

Enumeration 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 Enum and its members also have the following methods:

classmethod default(*, no_bunching)

Derive the default computation space from the legacy no_bunching flag.

Return type:

ComputationSpace

classmethod coerce(value)

Normalize user-provided values (enum instances or case-insensitive strings).

Return type:

ComputationSpace

class merlin.algorithms.feed_forward.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.algorithms.feed_forward.FFCircuitProvider(m, offset, default_circuit, name=None)

Bases: AFFConfigurator

DEFAULT_NAME = 'FFC'

For any measurement, FFCircuitProvider will return a circuit or a processor, picked from known mapping of configurations. Each configuration links a measurement to a circuit or processor. If a measurement is received and was not set in the mapping, a mandatory default circuit or processor is returned.

Parameters:
  • m – The number of classical modes that are detected (after a detector)

  • offset – The distance between the configurator and the first mode of the implemented circuits. For positive values, it is the number of empty modes between the configurator and the configured circuit below. For negative values, it is the same but the circuit is located above the configurator (the number of empty modes is abs(offset) - 1, so an offset of -1 means that there is no empty modes between the configurator and the circuit). All circuits are considered to have the size of the biggest possible circuit in this configurator.

  • default_circuit – The circuit to be used if the measured state does not befall into one of the declared cases

add_configuration(state, circuit)
Return type:

FFCircuitProvider

property circuit_map
circuit_template()

Return a fitting representation of the controlled circuit or processor.

Return type:

ACircuit

configure(measured_state)

Gives the circuit or processor that must be configured given the measured state

Parameters:

measured_state (BasicState) – The state of size self.m that corresponds to the measurements of the modes on which the configurator is located.

Return type:

ACircuit

Returns:

The processor or circuit that must be set

reset_map()
class merlin.algorithms.feed_forward.FFStage(unitary, active_modes, measured_modes, detectors, provider)

Bases: object

active_modes: tuple[int, ...]
detectors: dict[int, Optional[Detector]]
measured_modes: tuple[int, ...]
provider: Optional[FFCircuitProvider]
unitary: Circuit
class merlin.algorithms.feed_forward.FeedForwardBlock(experiment, *, input_state=None, trainable_parameters=None, input_parameters=None, computation_space=ComputationSpace.FOCK, measurement_strategy=MeasurementStrategy(type=<MeasurementKind.PROBABILITIES: 'PROBABILITIES'>, measured_modes=(), computation_space=<ComputationSpace.FOCK: 'fock'>, grouping=None), device=None, dtype=None)

Bases: MerlinModule

Feed-forward photonic block constructed directly from a Perceval experiment.

The block introspects the provided pcvl.Experiment, splits it into unitary / detector / FFCircuitProvider stages and turns each segment into one or more QuantumLayer instances. At run time the block executes every stage, branching on every partial measurement outcome and accumulating the classical probability for each branch.

Parameters

experiment:

Perceval experiment containing the full feed-forward definition. The current implementation requires noise-free experiments (NoiseModel() or None).

input_state:

Initial quantum state. May be provided as a Fock occupation list, pcvl.BasicState, pcvl.StateVector, or a tensor whose components represent amplitudes in the experiment Fock basis (the tensor is only required for amplitude-encoding inputs).

trainable_parameters:

Optional list of Perceval parameter prefixes that should remain learnable across all stages.

input_parameters:

Perceval parameter prefixes that receive classical inputs. They are consumed by the first stage only; once the first detection happens all branches switch to amplitude encoding and the classical tensor is ignored.

computation_space:

Currently restricted to FOCK.

measurement_strategy:

Controls how classical outputs are produced. - MeasurementStrategy.probs(computation_space) (default) returns a tensor of

shape (batch_size, num_output_keys) whose columns match the fully specified Fock states stored in :pyattr:`output_keys`.

  • MeasurementStrategy.mode_expectations(computation_space) collapses every branch into a single tensor of shape (batch_size, num_modes) that contains the per-mode photon expectations aggregated across all measurement keys. The :pyattr:`output_keys` attribute is retained for metadata while :pyattr:`output_state_sizes` reports num_modes for every key.

  • MeasurementStrategy.AMPLITUDES yields a list of tuples (measurement_key, branch_probability, remaining_photons, amplitudes) so callers can reason about the mixed state left by each branch.

describe()

Return a multi-line description of the feed-forward stages.

The summary lists, in order, the global modes that remain active at each step, the subset of measured modes, and the type of feed-forward configurator attached to the stage. It is primarily intended for debugging or for logging experiment structure.

Return type:

str

forward(x=None)

Execute the feed-forward experiment.

Return type:

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

Parameters

x:

Classical feature tensor. Only the first stage consumes classical inputs; subsequent stages operate purely in amplitude-encoding mode. When the experiment does not expose classical inputs this argument may be omitted (or None), in which case an empty tensor is automatically supplied.

Returns

torch.Tensor | list

PROBABILITIES returns a tensor of shape (batch_size, len(output_keys)) aligned with the fully specified Fock states in :pyattr:`output_keys`. MODE_EXPECTATIONS produces a tensor of shape (batch_size, total_modes) where the columns already encode the per-mode expectations aggregated across all measurement keys (:pyattr:`output_state_sizes` stores total_modes for every key). AMPLITUDES yields a list of tuples (measurement_key, branch_probability, remaining_photons, amplitudes) describing every branch of the resulting mixed state.

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

Return the measurement keys associated with the most recent classical forward pass.

The list is populated after forward() completes. For the PROBABILITIES strategy the list lines up with the tensor columns. For MODE_EXPECTATIONS it is retained for reference even though the returned tensor already aggregates all measurement outcomes. Calling the property before running the block raises RuntimeError.

property output_state_sizes: dict[tuple[int, ...], int]

Return the number of remaining Fock states represented by each entry in output_keys.

Only available when measurement_strategy is PROBABILITIES or MODE_EXPECTATIONS. For PROBABILITIES the value is always 1 because each key now denotes a fully specified Fock state, while for MODE_EXPECTATIONS it equals the total number of modes contributing to the expectation vector.

enum merlin.algorithms.feed_forward.MeasurementKind(value)

Bases: Enum

New 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.algorithms.feed_forward.MeasurementStrategy(type, measured_modes=(), computation_space=None, grouping=None)

Bases: object

New 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:

MeasurementStrategy

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:

MeasurementStrategy

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:

MeasurementStrategy

static probs(computation_space=ComputationSpace.UNBUNCHED, grouping=None)
Return type:

MeasurementStrategy

type: MeasurementKind
validate_modes(n_modes)

Validate mode indices and warn when the selection covers all modes.

Return type:

None

class merlin.algorithms.feed_forward.MerlinModule

Bases: Module

Generic MerLin module with shared utility functions

Merlin remote execution policy:
  • _force_simulation (bool) defaults to False. When True, the layer MUST run locally. The variable is set with property (getter and setter): force_local.

  • supports_offload() reports whether remote offload is possible (via export_config()).

  • should_offload(processor, shots) encapsulates the current offload policy:

    return supports_offload() and not force_local

  • as_simulation() provide local context forcing use as simulation

as_simulation()

Temporarily force local simulation within the context.

property force_local: bool

When True, this layer must run locally (Merlin will not offload it).

static setup_device_and_dtype(device, dtype)

Normalize device/dtype to final forms.

Return type:

tuple[Optional[device], dtype, dtype]

should_offload()

Return True if this layer should be offloaded under current policy.

Return type:

bool

supports_offload()

Return True if this layer is technically offloadable.

Return type:

bool

class merlin.algorithms.feed_forward.NoiseModel(brightness=None, indistinguishability=None, g2=None, g2_distinguishable=None, transmittance=None, phase_imprecision=None, phase_error=None)

Bases: object

The NoiseModel class contains all noise parameters which are supported by Perceval. Default value of each parameter means “no noise”, so a NoiseModel constructed with all default parameters leads to a perfect simulation.

Parameters:
  • brightness (float) – first lens brightness of a quantum dot

  • indistinguishability (float) – chance two photons are indistinguishable

  • g2 (float) – g²(0) - second order intensity autocorrelation at zero time delay. This parameter is correlated with how often two photons are emitted by the source instead of a single one.

  • g2_distinguishable (bool) – g2-generated photons indistinguishability

  • transmittance (float) – system-wide transmittance (warning, can interfere with the brightness parameter)

  • phase_imprecision (float) – maximum precision of the phase shifters (0 means infinite precision)

  • phase_error (float) – maximum random noise on the phase shifters (in radian)

brightness
g2
g2_distinguishable
indistinguishability
phase_error
phase_imprecision
transmittance
class merlin.algorithms.feed_forward.OutputMapper

Bases: object

Handles mapping quantum state amplitudes or probabilities to classical outputs.

This class provides factory methods for creating different types of output mappers that convert quantum state amplitudes or probabilities to classical outputs.

static create_mapping(strategy, computation_space=ComputationSpace.FOCK, keys=None, dtype=None)

Create an output mapping based on the specified strategy.

Args:

strategy: The measurement mapping strategy to use computation_space: The computation space for the measurement. keys: (Only used for ModeExpectations measurement strategy) List of tuples that represent the possible quantum Fock states.

For example, keys = [(0,1,0,2), (1,0,1,0), …]

dtype: Target dtype for internal tensors. Defaults to torch.float32.

Returns:

A PyTorch module that maps the per state amplitudes or probabilities to the desired format.

Raises:

ValueError: If strategy is unknown

class merlin.algorithms.feed_forward.QuantumLayer(input_size=None, builder=None, circuit=None, experiment=None, input_state=None, n_photons=None, trainable_parameters=None, input_parameters=None, amplitude_encoding=False, computation_space=None, measurement_strategy=None, return_object=False, device=None, dtype=None)

Bases: MerlinModule

Quantum Neural Network Layer with factory-based architecture.

This layer can be created either from a CircuitBuilder instance, a pre-compiled pcvl.Circuit, or an :class:Experiment`.

export_config()

Export a standalone configuration for remote execution.

Return type:

dict

forward(*input_parameters, shots=None, sampling_method=None, simultaneous_processes=None)

Forward pass through the quantum layer.

Encoding is inferred from the input type: :rtype: Tensor | PartialMeasurement | StateVector | ProbabilityDistribution

  • torch.Tensor (float): angle encoding (compatible with nn.Sequential)

  • torch.Tensor (complex): amplitude encoding

  • StateVector: amplitude encoding (preferred for quantum state injection)

Parameters

*input_parameterstorch.Tensor | StateVector

Input data. For angle encoding, pass float tensors. For amplitude encoding, pass a single StateVector or complex tensor.

shotsint | None, optional

Number of samples; if 0 or None, return exact amplitudes/probabilities.

sampling_methodstr | None, optional

Sampling method, e.g. “multinomial”.

simultaneous_processesint | None, optional

Batch size hint for parallel computation.

Returns

torch.Tensor | PartialMeasurement | StateVector | ProbabilityDistribution

Output after measurement mapping. Depending on the return_object argument and measurement strategy defined in the input, the output type will be different. Check the constructor for more details.

Raises

TypeError

If inputs mix torch.Tensor and StateVector, or if an unsupported input type is provided.

ValueError

If multiple StateVector inputs are provided.

property has_custom_detectors: bool
property output_keys

Return the Fock basis associated with the layer outputs.

property output_size: int
prepare_parameters(input_parameters)

Prepare parameter list for circuit evaluation.

Return type:

list[Tensor]

set_input_state(input_state)
set_sampling_config(shots=None, sampling_method=None)

Deprecated: sampling configuration must be provided at call time in forward.

classmethod simple(cls, input_size, output_size=None, device=None, dtype=None, computation_space=ComputationSpace.UNBUNCHED)

Create a ready-to-train layer with a input_size-mode, (input_size//2)-photon architecture.

The circuit is assembled via CircuitBuilder with the following layout:

  1. A fully trainable entangling layer acting on all modes;

  2. A full input encoding layer spanning all encoded features;

  3. A fully trainable entangling layer acting on all modes.

Args:

input_size: Size of the classical input vector. Must be 20 or lower. output_size: Optional classical output width. device: Optional target device for tensors. dtype: Optional tensor dtype. computation_space: Logical computation subspace; one of {“fock”, “unbunched”, “dual_rail”}.

Returns:

QuantumLayer configured with the described architecture.

to(*args, **kwargs)

Move and/or cast the parameters and buffers.

This can be called as

to(device=None, dtype=None, non_blocking=False)
to(dtype, non_blocking=False)
to(tensor, non_blocking=False)
to(memory_format=torch.channels_last)

Its signature is similar to torch.Tensor.to(), but only accepts floating point or complex dtypes. In addition, this method will only cast the floating point or complex parameters and buffers to dtype (if given). The integral parameters and buffers will be moved device, if that is given, but with dtypes unchanged. When non_blocking is set, it tries to convert/move asynchronously with respect to the host if possible, e.g., moving CPU Tensors with pinned memory to CUDA devices.

See below for examples.

Note

This method modifies the module in-place.

Args:
device (torch.device): the desired device of the parameters

and buffers in this module

dtype (torch.dtype): the desired floating point or complex dtype of

the parameters and buffers in this module

tensor (torch.Tensor): Tensor whose dtype and device are the desired

dtype and device for all parameters and buffers in this module

memory_format (torch.memory_format): the desired memory

format for 4D parameters and buffers in this module (keyword only argument)

Returns:

Module: self

Examples:

>>> # xdoctest: +IGNORE_WANT("non-deterministic")
>>> linear = nn.Linear(2, 2)
>>> linear.weight
Parameter containing:
tensor([[ 0.1913, -0.3420],
        [-0.5113, -0.2325]])
>>> linear.to(torch.double)
Linear(in_features=2, out_features=2, bias=True)
>>> linear.weight
Parameter containing:
tensor([[ 0.1913, -0.3420],
        [-0.5113, -0.2325]], dtype=torch.float64)
>>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_CUDA1)
>>> gpu1 = torch.device("cuda:1")
>>> linear.to(gpu1, dtype=torch.half, non_blocking=True)
Linear(in_features=2, out_features=2, bias=True)
>>> linear.weight
Parameter containing:
tensor([[ 0.1914, -0.3420],
        [-0.5112, -0.2324]], dtype=torch.float16, device='cuda:1')
>>> cpu = torch.device("cpu")
>>> linear.to(cpu)
Linear(in_features=2, out_features=2, bias=True)
>>> linear.weight
Parameter containing:
tensor([[ 0.1914, -0.3420],
        [-0.5112, -0.2324]], dtype=torch.float16)

>>> linear = nn.Linear(2, 2, bias=None).to(torch.cdouble)
>>> linear.weight
Parameter containing:
tensor([[ 0.3741+0.j,  0.2382+0.j],
        [ 0.5593+0.j, -0.4443+0.j]], dtype=torch.complex128)
>>> linear(torch.ones(3, 2, dtype=torch.cdouble))
tensor([[0.6122+0.j, 0.1150+0.j],
        [0.6122+0.j, 0.1150+0.j],
        [0.6122+0.j, 0.1150+0.j]], dtype=torch.complex128)
class merlin.algorithms.feed_forward.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.

class merlin.algorithms.feed_forward.StageRuntime(circuit, pre_layer, detector_transform, conditional_circuits, conditional_default_key, measured_modes, global_measured_modes, active_modes, detectors, provider, pre_layers=<factory>, detector_cache=<factory>, conditional_layer_cache=<factory>, trainable_parameters=None, initial_amplitudes=None, classical_input_size=0)

Bases: object

active_modes: tuple[int, ...]
circuit: Circuit
classical_input_size: int = 0
conditional_circuits: dict[tuple[int, ...], Circuit]
conditional_default_key: Optional[tuple[int, ...]]
conditional_layer_cache: dict[tuple[tuple[int, ...], int], QuantumLayer]
detector_cache: dict[int, DetectorTransform]
detector_transform: Optional[DetectorTransform]
detectors: dict[int, Optional[Detector]]
global_measured_modes: tuple[int, ...]
initial_amplitudes: Optional[Tensor] = None
measured_modes: tuple[int, ...]
pre_layer: Optional[QuantumLayer]
pre_layers: dict[int, QuantumLayer]
provider: Optional[FFCircuitProvider]
trainable_parameters: Optional[list[str]] = None
merlin.algorithms.feed_forward.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.algorithms.feed_forward.field(*, default=<dataclasses._MISSING_TYPE object>, default_factory=<dataclasses._MISSING_TYPE object>, init=True, repr=True, hash=None, compare=True, metadata=None, kw_only=<dataclasses._MISSING_TYPE object>)

Return an object to identify dataclass fields.

default is the default value of the field. default_factory is a 0-argument function called to initialize a field’s value. If init is true, the field will be a parameter to the class’s __init__() function. If repr is true, the field will be included in the object’s repr(). If hash is true, the field will be included in the object’s hash(). If compare is true, the field will be used in comparison functions. metadata, if specified, must be a mapping which is stored but not otherwise examined by dataclass. If kw_only is true, the field will become a keyword-only parameter to __init__().

It is an error to specify both default and default_factory.

merlin.algorithms.feed_forward.pcvl_to_tensor(state_vector, computation_space=ComputationSpace.FOCK, dtype=torch.complex64, device=device(type='cpu'))

Convert a Perceval StateVector into a torch Tensor.

Return type:

Tensor

Args:

state_vector: Perceval StateVector. computation_space: Computation space of the state vector following combinadics ordering. dtype: Desired torch dtype of the output Tensor. device: Desired torch device of the output Tensor.

Returns:

Equivalent torch Tensor.

Raises:
ValueError: If the StateVector includes states with incompatible photon number for the specified computation space,

or non consistent number of photons across the states.