Skip to content

photonics

eigenkit.photonics

Photonic circuits, which compute with linear optics.

This package is separate from the qubit core, and works with Quandela's Perceval software. It does not use the qubit Provider protocol, because Fock space, components that act on optical modes and photon statistics do not fit a CircuitSpec with Pauli Observables.

It has the same layers as the qubit core. ir holds the data, executor defines the protocol, gradients computes the gradients, backends/ holds the executors that call a software development kit (SDK), and torch is the PyTorch interface. Importing this package does not import Perceval or PyTorch. The Perceval SDK is imported only when an executor runs, and the PyTorch interface (PhotonicCircuit) is imported the first time the name is accessed. PhotonicCircuit is listed in __all__, so from eigenkit.photonics import * does import PyTorch. If that matters, import only the names that you use.

BeamSplitter dataclass

A beam splitter on two modes.

modes are two adjacent modes (m, m + 1), because Perceval can place a beam splitter only on adjacent modes. theta sets the reflectivity, with the Perceval convention R = cos²(theta/2), so theta = π/2 gives a balanced 50:50 beam splitter. phi is a relative phase. Each angle is a Parameter expression or a plain number, and a plain number is stored as a Constant. The exact unitary is set by the executor, which maps the component to Perceval's pcvl.BS, so this class only describes the component.

Compiled

Bases: Protocol

A handle to a compiled photonic circuit, cheap to call many times.

Its contents are internal to the executor that built it.

expectation(weights, inputs, observable)

Evaluate one observable that is diagonal in the Fock basis, for one sample.

Parameters:

Name Type Description Default
weights ndarray

The 1-D weight vector.

required
inputs ndarray

The 1-D input vector.

required
observable PhotonicObservable

A PhotonNumber or a FockProbability.

required

Returns:

Type Description
float

The expectation value of observable.

jacobian(weights, inputs, observable, *, method='parameter_shift', need_weight_grad=True, need_input_grad=True)

Compute the gradient of one observable with respect to weights and inputs.

Parameters:

Name Type Description Default
weights ndarray

The 1-D weight vector.

required
inputs ndarray

The 1-D input vector.

required
observable PhotonicObservable

A PhotonNumber or a FockProbability.

required
method str

How to differentiate, for example "parameter_shift".

'parameter_shift'
need_weight_grad bool

If True, compute the gradient with respect to the weights. If False, the implementation may skip it and return None in its place. The PyTorch bridge takes this value from ctx.needs_input_grad.

True
need_input_grad bool

The same as need_weight_grad, for the gradient with respect to the inputs.

True

Returns:

Name Type Description
weight_jac ndarray | None

The derivatives d<O>/d weights, or None if they were not requested.

input_jac ndarray | None

The derivatives d<O>/d inputs, or None if they were not requested.

run(weights, inputs)

Evaluate the circuit for one sample.

Parameters:

Name Type Description Default
weights ndarray

The 1-D weight vector, of length spec.n_weights.

required
inputs ndarray

The 1-D input vector, of length spec.n_inputs.

required

Returns:

Type Description
dict

The output Fock distribution, as a dictionary {photon_counts_tuple: probability}.

Executor

Bases: Protocol

An object that compiles a PhotonicCircuitSpec into a Compiled handle.

The handle can be reused for many evaluations.

compile(spec)

Prepare spec so that it can be evaluated many times.

Parameters:

Name Type Description Default
spec PhotonicCircuitSpec

The circuit to compile.

required

Returns:

Type Description
Compiled

A Compiled handle for spec.

FockProbability dataclass

The probability of detecting exactly the output Fock state target.

In formula form, <O> = P(target).

PercevalBackend

The photonic executor that runs on a local Perceval simulator.

compile(spec) returns a PercevalCompiled.

Parameters:

Name Type Description Default
backend_name str

A Perceval backend that computes the full output distribution. "SLOS" (the default) and "Naive" are exact, while "MPS" and "NaiveApprox" approximate the distribution, and so the gradients too. Backends that only sample, such as "CliffordClifford2017", are rejected, because run returns probabilities, not samples.

'SLOS'

Raises:

Type Description
ValueError

If backend_name is unknown or only samples.

compile(spec)

Wrap spec in a reusable handle. Perceval runs at each call of the handle.

Parameters:

Name Type Description Default
spec PhotonicCircuitSpec

The circuit to compile.

required

Returns:

Type Description
PercevalCompiled

The PercevalCompiled handle for spec.

PercevalCompiled

A reusable handle to a compiled photonic circuit, cheap to call many times.

It is the linear-optics counterpart of CompiledCircuit. PercevalBackend.compile builds it.

Parameters:

Name Type Description Default
spec PhotonicCircuitSpec

