symop.devices.models

Device models.

Provides concrete implementations of semantic devices used in the simulation framework, such as sources, linear-optical elements, filters, and measurement components.

The modules in this package define device behavior at the planning level, producing DeviceAction objects that are later executed by representation-specific kernels.

Subpackages

sources

Devices that generate quantum states (e.g., photon sources).

filters

Devices that transform states via selection or attenuation (e.g., spectral or polarization filters).

beamsplitters

Two-path mixing devices implementing linear mode coupling.

phase_shifters

Single-path devices applying constant phase rotations.

Notes

  • Device models are representation-agnostic and operate at the semantic level.

  • Execution is delegated to the runtime via registered kernels.

  • Linear-optical elements (e.g., beamsplitters, phase shifters) define unitary transformations at the operator level, realized by backend kernels.

  • New device types should be added as separate modules and registered through the device and kernel registries.

class BeamSplitter(theta: float, phi_t: float = 0.0, phi_r: float = 0.0) None

Bases: DeviceBase

Ideal path beamsplitter device.

A beamsplitter acts on matched mode pairs drawn from two input paths. Planning records the participating input modes, output paths, and beamsplitter parameters for backend execution.

The device uses the package Heisenberg convention, where creation operators transform as

\[\hat a^\dagger_{\mathrm{out},k} = \sum_j U_{k j}\,\hat a^\dagger_{\mathrm{in},j}.\]

The angle theta determines the transmission and reflection amplitudes by

\[t = \cos(\theta), \qquad r = \sin(\theta).\]

With phases phi_t and phi_r, the two-mode unitary is

\[\begin{split}U = \begin{pmatrix} t e^{i\phi_t} & r e^{i\phi_r} \\ -r e^{-i\phi_r} & t e^{-i\phi_t} \end{pmatrix}.\end{split}\]

Thus theta = pi / 4 gives a balanced 50/50 beamsplitter.

In this implementation, transmission corresponds to remaining on the same path index, while reflection corresponds to switching to the opposite path:

  • in0 -> out0: transmission

  • in0 -> out1: reflection

  • in1 -> out1: transmission

  • in1 -> out0: reflection, with the phase determined by the lower-left

unitary element

Thus a fully transmitting beamsplitter (theta = 0) leaves paths unchanged, while a fully reflecting beamsplitter (theta = pi/2) swaps the two paths.

Parameters:
  • theta (float) – Mixing angle of the beamsplitter. The transmission and reflection amplitudes are cos(theta) and sin(theta), respectively.

  • phi_t (float) – Transmission phase.

  • phi_r (float) – Reflection phase.

Examples

Create a balanced (50/50) beamsplitter and apply it to two paths:

>>> import numpy as np
>>> bs = BeamSplitter(theta=np.pi / 4)
>>> state_out = bs(
...     state_in,
...     ports={
...         "in0": Path("a"),
...         "in1": Path("b"),
...         "out0": Path("c"),
...         "out1": Path("d"),
...     },
... )

Notes

Planning does not relabel existing modes. The actual two-mode rewrite, including construction of output-path modes, is delegated to the runtime kernel through action.params["pairs"].

_abc_impl = <_abc._abc_data object>
apply(state: State, *, ports: Mapping[str, Path], selection: object | None = None, runtime: DeviceRuntime | None = None, ctx: ApplyContext | None = None, out_kind: Literal['ket', 'density'] | None = None) State

Apply the device to a state through a runtime.

Parameters:
  • state (State)

  • ports (Mapping[str, Path])

  • selection (object | None)

  • runtime (DeviceRuntime | None)

  • ctx (ApplyContext | None)

  • out_kind (Literal['ket', 'density'] | None)

Return type:

State

property kind: DeviceKind

Return the device kind identifier.

phi_r: float = 0.0
phi_t: float = 0.0
plan(*, state: State, ports: Mapping[str, Path], selection: object | None = None, ctx: ApplyContext | None = None) DeviceAction

