diff --git a/unsupported/Eigen/src/NonLinear/lmder.h b/unsupported/Eigen/src/NonLinear/lmder.h index 66294e98b..330b7047f 100644 --- a/unsupported/Eigen/src/NonLinear/lmder.h +++ b/unsupported/Eigen/src/NonLinear/lmder.h @@ -1,6 +1,7 @@ -template +template int ei_lmder( + const FunctorType &Functor, Matrix< Scalar, Dynamic, 1 > &x, Matrix< Scalar, Dynamic, 1 > &fvec, int &nfev, @@ -56,7 +57,7 @@ int ei_lmder( /* 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; @@ -73,17 +74,17 @@ int ei_lmder( /* calculate the jacobian matrix. */ - iflag = Functor::df(x, fjac); + iflag = Functor.df(x, fjac); ++njev; 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, fjac); + iflag = Functor.debug(x, fvec, fjac); if (iflag < 0) break; } @@ -179,7 +180,7 @@ int ei_lmder( /* 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; @@ -276,7 +277,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/lmder1.h b/unsupported/Eigen/src/NonLinear/lmder1.h index a4f968ae2..52bde21de 100644 --- a/unsupported/Eigen/src/NonLinear/lmder1.h +++ b/unsupported/Eigen/src/NonLinear/lmder1.h @@ -1,10 +1,11 @@ -template +template int ei_lmder1( + const FunctorType &Functor, Matrix< Scalar, Dynamic, 1 > &x, Matrix< Scalar, Dynamic, 1 > &fvec, VectorXi &ipvt, - Scalar tol = ei_sqrt(epsilon()) + const Scalar tol = ei_sqrt(epsilon()) ) { const int n = x.size(), m=fvec.size(); @@ -19,7 +20,8 @@ int ei_lmder1( } ipvt.resize(n); - info = ei_lmder( + info = ei_lmder( + Functor, x, fvec, nfev, njev, fjac, ipvt, qtf, diag, diff --git a/unsupported/test/NonLinear.cpp b/unsupported/test/NonLinear.cpp index 1b2433582..7a10d7dfe 100644 --- a/unsupported/test/NonLinear.cpp +++ b/unsupported/test/NonLinear.cpp @@ -101,9 +101,13 @@ void testChkder() } +/** + * This functor example uses non-static members, see other ones for static + * methods + */ struct lmder_functor { - static int debug(const VectorXd & /* x */, const VectorXd & /* fvec */, const MatrixXd & /* fjac */) { return 0;} - static int f(const VectorXd &x, VectorXd &fvec) + int debug(const VectorXd & /* x */, const VectorXd & /* fvec */, const MatrixXd & /* fjac */) const { return 0;} + int f(const VectorXd &x, VectorXd &fvec) const { double tmp1, tmp2, tmp3; double y[15] = {1.4e-1, 1.8e-1, 2.2e-1, 2.5e-1, 2.9e-1, 3.2e-1, 3.5e-1, @@ -119,7 +123,7 @@ struct lmder_functor { return 0; } - static int df(const VectorXd &x, MatrixXd &fjac) + int df(const VectorXd &x, MatrixXd &fjac) const { double tmp1, tmp2, tmp3, tmp4; for (int i = 0; i < 15; i++) @@ -148,7 +152,7 @@ void testLmder1() x.setConstant(n, 1.); // do the computation - info = ei_lmder1(x, fvec, ipvt); + info = ei_lmder1(lmder_functor(), x, fvec, ipvt); // check return value VERIFY( 1 == info); @@ -175,7 +179,7 @@ void testLmder() x.setConstant(n, 1.); // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag); + info = ei_lmder(lmder_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag); // check return values VERIFY( 1 == info); @@ -210,6 +214,10 @@ void testLmder() // VERIFY_IS_APPROX( covfac*fjac.corner(TopLeft) , cov_ref); } +/** + * This functor example uses static members, see lmder_functor for an + * example of a non-static functor. + */ struct hybrj_functor { static int debug(const VectorXd & /* x */, const VectorXd & /* fvec */, const MatrixXd & /* fjac */) { return 0;} @@ -633,7 +641,7 @@ void testNistChwirut2(void) */ x<< 0.1, 0.01, 0.02; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag); + info = ei_lmder(chwirut2_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag); // check return value VERIFY( 1 == info); @@ -651,7 +659,7 @@ void testNistChwirut2(void) */ x<< 0.15, 0.008, 0.010; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag, + info = ei_lmder(chwirut2_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag, 1, 100., 400, 1.E6*epsilon(), 1.E6*epsilon()); // check return value @@ -710,7 +718,7 @@ void testNistMisra1a(void) */ x<< 500., 0.0001; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag); + info = ei_lmder(misra1a_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag); // check return value VERIFY( 1 == info); @@ -727,7 +735,7 @@ void testNistMisra1a(void) */ x<< 250., 0.0005; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag); + info = ei_lmder(misra1a_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag); // check return value VERIFY( 1 == info); @@ -795,7 +803,7 @@ void testNistHahn1(void) */ x<< 10., -1., .05, -.00001, -.05, .001, -.000001; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag); + info = ei_lmder(hahn1_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag); // check return value VERIFY( 1 == info); @@ -817,7 +825,7 @@ void testNistHahn1(void) */ x<< .1, -.1, .005, -.000001, -.005, .0001, -.0000001; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag); + info = ei_lmder(hahn1_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag); // check return value VERIFY( 1 == info); @@ -880,7 +888,7 @@ void testNistMisra1d(void) */ x<< 500., 0.0001; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag); + info = ei_lmder(misra1d_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag); // check return value VERIFY( 3 == info); @@ -897,7 +905,7 @@ void testNistMisra1d(void) */ x<< 450., 0.0003; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag); + info = ei_lmder(misra1d_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag); // check return value VERIFY( 1 == info); @@ -957,7 +965,7 @@ void testNistLanczos1(void) */ x<< 1.2, 0.3, 5.6, 5.5, 6.5, 7.6; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag); + info = ei_lmder(lanczos1_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag); // check return value VERIFY( 2 == info); @@ -978,7 +986,7 @@ void testNistLanczos1(void) */ x<< 0.5, 0.7, 3.6, 4.2, 4., 6.3; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag); + info = ei_lmder(lanczos1_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag); // check return value VERIFY( 2 == info); @@ -1042,7 +1050,7 @@ void testNistRat42(void) */ x<< 100., 1., 0.1; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag); + info = ei_lmder(rat42_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag); // check return value VERIFY( 1 == info); @@ -1060,7 +1068,7 @@ void testNistRat42(void) */ x<< 75., 2.5, 0.07; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag); + info = ei_lmder(rat42_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag); // check return value VERIFY( 1 == info); @@ -1119,7 +1127,7 @@ void testNistMGH10(void) */ x<< 2., 400000., 25000.; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag); + info = ei_lmder(MGH10_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag); // check return value VERIFY( 2 == info); @@ -1137,7 +1145,7 @@ void testNistMGH10(void) */ x<< 0.02, 4000., 250.; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag); + info = ei_lmder(MGH10_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag); // check return value VERIFY( 2 == info); @@ -1194,7 +1202,7 @@ void testNistBoxBOD(void) */ x<< 1., 1.; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag, + info = ei_lmder(BoxBOD_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag, 1, 10., 400, 1E6*epsilon(), 1E6*epsilon()); // check return value @@ -1212,7 +1220,7 @@ void testNistBoxBOD(void) */ x<< 100., 0.75; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag, + info = ei_lmder(BoxBOD_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag, 1, 100., 14000, epsilon(), epsilon()); // check return value @@ -1271,7 +1279,7 @@ void testNistMGH17(void) */ x<< 50., 150., -100., 1., 2.; // do the computation - info = ei_lmder( + info = ei_lmder(MGH17_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag, 1, 100., 5000, epsilon(), epsilon()); @@ -1293,7 +1301,7 @@ void testNistMGH17(void) */ x<< 0.5 ,1.5 ,-1 ,0.01 ,0.02; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag); + info = ei_lmder(MGH17_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag); // check return value VERIFY( 1 == info); @@ -1357,7 +1365,7 @@ void testNistMGH09(void) */ x<< 25., 39, 41.5, 39.; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag, + info = ei_lmder(MGH09_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag, 1, 100., 5000); // check return value @@ -1377,7 +1385,7 @@ void testNistMGH09(void) */ x<< 0.25, 0.39, 0.415, 0.39; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag); + info = ei_lmder(MGH09_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag); // check return value VERIFY( 1 == info); @@ -1438,7 +1446,7 @@ void testNistBennett5(void) */ x<< -2000., 50., 0.8; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag, + info = ei_lmder(Bennett5_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag, 1, 100., 5000); // check return value @@ -1456,7 +1464,7 @@ void testNistBennett5(void) */ x<< -1500., 45., 0.85; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag); + info = ei_lmder(Bennett5_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag); // check return value VERIFY( 1 == info); @@ -1523,7 +1531,7 @@ void testNistThurber(void) */ x<< 1000 ,1000 ,400 ,40 ,0.7,0.3,0.0 ; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag, + info = ei_lmder(thurber_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag, 1, 100., 400, 1.E4*epsilon(), 1.E4*epsilon()); // check return value @@ -1546,7 +1554,7 @@ void testNistThurber(void) */ x<< 1300 ,1500 ,500 ,75 ,1 ,0.4 ,0.05 ; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag, + info = ei_lmder(thurber_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag, 1, 100., 400, 1.E4*epsilon(), 1.E4*epsilon()); // check return value @@ -1611,7 +1619,7 @@ void testNistRat43(void) */ x<< 100., 10., 1., 1.; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag, + info = ei_lmder(rat43_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag, 1, 100., 400, 1.E6*epsilon(), 1.E6*epsilon()); // check return value @@ -1631,7 +1639,7 @@ void testNistRat43(void) */ x<< 700., 5., 0.75, 1.3; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag, + info = ei_lmder(rat43_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag, 1, 100., 400, 1.E5*epsilon(), 1.E5*epsilon()); // check return value @@ -1694,7 +1702,7 @@ void testNistEckerle4(void) */ x<< 1., 10., 500.; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag); + info = ei_lmder(eckerle4_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag); // check return value VERIFY( 1 == info); @@ -1712,7 +1720,7 @@ void testNistEckerle4(void) */ x<< 1.5, 5., 450.; // do the computation - info = ei_lmder(x, fvec, nfev, njev, fjac, ipvt, qtf, diag); + info = ei_lmder(eckerle4_functor(), x, fvec, nfev, njev, fjac, ipvt, qtf, diag); // check return value VERIFY( 1 == info);