39 #include <visp3/core/vpMath.h>
40 #include "vpLevenbergMarquartd.h"
42 #define SIGN(x) ((x) < 0 ? -1 : 1)
43 #define SWAP(a, b, c) \
49 #define MIJ(m, i, j, s) ((m) + ((long)(i) * (long)(s)) + (long)(j))
55 double enorm(
const double *x,
int n)
57 const double rdwarf = 3.834e-20;
58 const double rgiant = 1.304e19;
61 double agiant, floatn;
62 double norm_eucl = 0.0;
63 double s1 = 0.0, s2 = 0.0, s3 = 0.0;
64 double x1max = 0.0, x3max = 0.0;
66 floatn =
static_cast<double>(n);
67 agiant = rgiant / floatn;
69 for (i = 0; i < n; ++i) {
70 double xabs = std::fabs(x[i]);
71 if ((xabs > rdwarf) && (xabs < agiant)) {
78 else if (xabs <= rdwarf) {
84 if (xabs > std::numeric_limits<double>::epsilon()) {
85 s3 += (xabs / x3max) * (xabs / x3max);
89 s3 = 1.0 + (s3 * (x3max / xabs) * (x3max / xabs));
99 s1 += (xabs / x1max) * (xabs / x1max);
102 s1 = 1.0 + (s1 * (x1max / xabs) * (x1max / xabs));
112 if (std::fabs(s1) <= std::numeric_limits<double>::epsilon()) {
114 if (std::fabs(s2) <= std::numeric_limits<double>::epsilon()) {
115 norm_eucl = x3max * sqrt(s3);
117 else if (s2 >= x3max) {
118 norm_eucl = sqrt(s2 * (1.0 + ((x3max / s2) * (x3max * s3))));
121 norm_eucl = sqrt(x3max * ((s2 / x3max) + (x3max * s3)));
125 norm_eucl = x1max * sqrt(s1 + ((s2 / x1max) / x1max));
131 int lmpar(
int n,
double *r,
int ldr,
int *ipvt,
double *diag,
double *qtb,
double *delta,
double *par,
double *x,
132 double *sdiag,
double *wa1,
double *wa2)
134 const double tol1 = 0.1;
141 double dwarf = DBL_MIN;
150 for (
int i = 0; i < n; ++i) {
152 double *pt = MIJ(r, i, i, ldr);
153 if ((std::fabs(*pt) <= std::numeric_limits<double>::epsilon()) && (nsing == n)) {
163 for (
int k = 0; k < nsing; ++k) {
164 int i = nsing - 1 - k;
165 wa1[i] /= *MIJ(r, i, i, ldr);
170 for (
unsigned int j = 0; j <= static_cast<unsigned int>(jm1); ++j) {
171 wa1[j] -= *MIJ(r, i, j, ldr) * temp;
177 for (
int j = 0; j < n; ++j) {
189 for (
int i = 0; i < n; ++i) {
190 wa2[i] = diag[i] * x[i];
193 dxnorm = enorm(wa2, n);
195 fp = dxnorm - *delta;
197 if (fp >(tol1 * (*delta))) {
206 for (
int i = 0; i < n; ++i) {
208 wa1[i] = diag[l] * (wa2[l] / dxnorm);
211 for (
int i = 0; i < n; ++i) {
217 for (
unsigned int j = 0; j <= static_cast<unsigned int>(im1); ++j) {
218 sum += (*MIJ(r, i, j, ldr) * wa1[j]);
221 wa1[i] = (wa1[i] - sum) / *MIJ(r, i, i, ldr);
224 temp = enorm(wa1, n);
225 parl = ((fp / *delta) / temp) / temp;
232 for (
int i = 0; i < n; ++i) {
235 for (
int j = 0; j <= i; ++j) {
236 sum += *MIJ(r, i, j, ldr) * qtb[j];
240 wa1[i] = sum / diag[l];
243 double gnorm = enorm(wa1, n);
244 double paru = gnorm / *delta;
247 if (std::fabs(paru) <= std::numeric_limits<double>::epsilon()) {
259 if (std::fabs(*par) <= std::numeric_limits<double>::epsilon()) {
260 *par = gnorm / dxnorm;
274 if (std::fabs(*par) <= std::numeric_limits<double>::epsilon()) {
275 const double tol001 = 0.001;
281 for (
int i = 0; i < n; ++i) {
282 wa1[i] = temp * diag[i];
285 qrsolv(n, r, ldr, ipvt, wa1, qtb, x, sdiag, wa2);
287 for (
int i = 0; i < n; ++i) {
288 wa2[i] = diag[i] * x[i];
291 dxnorm = enorm(wa2, n);
293 fp = dxnorm - *delta;
301 bool cond_part_1 = (std::fabs(fp) <= (tol1 * (*delta)));
302 bool cond_part_2 = (std::fabs(parl) <= std::numeric_limits<double>::epsilon()) && ((fp <= temp) && (temp < 0.0));
303 bool cond_part_3 = (iter == 10);
304 if (cond_part_1 || cond_part_2 || cond_part_3) {
314 for (
int i = 0; i < n; ++i) {
316 wa1[i] = diag[l] * (wa2[l] / dxnorm);
319 for (
unsigned int i = 0; i < static_cast<unsigned int>(n); ++i) {
320 wa1[i] = wa1[i] / sdiag[i];
322 unsigned int jp1 = i + 1;
323 if (
static_cast<unsigned int>(n) >= jp1) {
324 for (
unsigned int j = jp1; j < static_cast<unsigned int>(n); ++j) {
325 wa1[j] -= (*MIJ(r, i, j, ldr) * temp);
330 temp = enorm(wa1, n);
331 double parc = ((fp / *delta) / temp) / temp;
362 double pythag(
double a,
double b)
364 double pyth, p, r, t;
369 if (std::fabs(p) <= std::numeric_limits<double>::epsilon()) {
374 r = (std::min<double>(std::fabs(a), std::fabs(b)) / p) * (std::min<double>(std::fabs(a), std::fabs(b)) / p);
378 while (std::fabs(t - 4.0) < (std::fabs(
vpMath::maximum(t, 4.0)) * std::numeric_limits<double>::epsilon())) {
380 double u = 1.0 + (2.0 * s);
382 r *= (s / u) * (s / u);
390 int qrfac(
int m,
int n,
double *a,
int lda,
int *pivot,
int *ipvt,
int ,
double *rdiag,
double *acnorm,
393 const double tolerance = 0.05;
395 int i, j, ip1, k, kmax, minmn;
397 double sum, temp, tmp;
402 epsmch = std::numeric_limits<double>::epsilon();
408 for (i = 0; i < m; ++i) {
409 acnorm[i] = enorm(MIJ(a, i, 0, lda), n);
410 rdiag[i] = acnorm[i];
421 for (i = 0; i < minmn; ++i) {
428 for (k = i; k < m; ++k) {
429 if (rdiag[k] > rdiag[kmax]) {
435 for (j = 0; j < n; ++j) {
436 SWAP(*MIJ(a, i, j, lda), *MIJ(a, kmax, j, lda), tmp);
439 rdiag[kmax] = rdiag[i];
442 SWAP(ipvt[i], ipvt[kmax], k);
450 double ajnorm = enorm(MIJ(a, i, i, lda), n - i);
453 if (std::fabs(ajnorm) > std::numeric_limits<double>::epsilon()) {
454 if (*MIJ(a, i, i, lda) < 0.0) {
458 for (j = i; j < n; ++j) {
459 *MIJ(a, i, j, lda) /= ajnorm;
461 *MIJ(a, i, i, lda) += 1.0;
470 for (k = ip1; k < m; ++k) {
472 for (j = i; j < n; ++j) {
473 sum += *MIJ(a, i, j, lda) * *MIJ(a, k, j, lda);
476 temp = sum / *MIJ(a, i, i, lda);
478 for (j = i; j < n; ++j) {
479 *MIJ(a, k, j, lda) -= temp * *MIJ(a, i, j, lda);
482 if (pivot && (std::fabs(rdiag[k]) > std::numeric_limits<double>::epsilon())) {
483 temp = *MIJ(a, k, i, lda) / rdiag[k];
486 if ((tolerance * (rdiag[k] / wa[k]) * (rdiag[k] / wa[k])) <= epsmch) {
487 rdiag[k] = enorm(MIJ(a, k, ip1, lda), (n - 1 -
static_cast<int>(i)));
501 int qrsolv(
int n,
double *r,
int ldr,
int *ipvt,
double *diag,
double *qtb,
double *x,
double *sdiag,
double *wa)
505 double cosi, cotg, qtbpj, sinu, tg, temp;
512 for (i = 0; i < n; ++i) {
513 for (j = i; j < n; ++j) {
514 *MIJ(r, i, j, ldr) = *MIJ(r, j, i, ldr);
517 x[i] = *MIJ(r, i, i, ldr);
526 for (i = 0; i < n; ++i) {
534 if (std::fabs(diag[l]) > std::numeric_limits<double>::epsilon()) {
535 for (k = i; k < n; ++k) {
550 for (k = i; k < n; ++k) {
557 if (std::fabs(sdiag[k]) > std::numeric_limits<double>::epsilon()) {
558 if (std::fabs(*MIJ(r, k, k, ldr)) >= std::fabs(sdiag[k])) {
559 tg = sdiag[k] / *MIJ(r, k, k, ldr);
560 cosi = 0.5 / sqrt(0.25 + (0.25 * (tg * tg)));
564 cotg = *MIJ(r, k, k, ldr) / sdiag[k];
565 sinu = 0.5 / sqrt(0.25 + (0.25 * (cotg * cotg)));
574 *MIJ(r, k, k, ldr) = (cosi * *MIJ(r, k, k, ldr)) + (sinu * sdiag[k]);
575 temp = (cosi * wa[k]) + (sinu * qtbpj);
576 qtbpj = (-sinu * wa[k]) + (cosi * qtbpj);
587 for (j = kp1; j < n; ++j) {
588 temp = (cosi * *MIJ(r, k, j, ldr)) + (sinu * sdiag[j]);
589 sdiag[j] = (-sinu * *MIJ(r, k, j, ldr)) + (cosi * sdiag[j]);
590 *MIJ(r, k, j, ldr) = temp;
601 sdiag[i] = *MIJ(r, i, i, ldr);
602 *MIJ(r, i, i, ldr) = x[i];
611 for (i = 0; i < n; ++i) {
612 if ((std::fabs(sdiag[i]) <= std::numeric_limits<double>::epsilon()) && (nsing == n)) {
622 for (k = 0; k < nsing; ++k) {
628 for (j = jp1; j < nsing; ++j) {
629 sum += *MIJ(r, i, j, ldr) * wa[j];
632 wa[i] = (wa[i] - sum) / sdiag[i];
639 for (j = 0; j < n; ++j) {
646 bool lmderMostInnerLoop(ComputeFunctionAndJacobian ptr_fcn,
int m,
int n,
647 double *x,
double *fvec,
double *fjac,
int ldfjac,
double ftol,
double xtol,
unsigned int maxfev,
648 double *diag,
int nprint,
int *info,
unsigned int *nfev,
int *ipvt,
649 double *qtf,
double *wa1,
double *wa2,
double *wa3,
double *wa4,
const double &gnorm,
int &iter,
double &delta,
double &par,
double &pnorm,
650 int &iflag,
double &fnorm,
double &xnorm)
652 const double tol1 = 0.1, tol5 = 0.5, tol25 = 0.25, tol75 = 0.75, tol0001 = 0.0001;
654 const double epsmch = std::numeric_limits<double>::epsilon();
659 while (ratio < tol0001) {
664 lmpar(n, fjac, ldfjac, ipvt, diag, qtf, &delta, &par, wa1, wa2, wa3, wa4);
670 for (
int j = 0; j < n; ++j) {
672 wa2[j] = x[j] + wa1[j];
673 wa3[j] = diag[j] * wa1[j];
676 pnorm = enorm(wa3, n);
692 (*ptr_fcn)(m, n, wa2, wa4, fjac, ldfjac, iflag);
705 (*ptr_fcn)(m, n, x, fvec, fjac, ldfjac, iflag);
711 double fnorm1 = enorm(wa4, m);
717 double actred = -1.0;
719 if ((tol1 * fnorm1) < fnorm) {
720 actred = 1.0 - ((fnorm1 / fnorm) * (fnorm1 / fnorm));
728 for (
int i = 0; i < n; ++i) {
731 double temp = wa1[l];
732 for (
int j = 0; j <= i; ++j) {
733 wa3[j] += *MIJ(fjac, i, j, ldfjac) * temp;
737 double temp1 = enorm(wa3, n) / fnorm;
738 double temp2 = (sqrt(par) * pnorm) / fnorm;
739 double prered = (temp1 * temp1) + ((temp2 * temp2) / tol5);
740 double dirder = -((temp1 * temp1) + (temp2 * temp2));
749 if (std::fabs(prered) > std::numeric_limits<double>::epsilon()) {
750 ratio = actred / prered;
759 if ((std::fabs(par) <= std::numeric_limits<double>::epsilon()) || (ratio <= tol75)) {
760 delta = pnorm / tol5;
770 temp = (tol5 * dirder) / (dirder + (tol5 * actred));
773 if (((tol1 * fnorm1) >= fnorm) || (temp < tol1)) {
784 if (ratio >= tol0001) {
790 for (
int j = 0; j < n; ++j) {
792 wa2[j] = diag[j] * x[j];
795 for (
int i = 0; i < m; ++i) {
799 xnorm = enorm(wa2, n);
808 if ((std::fabs(actred) <= ftol) && (prered <= ftol) && ((tol5 * ratio) <= 1.0)) {
812 if (delta <= (xtol * xnorm)) {
813 const int flagInfo = 2;
818 if ((std::fabs(actred) <= ftol) && (prered <= ftol) && ((tol5 * ratio) <= 1.0) && (*info == info2)) {
819 const int flagInfo = 3;
834 (*ptr_fcn)(m, n, x, fvec, fjac, ldfjac, iflag);
844 if (*nfev >= maxfev) {
845 const int flagInfo = 5;
849 if ((std::fabs(actred) <= epsmch) && (prered <= epsmch) && ((tol5 * ratio) <= 1.0)) {
850 const int flagInfo = 6;
854 if (delta <= (epsmch * xnorm)) {
855 const int flagInfo = 7;
859 if (gnorm <= epsmch) {
860 const int flagInfo = 8;
875 (*ptr_fcn)(m, n, x, fvec, fjac, ldfjac, iflag);
884 int lmder(ComputeFunctionAndJacobian ptr_fcn,
int m,
int n,
885 double *x,
double *fvec,
double *fjac,
int ldfjac,
double ftol,
double xtol,
double gtol,
unsigned int maxfev,
886 double *diag,
int mode,
const double factor,
int nprint,
int *info,
unsigned int *nfev,
int *njev,
int *ipvt,
887 double *qtf,
double *wa1,
double *wa2,
double *wa3,
double *wa4)
895 double sum, temp, xnorm = 0.0;
924 bool cond_part_one = (n <= 0) || (m < n) || (ldfjac < m);
925 bool cond_part_two = (ftol < 0.0) || (xtol < 0.0) || (gtol < 0.0);
926 bool cond_part_three = (maxfev == 0) || (factor <= 0.0);
927 if (cond_part_one || cond_part_two || cond_part_three) {
938 (*ptr_fcn)(m, n, x, fvec, fjac, ldfjac, iflag);
946 for (j = 0; j < n; ++j) {
947 if (diag[j] <= 0.0) {
958 (*ptr_fcn)(m, n, x, fvec, fjac, ldfjac, iflag);
972 (*ptr_fcn)(m, n, x, fvec, fjac, ldfjac, iflag);
987 (*ptr_fcn)(m, n, x, fvec, fjac, ldfjac, iflag);
993 fnorm = enorm(fvec, m);
1002 const int iflag2 = 2;
1007 while (count <
static_cast<int>(maxfev)) {
1015 (*ptr_fcn)(m, n, x, fvec, fjac, ldfjac, iflag);
1030 (*ptr_fcn)(m, n, x, fvec, fjac, ldfjac, iflag);
1041 if (((iter - 1) % nprint) == 0) {
1042 (*ptr_fcn)(m, n, x, fvec, fjac, ldfjac, iflag);
1056 (*ptr_fcn)(m, n, x, fvec, fjac, ldfjac, iflag);
1066 qrfac(n, m, fjac, ldfjac, &oncol, ipvt, n, wa1, wa2, wa3);
1074 if (mode != mode2) {
1075 for (j = 0; j < n; ++j) {
1077 if (std::fabs(wa2[j]) <= std::numeric_limits<double>::epsilon()) {
1089 for (j = 0; j < n; ++j) {
1090 wa3[j] = diag[j] * x[j];
1093 xnorm = enorm(wa3, n);
1094 delta = factor * xnorm;
1096 if (std::fabs(delta) <= std::numeric_limits<double>::epsilon()) {
1105 for (i = 0; i < m; ++i) {
1109 for (i = 0; i < n; ++i) {
1110 double *pt = MIJ(fjac, i, i, ldfjac);
1111 if (std::fabs(*pt) > std::numeric_limits<double>::epsilon()) {
1114 for (j = i; j < m; ++j) {
1115 sum += *MIJ(fjac, i, j, ldfjac) * wa4[j];
1118 temp = -sum / *MIJ(fjac, i, i, ldfjac);
1120 for (j = i; j < m; ++j) {
1121 wa4[j] += *MIJ(fjac, i, j, ldfjac) * temp;
1125 *MIJ(fjac, i, i, ldfjac) = wa1[i];
1135 if (std::fabs(fnorm) > std::numeric_limits<double>::epsilon()) {
1136 for (i = 0; i < n; ++i) {
1138 if (std::fabs(wa2[l]) > std::numeric_limits<double>::epsilon()) {
1140 for (j = 0; j <= i; ++j) {
1141 sum += *MIJ(fjac, i, j, ldfjac) * (qtf[j] / fnorm);
1153 if (gnorm <= gtol) {
1154 const int info4 = 4;
1169 (*ptr_fcn)(m, n, x, fvec, fjac, ldfjac, iflag);
1179 if (mode != mode2) {
1180 for (j = 0; j < n; ++j) {
1185 bool hasFinished = lmderMostInnerLoop(ptr_fcn, m, n, x, fvec, fjac, ldfjac, ftol, xtol, maxfev,
1186 diag, nprint, info, nfev, ipvt, qtf, wa1, wa2, wa3, wa4, gnorm, iter, delta, par, pnorm,
1187 iflag, fnorm, xnorm);
1196 int lmder1(ComputeFunctionAndJacobian ptr_fcn,
int m,
int n,
1197 double *x,
double *fvec,
double *fjac,
int ldfjac,
double tol,
int *info,
int *ipvt,
int lwa,
double *wa)
1199 const double factor = 100.0;
1200 unsigned int maxfev, nfev;
1201 int mode, njev, nprint;
1202 double ftol, gtol, xtol;
1207 const int lwaThresh = ((5 * n) + m);
1208 if ( (m < n) || (ldfjac < m) || (tol < 0.0) || (lwa < lwaThresh)) {
1209 printf(
"%d %d %d %d \n", (m < n), (ldfjac < m), (tol < 0.0), (lwa < lwaThresh));
1214 const int factor100 = 100;
1215 maxfev =
static_cast<unsigned int>(factor100 * (n + 1));
1222 const int factor2 = 2, factor3 = 3, factor4 = 4, factor5 = 5;
1223 lmder(ptr_fcn, m, n, x, fvec, fjac, ldfjac, ftol, xtol, gtol, maxfev, wa, mode, factor, nprint, info, &nfev, &njev,
1224 ipvt, &wa[n], &wa[factor2 * n], &wa[factor3 * n], &wa[factor4 * n], &wa[factor5 * n]);
1226 const int info8 = 8, info4 = 4;
1227 if (*info == info8) {
static Type maximum(const Type &a, const Type &b)
static Type minimum(const Type &a, const Type &b)