## GwyNLFitter

GwyNLFitter — Marquardt-Levenberg nonlinear least square fitter

## Synopsis

    #include <libgwyddion/gwyddion.h>

    gdouble             (*GwyNLFitFunc)                     (gdouble x,
                                                             gint n_param,
                                                             const gdouble *param,
                                                             gpointer user_data,
                                                             gboolean *fres);
    void                (*GwyNLFitDerFunc)                  (gdouble x,
                                                             gint n_param,
                                                             const gdouble *param,
                                                             const gboolean *fixed_param,
                                                             GwyNLFitFunc fmarq,
                                                             gpointer user_data,
                                                             gdouble *deriv,
                                                             gboolean *dres);
                        GwyNLFitter;
    GwyNLFitter*        gwy_math_nlfit_new                  (GwyNLFitFunc ff,
                                                             GwyNLFitDerFunc df);
    void                gwy_math_nlfit_free                 (GwyNLFitter *nlfit);
    gdouble             gwy_math_nlfit_fit                  (GwyNLFitter *nlfit,
                                                             gint n_dat,
                                                             const gdouble *x,
                                                             const gdouble *y,
                                                             gint n_param,
                                                             gdouble *param,
                                                             gpointer user_data);
    gdouble             gwy_math_nlfit_fit_full             (GwyNLFitter *nlfit,
                                                             gint n_dat,
                                                             const gdouble *x,
                                                             const gdouble *y,
                                                             const gdouble *weight,
                                                             gint n_param,
                                                             gdouble *param,
                                                             const gboolean *fixed_param,
                                                             const gint *link_map,
                                                             gpointer user_data);
    gint                gwy_math_nlfit_get_max_iterations   (GwyNLFitter *nlfit);
    void                gwy_math_nlfit_set_max_iterations   (GwyNLFitter *nlfit,
                                                             gint maxiter);
    gboolean            gwy_math_nlfit_succeeded            (GwyNLFitter *nlfit);
    gdouble             gwy_math_nlfit_get_dispersion       (GwyNLFitter *nlfit);
    gdouble             gwy_math_nlfit_get_correlations     (GwyNLFitter *nlfit,
                                                             gint par1,
                                                             gint par2);
    gdouble             gwy_math_nlfit_get_sigma            (GwyNLFitter *nlfit,
                                                             gint par);
    void                gwy_math_nlfit_derive               (gdouble x,
                                                             gint n_param,
                                                             const gdouble *param,
                                                             const gboolean *fixed_param,
                                                             GwyNLFitFunc ff,
                                                             gpointer user_data,
                                                             gdouble *deriv,
                                                             gboolean *dres);

## Description

A new Marquardt-Levenberg nonlinear least square fitter can be created with `gwy_math_nlfit_new()`, specifying the function to fit (as GwyNLFitFunc) and its derivative (as GwyNLFitDerFunc). For functions for whose analytic derivative is not available or very impractical, `gwy_math_nlfit_derive()` (computing the derivative numerically) can be used instead.

A fitter can be then repeatedly used on different data either in `gwy_math_nlfit_fit()`, or `gwy_math_nlfit_fit_full()` when there are some fixed or linked parameters. Arbitrary additional (non-fitting) parameters can be passed to the fited function in `user_data`.

After a successfull fit additional fit information can be obtained with `gwy_math_nlfit_get_dispersion()`, `gwy_math_nlfit_get_correlations()`, `gwy_math_nlfit_get_sigma()`. Note these functions may be used only after a successfull fit. When a fitter is no longer needed, it should be freed with `gwy_math_nlfit_free()`.

Several common functions are also available as fitting presets that can be fitted with `gwy_nlfit_preset_fit()`. See GwyNLFitPreset for details.

## Details

### GwyNLFitFunc ()

    gdouble             (*GwyNLFitFunc)                     (gdouble x,
                                                             gint n_param,
                                                             const gdouble *param,
                                                             gpointer user_data,
                                                             gboolean *fres);

Fitting function type.

`x` : | The value to compute the function at.
`n_param` : | The number of parameters (size of `param`).
`param` : | Parameters.
`user_data` : | User data as passed to `gwy_math_nlfit_fit()`.
`fres` : | Set to `TRUE` if succeeds, `FALSE` on failure.
Returns : | The value at `x`.

