-module(gleastsq). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src\\gleastsq.gleam"). -export([least_squares/5, levenberg_marquardt/5, gauss_newton/5, trust_region_reflective/7]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -file("src\\gleastsq.gleam", 10). ?DOC( " The `least_squares` function is an alias for the `levenberg_marquardt` function.\n" " Check the documentation of the `levenberg_marquardt` function for more information.\n" ). -spec least_squares( list(float()), list(float()), fun((float(), list(float())) -> float()), list(float()), list(gleastsq@options:least_square_options()) ) -> {ok, list(float())} | {error, gleastsq@errors:fit_errors()}. least_squares(X, Y, Func, Initial_params, Opts) -> gleastsq@internal@methods@levenberg_marquardt:levenberg_marquardt( X, Y, Func, Initial_params, gleastsq@internal@params:decode_params(Opts) ). -file("src\\gleastsq.gleam", 76). ?DOC( " The `levenberg_marquardt` function performs the Levenberg-Marquardt optimization algorithm.\n" " It is used to solve non-linear least squares problems. This function takes as input the data points,\n" " the model function, and several optional parameters to control the optimization process.\n" "\n" " # Parameters\n" " - `x` (List(Float))\n" " A list of x-values of the data points.\n" " - `y` (List(Float))\n" " A list of y-values of the data points.\n" " - `func` (fn(Float, List(Float)) -> Float)\n" " The model function that takes an x-value and a list of parameters, and returns the corresponding y-value.\n" " - `initial_params` (List(Float))\n" " A list of initial guesses for the parameters of the model function.\n" " This list must not be empty.\n" " - `opts` (List(LeastSquareOptions))\n" " A list of optional parameters to control the optimization process.\n" " The available options are:\n" " - `Iterations(Int)`: The maximum number of iterations to perform. Default is 100.\n" " - `Epsilon(Float)`: A small value to change x when calculating the derivatives for the function. Default is 0.0001.\n" " - `Tolerance(Float)`: The convergence tolerance. Default is 0.0001.\n" " - `Damping(Float)`: The initial value of the damping parameter. Default is 0.0001.\n" " - `DampingIncrease(Float)`: The factor by which the damping parameter is increased when a step fails. Default is 10.0.\n" " - `DampingDecrease(Float)`: The factor by which the damping parameter is decreased when a step succeeds. Default is 0.1.\n" "\n" " # Errors\n" " Returns `Error(WrongParameters(_))` if `x` and `y` have different lengths or\n" " if `initial_params` is empty.\n" "\n" " # Example\n" " ```gleam\n" " import gleam/io\n" " import gleastsq\n" " import gleastsq/options.{Iterations, Tolerance}\n" "\n" " fn parabola(x: Float, params: List(Float)) -> Float {\n" " let assert [a, b, c] = params\n" " a *. x *. x +. b *. x +. c\n" " }\n" "\n" " pub fn main() {\n" " let x = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0]\n" " let y = [0.0, 1.0, 4.0, 9.0, 16.0, 25.0]\n" " let initial_guess = [1.0, 1.0, 1.0]\n" "\n" " let assert Ok(result) =\n" " gleastsq.levenberg_marquardt(\n" " x,\n" " y,\n" " parabola,\n" " initial_guess,\n" " opts: [Iterations(1000), Tolerance(0.001)]\n" " )\n" "\n" " io.debug(result) // [1.0, 0.0, 0.0] (within numerical error)\n" " }\n" " ```\n" ). -spec levenberg_marquardt( list(float()), list(float()), fun((float(), list(float())) -> float()), list(float()), list(gleastsq@options:least_square_options()) ) -> {ok, list(float())} | {error, gleastsq@errors:fit_errors()}. levenberg_marquardt(X, Y, Func, Initial_params, Opts) -> gleastsq@internal@methods@levenberg_marquardt:levenberg_marquardt( X, Y, Func, Initial_params, gleastsq@internal@params:decode_params(Opts) ). -file("src\\gleastsq.gleam", 140). ?DOC( " The `gauss_newton` function performs a basic least squares optimization algorithm.\n" " It is used to find the best-fit parameters for a given model function to a set of data points.\n" " This function takes as input the data points, the model function, and several optional parameters to control the optimization process.\n" "\n" " # Parameters\n" " - `x` (List(Float))\n" " A list of x-values of the data points.\n" " - `y` (List(Float))\n" " A list of y-values of the data points.\n" " - `func` (fn(Float, List(Float)) -> Float)\n" " The model function that takes an x-value and a list of parameters, and returns the corresponding y-value.\n" " - `initial_params` (List(Float))\n" " A list of initial guesses for the parameters of the model function.\n" " This list must not be empty.\n" " - `opts` (List(LeastSquareOptions))\n" " A list of optional parameters to control the optimization process.\n" " The available options are:\n" " - `Iterations(Int)`: The maximum number of iterations to perform. Default is 100.\n" " - `Epsilon(Float)`: A small value to change x when calculating the derivatives for the function. Default is 0.0001.\n" " - `Tolerance(Float)`: The convergence tolerance. Default is 0.0001.\n" " - `Damping(Float)`: The value of the damping parameter. Default is 0.001.\n" "\n" " # Errors\n" " Returns `Error(WrongParameters(_))` if `x` and `y` have different lengths or\n" " if `initial_params` is empty.\n" "\n" " # Example\n" " ```gleam\n" " import gleam/io\n" " import gleastsq\n" " import gleastsq/options.{Iterations, Tolerance}\n" "\n" " fn parabola(x: Float, params: List(Float)) -> Float {\n" " let assert [a, b, c] = params\n" " a *. x *. x +. b *. x +. c\n" " }\n" "\n" " pub fn main() {\n" " let x = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0]\n" " let y = [0.0, 1.0, 4.0, 9.0, 16.0, 25.0]\n" " let initial_guess = [1.0, 1.0, 1.0]\n" "\n" " let assert Ok(result) =\n" " gleastsq.gauss_newton(\n" " x,\n" " y,\n" " parabola,\n" " initial_guess,\n" " opts: [Iterations(1000), Tolerance(0.001)]\n" " )\n" "\n" " io.debug(result) // [1.0, 0.0, 0.0] (within numerical error)\n" " }\n" " ```\n" ). -spec gauss_newton( list(float()), list(float()), fun((float(), list(float())) -> float()), list(float()), list(gleastsq@options:least_square_options()) ) -> {ok, list(float())} | {error, gleastsq@errors:fit_errors()}. gauss_newton(X, Y, Func, Initial_params, Opts) -> gleastsq@internal@methods@gauss_newton:gauss_newton( X, Y, Func, Initial_params, gleastsq@internal@params:decode_params(Opts) ). -file("src\\gleastsq.gleam", 216). ?DOC( " The `trust_region_reflective` function performs a bounded trust-region least\n" " squares optimization.\n" " It is used to find the best-fit parameters for a given model function to a\n" " set of data points while respecting optional upper and lower bounds.\n" " This function takes as input the data points, the model function, and\n" " several optional parameters to control the optimization process.\n" "\n" " # Parameters\n" " - `x` (List(Float))\n" " A list of x-values of the data points.\n" " - `y` (List(Float))\n" " A list of y-values of the data points.\n" " - `func` (fn(Float, List(Float)) -> Float)\n" " The model function that takes an x-value and a list of parameters, and returns the corresponding y-value.\n" " - `initial_params` (List(Float))\n" " A list of initial guesses for the parameters of the model function.\n" " This list must not be empty. Values outside the provided bounds are\n" " clipped to the bounds before optimization begins.\n" " - `lower_bounds` (Option(List(Float)))\n" " A list of lower bounds for the parameters of the model function. If the lower bound is `None`, then the parameter is unbounded from below.\n" " - `upper_bounds` (Option(List(Float)))\n" " A list of upper bounds for the parameters of the model function. If the upper bound is `None`, then the parameter is unbounded from above.\n" " - `opts` (List(LeastSquareOptions))\n" " A list of optional parameters to control the optimization process.\n" " The available options are:\n" " - `Iterations(Int)`: The maximum number of iterations to perform. Default is 100.\n" " - `Epsilon(Float)`: A small value to change x when calculating the derivatives for the function. Default is 0.0001.\n" " - `Tolerance(Float)`: The convergence tolerance. Default is 0.00001.\n" " - `Damping(Float)`: The value of the damping parameter. Default is 0.001.\n" "\n" " # Errors\n" " Returns `Error(WrongParameters(_))` if `x` and `y` have different lengths,\n" " if `initial_params` is empty, or if the bound lists have different lengths\n" " from `initial_params`.\n" "\n" " # Example\n" " ```gleam\n" " import gleam/io\n" " import gleam/option.{Some}\n" " import gleastsq\n" " import gleastsq/options.{Iterations, Tolerance}\n" "\n" " fn parabola(x: Float, params: List(Float)) -> Float {\n" " let assert [a, b, c] = params\n" " a *. x *. x +. b *. x +. c\n" " }\n" "\n" " pub fn main() {\n" " let x = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0]\n" " let y = [0.0, 1.0, 4.0, 9.0, 16.0, 25.0]\n" " let initial_guess = [1.0, 1.0, 1.0]\n" "\n" " let assert Ok(result) =\n" " gleastsq.trust_region_reflective(\n" " x,\n" " y,\n" " parabola,\n" " initial_guess,\n" " lower_bounds: Some([0.0, 0.0, 0.0]),\n" " upper_bounds: Some([2.0, 2.0, 2.0]),\n" " opts: [Iterations(1000), Tolerance(0.001)]\n" " )\n" "\n" " io.debug(result) // [1.0, 0.0, 0.0] (within numerical error)\n" " }\n" " ```\n" ). -spec trust_region_reflective( list(float()), list(float()), fun((float(), list(float())) -> float()), list(float()), gleam@option:option(list(float())), gleam@option:option(list(float())), list(gleastsq@options:least_square_options()) ) -> {ok, list(float())} | {error, gleastsq@errors:fit_errors()}. trust_region_reflective( X, Y, Func, Initial_params, Lower_bounds, Upper_bounds, Opts ) -> gleastsq@internal@methods@trust_region_reflective:trust_region_reflective( X, Y, Func, Initial_params, Lower_bounds, Upper_bounds, gleastsq@internal@params:decode_params(Opts) ).