perceval_backend
eigenkit.photonics.backends.perceval_backend
The Perceval executor for photonic circuits (experimental).
It translates a
PhotonicCircuitSpec into a
Perceval Circuit, and computes the output distribution of photon numbers with an
exact Perceval simulator, by default simulation of linear optical systems (SLOS).
It is the linear-optics counterpart of a qubit Provider, but it does not
implement the qubit Provider protocol: there is no CircuitSpec, no Pauli
Observable and no array of expectation values. This is why photonics is a
separate package.
perceval is imported only inside the methods, when they run, so importing this
module (and therefore import eigenkit) never imports the Perceval software
development kit (SDK). The data module photonics.ir never uses Perceval at all.
The work is split between compilation and evaluation, as in the qubit providers:
compile() is called once, and run(weights, inputs) at every call. For now, the
Perceval circuit is built again at every call, after the Parameter expressions
are evaluated to numbers. Building it once with symbolic pcvl.P parameters, and
setting their values at each call, is not done yet. (This is the saving that the
qubit providers get from the split between compilation and evaluation.)
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'
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
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
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 |
'SLOS'
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
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 |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
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 |
required |
method
|
str
|
|
'parameter_shift'
|
need_weight_grad
|
bool
|
If True, compute the gradient with respect to
the weights. If False, it is skipped, and |
True
|
need_input_grad
|
bool
|
If True, compute the gradient with respect to
the inputs. If False, it is skipped, and |
True
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
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 |
required |
inputs
|
ndarray
|
The 1-D input vector, of length |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
build_perceval_circuit(spec, weights, inputs)
Translate a PhotonicCircuitSpec into a Perceval Circuit.
The Parameter angles are evaluated to numbers first. The local and the
remote executors both use this function, so they build exactly the same
circuit. (The live test of the remote executor compares sampled and exact
results on the same circuit.)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
PhotonicCircuitSpec
|
The circuit to translate. |
required |
weights
|
ndarray
|
The 1-D weight vector used to evaluate the angles. |
required |
inputs
|
ndarray
|
The 1-D input vector used to evaluate the angles. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
circuit |
Circuit
|
The circuit, on |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
fock_tuple(state, n_modes)
Convert a Perceval BasicState, or any indexable object, to a tuple of photon counts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
BasicState | Sequence[int]
|
The number of photons in each mode, indexed by mode. |
required |
n_modes
|
int
|
The number of modes to read. |
required |
Returns:
| Type | Description |
|---|---|
tuple[int, ...]
|
The number of photons in each mode, as a tuple of integers. |