Regularisation#
On noisy or under-constrained data the retrieved spectrum can overfit, picking
up ripples in amplitude or oscillations in phase that fit the noise rather than
the pulse. Every solver except COPRA (the L-BFGS family, the Levenberg–Marquardt
family and the global CMAES) accepts mild penalties that
suppress this, at the cost of a bias towards the chosen spectrum, smoothness or
time window. The objective is defined in
retrieval theory; the summary table
lists which option each solver takes.
Two penalties are on by default: amplitude smoothness (reg_amp=0.03) and,
when an independent spectrum is supplied, the spectral-match penalty
(reg_spectrum=0.01). The LM family uses 3e-5 and 1e-5 instead, because it
minimises squared residuals. Pass 0 to disable either. COPRA and copra-jax
take none of these penalties; warm-lbfgs applies them in its L-BFGS stage.
Second-difference smoothness#
Two penalties damp curvature via a discrete second difference (\(A_{k+1} - 2A_k + A_{k-1}\), the discrete analogue of \(\mathrm{d}^2/\mathrm{d}\omega^2\)):
reg_amp— penalises curvature of the spectral amplitude;reg_phase— penalises curvature of the spectral phase.
res = croak.retrieve(trace, g.omega, delays, "pg", algorithm="lbfgs",
reg_amp=0.01, reg_phase=0.01, maxiters=300)
A second difference vanishes for a constant or linear amplitude and for a
linear spectral phase (a time shift). Quadratic phase (pure GDD) has a constant,
nonzero second difference and so pays a small, uniform penalty, while ripple and
bin-to-bin oscillation have large second differences and are suppressed
strongly. reg_phase therefore prefers smooth phase rather than zero chirp.
The penalties have closed-form gradients, accumulated into the solver gradient (L-BFGS) or appended as extra residual rows (LM).
Choosing the weights#
croak’s defaults are reg_spectrum=0.01 and reg_amp=0.03. The validation
retrievals in the papers use reg_spectrum=0.03
and reg_amp=0.03; use those to reproduce them. Three points matter when
retuning:
The natural diagnostics fail. The retrieved duration is nearly flat in the weight, and the agreement with the target spectrum improves monotonically with it by construction: a regulariser cannot be tuned on the quantity it pulls towards. On simulated data, tune against the complex-field error relative to the known truth; on measured data, prefer the defaults and check the spread over random starts.
The two penalties work together. Too weak a spectral weight lets the amplitude collapse on chirped traces (a spiky spectrum a fraction of the true bandwidth); the amplitude-smoothness penalty suppresses exactly that collapse, which is why the pair works better than either alone.
The measured spectrum has its own error. A spectral weight strong enough to impose it exactly imports that error, or a difference in how it was collected, into the retrieved pulse. Excessive smoothing likewise removes real structure.
L-BFGS vs LM weight scaling
LBFGS adds the penalty to the trace error \(R\);
LM minimises the sum of squares, so its weight scales the
penalty relative to \(R^2\). The penalty functions are identical, but a given
numeric weight is not directly comparable between the two: at stationarity the
correspondence is roughly \(\lambda_{\rm LM} \approx 2R\,\lambda\), which for the
default reg_spectrum=0.01 at typical converged \(R\) puts the LM-side weight
near 1e-5–3e-5. Retune when switching solver families.
reg_phase is most valuable in phase-only retrieval, where the amplitude is
fixed and only the phase can absorb noise.
Spectral-match penalty#
When you have an independently measured fundamental spectrum, you can pull the
retrieved amplitude toward it (full amplitude-and-phase mode only) with
reg_spectrum and spectrum_target — the measured spectral intensity
on the retrieval grid, e.g. td.Iomega from
preprocessing:
res = croak.retrieve(td.trace, td.omega, td.delays, td.interaction,
algorithm="lbfgs", reg_spectrum=0.05,
spectrum_target=td.Iomega, omega0=td.omega0_pulse)
This keeps the retrieval consistent with a trusted spectrometer measurement while
still letting the trace determine the phase. retrieve_from_tracedata()
wires td.Iomega in for you (and warns if reg_spectrum > 0 but no spectrum is
available).
Temporal regularisation#
Some artefacts live in the time domain rather than the spectrum: a noisy or
under-constrained retrieval can grow spurious satellite pulses or a low pedestal
far from the main feature. The temporal penalty reg_time suppresses the
fraction of pulse energy \(|E(t)|^2\) that falls outside a time window
time_window (a (t_lo, t_hi) tuple in seconds; default the measured delay
range), with Planck-tapered edges so it does not introduce a hard cut:
res = croak.retrieve(trace, g.omega, delays, "pg", algorithm="lbfgs-ad",
reg_time=0.05, time_window=(-40e-15, 40e-15), maxiters=300)
Unlike the cosmetic post-retrieval temporal filter, this acts
during retrieval and keeps the spectrum and field an exact Fourier pair, so it
introduces no spectral artefacts; a window narrower than the pulse will, of
course, suppress real satellites. It is available on
LBFGSAD and CMAES (it needs the JAX
field transform), and works in every parameterisation including the B-spline basis.
The B-spline phase basis#
The penalties above are soft constraints added to the objective. The
B-spline phase basis is a harder, structural one: instead of optimising the
spectral phase per frequency bin, phase_basis="bspline" represents it as a cubic
B-spline with a handful of control points (n_nodes, default 20) over the
non-zero-spectrum support, holding the amplitude at the guess.
res = croak.retrieve(trace, g.omega, delays, "pg", algorithm="lbfgs-ad",
phase_basis="bspline", n_nodes=24, maxiters=300)
Because the phase then has only n_nodes degrees of freedom and is \(C^2\)-smooth by
construction, it cannot ripple from bin to bin: a strong regulariser that also makes the
problem low-dimensional enough for the derivative-free
CMA-ES global search. It
implies phase-only retrieval. A P-spline roughness term on the control points is
folded into reg_phase, so you can still smooth the spline itself. Supported by
lbfgs-ad, lbfgs-optx, lm, lm-optx and cma-es; see
croak._jax_pulse.make_spline_phase_basis().
Per-frequency scaling#
Not a penalty, but related: R_omega=True replaces the single intensity
scale factor with a per-frequency vector,
absorbing an uncalibrated frequency-dependent detection efficiency. It relaxes
a constraint, so it pairs well with a spectral-match penalty that re-adds physical
structure.
Rω lowers the reported error while degrading the spectrum
Do not use R_omega=True on its own. The per-frequency scale factors are exactly
the information that pins the retrieved spectral amplitude: one free factor
per row is the frequency marginal. With those extra parameters the amplitudes
are constrained only through the delay structure of each row, which is weakest
where the trace is weakest, at the edges of the band.
Because \(|E(\omega)|^2 \ge 0\) and the true value sits on that bound, the freed
bins can only drift upward. The signature is the retrieved spectrum rising at
both ends of the grid, and because \(I_\lambda = I_\omega\,2\pi c/\lambda^2\) the
short-wavelength end looks far worse than its long-wavelength twin, by a factor
\((\lambda_\mathrm{max}/\lambda_\mathrm{min})^2\), easily 5–10×.
edge_energy_fraction() puts a number on it, and the
plot_retrieval() spectrum panel reports it, in red above
EDGE_ENERGY_WARN (1 %).
On a perfect, noiseless, exactly modelled PG trace whose true pulse has \(10^{-6}\) % of its energy in the outer 10 bins of each end:
edge energy |
trace error |
|
|---|---|---|
|
0.02 % |
7.9e-5 |
|
5.4 % |
4.0e-3 |
Rω usually reports the lower R, since it has one extra free parameter per
frequency row, so the error alone cannot show that the spectrum has gone wrong.
On our measured traces it was routine for Rω to halve R while tripling the
edge energy.
The fix is to put back what Rω removed, from an independent measurement:
phase_only=True (hold the amplitude at the measured spectrum) or a light
reg_spectrum. Widening lam_min/lam_max helps too, because it moves the
edge taper
out onto empty trace. On one of our deep-UV TG-FROG datasets, widening the band
from 180–500 nm to 140–750 nm, with a reference spectrum carrying 0.01 % edge
energy:
edge energy |
|
|---|---|
Rω, tight band |
15.6 % |
Rω off, tight band |
6.0 % |
Rω off + |
0.01 % |
COPRA supports phase-only retrieval but not the spectral penalty.
Summary#
Option |
Solvers |
Effect |
|---|---|---|
|
LBFGS, LBFGSAD, LBFGSHand, OptxLBFGS, LM, OptxLM, CMAES |
smooth spectral amplitude |
|
LBFGS, LBFGSAD, LBFGSHand, OptxLBFGS, LM, OptxLM, CMAES |
smooth spectral phase (great for phase-only) |
|
LBFGS, LBFGSAD, LBFGSHand, OptxLBFGS, LM, OptxLM, CMAES (full mode) |
pull amplitude to a measured spectrum |
|
LBFGSAD, CMAES |
suppress energy outside a time window |
|
LBFGSAD, OptxLBFGS, LM, OptxLM, CMAES |
low-dimensional, intrinsically smooth phase |
|
all solvers |
per-frequency intensity scaling — never alone, see above |
(COPRA and its JAX twin take none of the penalties — their random-order local
sweep already smooths implicitly — but they do support R_omega; see
per-frequency scaling.)