mirror of
https://gitlab.com/libeigen/eigen.git
synced 2024-12-21 07:19:46 +08:00
playing with functors
This commit is contained in:
parent
6f567f10be
commit
15d2c3af90
@ -1,6 +1,7 @@
|
||||
|
||||
template<typename Functor, typename Scalar>
|
||||
template<typename FunctorType, typename Scalar>
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
|
||||
template<typename Functor, typename Scalar>
|
||||
template<typename FunctorType, typename Scalar>
|
||||
int ei_lmder1(
|
||||
const FunctorType &Functor,
|
||||
Matrix< Scalar, Dynamic, 1 > &x,
|
||||
Matrix< Scalar, Dynamic, 1 > &fvec,
|
||||
VectorXi &ipvt,
|
||||
Scalar tol = ei_sqrt(epsilon<Scalar>())
|
||||
const Scalar tol = ei_sqrt(epsilon<Scalar>())
|
||||
)
|
||||
{
|
||||
const int n = x.size(), m=fvec.size();
|
||||
@ -19,7 +20,8 @@ int ei_lmder1(
|
||||
}
|
||||
|
||||
ipvt.resize(n);
|
||||
info = ei_lmder<Functor,Scalar>(
|
||||
info = ei_lmder(
|
||||
Functor,
|
||||
x, fvec,
|
||||
nfev, njev,
|
||||
fjac, ipvt, qtf, diag,
|
||||
|
@ -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<lmder_functor>(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<lmder_functor>(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<n,n>(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<chwirut2_functor>(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<chwirut2_functor>(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<double>(), 1.E6*epsilon<double>());
|
||||
|
||||
// check return value
|
||||
@ -710,7 +718,7 @@ void testNistMisra1a(void)
|
||||
*/
|
||||
x<< 500., 0.0001;
|
||||
// do the computation
|
||||
info = ei_lmder<misra1a_functor>(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<misra1a_functor>(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<hahn1_functor>(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<hahn1_functor>(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<misra1d_functor>(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<misra1d_functor>(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<lanczos1_functor>(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<lanczos1_functor>(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<rat42_functor>(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<rat42_functor>(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<MGH10_functor>(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<MGH10_functor>(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<BoxBOD_functor>(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<double>(), 1E6*epsilon<double>());
|
||||
|
||||
// check return value
|
||||
@ -1212,7 +1220,7 @@ void testNistBoxBOD(void)
|
||||
*/
|
||||
x<< 100., 0.75;
|
||||
// do the computation
|
||||
info = ei_lmder<BoxBOD_functor>(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<double>(), epsilon<double>());
|
||||
|
||||
// check return value
|
||||
@ -1271,7 +1279,7 @@ void testNistMGH17(void)
|
||||
*/
|
||||
x<< 50., 150., -100., 1., 2.;
|
||||
// do the computation
|
||||
info = ei_lmder<MGH17_functor>(
|
||||
info = ei_lmder(MGH17_functor(),
|
||||
x, fvec, nfev, njev, fjac, ipvt, qtf, diag,
|
||||
1, 100., 5000, epsilon<double>(), epsilon<double>());
|
||||
|
||||
@ -1293,7 +1301,7 @@ void testNistMGH17(void)
|
||||
*/
|
||||
x<< 0.5 ,1.5 ,-1 ,0.01 ,0.02;
|
||||
// do the computation
|
||||
info = ei_lmder<MGH17_functor>(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<MGH09_functor>(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<MGH09_functor>(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<Bennett5_functor>(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<Bennett5_functor>(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<thurber_functor>(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<double>(), 1.E4*epsilon<double>());
|
||||
|
||||
// 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<thurber_functor>(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<double>(), 1.E4*epsilon<double>());
|
||||
|
||||
// check return value
|
||||
@ -1611,7 +1619,7 @@ void testNistRat43(void)
|
||||
*/
|
||||
x<< 100., 10., 1., 1.;
|
||||
// do the computation
|
||||
info = ei_lmder<rat43_functor>(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<double>(), 1.E6*epsilon<double>());
|
||||
|
||||
// check return value
|
||||
@ -1631,7 +1639,7 @@ void testNistRat43(void)
|
||||
*/
|
||||
x<< 700., 5., 0.75, 1.3;
|
||||
// do the computation
|
||||
info = ei_lmder<rat43_functor>(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<double>(), 1.E5*epsilon<double>());
|
||||
|
||||
// check return value
|
||||
@ -1694,7 +1702,7 @@ void testNistEckerle4(void)
|
||||
*/
|
||||
x<< 1., 10., 500.;
|
||||
// do the computation
|
||||
info = ei_lmder<eckerle4_functor>(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<eckerle4_functor>(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);
|
||||
|
Loading…
Reference in New Issue
Block a user