35 #define LM_MACHEP 1.2e-16
36 #define LM_DWARF 1.0e-38
37 #define LM_SQRT_DWARF 3.834e-20
38 #define LM_SQRT_GIANT 1.304e19
39 #define LM_USERTOL 1.e-14
44 const void *,
const double *fvec,
45 int printflags,
int iflag,
int iter,
int nfev)
60 if ( printflags & 1 ) {
63 printf(
"trying step in gradient direction ");
64 }
else if ( iflag == 1 ) {
65 printf(
"determining gradient (iteration %2d)", iter);
66 }
else if ( iflag == 0 ) {
67 printf(
"starting minimization ");
68 }
else if ( iflag == -1 ) {
69 printf(
"terminated after %3d evaluations ", nfev);
73 if ( printflags & 2 ) {
75 for ( i = 0; i < n_par; ++i ) {
76 printf(
" %18.11g", par[i]);
78 printf(
" => norm: %18.11g",
lm_enorm(m_dat, fvec));
81 if ( printflags & 3 ) {
85 if ( (printflags & 8) || ((printflags & 4) && iflag == -1) ) {
86 printf(
" residuals:\n");
87 for ( i = 0; i < m_dat; ++i ) {
88 printf(
" fvec[%2d]=%12g\n", i, fvec[i] );
96 void lmmin(
int n_par,
double *par,
int m_dat,
const void *
data,
97 void (*evaluate) (
const double *par,
int m_dat,
const void *data,
98 double *fvec,
int *
info),
100 void (*printout) (
int n_par,
const double *par,
int m_dat,
101 const void *data,
const double *fvec,
102 int printflags,
int iflag,
int iter,
int nfev) )
110 double *fvec, *diag, *fjac, *qtf, *wa1, *wa2, *wa3, *wa4;
117 fvec =
new double[m];
118 diag =
new double[n];
120 fjac =
new double[n*m];
127 catch (
const std::bad_alloc &) {
133 for (
int j=0; j<n_par; ++j ) {
146 &(status->
nfev), fjac, ipvt, qtf, wa1, wa2, wa3, wa4,
147 evaluate, printout, control->
printflags, data );
150 (*printout)( n, par, m,
data, fvec,
154 if ( status->
info < 0 ) {
174 void lm_lmpar(
int n,
double *r,
int ldr,
int *ipvt,
double *diag,
175 double *qtb,
double delta,
double *par,
double *
x,
176 double *sdiag,
double *aux,
double *xdi );
177 void lm_qrfac(
int m,
int n,
double *
a,
int pivot,
int *ipvt,
178 double *rdiag,
double *acnorm,
double *wa );
179 void lm_qrsolv(
int n,
double *r,
int ldr,
int *ipvt,
double *diag,
180 double *qtb,
double *
x,
double *sdiag,
double *wa );
182 #define MIN(a,b) (((a)<=(b)) ? (a) : (b))
183 #define MAX(a,b) (((a)>=(b)) ? (a) : (b))
184 #define SQR(x) (x)*(x)
187 void lm_lmdif(
int m,
int n,
double *
x,
double *fvec,
double ftol,
188 double xtol,
double gtol,
int maxfev,
double epsfcn,
189 double *diag,
int mode,
double factor,
int *info,
int *nfev,
190 double *fjac,
int *ipvt,
double *qtf,
double *wa1,
191 double *wa2,
double *wa3,
double *wa4,
192 void (*evaluate) (
const double *par,
int m_dat,
const void *data,
193 double *fvec,
int *info),
194 void (*printout) (
int n_par,
const double *par,
int m_dat,
195 const void *data,
const double *fvec,
196 int printflags,
int iflag,
int iter,
int nfev),
197 int printflags,
const void *data )
351 double actred, delta, dirder, eps, fnorm, fnorm1, par, pnorm,
352 prered, ratio, step,
sum, temp, temp1, temp2, temp3, xnorm;
353 static double p1 = 0.1;
354 static double p0001 = 1.0e-4;
366 if ( (n <= 0) || (m < n) || (ftol < 0.)
367 || (xtol < 0.) || (gtol < 0.) || (maxfev <= 0) || (factor <= 0.) ) {
372 for ( j = 0; j < n; j++ ) {
373 if ( diag[j] <= 0.0 ) {
379 #ifdef LMFIT_DEBUG_MESSAGES
389 (*printout) (n,
x, m,
data, fvec, printflags, 0, 0, *nfev);
403 #ifdef LMFIT_DEBUG_MESSAGES
404 printf(
"lmdif/ outer loop iter=%d nfev=%d fnorm=%.10e\n",
410 for ( j = 0; j < n; j++ ) {
412 step =
MAX(eps*eps, eps * fabs(temp));
418 (*printout) (n,
x, m,
data, wa4, printflags, 1, iter, *nfev);
423 for ( i = 0; i < m; i++ ) {
424 fjac[j*m+i] = (wa4[i] - fvec[i]) / step;
428 #ifdef LMFIT_DEBUG_MATRIX
430 for (i = 0; i < m; i++) {
431 for (j = 0; j < n; j++)
432 printf(
"%.5e ", fjac[j*m+i]);
439 lm_qrfac(m, n, fjac, 1, ipvt, wa1, wa2, wa3);
446 for ( j = 0; j < n; j++ ) {
448 if ( wa2[j] == 0. ) {
454 for ( j = 0; j < n; j++ ) {
455 wa3[j] = diag[j] * x[j];
459 delta = factor * xnorm;
465 for ( j = 0; j < n; j++ ) {
466 diag[j] =
MAX( diag[j], wa2[j] );
473 for ( i = 0; i < m; i++ ) {
477 for ( j = 0; j < n; j++ ) {
481 for ( i = j; i < m; i++ ) {
482 sum += fjac[j*m+i] * wa4[i];
485 for ( i = j; i < m; i++ ) {
486 wa4[i] += fjac[j*m+i] * temp;
489 fjac[j*m+j] = wa1[j];
496 for ( j = 0; j < n; j++ ) {
497 if ( wa2[ipvt[j]] == 0 ) {
501 for ( i = 0; i <= j; i++ ) {
502 sum += fjac[j*m+i] * qtf[i];
504 gnorm =
MAX( gnorm, fabs( sum / wa2[ipvt[j]] / fnorm ) );
507 if ( gnorm <= gtol ) {
514 #ifdef LMFIT_DEBUG_MESSAGES
515 printf(
"lmdif/ inner loop iter=%d nfev=%d\n", iter, *nfev);
520 lm_lmpar( n, fjac, m, ipvt, diag, qtf, delta, &par,
521 wa1, wa2, wa4, wa3 );
524 for ( j = 0; j < n; j++ ) {
525 wa2[j] = x[j] - wa1[j];
532 if ( *nfev <= 1+n ) {
533 delta =
MIN(delta, pnorm);
539 (*evaluate) (wa2, m,
data, wa4,
info);
542 (*printout) (n, wa2, m,
data, wa4, printflags, 2, iter, *nfev);
549 #ifdef LMFIT_DEBUG_MESSAGES
550 printf(
"lmdif/ pnorm %.10e fnorm1 %.10e fnorm %.10e"
551 " delta=%.10e par=%.10e\n",
552 pnorm, fnorm1, fnorm, delta, par);
557 if ( p1 * fnorm1 < fnorm ) {
558 actred = 1 -
SQR(fnorm1 / fnorm);
566 for ( j = 0; j < n; j++ ) {
568 for ( i = 0; i <= j; i++ ) {
569 wa3[i] -= fjac[j*m+i] * wa1[ipvt[j]];
573 temp2 = sqrt(par) * pnorm / fnorm;
574 prered =
SQR(temp1) + 2 *
SQR(temp2);
575 dirder = -(
SQR(temp1) +
SQR(temp2));
579 ratio = prered != 0 ? actred / prered : 0;
580 #ifdef LMFIT_DEBUG_MESSAGES
581 printf(
"lmdif/ actred=%.10e prered=%.10e ratio=%.10e"
582 " sq(1)=%.10e sq(2)=%.10e dd=%.10e\n",
583 actred, prered, prered != 0 ? ratio : 0.,
584 SQR(temp1),
SQR(temp2), dirder);
589 if ( ratio <= 0.25 ) {
590 if ( actred >= 0. ) {
593 temp = 0.5 * dirder / (dirder + 0.55 * actred);
595 if ( p1 * fnorm1 >= fnorm || temp < p1 ) {
598 delta = temp *
MIN(delta, pnorm / p1);
600 }
else if ( par == 0. || ratio >= 0.75 ) {
607 if ( ratio >= p0001 ) {
609 for ( j = 0; j < n; j++ ) {
611 wa2[j] = diag[j] * x[j];
613 for ( i = 0; i < m; i++ ) {
620 #ifdef LMFIT_DEBUG_MESSAGES
622 printf(
"ATTN: iteration considered unsuccessful\n");
634 if ( fabs(actred) <= ftol && prered <= ftol && 0.5 * ratio <= 1 ) {
637 if ( delta <= xtol * xnorm ) {
646 if ( *nfev >= maxfev ) {
651 prered <=
LM_MACHEP && 0.5 * ratio <= 1 ) {
666 }
while (ratio < p0001);
677 void lm_lmpar(
int n,
double *r,
int ldr,
int *ipvt,
double *diag,
678 double *qtb,
double delta,
double *par,
double *x,
679 double *sdiag,
double *aux,
double *xdi)
753 int i, iter, j, nsing;
754 double dxnorm, fp, gnorm, parl, paru;
756 static double p1 = 0.1;
758 #ifdef LMFIT_DEBUG_MESSAGES
766 for ( j = 0; j < n; j++ ) {
768 if ( r[j * ldr + j] == 0 && nsing == n ) {
775 #ifdef LMFIT_DEBUG_MESSAGES
776 printf(
"nsing %d ", nsing);
778 for ( j = nsing - 1; j >= 0; j-- ) {
779 aux[j] = aux[j] / r[j + ldr * j];
781 for ( i = 0; i < j; i++ ) {
782 aux[i] -= r[j * ldr + i] * temp;
786 for ( j = 0; j < n; j++ ) {
794 for ( j = 0; j < n; j++ ) {
795 xdi[j] = diag[j] * x[j];
799 if ( fp <= p1 * delta ) {
800 #ifdef LMFIT_DEBUG_MESSAGES
801 printf(
"lmpar/ terminate (fp<p1*delta)\n");
813 for ( j = 0; j < n; j++ ) {
814 aux[j] = diag[ipvt[j]] * xdi[ipvt[j]] / dxnorm;
817 for ( j = 0; j < n; j++ ) {
819 for ( i = 0; i < j; i++ ) {
820 sum += r[j * ldr + i] * aux[i];
822 aux[j] = (aux[j] -
sum) / r[j + ldr * j];
825 parl = fp / delta / temp / temp;
830 for ( j = 0; j < n; j++ ) {
832 for ( i = 0; i <= j; i++ ) {
833 sum += r[j * ldr + i] * qtb[i];
835 aux[j] = sum / diag[ipvt[j]];
838 paru = gnorm / delta;
846 *par =
MAX(*par, parl);
847 *par =
MIN(*par, paru);
849 *par = gnorm / dxnorm;
851 #ifdef LMFIT_DEBUG_MESSAGES
852 printf(
"lmpar/ parl %.4e par %.4e paru %.4e\n", parl, *par, paru);
865 for ( j = 0; j < n; j++ ) {
866 aux[j] = temp * diag[j];
869 lm_qrsolv( n, r, ldr, ipvt, aux, qtb, x, sdiag, xdi );
872 for ( j = 0; j < n; j++ ) {
873 xdi[j] = diag[j] * x[j];
883 if ( fabs(fp) <= p1 * delta
884 || (parl == 0. && fp <= fp_old && fp_old < 0.)
891 for ( j = 0; j < n; j++ ) {
892 aux[j] = diag[ipvt[j]] * xdi[ipvt[j]] / dxnorm;
895 for ( j = 0; j < n; j++ ) {
896 aux[j] = aux[j] / sdiag[j];
897 for ( i = j + 1; i < n; i++ ) {
898 aux[i] -= r[j * ldr + i] * aux[j];
902 double parc = fp / delta / temp / temp;
907 parl =
MAX(parl, *par);
908 }
else if ( fp < 0 ) {
909 paru =
MIN(paru, *par);
915 *par =
MAX(parl, *par + parc);
924 void lm_qrfac(
int m,
int n,
double *
a,
int pivot,
int *ipvt,
925 double *rdiag,
double *acnorm,
double *wa)
978 int i, j, k, kmax, minmn;
979 double ajnorm,
sum, temp;
983 for ( j = 0; j < n; j++ ) {
985 rdiag[j] = acnorm[j];
991 #ifdef LMFIT_DEBUG_MESSAGES
998 for ( j = 0; j < minmn; j++ ) {
1006 for ( k = j + 1; k < n; k++ ) {
1007 if ( rdiag[k] > rdiag[kmax] ) {
1015 for ( i = 0; i < m; i++ ) {
1017 a[j*m+i] = a[kmax*m+i];
1020 rdiag[kmax] = rdiag[j];
1023 ipvt[j] = ipvt[kmax];
1031 if ( ajnorm == 0. ) {
1036 if ( a[j*m+j] < 0. ) {
1039 for ( i = j; i < m; i++ ) {
1047 for ( k = j + 1; k < n; k++ ) {
1050 for ( i = j; i < m; i++ ) {
1051 sum += a[j*m+i] * a[k*m+i];
1054 temp = sum / a[j + m * j];
1056 for ( i = j; i < m; i++ ) {
1057 a[k*m+i] -= temp * a[j*m+i];
1060 if ( pivot && rdiag[k] != 0. ) {
1061 temp = a[m * k + j] / rdiag[k];
1062 temp =
MAX(0., 1 - temp * temp);
1063 rdiag[k] *= sqrt(temp);
1064 temp = rdiag[k] / wa[k];
1066 rdiag[k] =
lm_enorm(m-j-1, &a[m*k+j+1]);
1078 void lm_qrsolv(
int n,
double *r,
int ldr,
int *ipvt,
double *diag,
1079 double *qtb,
double *x,
double *sdiag,
double *wa)
1142 int i, kk, j, k, nsing;
1143 double qtbpj,
sum, temp;
1144 double _sin, _cos, _tan, _cot;
1149 for ( j = 0; j < n; j++ ) {
1150 for ( i = j; i < n; i++ ) {
1151 r[j * ldr + i] = r[i * ldr + j];
1153 x[j] = r[j * ldr + j];
1156 #ifdef LMFIT_DEBUG_MESSAGES
1162 for ( j = 0; j < n; j++ ) {
1167 if ( diag[ipvt[j]] == 0. ) {
1170 for ( k = j; k < n; k++ ) {
1173 sdiag[j] = diag[ipvt[j]];
1179 for ( k = j; k < n; k++ ) {
1184 if ( sdiag[k] == 0. ) {
1188 if ( fabs(r[kk]) < fabs(sdiag[k]) ) {
1189 _cot = r[kk] / sdiag[k];
1190 _sin = 1 / sqrt(1 +
SQR(_cot));
1193 _tan = sdiag[k] / r[kk];
1194 _cos = 1 / sqrt(1 +
SQR(_tan));
1201 r[kk] = _cos * r[kk] + _sin * sdiag[k];
1202 temp = _cos * wa[k] + _sin * qtbpj;
1203 qtbpj = -_sin * wa[k] + _cos * qtbpj;
1208 for ( i = k + 1; i < n; i++ ) {
1209 temp = _cos * r[k * ldr + i] + _sin * sdiag[i];
1210 sdiag[i] = -_sin * r[k * ldr + i] + _cos * sdiag[i];
1211 r[k * ldr + i] = temp;
1219 sdiag[j] = r[j * ldr + j];
1220 r[j * ldr + j] = x[j];
1227 for ( j = 0; j < n; j++ ) {
1228 if ( sdiag[j] == 0. && nsing == n ) {
1236 for ( j = nsing - 1; j >= 0; j-- ) {
1238 for ( i = j + 1; i < nsing; i++ ) {
1239 sum += r[j * ldr + i] * wa[i];
1241 wa[j] = (wa[j] -
sum) / sdiag[j];
1246 for ( j = 0; j < n; j++ ) {
1278 double agiant, s1, s2, s3, x1max, x3max, temp;
1289 for ( i = 0; i < n; i++ ) {
1290 double xabs = fabs(x[i]);
1292 if ( xabs < agiant ) {
1294 }
else if ( xabs > x1max ) {
1295 temp = x1max / xabs;
1296 s1 = 1 + s1 *
SQR(temp);
1299 temp = xabs / x1max;
1302 }
else if ( xabs > x3max ) {
1303 temp = x3max / xabs;
1304 s3 = 1 + s3 *
SQR(temp);
1306 }
else if ( xabs != 0. ) {
1307 temp = xabs / x3max;
1315 return x1max * sqrt(s1 + (s2 / x1max) / x1max);
1316 }
else if ( s2 != 0 ) {
1317 if ( s2 >= x3max ) {
1318 return sqrt(s2 * (1 + (x3max / s2) * (x3max * s3)));
1320 return sqrt(x3max * ((s2 / x3max) + (x3max * s3)));
1323 return x3max * sqrt(s3);
void lm_lmpar(int n, double *r, int ldr, int *ipvt, double *diag, double *qtb, double delta, double *par, double *x, double *sdiag, double *aux, double *xdi)
static void info(const char *fmt,...)
double lm_enorm(int n, const double *x)
void lm_qrfac(int m, int n, double *a, int pivot, int *ipvt, double *rdiag, double *acnorm, double *wa)
void lmmin(int n_par, double *par, int m_dat, const void *data, void(*evaluate)(const double *par, int m_dat, const void *data, double *fvec, int *info), lm_status_struct *status, void(*printout)(int n_par, const double *par, int m_dat, const void *data, const double *fvec, int printflags, int iflag, int iter, int nfev))
void lm_qrsolv(int n, double *r, int ldr, int *ipvt, double *diag, double *qtb, double *x, double *sdiag, double *wa)
double sum(InputIterator first, InputIterator last)
Returns the sum of all elements on the range [first, last)
void lm_printout_std(int n_par, const double *par, int m_dat, const void *, const double *fvec, int printflags, int iflag, int iter, int nfev)
void lm_lmdif(int m, int n, double *x, double *fvec, double ftol, double xtol, double gtol, int maxfev, double epsfcn, double *diag, int mode, double factor, int *info, int *nfev, double *fjac, int *ipvt, double *qtf, double *wa1, double *wa2, double *wa3, double *wa4, void(*evaluate)(const double *par, int m_dat, const void *data, double *fvec, int *info), void(*printout)(int n_par, const double *par, int m_dat, const void *data, const double *fvec, int printflags, int iflag, int iter, int nfev), int printflags, const void *data)