### GwyNLFitDerFunc ()

    void                (*GwyNLFitDerFunc)                  (gdouble x,
                                                             gint n_param,
                                                             const gdouble *param,
                                                             const gboolean *fixed_param,
                                                             GwyNLFitFunc fmarq,
                                                             gpointer user_data,
                                                             gdouble *deriv,
                                                             gboolean *dres);

Fitting function partial derivative type.

`x` : | x-data as passed to `gwy_math_nlfit_fit()`.
`n_param` : | The number of parameters (size of `param`).
`param` : | Parameters.
`fixed_param` : | Which parameters should be treated as fixed (corresponding entries are set to `TRUE`).
`fmarq` : | The fitting function.
`user_data` : | User data as passed to `gwy_math_nlfit_fit()`.
`deriv` : | Array where the `n_param` partial derivatives by each parameter are to be stored.
`dres` : | Set to `TRUE` if succeeds, `FALSE` on failure.

### GwyNLFitter

    typedef struct {
        GwyNLFitFunc fmarq;  /* fitting function */
        GwyNLFitDerFunc dmarq;  /* fitting function derivations */
        gint maxiter;  /* max number of iterations */
        gboolean eval;  /* success? */
        gdouble *covar; /* covariance matrix  */
        gdouble dispersion; /* dispersion */
        gdouble mfi;    /* fitting parameters --
                           fi, snizeni, zvyseni lambda, minimalni lambda */
        gdouble mdec;
        gdouble minc;
        gdouble mtol;
    } GwyNLFitter;

### gwy_math_nlfit_new ()

    GwyNLFitter*        gwy_math_nlfit_new                  (GwyNLFitFunc ff,
                                                             GwyNLFitDerFunc df);

Creates a new Marquardt-Levenberg nonlinear fitter for function `ff`.

`ff` : | The fitted function.
`df` : | The derivative of fitted function. You can use `gwy_math_nlfit_derive()` computing the derivative numerically, when you don't know the derivative explicitely.
Returns : | The newly created fitter.

### gwy_math_nlfit_free ()

    void                gwy_math_nlfit_free                 (GwyNLFitter *nlfit);

Completely frees a Marquardt-Levenberg nonlinear fitter.

`nlfit` : | A Marquardt-Levenberg nonlinear fitter.

### gwy_math_nlfit_fit ()

    gdouble             gwy_math_nlfit_fit                  (GwyNLFitter *nlfit,
                                                             gint n_dat,
                                                             const gdouble *x,
                                                             const gdouble *y,
                                                             gint n_param,
                                                             gdouble *param,
                                                             gpointer user_data);

Performs a nonlinear fit of `nlfit` function on (`x`,`y`) data.

`nlfit` : | A Marquardt-Levenberg nonlinear fitter.
`n_dat` : | The number of data points in `x`, `y`.
`x` : | Array of independent variable values.
`y` : | Array of dependent variable values.
`n_param` : | The nuber of parameters.
`param` : | Array of parameters (of size `n_param`). Note the parameters must be initialized to reasonably near values.
`user_data` : | Any pointer that will be passed to the function and derivative as `user_data`.
Returns : | The final residual sum, a negative number in the case of failure.

### gwy_math_nlfit_fit_full ()

    gdouble             gwy_math_nlfit_fit_full             (GwyNLFitter *nlfit,
                                                             gint n_dat,
                                                             const gdouble *x,
                                                             const gdouble *y,
                                                             const gdouble *weight,
                                                             gint n_param,
                                                             gdouble *param,
                                                             const gboolean *fixed_param,
                                                             const gint *link_map,
                                                             gpointer user_data);

Performs a nonlinear fit of `nlfit` function on (`x`,`y`) data, allowing some fixed parameters.

Initial values of linked (dependent) parameters are overwritten by master values, their `fixed_param` property is ignored and master's property controls whether all are fixed or all variable.

