merlin.algorithms.kernels module

class merlin.algorithms.kernels.FeatureMap(circuit=None, input_size=None, *, builder=None, experiment=None, input_parameters, trainable_parameters=None, dtype=torch.float32, device=None, encoder=None)

Bases: object

Quantum feature map.

FeatureMap describes how classical data is embedded in a photonic circuit for quantum kernel methods.

FidelityKernel treats this object as a descriptor. It passes the stored experiment, parameter prefixes, input size, dtype, and device to _CCInvQuantumLayer, the internal adapter over the QuantumLayer backend. Legacy unitary-building state remains on FeatureMap only to support deprecated direct calls to compute_unitary().

Parameters:
  • circuit (pcvl.Circuit | None) – Pre-compiled Perceval circuit used to encode features.

  • input_size (int | None) – Dimension of incoming classical data. Required.

  • builder (CircuitBuilder | None) – Optional builder used to compile a circuit declaratively.

  • experiment (pcvl.Experiment | None) – Optional experiment providing both the circuit and detector configuration. Exactly one of circuit, builder, or experiment must be supplied.

  • input_parameters (str | list[str] | None) – Parameter prefix(es) that host the classical data.

  • trainable_parameters (list[str] | None) – Optional trainable parameter prefixes.

  • dtype (str | torch.dtype) – Torch dtype used when constructing the unitary.

  • device (torch.device | None) – Torch device on which unitaries are evaluated.

  • encoder (Callable[[torch.Tensor], torch.Tensor] | None) – Optional custom encoder used only by the deprecated compute_unitary() path. FidelityKernel supports this argument for compatibility with a deprecation warning.

compute_unitary(x, *training_parameters)

Generate the circuit unitary after encoding x and applying trainables.

Warning

Deprecated since version 0.4: compute_unitary is deprecated and will be removed in a future release. It uses legacy compiler state stored on FeatureMap. Use FidelityKernel for kernel computations; FidelityKernel uses _CCInvQuantumLayer over the QuantumLayer backend and treats FeatureMap as a descriptor without relying on this method.

Parameters:
Returns:

Complex unitary matrix representing the prepared circuit.

Return type:

torch.Tensor

Raises:
  • TypeError – If x has an unsupported type.

  • ValueError – If angle encoding metadata is inconsistent with x.

is_datapoint(x)

Determine if x describes one sample or a batch.

Parameters:

x (torch.Tensor | numpy.ndarray | float | int) – Candidate input data.

Returns:

True when x corresponds to a single datapoint.

Return type:

bool

Raises:

ValueError – If x cannot be reshaped into samples of size input_size.

classmethod simple(cls, input_size, *, dtype=torch.float32, device=None, angle_encoding_scale=1.0, n_modes=None)

Simple factory method to create a FeatureMap with minimal configuration.

The circuit uses n_modes = input_size + 1 by default.

Parameters:
  • input_size (int) – Classical feature dimension. Maximum is 19.

  • dtype (str | torch.dtype) – Target dtype for internal tensors.

  • device (torch.device | None) – Optional torch device handle.

  • angle_encoding_scale (float) – Global scaling applied to angle encoding features. Default is 1.0.

  • n_modes (int | None) –

    Warning

    Deprecated since version 0.4: Passing n_modes is deprecated and will be removed in release 0.5. The value is still honoured in 0.4, but in 0.5 the mode count will be fixed to input_size + 1 and this parameter will be removed. Use CircuitBuilder directly if you need a different mode count.

Returns:

Configured feature-map instance.

Return type:

FeatureMap

Raises:

ValueError – If input_size is outside the supported range.

class merlin.algorithms.kernels.FidelityKernel(feature_map, input_state=None, *, n_photons=None, shots=None, sampling_method='multinomial', computation_space=None, force_psd=True, device=None, dtype=None)

Bases: MerlinModule

Fidelity Quantum Kernel

Next-release deprecations for the legacy FeatureMap unitary path:

  • FeatureMap.compute_unitary

  • FeatureMap._px_len

  • FeatureMap._encode_x

  • FeatureMap._encode_with_specs

  • FeatureMap._subset_sum_expand

FidelityKernel does not use these methods. It delegates kernel computation to _CCInvQuantumLayer, which uses the QuantumLayer backend.

For a given input Fock state, \(|s \rangle\) and feature map, \(U\), the fidelity quantum kernel estimates the following inner product using SLOS:

