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