1*5ddc57e5SXin Li<?xml version="1.0" ?> 2*5ddc57e5SXin Li<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 3*5ddc57e5SXin Li<html xmlns="http://www.w3.org/1999/xhtml"> 4*5ddc57e5SXin Li<head> 5*5ddc57e5SXin Li<title>lmfit: a self-contained C library for Levenberg-Marquardt least-squares minimization and curve fitting</title> 6*5ddc57e5SXin Li<meta http-equiv="content-type" content="text/html; charset=utf-8" /> 7*5ddc57e5SXin Li<link rev="made" href="mailto:root@localhost" /> 8*5ddc57e5SXin Li</head> 9*5ddc57e5SXin Li 10*5ddc57e5SXin Li<body> 11*5ddc57e5SXin Li 12*5ddc57e5SXin Li 13*5ddc57e5SXin Li 14*5ddc57e5SXin Li 15*5ddc57e5SXin Li 16*5ddc57e5SXin Li<link rel="stylesheet" href="podstyle.css" type="text/css" /> 17*5ddc57e5SXin Li 18*5ddc57e5SXin Li<h1 id="NAME">NAME</h1> 19*5ddc57e5SXin Li 20*5ddc57e5SXin Li<p>lmmin - Levenberg-Marquardt least-squares minimization</p> 21*5ddc57e5SXin Li 22*5ddc57e5SXin Li<h1 id="SYNOPSIS">SYNOPSIS</h1> 23*5ddc57e5SXin Li 24*5ddc57e5SXin Li<p><b>#include <lmmin.h</b>></p> 25*5ddc57e5SXin Li 26*5ddc57e5SXin Li<p><b>void lmmin( const int</b> <i>n_par</i><b>, double *</b><i>par</i><b>, const int</b> <i>m_dat</i><b>, const<span style="white-space: nowrap;"> </span>void *</b><i>data</i><b>, void *</b><i>evaluate</i><b>( const<span style="white-space: nowrap;"> </span>double *</b><i>par</i><b>, const int </b><i>m_dat</i><b>, const<span style="white-space: nowrap;"> </span>void *</b><i>data</i><b>, double *</b><i>fvec</i><b>, int *</b><i>userbreak</i><b>), const<span style="white-space: nowrap;"> </span>lm_control_struct *</b><i>control</i><b>, lm_status_struct *</b><i>status</i><b> );</b></p> 27*5ddc57e5SXin Li 28*5ddc57e5SXin Li<p><b>extern const lm_control_struct lm_control_double;</b></p> 29*5ddc57e5SXin Li 30*5ddc57e5SXin Li<p><b>extern const lm_control_struct lm_control_float;</b></p> 31*5ddc57e5SXin Li 32*5ddc57e5SXin Li<p><b>extern const char *lm_infmsg[];</b></p> 33*5ddc57e5SXin Li 34*5ddc57e5SXin Li<p><b>extern const char *lm_shortmsg[];</b></p> 35*5ddc57e5SXin Li 36*5ddc57e5SXin Li<h1 id="DESCRIPTION">DESCRIPTION</h1> 37*5ddc57e5SXin Li 38*5ddc57e5SXin Li<p><b>lmmin()</b> determines a vector <i>par</i> that minimizes the sum of squared elements of a vector <i>fvec</i> that is computed by a user-supplied function <i>evaluate</i>(). On success, <i>par</i> represents a local minimum, not necessarily a global one; it may depend on its starting value.</p> 39*5ddc57e5SXin Li 40*5ddc57e5SXin Li<p>For applications in curve fitting, the wrapper function <b>lmcurve(3)</b> offers a simplified API.</p> 41*5ddc57e5SXin Li 42*5ddc57e5SXin Li<p>The Levenberg-Marquardt minimization starts with a steepest-descent exploration of the parameter space, and achieves rapid convergence by crossing over into the Newton-Gauss method.</p> 43*5ddc57e5SXin Li 44*5ddc57e5SXin Li<p>Function arguments:</p> 45*5ddc57e5SXin Li 46*5ddc57e5SXin Li<dl> 47*5ddc57e5SXin Li 48*5ddc57e5SXin Li<dt id="n_par"><i>n_par</i></dt> 49*5ddc57e5SXin Li<dd> 50*5ddc57e5SXin Li 51*5ddc57e5SXin Li<p>Number of free variables. Length of parameter vector <i>par</i>.</p> 52*5ddc57e5SXin Li 53*5ddc57e5SXin Li</dd> 54*5ddc57e5SXin Li<dt id="par"><i>par</i></dt> 55*5ddc57e5SXin Li<dd> 56*5ddc57e5SXin Li 57*5ddc57e5SXin Li<p>Parameter vector. On input, it must contain a reasonable guess. On output, it contains the solution found to minimize ||<i>fvec</i>||.</p> 58*5ddc57e5SXin Li 59*5ddc57e5SXin Li</dd> 60*5ddc57e5SXin Li<dt id="m_dat"><i>m_dat</i></dt> 61*5ddc57e5SXin Li<dd> 62*5ddc57e5SXin Li 63*5ddc57e5SXin Li<p>Length of vector <i>fvec</i>. Must statisfy <i>n_par</i> <= <i>m_dat</i>.</p> 64*5ddc57e5SXin Li 65*5ddc57e5SXin Li</dd> 66*5ddc57e5SXin Li<dt id="data"><i>data</i></dt> 67*5ddc57e5SXin Li<dd> 68*5ddc57e5SXin Li 69*5ddc57e5SXin Li<p>This pointer is ignored by the fit algorithm, except for appearing as an argument in all calls to the user-supplied routine <i>evaluate</i>.</p> 70*5ddc57e5SXin Li 71*5ddc57e5SXin Li</dd> 72*5ddc57e5SXin Li<dt id="evaluate"><i>evaluate</i></dt> 73*5ddc57e5SXin Li<dd> 74*5ddc57e5SXin Li 75*5ddc57e5SXin Li<p>Pointer to a user-supplied function that computes <i>m_dat</i> elements of vector <i>fvec</i> for a given parameter vector <i>par</i>. If <i>evaluate</i> return with *<i>userbreak</i> set to a negative value, <b>lmmin()</b> will interrupt the fitting and terminate.</p> 76*5ddc57e5SXin Li 77*5ddc57e5SXin Li</dd> 78*5ddc57e5SXin Li<dt id="control"><i>control</i></dt> 79*5ddc57e5SXin Li<dd> 80*5ddc57e5SXin Li 81*5ddc57e5SXin Li<p>Parameter collection for tuning the fit procedure. In most cases, the default &<i>lm_control_double</i> is adequate. If <i>f</i> is only computed with single-precision accuracy, <i>&lm_control_float</i> should be used. See also below, NOTES on initializing parameter records.</p> 82*5ddc57e5SXin Li 83*5ddc57e5SXin Li<p><i>control</i> has the following members (for more details, see the source file <i>lmstruct.h</i>):</p> 84*5ddc57e5SXin Li 85*5ddc57e5SXin Li<dl> 86*5ddc57e5SXin Li 87*5ddc57e5SXin Li<dt id="double-control.ftol"><b>double</b> <i>control.ftol</i></dt> 88*5ddc57e5SXin Li<dd> 89*5ddc57e5SXin Li 90*5ddc57e5SXin Li<p>Relative error desired in the sum of squares. Recommended setting: somewhat above machine precision; less if <i>fvec</i> is computed with reduced accuracy.</p> 91*5ddc57e5SXin Li 92*5ddc57e5SXin Li</dd> 93*5ddc57e5SXin Li<dt id="double-control.xtol"><b>double</b> <i>control.xtol</i></dt> 94*5ddc57e5SXin Li<dd> 95*5ddc57e5SXin Li 96*5ddc57e5SXin Li<p>Relative error between last two approximations. Recommended setting: as <i>ftol</i>.</p> 97*5ddc57e5SXin Li 98*5ddc57e5SXin Li</dd> 99*5ddc57e5SXin Li<dt id="double-control.gtol"><b>double</b> <i>control.gtol</i></dt> 100*5ddc57e5SXin Li<dd> 101*5ddc57e5SXin Li 102*5ddc57e5SXin Li<p>A measure for degeneracy. Recommended setting: as <i>ftol</i>.</p> 103*5ddc57e5SXin Li 104*5ddc57e5SXin Li</dd> 105*5ddc57e5SXin Li<dt id="double-control.epsilon"><b>double</b> <i>control.epsilon</i></dt> 106*5ddc57e5SXin Li<dd> 107*5ddc57e5SXin Li 108*5ddc57e5SXin Li<p>Step used to calculate the Jacobian. Recommended setting: as <i>ftol</i>, but definitely less than the accuracy of <i>fvec</i>.</p> 109*5ddc57e5SXin Li 110*5ddc57e5SXin Li</dd> 111*5ddc57e5SXin Li<dt id="double-control.stepbound"><b>double</b> <i>control.stepbound</i></dt> 112*5ddc57e5SXin Li<dd> 113*5ddc57e5SXin Li 114*5ddc57e5SXin Li<p>Initial bound to steps in the outer loop, generally between 0.01 and 100; recommended value is 100.</p> 115*5ddc57e5SXin Li 116*5ddc57e5SXin Li</dd> 117*5ddc57e5SXin Li<dt id="int-control.patience"><b>int</b> <i>control.patience</i></dt> 118*5ddc57e5SXin Li<dd> 119*5ddc57e5SXin Li 120*5ddc57e5SXin Li<p>Used to set the maximum number of function evaluations to patience*n_par.</p> 121*5ddc57e5SXin Li 122*5ddc57e5SXin Li</dd> 123*5ddc57e5SXin Li<dt id="int-control.scale_diag"><b>int</b> <i>control.scale_diag</i></dt> 124*5ddc57e5SXin Li<dd> 125*5ddc57e5SXin Li 126*5ddc57e5SXin Li<p>Logical switch (0 or 1). If 1, then scale parameters to their initial value. This is the recommended setting.</p> 127*5ddc57e5SXin Li 128*5ddc57e5SXin Li</dd> 129*5ddc57e5SXin Li<dt id="FILE-control.msgfile"><b>FILE*</b> <i>control.msgfile</i></dt> 130*5ddc57e5SXin Li<dd> 131*5ddc57e5SXin Li 132*5ddc57e5SXin Li<p>Progress messages will be written to this file. Typically <i>stdout</i> or <i>stderr</i>. The value <i>NULL</i> will be interpreted as <i>stdout</i>.</p> 133*5ddc57e5SXin Li 134*5ddc57e5SXin Li</dd> 135*5ddc57e5SXin Li<dt id="int-control.verbosity"><b>int</b> <i>control.verbosity</i></dt> 136*5ddc57e5SXin Li<dd> 137*5ddc57e5SXin Li 138*5ddc57e5SXin Li<p>If nonzero, some progress information from within the LM algorithm is written to control.stream.</p> 139*5ddc57e5SXin Li 140*5ddc57e5SXin Li</dd> 141*5ddc57e5SXin Li<dt id="int-control.n_maxpri"><b>int</b> <i>control.n_maxpri</i></dt> 142*5ddc57e5SXin Li<dd> 143*5ddc57e5SXin Li 144*5ddc57e5SXin Li<p>-1, or maximum number of parameters to print.</p> 145*5ddc57e5SXin Li 146*5ddc57e5SXin Li</dd> 147*5ddc57e5SXin Li<dt id="int-control.m_maxpri"><b>int</b> <i>control.m_maxpri</i></dt> 148*5ddc57e5SXin Li<dd> 149*5ddc57e5SXin Li 150*5ddc57e5SXin Li<p>-1, or maximum number of residuals to print.</p> 151*5ddc57e5SXin Li 152*5ddc57e5SXin Li</dd> 153*5ddc57e5SXin Li</dl> 154*5ddc57e5SXin Li 155*5ddc57e5SXin Li</dd> 156*5ddc57e5SXin Li<dt id="status"><i>status</i></dt> 157*5ddc57e5SXin Li<dd> 158*5ddc57e5SXin Li 159*5ddc57e5SXin Li<p>A record used to return information about the minimization process:</p> 160*5ddc57e5SXin Li 161*5ddc57e5SXin Li<dl> 162*5ddc57e5SXin Li 163*5ddc57e5SXin Li<dt id="double-status.fnorm"><b>double</b> <i>status.fnorm</i></dt> 164*5ddc57e5SXin Li<dd> 165*5ddc57e5SXin Li 166*5ddc57e5SXin Li<p>Norm of the vector <i>fvec</i>;</p> 167*5ddc57e5SXin Li 168*5ddc57e5SXin Li</dd> 169*5ddc57e5SXin Li<dt id="int-status.nfev"><b>int</b> <i>status.nfev</i></dt> 170*5ddc57e5SXin Li<dd> 171*5ddc57e5SXin Li 172*5ddc57e5SXin Li<p>Actual number of iterations;</p> 173*5ddc57e5SXin Li 174*5ddc57e5SXin Li</dd> 175*5ddc57e5SXin Li<dt id="int-status.outcome"><b>int</b> <i>status.outcome</i></dt> 176*5ddc57e5SXin Li<dd> 177*5ddc57e5SXin Li 178*5ddc57e5SXin Li<p>Status of minimization; for the corresponding text message, print <i>lm_infmsg</i><b>[</b><i>status.outcome</i><b>]</b>; for a short code, print <i>lm_shortmsg</i><b>[</b><i>status.outcome</i><b>]</b>.</p> 179*5ddc57e5SXin Li 180*5ddc57e5SXin Li</dd> 181*5ddc57e5SXin Li<dt id="int-status.userbreak"><b>int</b> <i>status.userbreak</i></dt> 182*5ddc57e5SXin Li<dd> 183*5ddc57e5SXin Li 184*5ddc57e5SXin Li<p>Set when termination has been forced by the user-supplied routine <i>evaluate</i>.</p> 185*5ddc57e5SXin Li 186*5ddc57e5SXin Li</dd> 187*5ddc57e5SXin Li</dl> 188*5ddc57e5SXin Li 189*5ddc57e5SXin Li</dd> 190*5ddc57e5SXin Li</dl> 191*5ddc57e5SXin Li 192*5ddc57e5SXin Li<h1 id="NOTES">NOTES</h1> 193*5ddc57e5SXin Li 194*5ddc57e5SXin Li<h2 id="Initializing-parameter-records">Initializing parameter records.</h2> 195*5ddc57e5SXin Li 196*5ddc57e5SXin Li<p>The parameter record <i>control</i> should always be initialized from supplied default records:</p> 197*5ddc57e5SXin Li 198*5ddc57e5SXin Li<pre><code> lm_control_struct control = lm_control_double; /* or _float */</code></pre> 199*5ddc57e5SXin Li 200*5ddc57e5SXin Li<p>After this, parameters may be overwritten:</p> 201*5ddc57e5SXin Li 202*5ddc57e5SXin Li<pre><code> control.patience = 500; /* allow more iterations */ 203*5ddc57e5SXin Li control.verbosity = 15; /* for verbose monitoring */</code></pre> 204*5ddc57e5SXin Li 205*5ddc57e5SXin Li<p>An application written this way is guaranteed to work even if new parameters are added to <i>lm_control_struct</i>.</p> 206*5ddc57e5SXin Li 207*5ddc57e5SXin Li<p>Conversely, addition of parameters is not considered an API change; it may happen without increment of the major version number.</p> 208*5ddc57e5SXin Li 209*5ddc57e5SXin Li<h1 id="EXAMPLES">EXAMPLES</h1> 210*5ddc57e5SXin Li 211*5ddc57e5SXin Li<h2 id="Fitting-a-surface">Fitting a surface</h2> 212*5ddc57e5SXin Li 213*5ddc57e5SXin Li<p>Fit a data set y(t) by a function f(t;p) where t is a two-dimensional vector:</p> 214*5ddc57e5SXin Li 215*5ddc57e5SXin Li<pre><code> #include "lmmin.h" 216*5ddc57e5SXin Li #include <stdio.h> 217*5ddc57e5SXin Li 218*5ddc57e5SXin Li /* fit model: a plane p0 + p1*tx + p2*tz */ 219*5ddc57e5SXin Li double f( double tx, double tz, const double *p ) 220*5ddc57e5SXin Li { 221*5ddc57e5SXin Li return p[0] + p[1]*tx + p[2]*tz; 222*5ddc57e5SXin Li } 223*5ddc57e5SXin Li 224*5ddc57e5SXin Li /* data structure to transmit data arays and fit model */ 225*5ddc57e5SXin Li typedef struct { 226*5ddc57e5SXin Li double *tx, *tz; 227*5ddc57e5SXin Li double *y; 228*5ddc57e5SXin Li double (*f)( double tx, double tz, const double *p ); 229*5ddc57e5SXin Li } data_struct; 230*5ddc57e5SXin Li 231*5ddc57e5SXin Li /* function evaluation, determination of residues */ 232*5ddc57e5SXin Li void evaluate_surface( const double *par, int m_dat, 233*5ddc57e5SXin Li const void *data, double *fvec, int *userbreak ) 234*5ddc57e5SXin Li { 235*5ddc57e5SXin Li /* for readability, explicit type conversion */ 236*5ddc57e5SXin Li data_struct *D; 237*5ddc57e5SXin Li D = (data_struct*)data; 238*5ddc57e5SXin Li 239*5ddc57e5SXin Li int i; 240*5ddc57e5SXin Li for ( i = 0; i < m_dat; i++ ) 241*5ddc57e5SXin Li fvec[i] = D->y[i] - D->f( D->tx[i], D->tz[i], par ); 242*5ddc57e5SXin Li } 243*5ddc57e5SXin Li 244*5ddc57e5SXin Li int main() 245*5ddc57e5SXin Li { 246*5ddc57e5SXin Li /* parameter vector */ 247*5ddc57e5SXin Li int n_par = 3; /* number of parameters in model function f */ 248*5ddc57e5SXin Li double par[3] = { -1, 0, 1 }; /* arbitrary starting value */ 249*5ddc57e5SXin Li 250*5ddc57e5SXin Li /* data points */ 251*5ddc57e5SXin Li int m_dat = 4; 252*5ddc57e5SXin Li double tx[4] = { -1, -1, 1, 1 }; 253*5ddc57e5SXin Li double tz[4] = { -1, 1, -1, 1 }; 254*5ddc57e5SXin Li double y[4] = { 0, 1, 1, 2 }; 255*5ddc57e5SXin Li 256*5ddc57e5SXin Li data_struct data = { tx, tz, y, f }; 257*5ddc57e5SXin Li 258*5ddc57e5SXin Li /* auxiliary parameters */ 259*5ddc57e5SXin Li lm_status_struct status; 260*5ddc57e5SXin Li lm_control_struct control = lm_control_double; 261*5ddc57e5SXin Li control.verbosity = 3; 262*5ddc57e5SXin Li 263*5ddc57e5SXin Li /* perform the fit */ 264*5ddc57e5SXin Li printf( "Fitting:\n" ); 265*5ddc57e5SXin Li lmmin( n_par, par, m_dat, (const void*) &data, evaluate_surface, 266*5ddc57e5SXin Li &control, &status ); 267*5ddc57e5SXin Li 268*5ddc57e5SXin Li /* print results */ 269*5ddc57e5SXin Li printf( "\nResults:\n" ); 270*5ddc57e5SXin Li printf( "status after %d function evaluations:\n %s\n", 271*5ddc57e5SXin Li status.nfev, lm_infmsg[status.outcome] ); 272*5ddc57e5SXin Li 273*5ddc57e5SXin Li printf("obtained parameters:\n"); 274*5ddc57e5SXin Li int i; 275*5ddc57e5SXin Li for ( i=0; i<n_par; ++i ) 276*5ddc57e5SXin Li printf(" par[%i] = %12g\n", i, par[i]); 277*5ddc57e5SXin Li printf("obtained norm:\n %12g\n", status.fnorm ); 278*5ddc57e5SXin Li 279*5ddc57e5SXin Li printf("fitting data as follows:\n"); 280*5ddc57e5SXin Li double ff; 281*5ddc57e5SXin Li for ( i=0; i<m_dat; ++i ){ 282*5ddc57e5SXin Li ff = f(tx[i], tz[i], par); 283*5ddc57e5SXin Li printf( " t[%2d]=%12g,%12g y=%12g fit=%12g residue=%12g\n", 284*5ddc57e5SXin Li i, tx[i], tz[i], y[i], ff, y[i] - ff ); 285*5ddc57e5SXin Li } 286*5ddc57e5SXin Li 287*5ddc57e5SXin Li return 0; 288*5ddc57e5SXin Li }</code></pre> 289*5ddc57e5SXin Li 290*5ddc57e5SXin Li<h2 id="More-examples">More examples</h2> 291*5ddc57e5SXin Li 292*5ddc57e5SXin Li<p>For more examples, see the homepage and directories demo/ and test/ in the source distribution.</p> 293*5ddc57e5SXin Li 294*5ddc57e5SXin Li<h1 id="COPYING">COPYING</h1> 295*5ddc57e5SXin Li 296*5ddc57e5SXin Li<p>Copyright (C): 1980-1999 University of Chicago 2004-2015 Joachim Wuttke, Forschungszentrum Juelich GmbH</p> 297*5ddc57e5SXin Li 298*5ddc57e5SXin Li<p>Software: FreeBSD License</p> 299*5ddc57e5SXin Li 300*5ddc57e5SXin Li<p>Documentation: Creative Commons Attribution Share Alike</p> 301*5ddc57e5SXin Li 302*5ddc57e5SXin Li<h1 id="SEE-ALSO">SEE ALSO</h1> 303*5ddc57e5SXin Li 304*5ddc57e5SXin Li 305*5ddc57e5SXin Li 306*5ddc57e5SXin Li<a href="http://apps.jcns.fz-juelich.de/man/lmcurve.html"><b>lmcurve</b>(3)</a> 307*5ddc57e5SXin Li 308*5ddc57e5SXin Li<p>Homepage: http://apps.jcns.fz-juelich.de/lmfit</p> 309*5ddc57e5SXin Li 310*5ddc57e5SXin Li<h1 id="BUGS">BUGS</h1> 311*5ddc57e5SXin Li 312*5ddc57e5SXin Li<p>Please send bug reports and suggestions to the author <[email protected]>.</p> 313*5ddc57e5SXin Li 314*5ddc57e5SXin Li 315*5ddc57e5SXin Li</body> 316*5ddc57e5SXin Li 317*5ddc57e5SXin Li</html> 318*5ddc57e5SXin Li 319*5ddc57e5SXin Li 320