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