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)
-
-
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:
-
-
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
-