Interactions#
Choose an interaction to describe how the overlapping pulse replicas generate the nonlinear signal. This choice determines the trace carrier, sensitivity to phase and available ambiguities. The first tutorial uses SHG; the dispersive tutorial uses PG. The kernels below describe the instantaneous local response; propagation and collection are developed in the forward model.
Each interaction takes a test field \(E\) (undelayed) and a gate field \(G\) (delayed by \(\tau\)), both in the time domain, and returns the signal \(s(t)\).
The three geometries#
Class |
|
Signal \(s\) |
\(\omega_0\) scale |
|---|---|---|---|
|
\(E\,G\) |
2.0 |
|
|
\(E^2\,G^*\) |
1.0 |
|
|
\(E\,\lvert G\rvert^2\) |
1.0 |
omega0_scale records where the signal sits relative to the pulse carrier: the
SHG signal is generated near \(2\omega_0\), while SD and PG stay at the fundamental
\(\omega_0\). This single number has two consequences:
it sets the wavelength axis of an SHG-FROG trace (handled in Grids and filtering);
it determines which geometries support dispersive propagation. The slab propagation constant \(\beta(\omega)\) is built at the fundamental carrier, so it is only physically consistent for signals that stay there. Dispersive propagation is therefore supported for PG and SD, but not SHG — croak raises a
ValueErrorif you request a dispersive SHG model.
TG-FROG uses the PG kernel
Transient-grating FROG — the geometry of croak’s
validation — has the third-order signal
\(E_1 E_2^* E_3\) with three replicas of the pulse. When the gate replicas coincide in time and share the same local field, this
reduces to \(E\,\lvert G\rvert^2\), i.e. the PG kernel. Use
interaction="pg" for TG-FROG data.
Resolving an interaction#
Anywhere an interaction is expected you may pass its name (case-insensitive) or an
instance; get_interaction() resolves both, and
INTERACTIONS is the name→instance registry.
from croak.interactions import get_interaction, PG
get_interaction("PG") # -> PG()
get_interaction(PG()) # -> the same instance, unchanged
The adjoint convention#
croak supports automatic differentiation and analytic adjoints
(see Gradients). The analytic interaction interface provides
signal(test, gate) but also signal_adjoint(test, gate, s_bar), which
back-propagates a cotangent through the nonlinearity.
The convention is Wirtinger: the cotangent of a complex variable \(v\) is
which is the quantity gradient descent on a real loss \(L\) actually needs. Given
the output cotangent \(\bar s\), signal_adjoint returns \((\bar E, \bar G)\).
For example, polarisation gating \(s = E\lvert G\rvert^2\) has
which is exactly what PG.signal_adjoint
implements. The holomorphic SHG kernel and the mixed-holomorphy SD kernel have
similarly compact adjoints; see the Gradients page for the full
set and the derivation.
Extending to a new geometry#
Contributor interfaces and backend support are described in extending interactions and solvers. The signal and adjoint equations above remain the physical reference for users.
API#
See croak.interactions in the API reference.