\[|\langle s | U^{\dagger}(x_2) U(x_1) | s \rangle|^{2}\]

Transition probabilities are computed in parallel for each pair of datapoints in the input datasets.

Parameters:
  • feature_map (FeatureMap) – Feature map object that encodes a given datapoint within its circuit.

  • input_state (list[int] | None) – Input Fock state occupation list. If None, the state is derived from n_photons when given, otherwise defaults to an alternating single-photon state [1, 0, 1, 0, ...] of length feature_map.circuit.m. Passing torch.Tensor is removed; build a StateVector with from_tensor() for amplitude-state workflows.

  • n_photons (int | None) – Number of photons to place in the input state when input_state is None. If n_photons <= ceil(m / 2) (where m is the number of circuit modes), photons are spread in the alternating pattern [1, 0, 1, 0, ...]; otherwise all alternating positions are filled first and then remaining positions are filled left to right (e.g. 4 photons in 6 modes → [1, 1, 1, 0, 1, 0]), and a UserWarning is emitted. If input_state is also provided, sum(input_state) must equal n_photons, otherwise a ValueError is raised. Default: None.

  • shots (int | None) – Number of circuit shots. If None, the exact transition probabilities are returned. Default: None.

  • sampling_method (str) – Probability distributions are post-processed with a pseudo-sampling method: "multinomial", "binomial", or "gaussian". Default is "multinomial".

  • computation_space (ComputationSpace | str | None) – Logical computation subspace; one of {"fock", "unbunched", "dual_rail"}. Default: FOCK.

  • force_psd (bool) – Projects the training kernel matrix to the closest positive semi-definite matrix. Default is True.

  • device (torch.device | None) – Device on which to perform SLOS.

  • dtype (str | torch.dtype | None) – Datatype with which to perform SLOS.

Examples

For a given training and test datasets, one can construct the training and test kernel matrices with the following structure:

circuit = Circuit(2) // PS(P("X0")) // BS() // PS(P("X1")) // BS()
feature_map = FeatureMap(circuit, ["X"])

quantum_kernel = FidelityKernel(
    feature_map,
    input_state=[0, 4],
)
K_train = quantum_kernel(X_train)
K_test = quantum_kernel(X_test, X_train)

Use with scikit-learn for kernel-based machine learning:

from sklearn.svm import SVC

svc = SVC(kernel="precomputed")
svc.fit(K_train, y_train)
y_pred = svc.predict(K_test)

Warning

FidelityKernel is not thread-safe. The internal CircuitConverter holds shared mutable state. Using this module inside a DataLoader with num_workers > 0 will produce a data race. Always set num_workers=0 when the kernel is used as part of a DataLoader worker.

forward(x1, x2=None)

Calculate the quantum kernel for input data x1 and x2.

If x1 and x2 are datapoints, a scalar value is returned. For input datasets the kernel matrix is computed.

Parameters:
Returns:

Scalar kernel value for datapoints, or a kernel matrix for datasets.

Return type:

float | torch.Tensor

Raises:
  • TypeError – If x2 cannot be converted to a tensor when provided.

  • ValueError – If scalar datapoints are passed without x2 or if input shapes are incompatible with the feature-map input size.

property input_state: list[int]

Input Fock state occupation list used for kernel evaluation.

Returns:

Copy of the input Fock state used by the kernel backend.

Return type:

list[int]

classmethod simple(cls, input_size, *, shots=0, sampling_method='multinomial', computation_space=None, force_psd=True, dtype=torch.float32, device=None, angle_encoding_scale=1.0, n_modes=None)

Create a simple fidelity kernel with minimal configuration.

Warning

Deprecated since version 0.4: This factory method is deprecated and will be removed in release 0.5. Build a feature map with FeatureMap.simple() and pass it directly to FidelityKernel.

Parameters:
  • input_size (int) – Classical feature dimension.

  • shots (int) – Number of pseudo-sampling shots. Default is 0.

  • sampling_method (str) – Sampling method used when shots is positive. Default is "multinomial".

  • computation_space (ComputationSpace | str | None) – Logical computation subspace.

  • force_psd (bool) – Whether to project the training kernel matrix to the nearest positive semi-definite matrix. Default is True.

  • dtype (str | torch.dtype) – Target dtype for internal tensors. Default is torch.float32.

  • device (torch.device | None) – Device on which to execute computations.

  • angle_encoding_scale (float) – Global scaling applied to angle encoding features. Default is 1.0.

  • n_modes (int | None) –

    Warning

    Deprecated since version 0.4: Passing n_modes is deprecated and will be removed in release 0.5. The value is still honoured in 0.4, but in 0.5 the mode count will be fixed to input_size + 1 and this parameter will be removed. Use CircuitBuilder directly if you need a different mode count.

