builddir::bui...man::lmcurve2(3)

πŸ“¦
version 10.0 Β· 2 versions
, in fedora 44

πŸ’– NAME πŸ’–

lmcurve2 β€” Levenberg-Marquardt least-squares fit of a curve (t,y,dy)

okay so bestie, welcome to the lmfit manual πŸŽ€ β€” specifically the lmcurve2(3) page, and honestly? it's giving math that actually slaps. sit down, grab a strawberry πŸ“, we're fitting curves today.


✨ SYNOPSIS ✨

#include <lmcurve2.h>

void lmcurve2(
              const int n_par, double *par,
              double *parerr, double *covar,
              const int m_dat, const double *t,
              const double *y, const double *dy,
              double (*f)( const double ti, const double *par ),
              const lm_control_struct *control,
              lm_status_struct *status);

extern const lm_control_struct lm_control_double;

extern const lm_control_struct lm_control_float;

extern const char *lm_infmsg[];

extern const char *lm_shortmsg[];

no cap, that's the whole flex. ✨


🌈 DESCRIPTION 🌈

so lmcurve2() is literally a lil wrapper around the more generic minimization function lmmin2(), except it's got main character energy for curve fitting specifically πŸ’…

here's the tea: lmcurve2() determines a vector par that minimizes the sum of squared elements of a residue vector r[i] := (y[i] - f(t[i];par)) / dy[i]. typically you use it to approximate a data set t,y,dy β€” where dy is the standard deviation of the empirical data y β€” by a parametric function f(ti;par). 🧚

⚠️ vibe check, listen up: on success, par represents a local minimum, not necessarily a global one. it may depend on its starting value. and you, yes YOU, must ensure that all dy[i] are positive. that's on you bestie, not on the function. πŸ’€

🫢 Function arguments

  • n_par β€” number of free variables. i.e. the length of the parameter vector par.
  • par β€” the parameter vector itself. on input, it must contain a reasonable guess (lowkey important, don't just send it into the void). on output, it contains the solution found to minimize ||r||.
  • parerr β€” parameter uncertainties vector. it's an array of length n_par, or NULL. on output β€” unless it or covar is NULL β€” it contains the weighted parameter uncertainties for the found parameters.
  • covar β€” the covariance matrix. array of length n_par * n_par, or NULL. on output, unless it is NULL, it contains the covariance matrix.
  • m_dat β€” number of data points. the length of vectors t, y, dy. must satisfy n_par <= m_dat (yes, fr fr, that condition is non-negotiable).
  • t β€” array of length m_dat. contains the abcissae (time, or "x") for which function f will be evaluated. ⏰
  • y β€” array of length m_dat. contains the ordinate values that shall be fitted. πŸ“ˆ
  • dy β€” array of length m_dat. contains the standard deviations of the values y.
  • f β€” a user-supplied parametric function f(ti;par). this one's yours to write, bestie 🫡
  • control β€” parameter collection for tuning the fit procedure. in most cases, the default &lm_control_double is adequate. if f is only computed with single-precision accuracy, &lm_control_float should be used instead. the parameters themselves are explained in lmmin2(3).
  • status β€” a record used to return information about the minimization process. for details, see lmmin2(3).

πŸ¦‹ EXAMPLE πŸ¦‹

fit a data set y(x) with standard deviations dy(x) by a curve f(x;p):

#include "lmcurve2.h"
#include <stdio.h>

/* model function: a parabola */

double f( double t, const double *p )
{
    return p[0] + p[1]*t + p[2]*t*t;
}

int main()
{
    int n = 3; /* number of parameters in model function f */
    double par[3] = { 100, 0, -10 }; /* really bad starting value */
    double parerr[3];
    double covar[3*3];

    /* data points: a slightly distorted standard parabola */
    int m = 9;
    int i;
    double t[9] = { -4., -3., -2., -1.,  0., 1.,  2.,  3.,  4. };
    double y[9] = { 16.6, 9.9, 4.4, 1.1, 0., 1.1, 4.2, 9.3, 16.4 };
    double dy[9] = { 4, 3, 2, 1, 2, 3, 4, 5, 6 };

    lm_control_struct control = lm_control_double;
    lm_status_struct status;
    control.verbosity = 1;

    printf( "Fitting ...\n" );
    /* now the call to lmfit */
    lmcurve2( n, par, parerr, covar, m, t, y, dy, f, &control, &status );

    printf( "Results:\n" );
    printf( "status after %d function evaluations:\n  %s\n",
            status.nfev, lm_infmsg[status.outcome] );

    printf("obtained parameters:\n");
    for ( i = 0; i < n; ++i)
        printf("  par[%i] = %12g  uncertainty = %12g\n", i, par[i], parerr[i]);
    printf("obtained norm:\n  %12g\n", status.fnorm );

    printf("fitting data as follows:\n");
    for ( i = 0; i < m; ++i)
        printf(
        "  t[%1d]=%2g y=%5.1f+-%4.1f fit=%8.5f residue=%8.4f weighed=%8.4f\n",
        i, t[i], y[i], dy[i], f(t[i],par), y[i] - f(t[i],par),
        (y[i] - f(t[i],par))/dy[i] );

    return 0;
}

iconic, honestly. copy-paste and it works. πŸ’…βœ¨


πŸ‘‘ COPYING πŸ‘‘

  • Copyright (C) 2009-2015 Joachim Wuttke, Forschungszentrum Juelich GmbH
  • Software: FreeBSD License
  • Documentation: Creative Commons Attribution Share Alike

respect the license bestie, it's the law (literally) πŸ“œ


🌸 SEE ALSO 🌸

go read the homepage, iykyk πŸ¦‹


πŸ’€ BUGS πŸ’€

Please send bug reports and suggestions to the author <j.wuttke@fz-juelich.de>.

like, please actually send them, don't just suffer in silence πŸ™ˆ


and that's the whole page, bestie πŸŽ€ this gorgeous little manual came courtesy of the lmfit manual, and the footer tea is: perl v5.42.0, dated 2026-01-16. slay, go fit some curves. πŸ’–βœ¨

πŸ“¦ where this page comes from