Plan beamsplitter mixing on matched mode pairs.

Parameters:
  • state (State) – Input state whose mode labels are inspected.

  • ports (Mapping[str, Path]) – Mapping from device-port names to path labels. Must contain "in0", "in1", "out0", and "out1".

  • selection (object | None) – Optional selection object forwarded by the runtime. It is not used by this device.

  • ctx (ApplyContext | None) – Optional apply context forwarded by the runtime. It is not used by this device.

Returns:

Planned action containing:

  • params["pairs"]: tuple of beamsplitter pair specifications

  • edits: always empty for this device

Return type:

DeviceAction

Raises:
  • TypeError – If the state does not support path-based mode lookup.

  • ValueError – If both inputs are populated but contain incompatible numbers of modes.

Notes

The unitary itself is not applied here. This method only prepares semantic pairing and kernel parameters. If one side is missing, the backend kernel is expected to synthesize a matching vacuum partner.

property port_specs: tuple[PortSpec, ...]

Return the port specification of the device.

theta: float
class NumberStateSource(envelope: Envelope, polarization: Polarization, n: int) None

Bases: DeviceBase

Photon number-state source.

This device prepares a pure number state on a single emitted output mode. The mode is defined by an envelope and a polarization label and is placed on the path connected to the "out" port.

Parameters:
  • envelope (Envelope) – Envelope assigned to the emitted output mode.

  • polarization (Polarization) – Polarization assigned to the emitted output mode.

  • n (int) – Number of excitations emitted into the output mode.

Raises:

ValueError – If n < 0.

_abc_impl = <_abc._abc_data object>
envelope: Envelope
property kind: DeviceKind

Return the device kind identifier.

Returns:

The number-state source device kind.

Return type:

DeviceKind

n: int
plan(*, state: State, ports: Mapping[str, Path], selection: object | None = None, ctx: ApplyContext | None = None) DeviceAction

Plan emission of a fixed number state.

Parameters:
  • state (State) – Input state forwarded by the runtime. It is not used by this source planner.

  • ports (Mapping[str, Path]) – Mapping from device-port names to paths. Must contain "out".

  • selection (object | None) – Optional selection object forwarded by the runtime. It is stored unchanged in the returned action.

  • ctx (ApplyContext | None) – Optional apply context forwarded by the runtime. It is not used by this source planner.

Returns:

Planned action containing emitted source modes and excitation counts for backend kernels.

The returned action stores:

  • params["source_modes"]: tuple containing the emitted mode

  • params["excitations_by_mode"]: mapping from emitted mode signature to photon number

Return type:

DeviceAction

Notes

This planner creates the emitted mode directly on the output path. No label edits are required, because the source introduces a fresh mode rather than relabeling an existing one.

polarization: Polarization
property port_specs: tuple[PortSpec, ...]

Return the port specification of the device.

Returns:

Single output port named "out".

Return type:

tuple[PortSpec, …]

class PhaseShifter(phi: float) None

Bases: DeviceBase

Ideal path phase shifter.

A phase shifter applies a constant phase rotation to all modes on a selected path. The transformation is represented at the operator level and affects the phase of creation and annihilation operators associated with the path.

Parameters:

phi (float) – Phase angle (in radians) applied to the selected path.

Notes

  • The phase is applied uniformly across all modes on the path.

  • Planning does not inspect the state or enumerate modes.

  • The actual operator-level rewrite is performed by the backend kernel.

_abc_impl = <_abc._abc_data object>
apply(state: State, *, ports: Mapping[str, Path], selection: object | None = None, runtime: DeviceRuntime | None = None, ctx: ApplyContext | None = None, out_kind: Literal['ket', 'density'] | None = None) State

Apply the device to a state through a runtime.

Parameters:
  • state (State) – Input quantum state.

  • ports (Mapping[str, Path]) – Mapping from device port names to path labels. Must contain the key "path".

  • selection (object | None) – Optional device-specific selection object. Not used by this device.

  • runtime (DeviceRuntime | None) – Optional runtime instance. If not provided, the default runtime is used.

  • ctx (ApplyContext | None) – Optional apply context forwarded to the runtime.

  • out_kind (Optional[Literal['ket', 'density']]) – Optional requested output state kind.

