merge both c methods lmdif/lmdif1 into one class

LevenbergMarquardtNumericalDiff with two methods.
This commit is contained in:
Thomas Capricelli 2009-08-25 14:09:19 +02:00
parent a736378331
commit 3f1b81e129
4 changed files with 89 additions and 53 deletions

View File

@ -54,7 +54,6 @@ namespace Eigen {
#include "src/NonLinear/lmdif.h"
#include "src/NonLinear/hybrj.h"
#include "src/NonLinear/lmstr1.h"
#include "src/NonLinear/lmdif1.h"
#include "src/NonLinear/chkder.h"
//@}

View File

@ -1,7 +1,74 @@
template<typename FunctorType, typename Scalar>
int ei_lmdif(
const FunctorType &Functor,
class LevenbergMarquardtNumericalDiff
{
public:
LevenbergMarquardtNumericalDiff(const FunctorType &_functor)
: functor(_functor) {}
int minimize(
Matrix< Scalar, Dynamic, 1 > &x,
Matrix< Scalar, Dynamic, 1 > &fvec,
const Scalar tol = ei_sqrt(epsilon<Scalar>())
);
int minimize(
Matrix< Scalar, Dynamic, 1 > &x,
Matrix< Scalar, Dynamic, 1 > &fvec,
int &nfev,
Matrix< Scalar, Dynamic, Dynamic > &fjac,
VectorXi &ipvt,
Matrix< Scalar, Dynamic, 1 > &qtf,
Matrix< Scalar, Dynamic, 1 > &diag,
int mode=1,
Scalar factor = 100.,
int maxfev = 400,
Scalar ftol = ei_sqrt(epsilon<Scalar>()),
Scalar xtol = ei_sqrt(epsilon<Scalar>()),
Scalar gtol = Scalar(0.),
Scalar epsfcn = Scalar(0.),
int nprint=0
);
private:
const FunctorType &functor;
};
template<typename FunctorType, typename Scalar>
int LevenbergMarquardtNumericalDiff<FunctorType,Scalar>::minimize(
Matrix< Scalar, Dynamic, 1 > &x,
Matrix< Scalar, Dynamic, 1 > &fvec,
Scalar tol
)
{
const int n = x.size(), m=fvec.size();
int info, nfev=0;
Matrix< Scalar, Dynamic, Dynamic > fjac(m, n);
Matrix< Scalar, Dynamic, 1> diag, qtf;
VectorXi ipvt;
/* check the input parameters for errors. */
if (n <= 0 || m < n || tol < 0.) {
printf("ei_lmder1 bad args : m,n,tol,...");
return 0;
}
info = minimize(
x, fvec,
nfev,
fjac, ipvt, qtf, diag,
1,
100.,
(n+1)*200,
tol, tol, Scalar(0.), Scalar(0.)
);
return (info==8)?4:info;
}
template<typename FunctorType, typename Scalar>
int LevenbergMarquardtNumericalDiff<FunctorType,Scalar>::minimize(
Matrix< Scalar, Dynamic, 1 > &x,
Matrix< Scalar, Dynamic, 1 > &fvec,
int &nfev,
@ -9,14 +76,14 @@ int ei_lmdif(
VectorXi &ipvt,
Matrix< Scalar, Dynamic, 1 > &qtf,
Matrix< Scalar, Dynamic, 1 > &diag,
int mode=1,
Scalar factor = 100.,
int maxfev = 400,
Scalar ftol = ei_sqrt(epsilon<Scalar>()),
Scalar xtol = ei_sqrt(epsilon<Scalar>()),
Scalar gtol = Scalar(0.),
Scalar epsfcn = Scalar(0.),
int nprint=0
int mode,
Scalar factor,
int maxfev,
Scalar ftol,
Scalar xtol,
Scalar gtol,
Scalar epsfcn,
int nprint
)
{
const int m = fvec.size(), n = x.size();
@ -55,7 +122,7 @@ int ei_lmdif(
/* evaluate the function at the starting point */
/* and calculate its norm. */
iflag = Functor.f(x, fvec);
iflag = functor.f(x, fvec);
nfev = 1;
if (iflag < 0)
goto algo_end;
@ -72,17 +139,17 @@ int ei_lmdif(
/* calculate the jacobian matrix. */
iflag = ei_fdjac2(Functor, x, fvec, fjac, epsfcn);
iflag = ei_fdjac2(functor, x, fvec, fjac, epsfcn);
nfev += n;
if (iflag < 0)
break;
/* if requested, call Functor.f to enable printing of iterates. */
/* if requested, call functor.f to enable printing of iterates. */
if (nprint > 0) {
iflag = 0;
if ((iter - 1) % nprint == 0)
iflag = Functor.debug(x, fvec);
iflag = functor.debug(x, fvec);
if (iflag < 0)
break;
}
@ -178,7 +245,7 @@ int ei_lmdif(
/* evaluate the function at x + p and calculate its norm. */
iflag = Functor.f(wa2, wa4);
iflag = functor.f(wa2, wa4);
++nfev;
if (iflag < 0)
goto algo_end;
@ -275,7 +342,7 @@ algo_end:
if (iflag < 0)
info = iflag;
if (nprint > 0)
iflag = Functor.debug(x, fvec);
iflag = functor.debug(x, fvec);
return info;
}

View File

@ -1,34 +0,0 @@
template<typename FunctorType, typename Scalar>
int ei_lmdif1(
const FunctorType &Functor,
Matrix< Scalar, Dynamic, 1 > &x,
Matrix< Scalar, Dynamic, 1 > &fvec,
Scalar tol = ei_sqrt(epsilon<Scalar>())
)
{
const int n = x.size(), m=fvec.size();
int info, nfev=0;
Matrix< Scalar, Dynamic, Dynamic > fjac(m, n);
Matrix< Scalar, Dynamic, 1> diag, qtf;
VectorXi ipvt;
/* check the input parameters for errors. */
if (n <= 0 || m < n || tol < 0.) {
printf("ei_lmder1 bad args : m,n,tol,...");
return 0;
}
info = ei_lmdif(
Functor,
x, fvec,
nfev,
fjac, ipvt, qtf, diag,
1,
100.,
(n+1)*200,
tol, tol, Scalar(0.), Scalar(0.)
);
return (info==8)?4:info;
}

View File

@ -541,7 +541,9 @@ void testLmdif1()
x.setConstant(n, 1.);
// do the computation
info = ei_lmdif1(lmdif_functor(), x, fvec);
lmdif_functor functor;
LevenbergMarquardtNumericalDiff<lmdif_functor,double> lm(functor);
info = lm.minimize(x, fvec);
// check return value
VERIFY( 1 == info);
@ -569,7 +571,9 @@ void testLmdif()
x.setConstant(n, 1.);
// do the computation
info = ei_lmdif(lmdif_functor(), x, fvec, nfev, fjac, ipvt, qtf, diag);
lmdif_functor functor;
LevenbergMarquardtNumericalDiff<lmdif_functor,double> lm(functor);
info = lm.minimize(x, fvec, nfev, fjac, ipvt, qtf, diag);
// check return values
VERIFY( 1 == info);