The circuit that this handle evaluates.

required
backend_name str

The Perceval backend, as for PercevalBackend. Default: "SLOS".

'SLOS'

Raises:

Type Description
ValueError

If backend_name is unknown or only samples.

expectation(weights, inputs, observable)

Return the expectation value of a PhotonicObservable, as a single number.

The observable is diagonal in the Fock basis.

Parameters:

Name Type Description Default
weights ndarray

The 1-D weight vector.

required
inputs ndarray

The 1-D input vector.

required
observable PhotonicObservable

A PhotonNumber or a FockProbability.

required

Raises:

Type Description
ValueError

If observable can never match the output of the circuit.

jacobian(weights, inputs, observable, *, method='parameter_shift', need_weight_grad=True, need_input_grad=True)

Return (d<O>/d weights, d<O>/d inputs) for an observable.

The observable is diagonal in the Fock basis. Only one sample is accepted (1-D weights and inputs).

Parameters:

Name Type Description Default
weights ndarray

The 1-D weight vector.

required
inputs ndarray

The 1-D input vector.

required
observable PhotonicObservable

A PhotonNumber or a FockProbability.

required
method str

"parameter_shift" for the exact photonic parameter-shift rule (in gradients.py), or "finite_difference" for central finite differences, the reference method. Default: "parameter_shift".

'parameter_shift'
need_weight_grad bool

If True, compute the gradient with respect to the weights. If False, it is skipped, and None is returned in its place.

True
need_input_grad bool

If True, compute the gradient with respect to the inputs. If False, it is skipped, and None is returned in its place.

True

Raises:

Type Description
ValueError

If method is neither of these two values.

run(weights, inputs)

Return the output distribution of photon numbers.

The distribution is a dictionary {photon_counts_tuple: probability}. Fock states with probability zero may be left out, because Perceval's prob_distribution is sparse.

Parameters:

Name Type Description Default
weights ndarray

The 1-D weight vector, of length spec.n_weights.

required
inputs ndarray

The 1-D input vector, of length spec.n_inputs.

required

Raises:

Type Description
ValueError

If weights or inputs has the wrong shape.

Permutation dataclass

A reordering of the modes, which is a network of mode swaps given as one component.

perm[i] is the output mode to which input mode i is sent. The component acts on the modes 0 to len(perm) - 1, so perm must reorder exactly these modes.

PhaseShifter dataclass

A phase shift exp(i·phi·n̂) on a single mode.

n̂ is the photon-number operator of the mode. phi is a Parameter expression or a plain number, and a plain number is stored as a Constant.

PhotonNumber dataclass

The expected number of photons in a mode: <O> = <n̂_mode>.

PhotonicCircuitSpec dataclass

A description of a linear-optical circuit that does not depend on the backend.

It is the photonic counterpart of core.ir.CircuitSpec. It cannot be changed after it is built, and it can be hashed and pickled.

input_state is the Fock state sent into the circuit, as the number of photons in each mode. For example, (1, 0, 1, 0) means one photon in mode 0 and one in mode 2. What is measured (the full distribution of photon numbers, the expected photon number of each mode, or a function of the detection pattern) is left to the executor for now. A PhotonicMeasurement type is planned.

Every component must act on the modes 0 to n_modes - 1, and input_state must hold non-negative integers. Both are checked when the object is built, so a wrong circuit fails at that point, and not inside Perceval.

n_photons property

The total number of photons sent into the circuit.

This number sets the cost of the simulation in Fock space.

QuandelaCloudBackend

An executor that runs on a Quandela Cloud platform.

The platform is a real quantum processing unit (QPU) or a cloud simulator.

Parameters:

Name Type Description Default
platform str

The name of a Quandela Cloud platform, for example "qpu:ascella" for hardware or "sim:slos" for a cloud simulator. Default: "sim:slos".

'sim:slos'
token str | None

The access token. Without it, the token comes from $QUANDELA_TOKEN or $PERCEVAL_TOKEN, then from the token that Perceval has saved. Default: None.

None
shots int

The number of shots sampled in each run. Default: 10000.

10000
url str | None

The web address of the Quandela Cloud service, if it is not Perceval's default. Default: None.

None
min_detected_photons int | None

Keep only the shots that detect at least this many photons (post-selection). The default is the number of photons in the input state.

None
poll_timeout_seconds float

How long, in seconds, run and result() wait for a job before they raise TimeoutError. Default: 3600.

3600

compile(spec)

Tie spec to this platform, offline, with no network connection or token.

Parameters:

Name Type Description Default
spec PhotonicCircuitSpec

The circuit to compile.

required

Returns:

Type Description
RemoteCompiled

The RemoteCompiled handle for spec.