From d880e6f77417ece0ff40c013932c809afe434828 Mon Sep 17 00:00:00 2001 From: Thomas Capricelli Date: Tue, 25 Aug 2009 13:56:25 +0200 Subject: [PATCH] merge both c methods hybrj1/hybrj into one class HybridNonLinearSolver with two methods. hybrd stuff renamed to HybridNonLinearSolverNumericalDiff. --- unsupported/Eigen/NonLinear | 1 - unsupported/Eigen/src/NonLinear/hybrd.h | 8 +- unsupported/Eigen/src/NonLinear/hybrj.h | 97 ++++++++++++++++++++---- unsupported/Eigen/src/NonLinear/hybrj1.h | 35 --------- unsupported/test/NonLinear.cpp | 12 ++- 5 files changed, 96 insertions(+), 57 deletions(-) delete mode 100644 unsupported/Eigen/src/NonLinear/hybrj1.h diff --git a/unsupported/Eigen/NonLinear b/unsupported/Eigen/NonLinear index ca7d2224f..c177cd935 100644 --- a/unsupported/Eigen/NonLinear +++ b/unsupported/Eigen/NonLinear @@ -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" diff --git a/unsupported/Eigen/src/NonLinear/hybrd.h b/unsupported/Eigen/src/NonLinear/hybrd.h index 2f976ab38..69243f0e1 100644 --- a/unsupported/Eigen/src/NonLinear/hybrd.h +++ b/unsupported/Eigen/src/NonLinear/hybrd.h @@ -1,9 +1,9 @@ template -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 -int HybridNonLinearSolver::solve( +int HybridNonLinearSolverNumericalDiff::solve( Matrix< Scalar, Dynamic, 1 > &x, Matrix< Scalar, Dynamic, 1 > &fvec, Scalar tol @@ -70,7 +70,7 @@ int HybridNonLinearSolver::solve( template -int HybridNonLinearSolver::solve( +int HybridNonLinearSolverNumericalDiff::solve( Matrix< Scalar, Dynamic, 1 > &x, Matrix< Scalar, Dynamic, 1 > &fvec, int &nfev, diff --git a/unsupported/Eigen/src/NonLinear/hybrj.h b/unsupported/Eigen/src/NonLinear/hybrj.h index a77eecf45..6f6511158 100644 --- a/unsupported/Eigen/src/NonLinear/hybrj.h +++ b/unsupported/Eigen/src/NonLinear/hybrj.h @@ -1,7 +1,78 @@ + template -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()) + ); + + 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()), + int nprint=0 + ); + +private: + const FunctorType &functor; +}; + + + +template +int HybridNonLinearSolver::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 +int HybridNonLinearSolver::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()), - 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; } diff --git a/unsupported/Eigen/src/NonLinear/hybrj1.h b/unsupported/Eigen/src/NonLinear/hybrj1.h deleted file mode 100644 index 684a0e9ba..000000000 --- a/unsupported/Eigen/src/NonLinear/hybrj1.h +++ /dev/null @@ -1,35 +0,0 @@ - -template -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()) - ) -{ - 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; -} - diff --git a/unsupported/test/NonLinear.cpp b/unsupported/test/NonLinear.cpp index eb8de8df1..3a1c81f19 100644 --- a/unsupported/test/NonLinear.cpp +++ b/unsupported/test/NonLinear.cpp @@ -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 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 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 solver(functor); + HybridNonLinearSolverNumericalDiff solver(functor); info = solver.solve(x, fvec); // check return value @@ -385,7 +389,7 @@ void testHybrd() // do the computation hybrd_functor functor; - HybridNonLinearSolver solver(functor); + HybridNonLinearSolverNumericalDiff solver(functor); info = solver.solve(x,fvec, nfev, fjac, R, qtf, diag, mode, ml, mu); // check return value