45 #include <visp3/core/vpMath.h> 46 #include <visp3/vision/vpLevenbergMarquartd.h> 48 #define SIGN(x) ((x) < 0 ? -1 : 1) 49 #define SWAP(a, b, c) \ 55 #define MIJ(m, i, j, s) ((m) + ((long)(i) * (long)(s)) + (long)(j)) 86 double enorm(
const double *x,
int n)
88 const double rdwarf = 3.834e-20;
89 const double rgiant = 1.304e19;
92 double agiant, floatn;
93 double norm_eucl = 0.0;
94 double s1 = 0.0, s2 = 0.0, s3 = 0.0;
95 double x1max = 0.0, x3max = 0.0;
98 agiant = rgiant / floatn;
100 for (i = 0; i < n; i++) {
101 double xabs = std::fabs(x[i]);
102 if ((xabs > rdwarf) && (xabs < agiant)) {
109 else if (xabs <= rdwarf) {
115 if (xabs > std::numeric_limits<double>::epsilon())
116 s3 += (xabs / x3max) * (xabs / x3max);
118 s3 = 1.0 + s3 * (x3max / xabs) * (x3max / xabs);
128 s1 += (xabs / x1max) * (xabs / x1max);
130 s1 = 1.0 + s1 * (x1max / xabs) * (x1max / xabs);
140 if (std::fabs(s1) <= std::numeric_limits<double>::epsilon()) {
142 if (std::fabs(s2) <= std::numeric_limits<double>::epsilon())
143 norm_eucl = x3max * sqrt(s3);
144 else if (s2 >= x3max)
145 norm_eucl = sqrt(s2 * (1.0 + (x3max / s2) * (x3max * s3)));
147 norm_eucl = sqrt(x3max * ((s2 / x3max) + (x3max * s3)));
149 norm_eucl = x1max * sqrt(s1 + (s2 / x1max) / x1max);
226 int lmpar(
int n,
double *r,
int ldr,
int *ipvt,
double *diag,
double *qtb,
double *delta,
double *par,
double *x,
227 double *sdiag,
double *wa1,
double *wa2)
229 const double tol1 = 0.1;
236 double dwarf = DBL_MIN;
245 for (
int i = 0; i < n; i++) {
247 double *pt = MIJ(r, i, i, ldr);
249 if (std::fabs(*pt) <= std::numeric_limits<double>::epsilon() && nsing == n)
257 for (
int k = 0; k < nsing; k++) {
258 int i = nsing - 1 - k;
259 wa1[i] /= *MIJ(r, i, i, ldr);
264 for (
unsigned int j = 0; j <= (
unsigned int)jm1; j++)
265 wa1[j] -= *MIJ(r, i, j, ldr) * temp;
270 for (
int j = 0; j < n; j++) {
282 for (
int i = 0; i < n; i++)
283 wa2[i] = diag[i] * x[i];
285 dxnorm = enorm(wa2, n);
287 fp = dxnorm - *delta;
289 if (fp > tol1 * (*delta)) {
298 for (
int i = 0; i < n; i++) {
300 wa1[i] = diag[l] * (wa2[l] / dxnorm);
303 for (
int i = 0; i < n; i++) {
309 for (
unsigned int j = 0; j <= (
unsigned int)im1; j++)
310 sum += (*MIJ(r, i, j, ldr) * wa1[j]);
312 wa1[i] = (wa1[i] - sum) / *MIJ(r, i, i, ldr);
315 temp = enorm(wa1, n);
316 parl = ((fp / *delta) / temp) / temp;
323 for (
int i = 0; i < n; i++) {
326 for (
int j = 0; j <= i; j++)
327 sum += *MIJ(r, i, j, ldr) * qtb[j];
330 wa1[i] = sum / diag[l];
333 double gnorm = enorm(wa1, n);
334 double paru = gnorm / *delta;
337 if (std::fabs(paru) <= std::numeric_limits<double>::epsilon())
349 if (std::fabs(*par) <= std::numeric_limits<double>::epsilon())
350 *par = gnorm / dxnorm;
364 if (std::fabs(*par) <= std::numeric_limits<double>::epsilon()) {
365 const double tol001 = 0.001;
371 for (
int i = 0; i < n; i++)
372 wa1[i] = temp * diag[i];
374 qrsolv(n, r, ldr, ipvt, wa1, qtb, x, sdiag, wa2);
376 for (
int i = 0; i < n; i++)
377 wa2[i] = diag[i] * x[i];
379 dxnorm = enorm(wa2, n);
381 fp = dxnorm - *delta;
392 if ((std::fabs(fp) <= tol1 * (*delta)) ||
393 ((std::fabs(parl) <= std::numeric_limits<double>::epsilon()) && (fp <= temp) && (temp < 0.0)) ||
408 for (
int i = 0; i < n; i++) {
410 wa1[i] = diag[l] * (wa2[l] / dxnorm);
413 for (
unsigned int i = 0; i < (
unsigned int)n; i++) {
414 wa1[i] = wa1[i] / sdiag[i];
416 unsigned int jp1 = i + 1;
417 if ((
unsigned int)n >= jp1) {
418 for (
unsigned int j = jp1; j < (
unsigned int)n; j++)
419 wa1[j] -= (*MIJ(r, i, j, ldr) * temp);
423 temp = enorm(wa1, n);
424 double parc = ((fp / *delta) / temp) / temp;
466 double pythag(
double a,
double b)
468 double pyth, p, r, t;
473 if (std::fabs(p) <= std::numeric_limits<double>::epsilon()) {
478 r = ((std::min)(std::fabs(a), std::fabs(b)) / p) * ((std::min)(std::fabs(a), std::fabs(b)) / p);
482 while (std::fabs(t - 4.0) < std::fabs(
vpMath::maximum(t, 4.0)) * std::numeric_limits<double>::epsilon()) {
484 double u = 1.0 + 2.0 * s;
486 r *= (s / u) * (s / u);
539 int qrfac(
int m,
int n,
double *a,
int lda,
int *pivot,
int *ipvt,
int ,
double *rdiag,
double *acnorm,
542 const double tolerance = 0.05;
544 int i, j, ip1, k, kmax, minmn;
546 double sum, temp, tmp;
551 epsmch = std::numeric_limits<double>::epsilon();
557 for (i = 0; i < m; i++) {
558 acnorm[i] = enorm(MIJ(a, i, 0, lda), n);
559 rdiag[i] = acnorm[i];
569 for (i = 0; i < minmn; i++) {
576 for (k = i; k < m; k++) {
577 if (rdiag[k] > rdiag[kmax])
582 for (j = 0; j < n; j++)
583 SWAP(*MIJ(a, i, j, lda), *MIJ(a, kmax, j, lda), tmp);
585 rdiag[kmax] = rdiag[i];
588 SWAP(ipvt[i], ipvt[kmax], k);
596 double ajnorm = enorm(MIJ(a, i, i, lda), n - i);
599 if (std::fabs(ajnorm) > std::numeric_limits<double>::epsilon()) {
600 if (*MIJ(a, i, i, lda) < 0.0)
603 for (j = i; j < n; j++)
604 *MIJ(a, i, j, lda) /= ajnorm;
605 *MIJ(a, i, i, lda) += 1.0;
614 for (k = ip1; k < m; k++) {
616 for (j = i; j < n; j++)
617 sum += *MIJ(a, i, j, lda) * *MIJ(a, k, j, lda);
619 temp = sum / *MIJ(a, i, i, lda);
621 for (j = i; j < n; j++)
622 *MIJ(a, k, j, lda) -= temp * *MIJ(a, i, j, lda);
625 if (pivot && (std::fabs(rdiag[k]) > std::numeric_limits<double>::epsilon())) {
626 temp = *MIJ(a, k, i, lda) / rdiag[k];
629 if (tolerance * (rdiag[k] / wa[k]) * (rdiag[k] / wa[k]) <= epsmch) {
630 rdiag[k] = enorm(MIJ(a, k, ip1, lda), (n - 1 - (
int)i));
701 int qrsolv(
int n,
double *r,
int ldr,
int *ipvt,
double *diag,
double *qtb,
double *x,
double *sdiag,
double *wa)
705 double cosi, cotg, qtbpj, sinu, tg, temp;
712 for (i = 0; i < n; i++) {
713 for (j = i; j < n; j++)
714 *MIJ(r, i, j, ldr) = *MIJ(r, j, i, ldr);
716 x[i] = *MIJ(r, i, i, ldr);
725 for (i = 0; i < n; i++) {
734 if (std::fabs(diag[l]) > std::numeric_limits<double>::epsilon()) {
735 for (k = i; k < n; k++)
749 for (k = i; k < n; k++) {
757 if (std::fabs(sdiag[k]) > std::numeric_limits<double>::epsilon()) {
758 if (std::fabs(*MIJ(r, k, k, ldr)) >= std::fabs(sdiag[k])) {
759 tg = sdiag[k] / *MIJ(r, k, k, ldr);
760 cosi = 0.5 / sqrt(0.25 + 0.25 * (tg * tg));
763 cotg = *MIJ(r, k, k, ldr) / sdiag[k];
764 sinu = 0.5 / sqrt(0.25 + 0.25 * (cotg * cotg));
773 *MIJ(r, k, k, ldr) = cosi * *MIJ(r, k, k, ldr) + sinu * sdiag[k];
774 temp = cosi * wa[k] + sinu * qtbpj;
775 qtbpj = -sinu * wa[k] + cosi * qtbpj;
786 for (j = kp1; j < n; j++) {
787 temp = cosi * *MIJ(r, k, j, ldr) + sinu * sdiag[j];
788 sdiag[j] = -sinu * *MIJ(r, k, j, ldr) + cosi * sdiag[j];
789 *MIJ(r, k, j, ldr) = temp;
800 sdiag[i] = *MIJ(r, i, i, ldr);
801 *MIJ(r, i, i, ldr) = x[i];
810 for (i = 0; i < n; i++) {
812 if ((std::fabs(sdiag[i]) <= std::numeric_limits<double>::epsilon()) && nsing == n)
820 for (k = 0; k < nsing; k++) {
826 for (j = jp1; j < nsing; j++)
827 sum += *MIJ(r, i, j, ldr) * wa[j];
829 wa[i] = (wa[i] - sum) / sdiag[i];
836 for (j = 0; j < n; j++) {
949 int lmder(
void (*ptr_fcn)(
int m,
int n,
double *xc,
double *fvecc,
double *jac,
int ldfjac,
int iflag),
int m,
int n,
950 double *x,
double *fvec,
double *fjac,
int ldfjac,
double ftol,
double xtol,
double gtol,
unsigned int maxfev,
951 double *diag,
int mode,
const double factor,
int nprint,
int *info,
unsigned int *nfev,
int *njev,
int *ipvt,
952 double *qtf,
double *wa1,
double *wa2,
double *wa3,
double *wa4)
954 const double tol1 = 0.1, tol5 = 0.5, tol25 = 0.25, tol75 = 0.75, tol0001 = 0.0001;
959 double actred, delta, dirder, epsmch, fnorm, fnorm1;
960 double ratio = std::numeric_limits<double>::epsilon();
961 double par, pnorm, prered;
962 double sum, temp, temp1, temp2, xnorm = 0.0;
965 epsmch = std::numeric_limits<double>::epsilon();
990 if ((n <= 0) || (m < n) || (ldfjac < m) || (ftol < 0.0) || (xtol < 0.0) || (gtol < 0.0) || (maxfev == 0) ||
1001 (*ptr_fcn)(m, n, x, fvec, fjac, ldfjac, iflag);
1007 for (j = 0; j < n; j++) {
1008 if (diag[j] <= 0.0) {
1018 (*ptr_fcn)(m, n, x, fvec, fjac, ldfjac, iflag);
1031 (*ptr_fcn)(m, n, x, fvec, fjac, ldfjac, iflag);
1045 (*ptr_fcn)(m, n, x, fvec, fjac, ldfjac, iflag);
1050 fnorm = enorm(fvec, m);
1063 while (count < (
int)maxfev) {
1071 (*ptr_fcn)(m, n, x, fvec, fjac, ldfjac, iflag);
1085 (*ptr_fcn)(m, n, x, fvec, fjac, ldfjac, iflag);
1095 if ((iter - 1) % nprint == 0)
1096 (*ptr_fcn)(m, n, x, fvec, fjac, ldfjac, iflag);
1108 (*ptr_fcn)(m, n, x, fvec, fjac, ldfjac, iflag);
1117 qrfac(n, m, fjac, ldfjac, &oncol, ipvt, n, wa1, wa2, wa3);
1126 for (j = 0; j < n; j++) {
1129 if (std::fabs(wa2[j]) <= std::numeric_limits<double>::epsilon())
1140 for (j = 0; j < n; j++)
1141 wa3[j] = diag[j] * x[j];
1143 xnorm = enorm(wa3, n);
1144 delta = factor * xnorm;
1147 if (std::fabs(delta) <= std::numeric_limits<double>::epsilon())
1155 for (i = 0; i < m; i++)
1158 for (i = 0; i < n; i++) {
1159 double *pt = MIJ(fjac, i, i, ldfjac);
1161 if (std::fabs(*pt) > std::numeric_limits<double>::epsilon()) {
1164 for (j = i; j < m; j++)
1165 sum += *MIJ(fjac, i, j, ldfjac) * wa4[j];
1167 temp = -sum / *MIJ(fjac, i, i, ldfjac);
1169 for (j = i; j < m; j++)
1170 wa4[j] += *MIJ(fjac, i, j, ldfjac) * temp;
1173 *MIJ(fjac, i, i, ldfjac) = wa1[i];
1184 if (std::fabs(fnorm) > std::numeric_limits<double>::epsilon()) {
1185 for (i = 0; i < n; i++) {
1188 if (std::fabs(wa2[l]) > std::numeric_limits<double>::epsilon()) {
1190 for (j = 0; j <= i; j++)
1191 sum += *MIJ(fjac, i, j, ldfjac) * (qtf[j] / fnorm);
1215 (*ptr_fcn)(m, n, x, fvec, fjac, ldfjac, iflag);
1225 for (j = 0; j < n; j++)
1233 while (ratio < tol0001) {
1238 lmpar(n, fjac, ldfjac, ipvt, diag, qtf, &delta, &par, wa1, wa2, wa3, wa4);
1244 for (j = 0; j < n; j++) {
1246 wa2[j] = x[j] + wa1[j];
1247 wa3[j] = diag[j] * wa1[j];
1250 pnorm = enorm(wa3, n);
1265 (*ptr_fcn)(m, n, wa2, wa4, fjac, ldfjac, iflag);
1277 (*ptr_fcn)(m, n, x, fvec, fjac, ldfjac, iflag);
1282 fnorm1 = enorm(wa4, m);
1290 if ((tol1 * fnorm1) < fnorm)
1291 actred = 1.0 - ((fnorm1 / fnorm) * (fnorm1 / fnorm));
1298 for (i = 0; i < n; i++) {
1302 for (j = 0; j <= i; j++)
1303 wa3[j] += *MIJ(fjac, i, j, ldfjac) * temp;
1306 temp1 = enorm(wa3, n) / fnorm;
1307 temp2 = (sqrt(par) * pnorm) / fnorm;
1308 prered = (temp1 * temp1) + (temp2 * temp2) / tol5;
1309 dirder = -((temp1 * temp1) + (temp2 * temp2));
1318 if (std::fabs(prered) > std::numeric_limits<double>::epsilon())
1319 ratio = actred / prered;
1325 if (ratio > tol25) {
1327 if ((std::fabs(par) <= std::numeric_limits<double>::epsilon()) || (ratio <= tol75)) {
1328 delta = pnorm / tol5;
1336 temp = tol5 * dirder / (dirder + tol5 * actred);
1338 if ((tol1 * fnorm1 >= fnorm) || (temp < tol1))
1348 if (ratio >= tol0001) {
1354 for (j = 0; j < n; j++) {
1356 wa2[j] = diag[j] * x[j];
1359 for (i = 0; i < m; i++)
1362 xnorm = enorm(wa2, n);
1371 if ((std::fabs(actred) <= ftol) && (prered <= ftol) && (tol5 * ratio <= 1.0))
1374 if (delta <= xtol * xnorm)
1377 if ((std::fabs(actred) <= ftol) && (prered <= ftol) && (tol5 * ratio <= 1.0) && *info == 2)
1390 (*ptr_fcn)(m, n, x, fvec, fjac, ldfjac, iflag);
1399 if (*nfev >= maxfev)
1402 if ((std::fabs(actred) <= epsmch) && (prered <= epsmch) && (tol5 * ratio <= 1.0))
1405 if (delta <= epsmch * xnorm)
1408 if (gnorm <= epsmch)
1421 (*ptr_fcn)(m, n, x, fvec, fjac, ldfjac, iflag);
1511 int lmder1(
void (*ptr_fcn)(
int m,
int n,
double *xc,
double *fvecc,
double *jac,
int ldfjac,
int iflag),
int m,
int n,
1512 double *x,
double *fvec,
double *fjac,
int ldfjac,
double tol,
int *info,
int *ipvt,
int lwa,
double *wa)
1514 const double factor = 100.0;
1515 unsigned int maxfev, nfev;
1516 int mode, njev, nprint;
1517 double ftol, gtol, xtol;
1523 if ( (m < n) || (ldfjac < m) || (tol < 0.0) || (lwa < (5 * n + m))) {
1524 printf(
"%d %d %d %d \n", (m < n), (ldfjac < m), (tol < 0.0), (lwa < (5 * n + m)));
1530 maxfev = (
unsigned int)(100 * (n + 1));
1537 lmder(ptr_fcn, m, n, x, fvec, fjac, ldfjac, ftol, xtol, gtol, maxfev, wa, mode, factor, nprint, info, &nfev, &njev,
1538 ipvt, &wa[n], &wa[2 * n], &wa[3 * n], &wa[4 * n], &wa[5 * n]);
static Type maximum(const Type &a, const Type &b)
static Type minimum(const Type &a, const Type &b)