component_layers

The componet_layers submodule contains functionality for assembling optical components on a simulated chip and computing their transfer operations. A ComponentLayer represents a physical “column” of optical components which acts on an input in parallel. ComponentLayers can be assembled into an OpticalMesh or put into a NetworkLayer.

class neuroptica.component_layers.ComponentLayer(N: int, components: List[Type[neuroptica.components.OpticalComponent]])[source]

Bases: object

Base class for a single physical column of optical components which acts on inputs in parallel.

__init__(N: int, components: List[Type[neuroptica.components.OpticalComponent]])[source]

Initialize the ComponentLayer :param int N: number of waveguides in the ComponentLayer :param list[OpticalComponent] components: list of

__iter__() → Iterable[Type[neuroptica.components.OpticalComponent]][source]

Iterate over the optical components in the ComponentLayer

__weakref__

list of weak references to the object (if defined)

all_tunable_params() → Iterable[float][source]

Enumerate all tunable parameters of the ComponentLayer; should be overwritten.

get_transfer_matrix() → <MagicMock id='140414712631816'>[source]

Enumerate all tunable parameters of the ComponentLayer; should be overwritten.

class neuroptica.component_layers.MZILayer(N: int, mzis: List[neuroptica.components.MZI])[source]

Bases: neuroptica.component_layers.ComponentLayer

Represents a physical column of MZI’s attached to an ensemble of waveguides

__init__(N: int, mzis: List[neuroptica.components.MZI])[source]
Parameters:
  • N – number of waveguides in the system the MZI layer is embedded
  • mzis – list of MZIs in the column (can be less than N)
__iter__() → Iterable[neuroptica.components.MZI][source]

Iterate over the optical components in the ComponentLayer

all_tunable_params()[source]

Enumerate all tunable parameters of the ComponentLayer; should be overwritten.

classmethod from_waveguide_indices(N: int, waveguide_indices: List[int])[source]

Create an MZI layer from a list of an even number of input/output indices. Each pair of waveguides in the iteration order will be assigned to an MZI :param N: size of MZILayer :param waveguide_indices: list of waveguides the layer attaches to :return: MZILayer class instance with size N and MZIs attached to waveguide_indices

get_partial_transfer_matrices(backward=False, cumulative=True, add_uncertainties=False) → <MagicMock id='140414712740048'>[source]

Return a list of 4 partial transfer matrices for the entire MZI layer corresponding to (1) after first BS in each MZI, (2) after theta shifter, (3) after second BS, and (4) after phi shifter. Order is reversed in the backwards case :param backward: whether to compute the backward partial transfer matrices :param cumulative: if true, each partial transfer matrix represents the total transfer matrix up to that point in the device :param add_uncertainties: whether to include uncertainties in transfer matrix computation :return: numpy array of partial transfer matrices

get_partial_transfer_vectors(backward=False, cumulative=True, add_uncertainties=False) → <MagicMock id='140414712752504'>[source]
Parameters:
  • backward
  • cumulative
  • add_uncertainties
Returns:

get_transfer_matrix(add_uncertainties=False) → <MagicMock id='140414712614808'>[source]

Enumerate all tunable parameters of the ComponentLayer; should be overwritten.

static verify_inputs(N: int, mzis: List[neuroptica.components.MZI])[source]

Checks that the input MZIs are valid :param N: size of MZILayer :param mzis: list of MZIs

class neuroptica.component_layers.OpticalMesh(N: int, layers: List[Type[neuroptica.component_layers.ComponentLayer]])[source]

Bases: object

Represents an optical “mesh” consisting of several layers of optical components, e.g. a rectangular MZI mesh

__init__(N: int, layers: List[Type[neuroptica.component_layers.ComponentLayer]])[source]

Initialize the OpticalMesh :param N: number of waveguides in the system the mesh is embedded in :param layers: list of ComponentLayers that the mesh contains (enumerates the columns of components)

__weakref__

list of weak references to the object (if defined)