Returns:

Configured fidelity kernel.

Return type:

FidelityKernel

Raises:
  • ValueError – If the generated feature map or input state is incompatible with fidelity-kernel evaluation.

  • RuntimeError – If the generated experiment configuration is incompatible with the requested computation space.

Deprecations

Warning

Deprecated since version 0.4: KernelCircuitBuilder is deprecated and will be removed in release 0.5. Use CircuitBuilder with FeatureMap and FidelityKernel directly instead.

class merlin.algorithms.kernels.KernelCircuitBuilder

Bases: object

Builder for creating photonic quantum kernel circuits.

Warning

Deprecated since version 0.4: KernelCircuitBuilder is deprecated and will be removed in release 0.5. Use CircuitBuilder with FeatureMap and FidelityKernel directly instead:

builder = CircuitBuilder(n_modes=3)
builder.add_entangling_layer(name="U1")
builder.add_angle_encoding(modes=[0, 1], name="input")
builder.add_entangling_layer(name="U2")
feature_map = FeatureMap(builder=builder, input_size=2)
kernel = FidelityKernel(feature_map=feature_map, input_state=[1, 0, 1])

This class provides a fluent interface for building quantum kernel circuits with various configurations, inspired by the core.layer architecture.

angle_encoding(*, scale=1.0)

Configure the angle encoding scale.

Parameters:

scale (float) – Multiplicative scale applied to angle encoding features. Default is 1.0.

Returns:

Builder instance for method chaining.

Return type:

KernelCircuitBuilder

build_feature_map()

Build and return a FeatureMap instance.

Warning

Deprecated since version 0.4: Use CircuitBuilder with FeatureMap directly instead.

Returns:

Configured feature map.

Return type:

FeatureMap

Raises:

ValueError – If required parameters are missing.

build_fidelity_kernel(input_state=None, *, shots=0, sampling_method='multinomial', computation_space=None, force_psd=True)

Build and return a FidelityKernel instance.

Warning

Deprecated since version 0.4: Use CircuitBuilder with FeatureMap and FidelityKernel directly instead.

Parameters:
  • input_state (list[int] | None) – Input Fock state. If None, it is generated automatically.

  • shots (int) – Number of sampling shots. Default is 0.

  • sampling_method (str) – Sampling method for pseudo-sampling. Default is "multinomial".

  • computation_space (ComputationSpace | str | None) – Logical computation subspace; one of {"fock", "unbunched", "dual_rail"}.

  • force_psd (bool) – Whether to project to the nearest positive semi-definite matrix. Default is True.

Returns:

Configured fidelity kernel.

Return type:

FidelityKernel

device(device)

Set the computation device.

Parameters:

device (torch.device) – Device on which generated kernels evaluate tensors.

Returns:

Builder instance for method chaining.

Return type:

KernelCircuitBuilder

dtype(dtype)

Set the data type for computations.

Parameters:

dtype (str | torch.dtype) – Real dtype used by generated feature maps and kernels.

Returns:

Builder instance for method chaining.

Return type:

KernelCircuitBuilder

input_size(size)

Set the input dimensionality.

Parameters:

size (int) – Number of classical features encoded by the kernel circuit.

Returns:

Builder instance for method chaining.

Return type:

KernelCircuitBuilder

n_modes(modes)

Set the number of modes in the circuit.

Parameters:

modes (int) – Number of photonic modes in the generated circuit.

Returns:

Builder instance for method chaining.

Return type:

KernelCircuitBuilder

n_photons(photons)

Set the number of photons.

Parameters:

photons (int) – Number of photons used when generating a default input state.

Returns:

Builder instance for method chaining.

Return type:

KernelCircuitBuilder

trainable(enabled=True, *, prefix='phi')

Enable or disable trainable rotations generated by the helper.

