Extending interactions and solvers#
An extension must specify both the physical model it implements and the interfaces through which it is used. Start with the existing implementation closest to the intended behaviour, and state unsupported combinations explicitly.
Interactions#
Define the signal, carrier relation and derivative convention together. Test the local derivative with complex perturbations before checking a full trace. The interaction physics page gives the implemented kernels.
Define a local kernel#
A new geometry is a small subclass:
import numpy as np
from croak.interactions import Interaction
class THG(Interaction): # third-harmonic generation, s = E^2 G
name = "thg"
omega0_scale = 3.0 # signal near 3*omega0
def signal(self, test, gate):
return test**2 * gate
def signal_adjoint(self, test, gate, s_bar):
test_bar = 2.0 * np.conj(test) * np.conj(gate) * s_bar
gate_bar = np.conj(test**2) * s_bar
return test_bar, gate_bar
This defines a thin-medium local kernel and its analytic derivative. Register an
instance in INTERACTIONS, or pass an instance to a
NumPy interface that accepts it. Registration alone does not add a new JAX
kernel: the JAX forward implementation dispatches supported names explicitly.
Implement and test that path before advertising support in AD solvers. Automatic
differentiation can differentiate a JAX kernel once it is expressed there; it
cannot infer the implementation from an arbitrary NumPy subclass.
To support geometric smearing as well, add
smeared_shifts() and
smeared_signal(): the same signal written as a
product of three separately shifted replicas, because the factors that coincide
in the 1-D model acquire different arrival times across the focal spot. PG and SD
implement them; a geometry without a three-arm form (SHG) simply does not, and the
forward model raises if a kernel is supplied.
Solvers#
The retrieval wrapper selects a solver through
croak.retrieve.ALGORITHMS. See the
retrieval API for the base interface, result
object, and progress reporting. An added solver must expose its supported
parameters consistently and identify which forward-model and regularisation
options it accepts.
Check derivatives and numerical behaviour using the approach in numerical validation. Document scientific behaviour in the user guide as well as the API.