gleastsq

Package Version Hex Docs

A least squares curve fitting library for Gleam. This library uses the Nx library from Elixir under the hood to perform matrix operations.

gleastsq targets Erlang only. Nx is a BEAM dependency, so you will want a working Erlang/Elixir toolchain available when developing locally.

Which method should I use?

The library provides four functions for curve fitting: least_squares, gauss_newton, levenberg_marquardt and trust_region_reflective.

Least Squares

Docs and examples

The least_squares function is just an alias for the levenberg_marquardt function.

Levenberg-Marquardt

Docs and examples

Ideal for non-linear least squares problems, particularly when the initial guess is far from the solution. It combines the benefits of the Gauss-Newton method and gradient descent, making it robust and efficient for various scenarios. However, it requires careful tuning of the damping parameter to balance convergence speed and stability.

Trust-Region Reflective

Docs and examples

Best suited for problems with constraints (upper and lower bounds for each function parameter), this method uses a bounded trust-region style update so each iteration stays within a controlled step size and respects the provided parameter bounds. It can be more stable than a plain Gauss-Newton step on constrained problems, but it is also more computationally intensive.

Gauss-Newton

Docs and examples

Efficient for problems where residuals are small and the initial guess is close to the true solution. It approximates the Hessian matrix, leading to faster convergence for well-behaved problems. However, it may struggle with highly non-linear problems or poor initial guesses, as it lacks the robustness of the Levenberg-Marquardt and trust-region reflective methods.

Installation and Example

gleam add gleastsq
import gleam/io
import gleastsq

fn parabola(x: Float, params: List(Float)) -> Float {
  let assert [a, b, c] = params
  a *. x *. x +. b *. x +. c
}

pub fn main() {
  let x = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0]
  let y = [0.0, 1.0, 4.0, 9.0, 16.0, 25.0]
  let initial_guess = [1.0, 1.0, 1.0]

  let assert Ok(result) =
    gleastsq.least_squares(x, y, parabola, initial_guess, opts: [])

  io.debug(result) // [1.0, 0.0, 0.0] (within numerical error)
}

Further documentation can be found at https://hexdocs.pm/gleastsq.

Validation

All fitting functions return Error(WrongParameters(_)) when x and y have different lengths or when initial_params is empty. The trust_region_reflective function also validates that any bound lists have the same length as initial_params.

Search Document