pyextal.jaxMultipole.fit¶
Weighted least-squares fit of a multipole model to structure factors.
The objective is the usual
over the observations (real parts, and imaginary parts where an observation
carries one) and any soft restraints. It is minimised with
scipy.optimize.least_squares (trust-region reflective, box bounds), with an
exact Jacobian from jax.jacfwd – in float64, inside jax.enable_x64, so
the rest of the process (the float32 Bloch engine) is unaffected.
What is reported¶
esd– from(J^T J)^-1, i.e. taking the sigmas at face value, andesd_scaled– the same times the goodness of fit, the conventional crystallographic choice when GoF > 1;the correlation matrix of the free parameters and the pairs above 0.9;
R = sum |dy| / sum |y|,wR = sqrt(sum w dy^2 / sum w y^2), GoF= sqrt(chi^2 / (n - m));the singular values and condition number of the weighted Jacobian.
design_check() gives the last two before fitting, at the start point:
which directions in parameter space the data do not constrain, and which
parameters they load on. With ~25 reflections and ADPs refined it is the first
thing to look at. hamilton_test() compares nested models.
Device: the fit runs on the CPU by default (device='cpu'). With some 30
reflections it is a few hundred small float64 kernels, which a CPU does in
~15 s for the STO ladder while a consumer GPU – float64 at a small fraction of
its float32 rate, plus launch overhead – takes ~50 s, to identical results.
device='default' uses whatever JAX picks; the GPU matters for refining
against intensities (Option 2), not here.
Classes¶
Functions¶
|
|
|
Fits the free parameters of |
|
How well the data constrain each direction in parameter space. |
|
Hamilton's R-factor ratio test of a nested pair of fits. |
Module Contents¶
- class pyextal.jaxMultipole.fit.Restraint¶
A soft restraint on one physical parameter:
(p[name] - target) / sigma.- name: str¶
- target: float¶
- sigma: float¶
- class pyextal.jaxMultipole.fit.FitResult¶
Outcome of
fit().Attributes are NumPy arrays or floats;
nameslabelx,esdand the rows/columns ofcov/corr;pandp_esdfollow the model layout.- names: list¶
- x: numpy.ndarray¶
- p: numpy.ndarray¶
- p_esd: numpy.ndarray¶
- cov: numpy.ndarray¶
- esd: numpy.ndarray¶
- esd_scaled: numpy.ndarray¶
- corr: numpy.ndarray¶
- chi2: float¶
- n_obs: int¶
- n_par: int¶
- gof: float¶
- R: float¶
- wR: float¶
- calc: numpy.ndarray¶
- obs: object¶
- singular_values: numpy.ndarray = None¶
- condition: float = None¶
- success: bool = True¶
- message: str = ''¶
- pmap: object = None¶
- value(name)¶
- p_esd_of(name)¶
- has(name)¶
- strong_correlations(threshold=0.9)¶
- pyextal.jaxMultipole.fit.residual_fn(model, obs, pmap, restraints=())¶
x -> weighted residual vector(real), plusx -> calc.Real parts always count; imaginary parts only where
obs.use_imag.
- class pyextal.jaxMultipole.fit.Fitter(model, obs, restraints=(), device='cpu')¶
A model and a data set with their residual and Jacobian compiled once.
The residuals are compiled as a function of the full physical vector p, so any ParameterMap – any choice of frozen and free parameters – reuses them:
r(x) = r_p(p0 + M x),J(x) = J_p(p) M. Refinements that change what is refined many times over (ladders, iterative block schemes, chi^2 profiles) then cost one compilation instead of one per fit. fit keeps a small cache of these, so ordinary calls benefit too.- restraints = ()¶
- pyextal.jaxMultipole.fit.fit(model, obs, pmap, restraints=(), x0=None, max_nfev=200, verbose=0, device='cpu')¶
Fits the free parameters of
pmaptoobs.- Parameters:
model (MultipoleModel) – The model.
obs (Observations) – Data (jaxMultipole.data).
pmap (ParameterMap) – Free parameters (jaxMultipole.params).
restraints (list[Restraint]) – Soft restraints.
x0 (array, optional) – Start;
pmap.x0by default.max_nfev (int) – Function-evaluation budget.
verbose (int) –
least_squaresverbosity.device (str) –
'cpu'(default),'gpu'or'default'.
- Returns:
FitResult
Note
The compiled residuals are cached per (model, obs, restraints, device) object, so repeated fits of the same data with different free parameters compile once (Fitter).
- pyextal.jaxMultipole.fit.design_check(model, obs, pmap, restraints=(), x=None, top=4, device='cpu')¶
How well the data constrain each direction in parameter space.
- Returns:
singular_values,condition, predictedesdandcorratx(the start by default), andweak– for each singular value below 1e-3 of the largest, the parameters it loads on.- Return type:
dict
- pyextal.jaxMultipole.fit.hamilton_test(fit_restricted, fit_full, alpha=0.05)¶
Hamilton’s R-factor ratio test of a nested pair of fits.