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 |
required |
Returns:
| Type | Description |
|---|---|
float
|
The expectation value of |
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 |
required |
method
|
str
|
How to differentiate, for example |
'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
|
True
|
need_input_grad
|
bool
|
The same as |
True
|
Returns:
| Name | Type | Description |
|---|---|---|
weight_jac |
ndarray | None
|
The derivatives |
input_jac |
ndarray | None
|
The derivatives |
run(weights, inputs)
Evaluate the circuit for one sample.
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 |
Returns:
| Type | Description |
|---|---|
dict
|
The output Fock distribution, as a dictionary
|
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 |
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'
|
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 |
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
|
'sim:slos'
|
token
|
str | None
|
The access token. Without it, the token comes from
|
None
|
shots
|
int
|
The number of shots sampled in each run. Default: |
10000
|
url
|
str | None
|
The web address of the Quandela Cloud service, if it is
not Perceval's default. Default: |
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, |
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 |