`nlfit` : | A Marquardt-Levenberg nonlinear fitter.
`n_dat` : | The number of data points in `x`, `y`, `weight`.
`x` : | Array of independent variable values.
`y` : | Array of dependent variable values.
`weight` : | Array of weights associated to each data point. Can be `NULL`, weight of 1 is then used for all data.
`n_param` : | The nuber of parameters.
`param` : | Array of parameters (of size `n_param`). Note the parameters must be initialized to reasonably near values.
`fixed_param` : | Which parameters should be treated as fixed (set corresponding element to `TRUE` for them). May be `NULL` if all parameters are variable.
`link_map` : | Map of linked parameters. One of linked parameters is master, Values in this array are indices of corresponding master parameter for each parameter (for independent parameters set `link_map`[i] == i). May be `NULL` if all parameter are independent.
`user_data` : | Any pointer that will be passed to the function and derivative
Returns : | The final residual sum, a negative number in the case of failure.

### gwy_math_nlfit_get_max_iterations ()

    gint                gwy_math_nlfit_get_max_iterations   (GwyNLFitter *nlfit);

Returns the maximum number of iterations of nonlinear fitter `nlfit`.

`nlfit` : | A Marquardt-Levenberg nonlinear fitter.
Returns : | The maximum number of iterations.

### gwy_math_nlfit_set_max_iterations ()

    void                gwy_math_nlfit_set_max_iterations   (GwyNLFitter *nlfit,
                                                             gint maxiter);

Sets the maximum number of iterations for nonlinear fitter `nlfit`.

`nlfit` : | A Marquardt-Levenberg nonlinear fitter.
`maxiter` : | The maximum number of iterations.

### gwy_math_nlfit_succeeded ()

    gboolean            gwy_math_nlfit_succeeded            (GwyNLFitter *nlfit);

Obtains the status of the last fitting.

Fitting failure can be (and usually should be) also determined by checking for negative return value of `gwy_math_nlfit_fit()` or `gwy_math_nlfit_fit_full()`. This function allows to test it later.

`nlfit` : | A Marquardt-Levenberg nonlinear fitter.
Returns : | `TRUE` if the last fitting suceeded, `FALSE` if it failed.

Since 2.7

### gwy_math_nlfit_get_dispersion ()

    gdouble             gwy_math_nlfit_get_dispersion       (GwyNLFitter *nlfit);

Returns the residual sum divided by the number of degrees of freedom.

This function can be used only after a successful fit.

`nlfit` : | A Marquardt-Levenberg nonlinear fitter.
Returns : | The dispersion.

### gwy_math_nlfit_get_correlations ()

    gdouble             gwy_math_nlfit_get_correlations     (GwyNLFitter *nlfit,
                                                             gint par1,
                                                             gint par2);

Returns the correlation coefficient between `par1`-th and `par2`-th parameter.

This function can be used only after a successful fit.

`nlfit` : | A Marquardt-Levenberg nonlinear fitter.
`par1` : | First parameter index.
`par2` : | Second parameter index.
Returns : | The correlation coefficient.

### gwy_math_nlfit_get_sigma ()

    gdouble             gwy_math_nlfit_get_sigma            (GwyNLFitter *nlfit,
                                                             gint par);

Returns the standard deviation of parameter number `par`.

This function makes sense only after a successful fit.

`nlfit` : | A Marquardt-Levenberg nonlinear fitter.
`par` : | Parameter index.
Returns : | The SD of `par`-th parameter.

### gwy_math_nlfit_derive ()

    void                gwy_math_nlfit_derive               (gdouble x,
                                                             gint n_param,
                                                             const gdouble *param,
                                                             const gboolean *fixed_param,
                                                             GwyNLFitFunc ff,
                                                             gpointer user_data,
                                                             gdouble *deriv,
                                                             gboolean *dres);

Numerically computes the partial derivative of a fitting function.

`x` : | The value to compute the derivative at.
`n_param` : | The nuber of parameters.
`param` : | Array of parameters (of size `n_param`).
`fixed_param` : | Which parameters should be treated as fixed (corresponding entries are set to `TRUE`).
`ff` : | The fitted function.
`user_data` : | User data as passed to `gwy_math_nlfit_fit()`.
`deriv` : | Array where the put the result to.
`dres` : | Set to `TRUE` if succeeds, `FALSE` on failure.

## See Also

GwyNLFitPreset