xref: /aosp_15_r20/external/lmfit/man/lmmin.html (revision 5ddc57e5d924f146ab5fd87df586563e2270da38)
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 &lt;lmmin.h</b>&gt;</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> &lt;= <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 &amp;<i>lm_control_double</i> is adequate. If <i>f</i> is only computed with single-precision accuracy, <i>&amp;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 &quot;lmmin.h&quot;
216*5ddc57e5SXin Li    #include &lt;stdio.h&gt;
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 &lt; m_dat; i++ )
241*5ddc57e5SXin Li        fvec[i] = D-&gt;y[i] - D-&gt;f( D-&gt;tx[i], D-&gt;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( &quot;Fitting:\n&quot; );
265*5ddc57e5SXin Li        lmmin( n_par, par, m_dat, (const void*) &amp;data, evaluate_surface,
266*5ddc57e5SXin Li               &amp;control, &amp;status );
267*5ddc57e5SXin Li
268*5ddc57e5SXin Li        /* print results */
269*5ddc57e5SXin Li        printf( &quot;\nResults:\n&quot; );
270*5ddc57e5SXin Li        printf( &quot;status after %d function evaluations:\n  %s\n&quot;,
271*5ddc57e5SXin Li                status.nfev, lm_infmsg[status.outcome] );
272*5ddc57e5SXin Li
273*5ddc57e5SXin Li        printf(&quot;obtained parameters:\n&quot;);
274*5ddc57e5SXin Li        int i;
275*5ddc57e5SXin Li        for ( i=0; i&lt;n_par; ++i )
276*5ddc57e5SXin Li        printf(&quot;  par[%i] = %12g\n&quot;, i, par[i]);
277*5ddc57e5SXin Li        printf(&quot;obtained norm:\n  %12g\n&quot;, status.fnorm );
278*5ddc57e5SXin Li
279*5ddc57e5SXin Li        printf(&quot;fitting data as follows:\n&quot;);
280*5ddc57e5SXin Li        double ff;
281*5ddc57e5SXin Li        for ( i=0; i&lt;m_dat; ++i ){
282*5ddc57e5SXin Li            ff = f(tx[i], tz[i], par);
283*5ddc57e5SXin Li            printf( &quot;  t[%2d]=%12g,%12g y=%12g fit=%12g residue=%12g\n&quot;,
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 &lt;[email protected]&gt;.</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