Sidereon.LeastSquares (Sidereon v0.12.0)

Copy Markdown View Source

Generic data-driven trust-region least squares.

Pick a built-in residual kind (:linear, :polynomial, or :exponential), hand over the data arrays, and the whole trust-region iteration runs in Rust: the residual and Jacobian for every step are evaluated inside the trust-region-least-squares engine, so a fit pays one boundary crossing in and one out, never one per function evaluation. This mirrors SciPy's least_squares(method="trf") on its unbounded path.

Residual kinds

  • %{kind: :linear, a: rows, b: rhs} - dense linear least squares, with a the m-by-n design matrix (a list of m rows of n numbers) and b the length-m right-hand side. Solves min ||a x - b||.
  • %{kind: :polynomial, degree: d, t: ts, y: ys} - polynomial fit of degree d (so n = d + 1 coefficients, lowest-order first) over the t/y sample pairs.
  • %{kind: :exponential, t: ts, y: ys} - the three-parameter model y = amp * exp(rate * t) + offset, i.e. x = [amp, rate, offset].

Options

  • :x0 - starting parameter vector. Defaults to zeros for :linear and :polynomial, and [1.0, 0.0, 0.0] for :exponential.
  • :loss - :linear (default), :soft_l1, :huber, :cauchy, :arctan.
  • :f_scale - robust-loss soft-margin scale (default 1.0; only consulted for a robust loss).
  • :x_scale - :unit (default), :jac, or a list of positive per-parameter scales.
  • :max_nfev - residual-evaluation budget (default SciPy's 100 * n).
  • :ftol, :xtol, :gtol - convergence tolerances (SciPy defaults 1.0e-8, 1.0e-8, 1.0e-10).
  • :backend - :native (default, in-crate nalgebra SVD; works everywhere) or :lapack (host LAPACK/numpy BLAS for bit-for-bit SciPy parity, requires the TRUST_REGION_LEAST_SQUARES_LAPACK_PATH environment variable).

Result

least_squares/2 returns {:ok, %Sidereon.LeastSquares.Result{}} or {:error, reason} where reason is a typed atom from the solver (:insufficient_rows, :non_finite_parameters, ...). least_squares_drop_one/2 returns {:ok, %Sidereon.LeastSquares.DropOneReport{}}: the base solve over all rows plus one re-solve per masked residual row, with the per-row cost deltas (leave-one-out RAIM/FDE).

Summary

Functions

Solve a data-driven least-squares problem. See the module doc for the spec shapes and options.

Leave-one-out (drop-one) sweep over the residual rows for RAIM/FDE. Same spec/options as least_squares/2.

Types

spec()

@type spec() ::
  %{kind: :linear, a: [[number()]], b: [number()]}
  | %{
      kind: :polynomial,
      degree: non_neg_integer(),
      t: [number()],
      y: [number()]
    }
  | %{kind: :exponential, t: [number()], y: [number()]}

Functions

least_squares(spec, opts \\ [])

@spec least_squares(
  spec(),
  keyword()
) :: {:ok, Sidereon.LeastSquares.Result.t()} | {:error, atom()}

Solve a data-driven least-squares problem. See the module doc for the spec shapes and options.

least_squares_drop_one(spec, opts \\ [])

@spec least_squares_drop_one(
  spec(),
  keyword()
) :: {:ok, Sidereon.LeastSquares.DropOneReport.t()} | {:error, atom()}

Leave-one-out (drop-one) sweep over the residual rows for RAIM/FDE. Same spec/options as least_squares/2.