Curve fitting
Nautilus.CurveFit exports two Levenberg-Marquardt fitters:
lm_scalar_1param, which takes an analytical scalar derivative;lm_scalar_nparam, which fits a tensor parameter vector using a finite-difference Jacobian.
lm_scalar_1param
Section titled “lm_scalar_1param”lm_scalar_1param( model: f32 -> f32 -> f32, -- model(x, theta) -> predicted y dmodel: f32 -> f32 -> f32, -- dmodel(x, theta) -> d(predicted_y)/d(theta) xs: &tensor[n, f32], ys: &tensor[n, f32], theta0: f32, lambda0: f32, tol: f32, max_iters: i64) -> f32The optimizer applies a damped Gauss-Newton update. Here each Jacobian entry is
the caller-supplied dmodel(x, theta). Convergence is declared when
|theta_next - theta| < tol; empty data returns NaN.
Example: fitting a slope
Section titled “Example: fitting a slope”module Nautilus.BookFitSlopeimport Nautilus.CurveFit (lm_scalar_1param)export (fit_slope)def linear_model(x: f32, theta: f32) -> f32 = mul(theta, x)def linear_dmodel(x: f32, theta: f32) -> f32 = xdef fit_slope[n](xs: tensor[n, f32], ys: tensor[n, f32]) -> f32 = lm_scalar_1param(linear_model, linear_dmodel, xs, ys, cast(0.0, f32), cast(0.01, f32), cast(1e-8, f32), cast(100, i64))For data generated by y = 2*x + noise, this converges to approximately 2.0.
lm_scalar_nparam
Section titled “lm_scalar_nparam”lm_scalar_nparam( model: &tensor[n, f32] -> &tensor[m, f32] -> tensor[m, f32], x: &tensor[m, f32], y: &tensor[m, f32], theta0: tensor[n, f32], tol: f32, max_iters: i64) -> tensor[n, f32]model(theta, x) predicts the m observations. The fitter forms
J^T J + 0.01 I, solves the damped normal equations with conjugate gradient,
and updates the n parameters. It runs exactly max_iters iterations;
tol is currently unused and does not stop iterations early.
The Jacobian uses forward differences with eps=1e-5. The fitter does
not differentiate through the full optimization loop.
Scale parameters and predictions to roughly O(1). At larger magnitudes an
eps=1e-5 perturbation can fall below an f32 ULP, produce a zero Jacobian
column, and permanently stall the fit.
Limitations
Section titled “Limitations”- Both APIs are f32-only.
lm_scalar_1paramrequires an analytical derivative and keeps its supplied damping factor fixed.lm_scalar_nparamkeeps lambda fixed at0.01, does not usetolfor early exit, and uses finite differences for the Jacobian.