Returns:

Output state after applying the phase shifter.

Return type:

StateProtocol

Notes

This method delegates execution to the device runtime. The actual phase transformation is performed by a representation-specific kernel.

property kind: DeviceKind

Return the device kind identifier.

phi: float
plan(*, state: State, ports: Mapping[str, Path], selection: object | None = None, ctx: ApplyContext | None = None) DeviceAction

Plan a phase shift on a selected path.

Parameters:
  • state (State) – Input state. Not inspected by this device.

  • ports (Mapping[str, Path]) – Mapping from device-port names to path labels. Must contain the key "path".

  • selection (object | None) – Optional selection object forwarded by the runtime. Not used.

  • ctx (ApplyContext | None) – Optional apply context forwarded by the runtime. Not used.

Returns:

Planned action containing:

  • params["path"]: target path label

  • params["phi"]: phase angle

  • edits: always empty

Return type:

DeviceAction

Notes

Planning is purely semantic and does not modify the state or labels. The backend kernel is responsible for applying the phase rotation to all modes associated with the selected path.

property port_specs: tuple[PortSpec, ...]

Return the port specification of the device.

Returns:

A single in-place port named "path" with direction "inout".

Return type:

tuple of PortSpec

Notes

The phase shifter acts on a single path and does not create or destroy paths.

class PolarizingFilter(passed_polarization: Polarization) None

Bases: DeviceBase

Ideal polarizing filter device.

A polarizing filter acts on all modes on a selected input path by projecting their polarization content onto a configured transmitted polarization. The updated mode labels are routed to the output path, while the corresponding attenuation strengths are recorded for the backend kernel.

Parameters:

passed_polarization (Polarization) – Polarization transmitted by the filter.

Notes

Planning performs descriptor updates only. The actual physical attenuation is delegated to the runtime kernel through action.params["eta_by_mode"].

_abc_impl = <_abc._abc_data object>
apply(state: State, *, ports: Mapping[str, Path], selection: object | None = None, runtime: DeviceRuntime | None = None, ctx: ApplyContext | None = None, out_kind: Literal['ket', 'density'] | None = None) State

Apply the device to a state through a runtime.

Parameters:
  • state (State) – Input state to which the device is applied.

  • ports (Mapping[str, Path]) – Mapping from logical port names to path labels.

  • selection (object | None) – Optional device-specific selection or configuration object.

  • runtime (DeviceRuntime | None) – Runtime used to execute the device application. If None, the default runtime is used.

  • ctx (ApplyContext | None) – Optional apply context shared across planning and execution.

  • out_kind (Optional[Literal['ket', 'density']]) – Optional requested output state kind.

Returns:

Output state returned by the runtime.

Return type:

StateProtocol

Notes

This method first selects a runtime and then delegates execution to runtime.apply(...).

property kind: DeviceKind

Return the device kind identifier.

Returns:

The polarizing-filter device kind.

Return type:

DeviceKind

passed_polarization: Polarization
plan(*, state: State, ports: Mapping[str, Path], selection: object | None = None, ctx: ApplyContext | None = None) DeviceAction

Plan ideal polarization filtering on all modes of the input path.

For every mode on ports["in"], this method:

  1. computes the overlap with the transmitted polarization,

  2. converts that overlap into an effective transmissivity,

  3. emits a label edit redirecting the mode to ports["out"] with the transmitted polarization label.

Parameters:
  • state (State) – Input state whose mode labels are inspected.

  • ports (Mapping[str, Path]) – Mapping from device-port names to physical or logical paths. Must contain the keys "in" and "out".

  • selection (object | None) – Optional selection object forwarded by the runtime. It is not used by this device.

  • ctx (ApplyContext | None) – Optional apply context forwarded by the runtime. It is not used by this device.

