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) + (static_cast<long>(i) * static_cast<long>(s)) + static_cast<long>(j))
55bool lmderMostInnerLoop(ComputeFunctionAndJacobian ptr_fcn,
int m,
int n,
56 double *x,
double *fvec,
double *fjac,
int ldfjac,
double ftol,
double xtol,
unsigned int maxfev,
57 double *diag,
int nprint,
int *info,
unsigned int *nfev,
int *ipvt,
58 double *qtf,
double *wa1,
double *wa2,
double *wa3,
double *wa4,
const double &gnorm,
int &iter,
double &delta,
double &par,
double &pnorm,
59 int &iflag,
double &fnorm,
double &xnorm);
61double enorm(
const double *x,
int n)
63 const double rdwarf = 3.834e-20;
64 const double rgiant = 1.304e19;
67 double agiant, floatn;
68 double norm_eucl = 0.0;
69 double s1 = 0.0, s2 = 0.0, s3 = 0.0;
70 double x1max = 0.0, x3max = 0.0;
72 floatn =
static_cast<double>(n);
73 agiant = rgiant / floatn;
75 for (i = 0;
i < n; ++
i) {
76 double xabs = std::fabs(x[i]);
77 if ((xabs > rdwarf) && (xabs < agiant)) {
84 else if (xabs <= rdwarf) {
90 if (xabs > std::numeric_limits<double>::epsilon()) {
91 s3 += (xabs / x3max) * (xabs / x3max);
95 s3 = 1.0 + (s3 * (x3max / xabs) * (x3max / xabs));
105 s1 += (xabs / x1max) * (xabs / x1max);
108 s1 = 1.0 + (s1 * (x1max / xabs) * (x1max / xabs));
118 if (std::fabs(s1) <= std::numeric_limits<double>::epsilon()) {
120 if (std::fabs(s2) <= std::numeric_limits<double>::epsilon()) {
121 norm_eucl = x3max * sqrt(s3);
123 else if (s2 >= x3max) {
124 norm_eucl = sqrt(s2 * (1.0 + ((x3max / s2) * (x3max * s3))));
127 norm_eucl = sqrt(x3max * ((s2 / x3max) + (x3max * s3)));
131 norm_eucl = x1max * sqrt(s1 + ((s2 / x1max) / x1max));
137int lmpar(
int n,
double *r,
int ldr,
int *ipvt,
double *diag,
double *qtb,
double *delta,
double *par,
double *x,
138 double *sdiag,
double *wa1,
double *wa2)
140 const double tol1 = 0.1;
147 double dwarf = DBL_MIN;
156 for (
int i = 0;
i < n; ++
i) {
158 double *pt = MIJ(r, i, i, ldr);
159 if ((std::fabs(*pt) <= std::numeric_limits<double>::epsilon()) && (nsing == n)) {
169 for (
int k = 0; k < nsing; ++k) {
170 int i = nsing - 1 - k;
171 wa1[
i] /= *MIJ(r, i, i, ldr);
176 for (
unsigned int j = 0; j <= static_cast<unsigned int>(jm1); ++
j) {
177 wa1[
j] -= *MIJ(r, i, j, ldr) * temp;
183 for (
int j = 0;
j < n; ++
j) {
195 for (
int i = 0;
i < n; ++
i) {
196 wa2[
i] = diag[
i] *
x[
i];
199 dxnorm = enorm(wa2, n);
201 fp = dxnorm - *delta;
203 if (fp >(tol1 * (*delta))) {
212 for (
int i = 0;
i < n; ++
i) {
214 wa1[
i] = diag[l] * (wa2[l] / dxnorm);
217 for (
int i = 0;
i < n; ++
i) {
223 for (
unsigned int j = 0; j <= static_cast<unsigned int>(im1); ++
j) {
224 sum += (*MIJ(r, i, j, ldr) * wa1[
j]);
227 wa1[
i] = (wa1[
i] - sum) / *MIJ(r, i, i, ldr);
230 temp = enorm(wa1, n);
231 parl = ((fp / *delta) / temp) / temp;
238 for (
int i = 0;
i < n; ++
i) {
241 for (
int j = 0;
j <=
i; ++
j) {
242 sum += *MIJ(r, i, j, ldr) * qtb[
j];
246 wa1[
i] = sum / diag[l];
249 double gnorm = enorm(wa1, n);
250 double paru = gnorm / *delta;
253 if (std::fabs(paru) <= std::numeric_limits<double>::epsilon()) {
265 if (std::fabs(*par) <= std::numeric_limits<double>::epsilon()) {
266 *par = gnorm / dxnorm;
280 if (std::fabs(*par) <= std::numeric_limits<double>::epsilon()) {
281 const double tol001 = 0.001;
287 for (
int i = 0;
i < n; ++
i) {
288 wa1[
i] = temp * diag[
i];
291 qrsolv(n, r, ldr, ipvt, wa1, qtb, x, sdiag, wa2);
293 for (
int i = 0;
i < n; ++
i) {
294 wa2[
i] = diag[
i] *
x[
i];
297 dxnorm = enorm(wa2, n);
299 fp = dxnorm - *delta;
307 bool cond_part_1 = (std::fabs(fp) <= (tol1 * (*delta)));
308 bool cond_part_2 = (std::fabs(parl) <= std::numeric_limits<double>::epsilon()) && ((fp <= temp) && (temp < 0.0));
309 bool cond_part_3 = (
iter == 10);
310 if (cond_part_1 || cond_part_2 || cond_part_3) {
320 for (
int i = 0;
i < n; ++
i) {
322 wa1[
i] = diag[l] * (wa2[l] / dxnorm);
325 for (
unsigned int i = 0; i < static_cast<unsigned int>(n); ++
i) {
326 wa1[
i] = wa1[
i] / sdiag[
i];
328 unsigned int jp1 =
i + 1;
329 if (
static_cast<unsigned int>(n) >= jp1) {
330 for (
unsigned int j = jp1; j < static_cast<unsigned int>(n); ++
j) {
331 wa1[
j] -= (*MIJ(r, i, j, ldr) * temp);
336 temp = enorm(wa1, n);
337 double parc = ((fp / *delta) / temp) / temp;
368double pythag(
double a,
double b)
370 double pyth,
p,
r,
t;
375 if (std::fabs(p) <= std::numeric_limits<double>::epsilon()) {
380 r = (std::min<double>(std::fabs(a), std::fabs(b)) /
p) * (std::min<double>(std::fabs(a), std::fabs(b)) / p);
384 while (std::fabs(t - 4.0) < (std::fabs(
vpMath::maximum(t, 4.0)) * std::numeric_limits<double>::epsilon())) {
386 double u = 1.0 + (2.0 *
s);
388 r *= (
s /
u) * (s / u);
396int qrfac(
int m,
int n,
double *a,
int lda,
int *pivot,
int *ipvt,
int ,
double *rdiag,
double *acnorm,
399 const double tolerance = 0.05;
401 int i,
j, ip1, k, kmax, minmn;
403 double sum, temp, tmp;
408 epsmch = std::numeric_limits<double>::epsilon();
414 for (i = 0;
i < m; ++
i) {
415 acnorm[
i] = enorm(MIJ(a, i, 0, lda), n);
416 rdiag[
i] = acnorm[
i];
427 for (i = 0;
i < minmn; ++
i) {
434 for (k = i; k < m; ++k) {
435 if (rdiag[k] > rdiag[kmax]) {
441 for (j = 0;
j < n; ++
j) {
442 SWAP(*MIJ(a, i, j, lda), *MIJ(a, kmax, j, lda), tmp);
445 rdiag[kmax] = rdiag[
i];
448 SWAP(ipvt[i], ipvt[kmax], k);
456 double ajnorm = enorm(MIJ(a, i, i, lda), n - i);
459 if (std::fabs(ajnorm) > std::numeric_limits<double>::epsilon()) {
460 if (*MIJ(a, i, i, lda) < 0.0) {
464 for (j = i;
j < n; ++
j) {
465 *MIJ(a, i, j, lda) /= ajnorm;
467 *MIJ(a, i, i, lda) += 1.0;
476 for (k = ip1; k < m; ++k) {
478 for (j = i;
j < n; ++
j) {
479 sum += *MIJ(a, i, j, lda) * *MIJ(a, k, j, lda);
482 temp = sum / *MIJ(a, i, i, lda);
484 for (j = i;
j < n; ++
j) {
485 *MIJ(a, k, j, lda) -= temp * *MIJ(a, i, j, lda);
488 if (pivot && (std::fabs(rdiag[k]) > std::numeric_limits<double>::epsilon())) {
489 temp = *MIJ(a, k, i, lda) / rdiag[k];
492 if ((tolerance * (rdiag[k] / wa[k]) * (rdiag[k] / wa[k])) <= epsmch) {
493 rdiag[k] = enorm(MIJ(a, k, ip1, lda), (n - 1 -
static_cast<int>(i)));
507int qrsolv(
int n,
double *r,
int ldr,
int *ipvt,
double *diag,
double *qtb,
double *x,
double *sdiag,
double *wa)
511 double cosi, cotg, qtbpj, sinu, tg, temp;
518 for (i = 0;
i < n; ++
i) {
519 for (j = i;
j < n; ++
j) {
520 *MIJ(r, i, j, ldr) = *MIJ(r, j, i, ldr);
523 x[
i] = *MIJ(r, i, i, ldr);
532 for (i = 0;
i < n; ++
i) {
540 if (std::fabs(diag[l]) > std::numeric_limits<double>::epsilon()) {
541 for (k = i; k < n; ++k) {
556 for (k = i; k < n; ++k) {
563 if (std::fabs(sdiag[k]) > std::numeric_limits<double>::epsilon()) {
564 if (std::fabs(*MIJ(r, k, k, ldr)) >= std::fabs(sdiag[k])) {
565 tg = sdiag[k] / *MIJ(r, k, k, ldr);
566 cosi = 0.5 / sqrt(0.25 + (0.25 * (tg * tg)));
570 cotg = *MIJ(r, k, k, ldr) / sdiag[k];
571 sinu = 0.5 / sqrt(0.25 + (0.25 * (cotg * cotg)));
580 *MIJ(r, k, k, ldr) = (cosi * *MIJ(r, k, k, ldr)) + (sinu * sdiag[k]);
581 temp = (cosi * wa[k]) + (sinu * qtbpj);
582 qtbpj = (-sinu * wa[k]) + (cosi * qtbpj);
593 for (j = kp1;
j < n; ++
j) {
594 temp = (cosi * *MIJ(r, k, j, ldr)) + (sinu * sdiag[j]);
595 sdiag[
j] = (-sinu * *MIJ(r, k, j, ldr)) + (cosi * sdiag[j]);
596 *MIJ(r, k, j, ldr) = temp;
607 sdiag[
i] = *MIJ(r, i, i, ldr);
608 *MIJ(r, i, i, ldr) =
x[
i];
617 for (i = 0;
i < n; ++
i) {
618 if ((std::fabs(sdiag[i]) <= std::numeric_limits<double>::epsilon()) && (nsing == n)) {
628 for (k = 0; k < nsing; ++k) {
634 for (j = jp1;
j < nsing; ++
j) {
635 sum += *MIJ(r, i, j, ldr) * wa[
j];
638 wa[
i] = (wa[
i] - sum) / sdiag[i];
645 for (j = 0;
j < n; ++
j) {
652bool lmderMostInnerLoop(ComputeFunctionAndJacobian ptr_fcn,
int m,
int n,
653 double *x,
double *fvec,
double *fjac,
int ldfjac,
double ftol,
double xtol,
unsigned int maxfev,
654 double *diag,
int nprint,
int *info,
unsigned int *nfev,
int *ipvt,
655 double *qtf,
double *wa1,
double *wa2,
double *wa3,
double *wa4,
const double &gnorm,
int &iter,
double &delta,
double &par,
double &pnorm,
656 int &iflag,
double &fnorm,
double &xnorm)
658 const double tol1 = 0.1, tol5 = 0.5, tol25 = 0.25, tol75 = 0.75, tol0001 = 0.0001;
660 const double epsmch = std::numeric_limits<double>::epsilon();
665 while (ratio < tol0001) {
670 lmpar(n, fjac, ldfjac, ipvt, diag, qtf, &delta, &par, wa1, wa2, wa3, wa4);
676 for (
int j = 0;
j < n; ++
j) {
678 wa2[
j] =
x[
j] + wa1[
j];
679 wa3[
j] = diag[
j] * wa1[
j];
682 pnorm = enorm(wa3, n);
698 (*ptr_fcn)(m, n, wa2, wa4, fjac, ldfjac, iflag);
711 (*ptr_fcn)(m, n,
x, fvec, fjac, ldfjac, iflag);
717 double fnorm1 = enorm(wa4, m);
723 double actred = -1.0;
725 if ((tol1 * fnorm1) < fnorm) {
726 actred = 1.0 - ((fnorm1 / fnorm) * (fnorm1 / fnorm));
734 for (
int i = 0;
i < n; ++
i) {
737 double temp = wa1[l];
738 for (
int j = 0;
j <=
i; ++
j) {
739 wa3[
j] += *MIJ(fjac, i, j, ldfjac) * temp;
743 double temp1 = enorm(wa3, n) / fnorm;
744 double temp2 = (sqrt(par) * pnorm) / fnorm;
745 double prered = (temp1 * temp1) + ((temp2 * temp2) / tol5);
746 double dirder = -((temp1 * temp1) + (temp2 * temp2));
755 if (std::fabs(prered) > std::numeric_limits<double>::epsilon()) {
756 ratio = actred / prered;
765 if ((std::fabs(par) <= std::numeric_limits<double>::epsilon()) || (ratio <= tol75)) {
766 delta = pnorm / tol5;
776 temp = (tol5 * dirder) / (dirder + (tol5 * actred));
779 if (((tol1 * fnorm1) >= fnorm) || (temp < tol1)) {
790 if (ratio >= tol0001) {
796 for (
int j = 0;
j < n; ++
j) {
798 wa2[
j] = diag[
j] *
x[
j];
801 for (
int i = 0;
i < m; ++
i) {
805 xnorm = enorm(wa2, n);
814 if ((std::fabs(actred) <= ftol) && (prered <= ftol) && ((tol5 * ratio) <= 1.0)) {
818 if (delta <= (xtol * xnorm)) {
819 const int flagInfo = 2;
824 if ((std::fabs(actred) <= ftol) && (prered <= ftol) && ((tol5 * ratio) <= 1.0) && (*info == info2)) {
825 const int flagInfo = 3;
840 (*ptr_fcn)(m, n,
x, fvec, fjac, ldfjac, iflag);
850 if (*nfev >= maxfev) {
851 const int flagInfo = 5;
855 if ((std::fabs(actred) <= epsmch) && (prered <= epsmch) && ((tol5 * ratio) <= 1.0)) {
856 const int flagInfo = 6;
860 if (delta <= (epsmch * xnorm)) {
861 const int flagInfo = 7;
865 if (gnorm <= epsmch) {
866 const int flagInfo = 8;
881 (*ptr_fcn)(m, n,
x, fvec, fjac, ldfjac, iflag);
890int lmder(ComputeFunctionAndJacobian ptr_fcn,
int m,
int n,
891 double *x,
double *fvec,
double *fjac,
int ldfjac,
double ftol,
double xtol,
double gtol,
unsigned int maxfev,
892 double *diag,
int mode,
const double factor,
int nprint,
int *info,
unsigned int *nfev,
int *njev,
int *ipvt,
893 double *qtf,
double *wa1,
double *wa2,
double *wa3,
double *wa4)
901 double sum, temp, xnorm = 0.0;
930 bool cond_part_one = (n <= 0) || (m < n) || (ldfjac < m);
931 bool cond_part_two = (ftol < 0.0) || (xtol < 0.0) || (gtol < 0.0);
932 bool cond_part_three = (maxfev == 0) || (factor <= 0.0);
933 if (cond_part_one || cond_part_two || cond_part_three) {
944 (*ptr_fcn)(m, n,
x, fvec, fjac, ldfjac, iflag);
952 for (j = 0;
j < n; ++
j) {
953 if (diag[j] <= 0.0) {
964 (*ptr_fcn)(m, n,
x, fvec, fjac, ldfjac, iflag);
978 (*ptr_fcn)(m, n,
x, fvec, fjac, ldfjac, iflag);
993 (*ptr_fcn)(m, n,
x, fvec, fjac, ldfjac, iflag);
999 fnorm = enorm(fvec, m);
1008 const int iflag2 = 2;
1013 while (count <
static_cast<int>(maxfev)) {
1021 (*ptr_fcn)(m, n,
x, fvec, fjac, ldfjac, iflag);
1036 (*ptr_fcn)(m, n,
x, fvec, fjac, ldfjac, iflag);
1047 if (((iter - 1) % nprint) == 0) {
1048 (*ptr_fcn)(m, n,
x, fvec, fjac, ldfjac, iflag);
1062 (*ptr_fcn)(m, n,
x, fvec, fjac, ldfjac, iflag);
1072 qrfac(n, m, fjac, ldfjac, &oncol, ipvt, n, wa1, wa2, wa3);
1080 if (mode != mode2) {
1081 for (j = 0;
j < n; ++
j) {
1083 if (std::fabs(wa2[j]) <= std::numeric_limits<double>::epsilon()) {
1095 for (j = 0;
j < n; ++
j) {
1096 wa3[
j] = diag[
j] *
x[
j];
1099 xnorm = enorm(wa3, n);
1100 delta = factor * xnorm;
1102 if (std::fabs(delta) <= std::numeric_limits<double>::epsilon()) {
1111 for (i = 0;
i < m; ++
i) {
1115 for (i = 0;
i < n; ++
i) {
1116 double *pt = MIJ(fjac, i, i, ldfjac);
1117 if (std::fabs(*pt) > std::numeric_limits<double>::epsilon()) {
1120 for (j = i;
j < m; ++
j) {
1121 sum += *MIJ(fjac, i, j, ldfjac) * wa4[
j];
1124 temp = -sum / *MIJ(fjac, i, i, ldfjac);
1126 for (j = i;
j < m; ++
j) {
1127 wa4[
j] += *MIJ(fjac, i, j, ldfjac) * temp;
1131 *MIJ(fjac, i, i, ldfjac) = wa1[
i];
1141 if (std::fabs(fnorm) > std::numeric_limits<double>::epsilon()) {
1142 for (i = 0;
i < n; ++
i) {
1144 if (std::fabs(wa2[l]) > std::numeric_limits<double>::epsilon()) {
1146 for (j = 0;
j <=
i; ++
j) {
1147 sum += *MIJ(fjac, i, j, ldfjac) * (qtf[
j] / fnorm);
1159 if (gnorm <= gtol) {
1160 const int info4 = 4;
1175 (*ptr_fcn)(m, n,
x, fvec, fjac, ldfjac, iflag);
1185 if (mode != mode2) {
1186 for (j = 0;
j < n; ++
j) {
1191 bool hasFinished = lmderMostInnerLoop(ptr_fcn, m, n, x, fvec, fjac, ldfjac, ftol, xtol, maxfev,
1192 diag, nprint, info, nfev, ipvt, qtf, wa1, wa2, wa3, wa4, gnorm, iter, delta, par, pnorm,
1193 iflag, fnorm, xnorm);
1202int lmder1(ComputeFunctionAndJacobian ptr_fcn,
int m,
int n,
1203 double *x,
double *fvec,
double *fjac,
int ldfjac,
double tol,
int *info,
int *ipvt,
int lwa,
double *wa)
1205 const double factor = 100.0;
1206 unsigned int maxfev, nfev;
1207 int mode, njev, nprint;
1208 double ftol, gtol, xtol;
1213 const int lwaThresh = ((5 * n) + m);
1214 if ( (m < n) || (ldfjac < m) || (tol < 0.0) || (lwa < lwaThresh)) {
1215 printf(
"%d %d %d %d \n", (m < n), (ldfjac < m), (tol < 0.0), (lwa < lwaThresh));
1220 const int factor100 = 100;
1221 maxfev =
static_cast<unsigned int>(factor100 * (n + 1));
1228 const int factor2 = 2, factor3 = 3, factor4 = 4, factor5 = 5;
1229 lmder(ptr_fcn, m, n, x, fvec, fjac, ldfjac, ftol, xtol, gtol, maxfev, wa, mode, factor, nprint, info, &nfev, &njev,
1230 ipvt, &wa[n], &wa[factor2 * n], &wa[factor3 * n], &wa[factor4 * n], &wa[factor5 * n]);
1232 const int info8 = 8, info4 = 4;
1233 if (*info == info8) {
static Type maximum(const Type &a, const Type &b)
static Type minimum(const Type &a, const Type &b)