merge both c methods hybrj1/hybrj into one class HybridNonLinearSolver with

two methods. hybrd stuff renamed to HybridNonLinearSolverNumericalDiff.
This commit is contained in:
Thomas Capricelli 2009-08-25 13:56:25 +02:00
parent a043708e87
commit d880e6f774
5 changed files with 96 additions and 57 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/hybrj1.h"
#include "src/NonLinear/lmdif1.h"
#include "src/NonLinear/chkder.h"

View File

@ -1,9 +1,9 @@
template<typename FunctorType, typename Scalar>
class HybridNonLinearSolver
class HybridNonLinearSolverNumericalDiff
{
public:
HybridNonLinearSolver(const FunctorType &_functor)
HybridNonLinearSolverNumericalDiff(const FunctorType &_functor)
: functor(_functor) {}
int solve(
Matrix< Scalar, Dynamic, 1 > &x,
@ -36,7 +36,7 @@ private:
template<typename FunctorType, typename Scalar>
int HybridNonLinearSolver<FunctorType,Scalar>::solve(
int HybridNonLinearSolverNumericalDiff<FunctorType,Scalar>::solve(
Matrix< Scalar, Dynamic, 1 > &x,
Matrix< Scalar, Dynamic, 1 > &fvec,
Scalar tol
@ -70,7 +70,7 @@ int HybridNonLinearSolver<FunctorType,Scalar>::solve(
template<typename FunctorType, typename Scalar>
int HybridNonLinearSolver<FunctorType,Scalar>::solve(
int HybridNonLinearSolverNumericalDiff<FunctorType,Scalar>::solve(
Matrix< Scalar, Dynamic, 1 > &x,
Matrix< Scalar, Dynamic, 1 > &fvec,
int &nfev,

View File

@ -1,7 +1,78 @@
template<typename FunctorType, typename Scalar>
int ei_hybrj(
const FunctorType &Functor,
class HybridNonLinearSolver
{
public:
HybridNonLinearSolver(const FunctorType &_functor)
: functor(_functor) {}
int solve(
Matrix< Scalar, Dynamic, 1 > &x,
Matrix< Scalar, Dynamic, 1 > &fvec,
Matrix< Scalar, Dynamic, Dynamic > &fjac,
Scalar tol = ei_sqrt(epsilon<Scalar>())
);
int solve(
Matrix< Scalar, Dynamic, 1 > &x,
Matrix< Scalar, Dynamic, 1 > &fvec,
int &nfev,
int &njev,
Matrix< Scalar, Dynamic, Dynamic > &fjac,
Matrix< Scalar, Dynamic, 1 > &R,
Matrix< Scalar, Dynamic, 1 > &qtf,
Matrix< Scalar, Dynamic, 1 > &diag,
int mode=1,
int maxfev = 1000,
Scalar factor = Scalar(100.),
Scalar xtol = ei_sqrt(epsilon<Scalar>()),
int nprint=0
);
private:
const FunctorType &functor;
};
template<typename FunctorType, typename Scalar>
int HybridNonLinearSolver<FunctorType,Scalar>::solve(
Matrix< Scalar, Dynamic, 1 > &x,
Matrix< Scalar, Dynamic, 1 > &fvec,
Matrix< Scalar, Dynamic, Dynamic > &fjac,
Scalar tol
)
{
const int n = x.size();
int info, nfev=0, njev=0;
Matrix< Scalar, Dynamic, 1> R, qtf, diag;
/* check the input parameters for errors. */
if (n <= 0 || tol < 0.) {
printf("ei_hybrd1 bad args : n,tol,...");
return 0;
}
diag.setConstant(n, 1.);
info = solve(
x, fvec,
nfev, njev,
fjac,
R, qtf, diag,
2,
(n+1)*100,
100.,
tol
);
return (info==5)?4:info;
}
template<typename FunctorType, typename Scalar>
int HybridNonLinearSolver<FunctorType,Scalar>::solve(
Matrix< Scalar, Dynamic, 1 > &x,
Matrix< Scalar, Dynamic, 1 > &fvec,
int &nfev,
@ -10,11 +81,11 @@ int ei_hybrj(
Matrix< Scalar, Dynamic, 1 > &R,
Matrix< Scalar, Dynamic, 1 > &qtf,
Matrix< Scalar, Dynamic, 1 > &diag,
int mode=1,
int maxfev = 1000,
Scalar factor = Scalar(100.),
Scalar xtol = ei_sqrt(epsilon<Scalar>()),
int nprint=0
int mode,
int maxfev,
Scalar factor,
Scalar xtol,
int nprint
)
{
const int n = x.size();
@ -60,7 +131,7 @@ int ei_hybrj(
/* 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;
@ -81,7 +152,7 @@ int ei_hybrj(
/* calculate the jacobian matrix. */
iflag = Functor.df(x, fjac);
iflag = functor.df(x, fjac);
++njev;
if (iflag < 0)
break;
@ -152,12 +223,12 @@ int ei_hybrj(
/* beginning of the inner loop. */
while (true) {
/* 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, fjac);
iflag = functor.debug(x, fvec, fjac);
if (iflag < 0)
goto algo_end;
}
@ -180,7 +251,7 @@ int ei_hybrj(
/* 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;
@ -307,7 +378,7 @@ algo_end:
if (iflag < 0)
info = iflag;
if (nprint > 0)
iflag = Functor.debug(x, fvec, fjac);
iflag = functor.debug(x, fvec, fjac);
return info;
}

View File

@ -1,35 +0,0 @@
template<typename FunctorType, typename Scalar>
int ei_hybrj1(
const FunctorType &Functor,
Matrix< Scalar, Dynamic, 1 > &x,
Matrix< Scalar, Dynamic, 1 > &fvec,
Matrix< Scalar, Dynamic, Dynamic > &fjac,
Scalar tol = ei_sqrt(epsilon<Scalar>())
)
{
const int n = x.size();
int info, nfev=0, njev=0;
Matrix< Scalar, Dynamic, 1> R, qtf, diag;
/* check the input parameters for errors. */
if (n <= 0 || tol < 0.) {
printf("ei_hybrd1 bad args : n,tol,...");
return 0;
}
diag.setConstant(n, 1.);
info = ei_hybrj(
Functor,
x, fvec,
nfev, njev,
fjac,
R, qtf, diag,
2,
(n+1)*100,
100.,
tol
);
return (info==5)?4:info;
}

View File

@ -269,7 +269,9 @@ void testHybrj1()
x.setConstant(n, -1.);
// do the computation
info = ei_hybrj1(hybrj_functor(), x,fvec, fjac);
hybrj_functor functor;
HybridNonLinearSolver<hybrj_functor,double> solver(functor);
info = solver.solve(x, fvec, fjac);
// check return value
VERIFY( 1 == info);
@ -301,7 +303,9 @@ void testHybrj()
diag.setConstant(n, 1.);
// do the computation
info = ei_hybrj(hybrj_functor(), x,fvec, nfev, njev, fjac, R, qtf, diag, mode);
hybrj_functor functor;
HybridNonLinearSolver<hybrj_functor,double> solver(functor);
info = solver.solve(x,fvec, nfev, njev, fjac, R, qtf, diag, mode);
// check return value
VERIFY( 1 == info);
@ -353,7 +357,7 @@ void testHybrd1()
// do the computation
hybrd_functor functor;
HybridNonLinearSolver <hybrd_functor,double> solver(functor);
HybridNonLinearSolverNumericalDiff <hybrd_functor,double> solver(functor);
info = solver.solve(x, fvec);
// check return value
@ -385,7 +389,7 @@ void testHybrd()
// do the computation
hybrd_functor functor;
HybridNonLinearSolver <hybrd_functor,double> solver(functor);
HybridNonLinearSolverNumericalDiff <hybrd_functor,double> solver(functor);
info = solver.solve(x,fvec, nfev, fjac, R, qtf, diag, mode, ml, mu);
// check return value