Python callbacks, Rust optimization, and fit-time inference
MEstimator is the callback-driven alternative to a built-in likelihood. Python defines the objective and observation-level scores; Rust owns L-BFGS, convergence checks, covariance construction, and bootstrap orchestration. The class reference gives the full signature. The implementation lives in src/estimators/mle.rs.
Callback contracts
objective_fn(theta, data) returns a finite scalar to minimize and its one-dimensional NumPy gradient, of length len(theta).
score_fn(theta, data) returns a finite (n, p) NumPy array of individual estimating-function contributions. It must have a stable shape at nearby parameter values.
Neither callback should mutate its inputs. Both must refer to the same statistical model and support the resampling indices when bootstrap is used.
Cost and gradient requests cross the Python boundary separately, so expensive callbacks can dominate runtime. Built-in estimators avoid this callback overhead.
Fit and inference
fit(data, theta0) clears prior state, validates inputs, and runs L-BFGS with a More-Thuente line search. Exhausting the iteration budget raises an error. Before a successful fit returns, Rust evaluates the scores and constructs
The bread \(A\) is the central-difference derivative of the mean scores, not a second copy of \(B\). The parameter-specific finite-difference step is derivative_step * max(abs(theta[j]), 1). A singular bread or invalid callback output causes the fit to fail and clears the partial result.
summary() reuses the fit-time covariance. Mutating callback data afterward does not silently change that summary. compute_vcov() explicitly recomputes it using the retained data; bootstrap also reuses those data, so keep them immutable for the fitted object’s lifetime.
A complete callback example
This least-squares objective includes its own intercept column. MEstimator does not add one or reorder the parameters.
The bootstrap requires a dictionary containing n. Each draw shallow-copies that dictionary, supplies fresh row indices, and refits the objective. The example’s 20 draws demonstrate the interface, not a precise tail interval. Use GMM when the starting point is a vector of moment conditions and you need explicit weighting or dependence-robust inference.