precondition_factors

ell1fit.scaling.precondition_factors(posterior_func, factors, n_parameters, target=1.0)[source]

Rescale parameter factors so every direction has a comparable local scale.

get_factors() derives each parameter’s scale from whatever uncertainty information happens to be available, and for some parameters there is none. Phase_i is the clear case: ell1fit.models._get_par_dict() records its uncertainty as 0, no model-based estimate covers it, and it falls through to the default factor of 1. Every other parameter gets a data-derived scale, so the directions end up wildly mismatched – measured at a 1000x spread on a routine two-epoch fit.

That matters because L-BFGS-B maintains a single Hessian approximation: no step size suits directions three orders of magnitude apart, and it stalls on the shallow ones. Measured on a two-epoch fit, rescaling took the optimizer from reaching the global optimum in 7 of 12 starts to 12 of 12, and collapsed a 3.2-nat spread in the achieved log-posterior to zero. It also fixes the MCMC’s starting ball, which was 0.0006 sigma wide in Phase and 0.58 sigma wide in A1.

The scale is measured from the posterior itself rather than derived per-parameter, so it needs no formula for each new parameter type and adapts to the actual data. It is measured as a curvature, by _curvature_drop(), and not as the fall in the log-posterior over one step – see that function for why the difference is worth several extra evaluations, and for what it cost when it was not.

Parameters:
posterior_funccallable

Log-posterior in local coordinates.

factorssequence of float

Current per-parameter factors.

n_parametersint

Number of free parameters.

targetfloat, optional

Local step that should correspond to one standard deviation.

Returns:
list of float

Rescaled factors. A parameter whose scale cannot be measured – a flat or non-finite direction – keeps the factor it came in with.