Parameters:
  • enabled (bool) – Whether trainable rotations are added to generated feature maps. Default is True.

  • prefix (str) – Parameter prefix used for trainable rotations when enabled is True. Default is "phi".

Returns:

Builder instance for method chaining.

Return type:

KernelCircuitBuilder

Warning

Removed in version 0.4: The no_bunching flag accepted by legacy kernel constructors is removed in version 0.4. Use computation_space=ComputationSpace.UNBUNCHED or computation_space=ComputationSpace.FOCK instead. See Migration guide.

Warning

Removed in version 0.4: Passing torch.Tensor as FidelityKernel(input_state=...) is removed. Kernel input_state must be a Fock occupation list such as [1, 0, 1]. For amplitude tensors, build a StateVector with from_tensor() and use QuantumLayer instead.

Warning

Deprecated since version 0.4: Direct unitary construction through FeatureMap.compute_unitary() is a legacy path. It still owns compiler state for backwards compatibility, but FidelityKernel no longer uses it. Use FidelityKernel for kernel computations.

Note

FeatureMap is the descriptor used by FidelityKernel: it stores the circuit or experiment, input size, parameter prefixes, dtype, and device. FidelityKernel uses the internal CCInvQuantumLayer adapter, and CCInvQuantumLayer uses the QuantumLayer backend.

Note

When the wrapped FeatureMap exposes a pcvl.Experiment, fidelity kernels compose the attached pcvl.NoiseModel (photon loss) before applying any detector transforms. The resulting kernel values therefore reflect both survival probabilities and detector post-processing.

Examples

Quickstart: Fidelity kernel in a few lines

import torch
from merlin import ComputationSpace
from merlin.algorithms.kernels import FeatureMap, FidelityKernel

# Build a kernel where inputs of size 2 are encoded in a 3-mode circuit
feature_map = FeatureMap.simple(
    input_size=2,
    dtype=torch.float32,
    device=torch.device("cpu"),
)
kernel = FidelityKernel(
    feature_map=feature_map,
    shots=0,                 # exact probabilities (no sampling)
    computation_space=ComputationSpace.FOCK,       # allow bunched outcomes if needed
)

# X_train: (N, 2), X_test: (M, 2)
X_train = torch.rand(10, 2)
X_test = torch.rand(5, 2)

K_train = kernel(X_train)           # (N, N)
K_test = kernel(X_test, X_train)    # (M, N)

Custom experiment with FeatureMap

import torch
import perceval as pcvl
from merlin.algorithms.kernels import FeatureMap, FidelityKernel

# Define a photonic circuit with two input parameters
circuit = pcvl.Circuit(6)
circuit.add(0, pcvl.PS(pcvl.P("x0")))
circuit.add(1, pcvl.PS(pcvl.P("x1")))

# Define the Experiment
experiment = pcvl.Experiment(circuit)
# Add noise models, detectors, etc...
experiment.noise = pcvl.NoiseModel(brightness=0.9)
experiment.detectors[0] = pcvl.Detector.threshold()
experiment.detectors[5] = pcvl.Detector.ppnr(n_wires=3)

# Use the experiment to create a FeatureMap
feature_map = FeatureMap(
    experiment=experiment,
    input_size=2,
    input_parameters="x",
)

# Build the kernel with a specific input state
kernel = FidelityKernel(
    feature_map=feature_map,
    input_state=[2, 0, 2, 0, 2, 0],
    computation_space=ComputationSpace.FOCK,
)

X = torch.rand(8, 2)
K = kernel(X)  # (8, 8)

Use with scikit-learn (precomputed kernel)

import torch
from sklearn.svm import SVC
from merlin.algorithms.kernels import FeatureMap, FidelityKernel
from merlin.builder import CircuitBuilder

# Build a kernel with 4 input features in 5 modes
builder = CircuitBuilder(n_modes=5)
builder.add_superpositions(depth=1)
builder.add_angle_encoding(modes=[0, 1, 2, 3], name="input")
builder.add_superpositions(depth=1)

feature_map = FeatureMap(builder=builder, input_size=4, input_parameters=None)
kernel = FidelityKernel(feature_map=feature_map, input_state=[1, 0, 1, 0, 1])

K_train = kernel(X_train)
K_test = kernel(X_test, X_train)

# Train a precomputed-kernel SVM
clf = SVC(kernel="precomputed")
clf.fit(K_train, y_train)
y_pred = clf.predict(K_test)