adjoint_optimize(forward_field: <MagicMock id='140414712694880'>, adjoint_field: <MagicMock id='140414711705216'>, update_fn: Callable, accumulator: Callable[<MagicMock id='140414712246056'>, float] = <MagicMock id='140414712670136'>, dry_run=False, cache_fields=False, use_partial_vectors=False)[source]

Compute the loss gradient as described in Hughes, et al (2018), “Training of photonic neural networks through in situ backpropagation and gradient measurement” and adjust the phase shifting parameters accordingly :param forward_field: forward-propagating input electric field at the beginning of the optical mesh :param adjoint_field: backward-propagating output electric field at the end of the optical mesh :param update_fn: a float=>float function to compute how to update parameters given a gradient :param accumulator: an array=>float function to compute how to compute a gradient from a batch of gradients; np.mean is used by default :param dry_run: if True, parameters will not be adjusted and a dictionary of parameter gradients for each ComponentLayer will be returned instead :param cache_fields: if True, forward and adjoint fields within the mesh will be cached :param use_partial_vectors: if True, uses partial vectors method to speed up transfer matrix computation :return: None, or (if dry_run==True) a dictionary of parameter gradients for each ComponentLayer

compute_adjoint_phase_shifter_fields(delta: <MagicMock id='140414711655392'>, align='right', use_partial_vectors=False) → List[List[<MagicMock id='140414711680024'>]][source]

Compute the backward propagating (adjoint) electric fields at the left/right of each phase shifter in the mesh :param delta: input adjoint field to the mesh :param align: whether to align the fields at the beginning or end of each column :return: a list of (list of field values to the left/right of each phase shifter in a layer) for each layer The ordering of the list is the opposite as in compute_phase_shifter_fields()

compute_gradients(forward_field: <MagicMock id='140414712275520'>, adjoint_field: <MagicMock id='140414712304528'>, cache_fields=False, use_partial_vectors=False) → Dict[Type[neuroptica.components.OpticalComponent], <MagicMock id='140414712325176'>][source]

Compute the gradients for each optical component within the mesh, without adjusting the parameters :param forward_field: forward-propagating input electric field at the beginning of the optical mesh :param adjoint_field: backward-propagating output electric field at the end of the optical mesh :param cache_fields: if True, forward and adjoint fields within the mesh will be cached :param use_partial_vectors: if True, uses partial vectors method to speed up transfer matrix computation :return:

compute_phase_shifter_fields(X: <MagicMock id='140414711576280'>, align='right', use_partial_vectors=False, include_bs=False) → List[List[<MagicMock id='140414711601136'>]][source]

Compute the forward-propagating electric fields at the left/right of each phase shifter in the mesh :param X: input field to the mesh :param align: whether to align the fields at the beginning or end of each column :use_partial_vectors: can speed up the computation if set to True :include_bs: if true, also compute the phase shifter fields before/after each beamsplitter in the mesh :return: a list of (list of field values to the left/right of each phase shifter in a layer) for each layer

get_partial_transfer_matrices(backward=False, cumulative=True) → List[<MagicMock id='140414711551032'>][source]

Return the partial transfer matrices for the optical mesh after each column of components :param backward: whether to compute the backward partial transfer matrices :param cumulative: if true, each partial transfer matrix represents the total transfer matrix up to that point in the device :return: list of partial transfer matrices

class neuroptica.component_layers.PhaseShifterLayer(N: int, phase_shifters: List[neuroptica.components.PhaseShifter] = None)[source]

Bases: neuroptica.component_layers.ComponentLayer

Represents a column of N single-mode phase shifters

__init__(N: int, phase_shifters: List[neuroptica.components.PhaseShifter] = None)[source]
Parameters:
  • N – number of waveguides the column is embedded in
  • phase_shifters – list of phase shifters in the column (can be less than N)
__iter__() → Iterable[neuroptica.components.PhaseShifter][source]

Iterate over the optical components in the ComponentLayer

all_tunable_params()[source]

Enumerate all tunable parameters of the ComponentLayer; should be overwritten.

get_transfer_matrix(add_uncertainties=False) → <MagicMock id='140414711504736'>[source]

Enumerate all tunable parameters of the ComponentLayer; should be overwritten.