Returns:

Planned action containing:

  • params["eta_by_mode"]: transmissivity per affected mode

  • edits: label updates for all transformed modes

Return type:

DeviceAction

Raises:

TypeError – If the state does not support label editing and path-based mode lookup.

Notes

The attenuation channel itself is not applied here. This method only prepares the semantic and kernel parameters required for execution.

property port_specs: tuple[PortSpec, ...]

Return the port specification of the device.

Returns:

Two-port specification consisting of one input port named "in" and one output port named "out".

Return type:

tuple[PortSpec, …]

class SpectralFilter(transfer: TransferFunction) None

Bases: DeviceBase

Spectral filter device.

A spectral filter acts on all modes on a selected input path by applying a transfer function to each mode envelope. The updated mode labels are routed to the output path, while the corresponding attenuation strengths are recorded for the backend kernel.

Parameters:

transfer (TransferFunction) – Spectral transfer function applied to each compatible mode envelope.

Notes

Planning performs descriptor updates only. The actual physical attenuation is delegated to the runtime kernel through action.params["eta_by_mode"].

_abc_impl = <_abc._abc_data object>
apply(state: State, *, ports: Mapping[str, Path], selection: object | None = None, runtime: DeviceRuntime | None, ctx: ApplyContext | None = None, out_kind: Literal['ket', 'density'] | None = None) State

Apply the device to a state through a runtime.

Parameters:
  • state (State) – Input state to which the device is applied.

  • ports (Mapping[str, Path]) – Mapping from logical port names to path labels.

  • selection (object | None) – Optional device-specific selection or configuration object.

  • runtime (DeviceRuntime | None) – Runtime used to execute the device application. If None, the default runtime is used.

  • ctx (ApplyContext | None) – Optional apply context shared across planning and execution.

  • out_kind (Optional[Literal['ket', 'density']]) – Optional requested output state kind.

Returns:

Output state returned by the runtime.

Return type:

StateProtocol

Notes

This method first selects a runtime and then delegates execution to runtime.apply(...).

property kind: DeviceKind

Return the device kind identifier.

Returns:

The spectral-filter device kind.

Return type:

DeviceKind

plan(*, state: State, ports: Mapping[str, Path], selection: object | None = None, ctx: ApplyContext | None = None) DeviceAction

Plan spectral filtering on all modes of the input path.

For every mode on ports["in"], this method:

  1. checks that the mode envelope supports time/frequency access,

  2. applies the transfer function to obtain a filtered envelope,

  3. records the corresponding transmissivity,

  4. emits a label edit redirecting the mode to ports["out"] with the updated envelope.

Parameters:
  • state (State) – Input state whose mode labels are inspected.

  • ports (Mapping[str, Path]) – Mapping from device-port names to physical or logical paths. Must contain the keys "in" and "out".

  • selection (object | None) – Optional selection object forwarded by the runtime. It is not used by this device.

  • ctx (ApplyContext | None) – Optional apply context forwarded by the runtime. It is not used by this device.

Returns:

Planned action containing:

  • params["eta_by_mode"]: transmissivity per affected mode

  • edits: label updates for all transformed modes

Return type:

DeviceAction

Raises:
  • TypeError – If the state does not support label editing and path-based mode lookup.

  • TypeError – If an affected mode carries an envelope that does not implement TimeFrequencyEnvelope.

Notes

The attenuation channel itself is not applied here. This method only prepares the semantic and kernel parameters required for execution.

property port_specs: tuple[PortSpec, ...]

Return the port specification of the device.

Returns:

Two-port specification consisting of one input port named "in" and one output port named "out".

Return type:

tuple[PortSpec, …]

transfer: TransferFunction

Modules

base

Abstract base class for semantic devices.

beamsplitters

Beamsplitter device models.

detectors

Measurement device models.

filters

Filtering devices for mode descriptors.

paths

Semantic device model package.

phase_shifters

Phase shifter device models.

sources

Measurement devices.