Skip to main content

fit_pow3

Function fit_pow3 

pub fn fit_pow3(points: &[(f64, f64)]) -> Option<Pow3Fit>
Expand description

Fits the Domhan pow-3 law y(t) = c − a·t^(−α) to points (each (t, y) with t ≥ 1) by in-house Levenberg–Marquardt least squares.

The residual of point i is r_i = y_i − (c − a·t_i^(−α)), and the fit minimises Σ r_i². Writing p_i = t_i^(−α), the residual Jacobian columns are

∂r/∂a = p_i,   ∂r/∂α = −a·p_i·ln(t_i),   ∂r/∂c = −1

so each iteration forms the 3×3 Gauss–Newton normal matrix H = JᵀJ and gradient g = Jᵀr, solves the damped system (H + λ·diag H) δ = −g by Cramer’s rule (solve3), and accepts the step when it lowers the sum of squares (shrinking λ) or rejects it (growing λ) — plain Marquardt damping. It is initialised with α₀ = 1, c₀ just above the largest observed value (the asymptote sits above a rising curve), and a₀ chosen to match the first point exactly.

Returns None for a degenerate, failed, or unsupported fit — fewer than three points, a non-finite input, a singular normal matrix, a non-finite result, or an unsupported extrapolation (a near-linear curve with decay exponent below MIN_ALPHA, or an asymptote more than REMAINING_FACTOR× the observed range above the data) — so a caller that cannot model a curve, or that can only mirage one, declines to act on it rather than inventing a number This is the fail-safe that keeps a still rising trial’s inflated projection from freezing a genuinely-better plateaued one. a and α are kept strictly positive throughout.