// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Thomas Capricelli <orzel@freehackers.org>
#include <stdio.h>
#include "main.h"
#include <unsupported/Eigen/NonLinearOptimization>
// This disables some useless Warnings on MSVC.
// It is intended to be done for this test only.
#include <Eigen/src/Core/util/DisableStupidWarnings.h>
// tolerance for chekcing number of iterations
#define LM_EVAL_COUNT_TOL
4 /
3
#define LM_CHECK_N_ITERS(SOLVER,NFEV,NJEV) { \
++g_test_level; \
VERIFY_IS_EQUAL(SOLVER.nfev, NFEV); \
VERIFY_IS_EQUAL(SOLVER.njev, NJEV); \
--g_test_level; \
VERIFY(SOLVER.nfev <= NFEV * LM_EVAL_COUNT_TOL); \
VERIFY(SOLVER.njev <= NJEV * LM_EVAL_COUNT_TOL); \
}
int fcn_chkder(
const VectorXd &x, VectorXd &fvec, MatrixXd &fjac,
int iflag)
{
/* subroutine fcn for chkder example. */
int i;
assert(
15 == fvec.size());
assert(
3 == x.size());
double tmp1, tmp2, tmp3, tmp4;
static const double y[
15 ]={
1 .
4 e-
1 ,
1 .
8 e-
1 ,
2 .
2 e-
1 ,
2 .
5 e-
1 ,
2 .
9 e-
1 ,
3 .
2 e-
1 ,
3 .
5 e-
1 ,
3 .
9 e-
1 ,
3 .
7 e-
1 ,
5 .
8 e-
1 ,
7 .
3 e-
1 ,
9 .
6 e-
1 ,
1 .
34 ,
2 .
1 ,
4 .
39 };
if (iflag ==
0 )
return 0 ;
if (iflag !=
2 )
for (i=
0 ; i<
15 ; i++) {
tmp1 = i+
1 ;
tmp2 =
16 -i-
1 ;
tmp3 = tmp1;
if (i >=
8 ) tmp3 = tmp2;
fvec[i] = y[i] - (x[
0 ] + tmp1/(x[
1 ]*tmp2 + x[
2 ]*tmp3));
}
else {
for (i =
0 ; i <
15 ; i++) {
tmp1 = i+
1 ;
tmp2 =
16 -i-
1 ;
/* error introduced into next statement for illustration. */
/* corrected statement should read tmp3 = tmp1 . */
tmp3 = tmp2;
if (i >=
8 ) tmp3 = tmp2;
tmp4 = (x[
1 ]*tmp2 + x[
2 ]*tmp3); tmp4=tmp4*tmp4;
fjac(i,
0 ) = -
1 .;
fjac(i,
1 ) = tmp1*tmp2/tmp4;
fjac(i,
2 ) = tmp1*tmp3/tmp4;
}
}
return 0 ;
}
void testChkder()
{
const int m=
15 , n=
3 ;
VectorXd x(n), fvec(m), xp, fvecp(m), err;
MatrixXd fjac(m,n);
VectorXi ipvt;
/* the following values should be suitable for */
/* checking the jacobian matrix. */
x <<
9 .
2 e-
1 ,
1 .
3 e-
1 ,
5 .
4 e-
1 ;
internal::chkder(x, fvec, fjac, xp, fvecp,
1 , err);
fcn_chkder(x, fvec, fjac,
1 );
fcn_chkder(x, fvec, fjac,
2 );
fcn_chkder(xp, fvecp, fjac,
1 );
internal::chkder(x, fvec, fjac, xp, fvecp,
2 , err);
fvecp -= fvec;
// check those
VectorXd fvec_ref(m), fvecp_ref(m), err_ref(m);
fvec_ref <<
-
1 .
181606 , -
1 .
429655 , -
1 .
606344 ,
-
1 .
745269 , -
1 .
840654 , -
1 .
921586 ,
-
1 .
984141 , -
2 .
022537 , -
2 .
468977 ,
-
2 .
827562 , -
3 .
473582 , -
4 .
437612 ,
-
6 .
047662 , -
9 .
267761 , -
18 .
91806 ;
fvecp_ref <<
-
7 .
724666 e-
09 , -
3 .
432406 e-
09 , -
2 .
034843 e-
10 ,
2 .
313685 e-
09 ,
4 .
331078 e-
09 ,
5 .
984096 e-
09 ,
7 .
363281 e-
09 ,
8 .
53147 e-
09 ,
1 .
488591 e-
08 ,
2 .
33585 e-
08 ,
3 .
522012 e-
08 ,
5 .
301255 e-
08 ,
8 .
26666 e-
08 ,
1 .
419747 e-
07 ,
3 .
19899 e-
07 ;
err_ref <<
0 .
1141397 ,
0 .
09943516 ,
0 .
09674474 ,
0 .
09980447 ,
0 .
1073116 ,
0 .
1220445 ,
0 .
1526814 ,
1 ,
1 ,
1 ,
1 ,
1 ,
1 ,
1 ,
1 ;
VERIFY_IS_APPROX(fvec, fvec_ref);
VERIFY_IS_APPROX(fvecp, fvecp_ref);
VERIFY_IS_APPROX(err, err_ref);
}
// Generic functor
template <
typename _Scalar,
int NX=Dynamic,
int NY=Dynamic>
struct Functor
{
typedef _Scalar Scalar;
enum {
InputsAtCompileTime = NX,
ValuesAtCompileTime = NY
};
typedef Matrix<Scalar,InputsAtCompileTime,
1 > InputType;
typedef Matrix<Scalar,ValuesAtCompileTime,
1 > ValueType;
typedef Matrix<Scalar,ValuesAtCompileTime,InputsAtCompileTime> JacobianType;
const int m_inputs, m_values;
Functor() : m_inputs(InputsAtCompileTime), m_values(ValuesAtCompileTime) {}
Functor(
int inputs,
int values) : m_inputs(inputs), m_values(values) {}
int inputs()
const {
return m_inputs; }
int values()
const {
return m_values; }
// you should define that in the subclass :
// void operator() (const InputType& x, ValueType* v, JacobianType* _j=0) const;
};
struct lmder_functor : Functor<
double >
{
lmder_functor(
void ): Functor<
double >(
3 ,
15 ) {}
int operator ()(
const VectorXd &x, VectorXd &fvec)
const
{
double tmp1, tmp2, tmp3;
static const double y[
15 ] = {
1 .
4 e-
1 ,
1 .
8 e-
1 ,
2 .
2 e-
1 ,
2 .
5 e-
1 ,
2 .
9 e-
1 ,
3 .
2 e-
1 ,
3 .
5 e-
1 ,
3 .
9 e-
1 ,
3 .
7 e-
1 ,
5 .
8 e-
1 ,
7 .
3 e-
1 ,
9 .
6 e-
1 ,
1 .
34 ,
2 .
1 ,
4 .
39 };
for (
int i =
0 ; i < values(); i++)
{
tmp1 = i+
1 ;
tmp2 =
16 - i -
1 ;
tmp3 = (i>=
8 )? tmp2 : tmp1;
fvec[i] = y[i] - (x[
0 ] + tmp1/(x[
1 ]*tmp2 + x[
2 ]*tmp3));
}
return 0 ;
}
int df(
const VectorXd &x, MatrixXd &fjac)
const
{
double tmp1, tmp2, tmp3, tmp4;
for (
int i =
0 ; i < values(); i++)
{
tmp1 = i+
1 ;
tmp2 =
16 - i -
1 ;
tmp3 = (i>=
8 )? tmp2 : tmp1;
tmp4 = (x[
1 ]*tmp2 + x[
2 ]*tmp3); tmp4 = tmp4*tmp4;
fjac(i,
0 ) = -
1 ;
fjac(i,
1 ) = tmp1*tmp2/tmp4;
fjac(i,
2 ) = tmp1*tmp3/tmp4;
}
return 0 ;
}
};
void testLmder1()
{
int n=
3 , info;
VectorXd x;
/* the following starting values provide a rough fit. */
x.setConstant(n,
1 .);
// do the computation
lmder_functor functor;
LevenbergMarquardt<lmder_functor> lm(functor);
info = lm.lmder1(x);
// check return value
VERIFY_IS_EQUAL(info,
1 );
LM_CHECK_N_ITERS(lm,
6 ,
5 );
// check norm
VERIFY_IS_APPROX(lm.fvec.blueNorm(),
0 .
09063596 );
// check x
VectorXd x_ref(n);
x_ref <<
0 .
08241058 ,
1 .
133037 ,
2 .
343695 ;
VERIFY_IS_APPROX(x, x_ref);
}
void testLmder()
{
const int m=
15 , n=
3 ;
int info;
double fnorm, covfac;
VectorXd x;
/* the following starting values provide a rough fit. */
x.setConstant(n,
1 .);
// do the computation
lmder_functor functor;
LevenbergMarquardt<lmder_functor> lm(functor);
info = lm.minimize(x);
// check return values
VERIFY_IS_EQUAL(info,
1 );
LM_CHECK_N_ITERS(lm,
6 ,
5 );
// check norm
fnorm = lm.fvec.blueNorm();
VERIFY_IS_APPROX(fnorm,
0 .
09063596 );
// check x
VectorXd x_ref(n);
x_ref <<
0 .
08241058 ,
1 .
133037 ,
2 .
343695 ;
VERIFY_IS_APPROX(x, x_ref);
// check covariance
covfac = fnorm*fnorm/(m-n);
internal::covar(lm.fjac, lm.permutation.indices());
// TODO : move this as a function of lm
MatrixXd cov_ref(n,n);
cov_ref <<
0 .
0001531202 ,
0 .
002869941 , -
0 .
002656662 ,
0 .
002869941 ,
0 .
09480935 , -
0 .
09098995 ,
-
0 .
002656662 , -
0 .
09098995 ,
0 .
08778727 ;
// std::cout << fjac*covfac << std::endl;
MatrixXd cov;
cov = covfac*lm.fjac.topLeftCorner<n,n>();
VERIFY_IS_APPROX( cov, cov_ref);
// TODO: why isn't this allowed ? :
// VERIFY_IS_APPROX( covfac*fjac.topLeftCorner<n,n>() , cov_ref);
}
struct hybrj_functor : Functor<
double >
{
hybrj_functor(
void ) : Functor<
double >(
9 ,
9 ) {}
int operator ()(
const VectorXd &x, VectorXd &fvec)
{
double temp, temp1, temp2;
const VectorXd::Index n = x.size();
assert(fvec.size()==n);
for (VectorXd::Index k =
0 ; k < n; k++)
{
temp = (
3 . -
2 .*x[k])*x[k];
temp1 =
0 .;
if (k) temp1 = x[k-
1 ];
temp2 =
0 .;
if (k != n-
1 ) temp2 = x[k+
1 ];
fvec[k] = temp - temp1 -
2 .*temp2 +
1 .;
}
return 0 ;
}
int df(
const VectorXd &x, MatrixXd &fjac)
{
const VectorXd::Index n = x.size();
assert(fjac.rows()==n);
assert(fjac.cols()==n);
for (VectorXd::Index k =
0 ; k < n; k++)
{
for (VectorXd::Index j =
0 ; j < n; j++)
fjac(k,j) =
0 .;
fjac(k,k) =
3 .-
4 .*x[k];
if (k) fjac(k,k-
1 ) = -
1 .;
if (k != n-
1 ) fjac(k,k+
1 ) = -
2 .;
}
return 0 ;
}
};
void testHybrj1()
{
const int n=
9 ;
int info;
VectorXd x(n);
/* the following starting values provide a rough fit. */
x.setConstant(n, -
1 .);
// do the computation
hybrj_functor functor;
HybridNonLinearSolver<hybrj_functor> solver(functor);
info = solver.hybrj1(x);
// check return value
VERIFY_IS_EQUAL(info,
1 );
LM_CHECK_N_ITERS(solver,
11 ,
1 );
// check norm
VERIFY_IS_APPROX(solver.fvec.blueNorm(),
1 .
192636 e-
08 );
// check x
VectorXd x_ref(n);
x_ref <<
-
0 .
5706545 , -
0 .
6816283 , -
0 .
7017325 ,
-
0 .
7042129 , -
0 .
701369 , -
0 .
6918656 ,
-
0 .
665792 , -
0 .
5960342 , -
0 .
4164121 ;
VERIFY_IS_APPROX(x, x_ref);
}
void testHybrj()
{
const int n=
9 ;
int info;
VectorXd x(n);
/* the following starting values provide a rough fit. */
x.setConstant(n, -
1 .);
// do the computation
hybrj_functor functor;
HybridNonLinearSolver<hybrj_functor> solver(functor);
solver.diag.setConstant(n,
1 .);
solver.useExternalScaling =
true ;
info = solver.solve(x);
// check return value
VERIFY_IS_EQUAL(info,
1 );
LM_CHECK_N_ITERS(solver,
11 ,
1 );
// check norm
VERIFY_IS_APPROX(solver.fvec.blueNorm(),
1 .
192636 e-
08 );
// check x
VectorXd x_ref(n);
x_ref <<
-
0 .
5706545 , -
0 .
6816283 , -
0 .
7017325 ,
-
0 .
7042129 , -
0 .
701369 , -
0 .
6918656 ,
-
0 .
665792 , -
0 .
5960342 , -
0 .
4164121 ;
VERIFY_IS_APPROX(x, x_ref);
}
struct hybrd_functor : Functor<
double >
{
hybrd_functor(
void ) : Functor<
double >(
9 ,
9 ) {}
int operator ()(
const VectorXd &x, VectorXd &fvec)
const
{
double temp, temp1, temp2;
const VectorXd::Index n = x.size();
assert(fvec.size()==n);
for (VectorXd::Index k=
0 ; k < n; k++)
{
temp = (
3 . -
2 .*x[k])*x[k];
temp1 =
0 .;
if (k) temp1 = x[k-
1 ];
temp2 =
0 .;
if (k != n-
1 ) temp2 = x[k+
1 ];
fvec[k] = temp - temp1 -
2 .*temp2 +
1 .;
}
return 0 ;
}
};
void testHybrd1()
{
int n=
9 , info;
VectorXd x(n);
/* the following starting values provide a rough solution. */
x.setConstant(n, -
1 .);
// do the computation
hybrd_functor functor;
HybridNonLinearSolver<hybrd_functor> solver(functor);
info = solver.hybrd1(x);
// check return value
VERIFY_IS_EQUAL(info,
1 );
VERIFY_IS_EQUAL(solver.nfev,
20 );
// check norm
VERIFY_IS_APPROX(solver.fvec.blueNorm(),
1 .
192636 e-
08 );
// check x
VectorXd x_ref(n);
x_ref << -
0 .
5706545 , -
0 .
6816283 , -
0 .
7017325 , -
0 .
7042129 , -
0 .
701369 , -
0 .
6918656 , -
0 .
665792 ,
-0 .5960342 , -0 .4164121 ;
VERIFY_IS_APPROX(x, x_ref);
}
void testHybrd()
{
const int n=9 ;
int info;
VectorXd x;
/* the following starting values provide a rough fit. */
x.setConstant(n, -1 .);
// do the computation
hybrd_functor functor;
HybridNonLinearSolver<hybrd_functor> solver(functor);
solver.parameters.nb_of_subdiagonals = 1 ;
solver.parameters.nb_of_superdiagonals = 1 ;
solver.diag.setConstant(n, 1 .);
solver.useExternalScaling = true ;
info = solver.solveNumericalDiff(x);
// check return value
VERIFY_IS_EQUAL(info, 1 );
VERIFY_IS_EQUAL(solver.nfev, 14 );
// check norm
VERIFY_IS_APPROX(solver.fvec.blueNorm(), 1 .192636 e-08 );
// check x
VectorXd x_ref(n);
x_ref <<
-0 .5706545 , -0 .6816283 , -0 .7017325 ,
-0 .7042129 , -0 .701369 , -0 .6918656 ,
-0 .665792 , -0 .5960342 , -0 .4164121 ;
VERIFY_IS_APPROX(x, x_ref);
}
struct lmstr_functor : Functor<double >
{
lmstr_functor(void ) : Functor<double >(3 ,15 ) {}
int operator ()(const VectorXd &x, VectorXd &fvec)
{
/* subroutine fcn for lmstr1 example. */
double tmp1, tmp2, tmp3;
static const double y[15 ]={1 .4 e-1 , 1 .8 e-1 , 2 .2 e-1 , 2 .5 e-1 , 2 .9 e-1 , 3 .2 e-1 , 3 .5 e-1 ,
3 .9 e-1 , 3 .7 e-1 , 5 .8 e-1 , 7 .3 e-1 , 9 .6 e-1 , 1 .34 , 2 .1 , 4 .39 };
assert(15 ==fvec.size());
assert(3 ==x.size());
for (int i=0 ; i<15 ; i++)
{
tmp1 = i+1 ;
tmp2 = 16 - i - 1 ;
tmp3 = (i>=8 )? tmp2 : tmp1;
fvec[i] = y[i] - (x[0 ] + tmp1/(x[1 ]*tmp2 + x[2 ]*tmp3));
}
return 0 ;
}
int df(const VectorXd &x, VectorXd &jac_row, VectorXd::Index rownb)
{
assert(x.size()==3 );
assert(jac_row.size()==x.size());
double tmp1, tmp2, tmp3, tmp4;
VectorXd::Index i = rownb-2 ;
tmp1 = i+1 ;
tmp2 = 16 - i - 1 ;
tmp3 = (i>=8 )? tmp2 : tmp1;
tmp4 = (x[1 ]*tmp2 + x[2 ]*tmp3); tmp4 = tmp4*tmp4;
jac_row[0 ] = -1 ;
jac_row[1 ] = tmp1*tmp2/tmp4;
jac_row[2 ] = tmp1*tmp3/tmp4;
return 0 ;
}
};
void testLmstr1()
{
const int n=3 ;
int info;
VectorXd x(n);
/* the following starting values provide a rough fit. */
x.setConstant(n, 1 .);
// do the computation
lmstr_functor functor;
LevenbergMarquardt<lmstr_functor> lm(functor);
info = lm.lmstr1(x);
// check return value
VERIFY_IS_EQUAL(info, 1 );
LM_CHECK_N_ITERS(lm, 6 , 5 );
// check norm
VERIFY_IS_APPROX(lm.fvec.blueNorm(), 0 .09063596 );
// check x
VectorXd x_ref(n);
x_ref << 0 .08241058 , 1 .133037 , 2 .343695 ;
VERIFY_IS_APPROX(x, x_ref);
}
void testLmstr()
{
const int n=3 ;
int info;
double fnorm;
VectorXd x(n);
/* the following starting values provide a rough fit. */
x.setConstant(n, 1 .);
// do the computation
lmstr_functor functor;
LevenbergMarquardt<lmstr_functor> lm(functor);
info = lm.minimizeOptimumStorage(x);
// check return values
VERIFY_IS_EQUAL(info, 1 );
LM_CHECK_N_ITERS(lm, 6 , 5 );
// check norm
fnorm = lm.fvec.blueNorm();
VERIFY_IS_APPROX(fnorm, 0 .09063596 );
// check x
VectorXd x_ref(n);
x_ref << 0 .08241058 , 1 .133037 , 2 .343695 ;
VERIFY_IS_APPROX(x, x_ref);
}
struct lmdif_functor : Functor<double >
{
lmdif_functor(void ) : Functor<double >(3 ,15 ) {}
int operator ()(const VectorXd &x, VectorXd &fvec) const
{
int i;
double tmp1,tmp2,tmp3;
static const double y[15 ]={1 .4 e-1 ,1 .8 e-1 ,2 .2 e-1 ,2 .5 e-1 ,2 .9 e-1 ,3 .2 e-1 ,3 .5 e-1 ,3 .9 e-1 ,
3 .7 e-1 ,5 .8 e-1 ,7 .3 e-1 ,9 .6 e-1 ,1 .34 e0,2 .1 e0,4 .39 e0};
assert(x.size()==3 );
assert(fvec.size()==15 );
for (i=0 ; i<15 ; i++)
{
tmp1 = i+1 ;
tmp2 = 15 - i;
tmp3 = tmp1;
if (i >= 8 ) tmp3 = tmp2;
fvec[i] = y[i] - (x[0 ] + tmp1/(x[1 ]*tmp2 + x[2 ]*tmp3));
}
return 0 ;
}
};
void testLmdif1()
{
const int n=3 ;
int info;
VectorXd x(n), fvec(15 );
/* the following starting values provide a rough fit. */
x.setConstant(n, 1 .);
// do the computation
lmdif_functor functor;
DenseIndex nfev = -1 ; // initialize to avoid maybe-uninitialized warning
info = LevenbergMarquardt<lmdif_functor>::lmdif1(functor, x, &nfev);
// check return value
VERIFY_IS_EQUAL(info, 1 );
VERIFY_IS_EQUAL(nfev, 26 );
// check norm
functor(x, fvec);
VERIFY_IS_APPROX(fvec.blueNorm(), 0 .09063596 );
// check x
VectorXd x_ref(n);
x_ref << 0 .0824106 , 1 .1330366 , 2 .3436947 ;
VERIFY_IS_APPROX(x, x_ref);
}
void testLmdif()
{
const int m=15 , n=3 ;
int info;
double fnorm, covfac;
VectorXd x(n);
/* the following starting values provide a rough fit. */
x.setConstant(n, 1 .);
// do the computation
lmdif_functor functor;
NumericalDiff<lmdif_functor> numDiff(functor);
LevenbergMarquardt<NumericalDiff<lmdif_functor> > lm(numDiff);
info = lm.minimize(x);
// check return values
VERIFY_IS_EQUAL(info, 1 );
VERIFY_IS_EQUAL(lm.nfev, 26 );
// check norm
fnorm = lm.fvec.blueNorm();
VERIFY_IS_APPROX(fnorm, 0 .09063596 );
// check x
VectorXd x_ref(n);
x_ref << 0 .08241058 , 1 .133037 , 2 .343695 ;
VERIFY_IS_APPROX(x, x_ref);
// check covariance
covfac = fnorm*fnorm/(m-n);
internal::covar(lm.fjac, lm.permutation.indices()); // TODO : move this as a function of lm
MatrixXd cov_ref(n,n);
cov_ref <<
0 .0001531202 , 0 .002869942 , -0 .002656662 ,
0 .002869942 , 0 .09480937 , -0 .09098997 ,
-0 .002656662 , -0 .09098997 , 0 .08778729 ;
// std::cout << fjac*covfac << std::endl;
MatrixXd cov;
cov = covfac*lm.fjac.topLeftCorner<n,n>();
VERIFY_IS_APPROX( cov, cov_ref);
// TODO: why isn't this allowed ? :
// VERIFY_IS_APPROX( covfac*fjac.topLeftCorner<n,n>() , cov_ref);
}
struct chwirut2_functor : Functor<double >
{
chwirut2_functor(void ) : Functor<double >(3 ,54 ) {}
static const double m_x[54 ];
static const double m_y[54 ];
int operator ()(const VectorXd &b, VectorXd &fvec)
{
int i;
assert(b.size()==3 );
assert(fvec.size()==54 );
for (i=0 ; i<54 ; i++) {
double x = m_x[i];
fvec[i] = exp(-b[0 ]*x)/(b[1 ]+b[2 ]*x) - m_y[i];
}
return 0 ;
}
int df(const VectorXd &b, MatrixXd &fjac)
{
assert(b.size()==3 );
assert(fjac.rows()==54 );
assert(fjac.cols()==3 );
for (int i=0 ; i<54 ; i++) {
double x = m_x[i];
double factor = 1 ./(b[1 ]+b[2 ]*x);
double e = exp(-b[0 ]*x);
fjac(i,0 ) = -x*e*factor;
fjac(i,1 ) = -e*factor*factor;
fjac(i,2 ) = -x*e*factor*factor;
}
return 0 ;
}
};
const double chwirut2_functor::m_x[54 ] = { 0 .500 E0, 1 .000 E0, 1 .750 E0, 3 .750 E0, 5 .750 E0, 0 .875 E0, 2 .250 E0, 3 .250 E0, 5 .250 E0, 0 .750 E0, 1 .750 E0, 2 .750 E0, 4 .750 E0, 0 .625 E0, 1 .250 E0, 2 .250 E0, 4 .250 E0, .500 E0, 3 .000 E0, .750 E0, 3 .000 E0, 1 .500 E0, 6 .000 E0, 3 .000 E0, 6 .000 E0, 1 .500 E0, 3 .000 E0, .500 E0, 2 .000 E0, 4 .000 E0, .750 E0, 2 .000 E0, 5 .000 E0, .750 E0, 2 .250 E0, 3 .750 E0, 5 .750 E0, 3 .000 E0, .750 E0, 2 .500 E0, 4 .000 E0, .750 E0, 2 .500 E0, 4 .000 E0, .750 E0, 2 .500 E0, 4 .000 E0, .500 E0, 6 .000 E0, 3 .000 E0, .500 E0, 2 .750 E0, .500 E0, 1 .750 E0};
const double chwirut2_functor::m_y[54 ] = { 92 .9000 E0 ,57 .1000 E0 ,31 .0500 E0 ,11 .5875 E0 ,8 .0250 E0 ,63 .6000 E0 ,21 .4000 E0 ,14 .2500 E0 ,8 .4750 E0 ,63 .8000 E0 ,26 .8000 E0 ,16 .4625 E0 ,7 .1250 E0 ,67 .3000 E0 ,41 .0000 E0 ,21 .1500 E0 ,8 .1750 E0 ,81 .5000 E0 ,13 .1200 E0 ,59 .9000 E0 ,14 .6200 E0 ,32 .9000 E0 ,5 .4400 E0 ,12 .5600 E0 ,5 .4400 E0 ,32 .0000 E0 ,13 .9500 E0 ,75 .8000 E0 ,20 .0000 E0 ,10 .4200 E0 ,59 .5000 E0 ,21 .6700 E0 ,8 .5500 E0 ,62 .0000 E0 ,20 .2000 E0 ,7 .7600 E0 ,3 .7500 E0 ,11 .8100 E0 ,54 .7000 E0 ,23 .7000 E0 ,11 .5500 E0 ,61 .3000 E0 ,17 .7000 E0 ,8 .7400 E0 ,59 .2000 E0 ,16 .3000 E0 ,8 .6200 E0 ,81 .0000 E0 ,4 .8700 E0 ,14 .6200 E0 ,81 .7000 E0 ,17 .1700 E0 ,81 .3000 E0 ,28 .9000 E0 };
// http://www.itl.nist.gov/div898/strd/nls/data/chwirut2.shtml
void testNistChwirut2(void )
{
const int n=3 ;
int info;
VectorXd x(n);
/*
* First try
*/
x<< 0 .1 , 0 .01 , 0 .02 ;
// do the computation
chwirut2_functor functor;
LevenbergMarquardt<chwirut2_functor> lm(functor);
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 1 );
LM_CHECK_N_ITERS(lm, 10 , 8 );
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5 .1304802941 E+02 );
// check x
VERIFY_IS_APPROX(x[0 ], 1 .6657666537 E-01 );
VERIFY_IS_APPROX(x[1 ], 5 .1653291286 E-03 );
VERIFY_IS_APPROX(x[2 ], 1 .2150007096 E-02 );
/*
* Second try
*/
x<< 0 .15 , 0 .008 , 0 .010 ;
// do the computation
lm.resetParameters();
lm.parameters.ftol = 1 .E6*NumTraits<double >::epsilon();
lm.parameters.xtol = 1 .E6*NumTraits<double >::epsilon();
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 1 );
LM_CHECK_N_ITERS(lm, 7 , 6 );
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5 .1304802941 E+02 );
// check x
VERIFY_IS_APPROX(x[0 ], 1 .6657666537 E-01 );
VERIFY_IS_APPROX(x[1 ], 5 .1653291286 E-03 );
VERIFY_IS_APPROX(x[2 ], 1 .2150007096 E-02 );
}
struct misra1a_functor : Functor<double >
{
misra1a_functor(void ) : Functor<double >(2 ,14 ) {}
static const double m_x[14 ];
static const double m_y[14 ];
int operator ()(const VectorXd &b, VectorXd &fvec)
{
assert(b.size()==2 );
assert(fvec.size()==14 );
for (int i=0 ; i<14 ; i++) {
fvec[i] = b[0 ]*(1 .-exp(-b[1 ]*m_x[i])) - m_y[i] ;
}
return 0 ;
}
int df(const VectorXd &b, MatrixXd &fjac)
{
assert(b.size()==2 );
assert(fjac.rows()==14 );
assert(fjac.cols()==2 );
for (int i=0 ; i<14 ; i++) {
fjac(i,0 ) = (1 .-exp(-b[1 ]*m_x[i]));
fjac(i,1 ) = (b[0 ]*m_x[i]*exp(-b[1 ]*m_x[i]));
}
return 0 ;
}
};
const double misra1a_functor::m_x[14 ] = { 77 .6 E0, 114 .9 E0, 141 .1 E0, 190 .8 E0, 239 .9 E0, 289 .0 E0, 332 .8 E0, 378 .4 E0, 434 .8 E0, 477 .3 E0, 536 .8 E0, 593 .1 E0, 689 .1 E0, 760 .0 E0};
const double misra1a_functor::m_y[14 ] = { 10 .07 E0, 14 .73 E0, 17 .94 E0, 23 .93 E0, 29 .61 E0, 35 .18 E0, 40 .02 E0, 44 .82 E0, 50 .76 E0, 55 .05 E0, 61 .01 E0, 66 .40 E0, 75 .47 E0, 81 .78 E0};
// http://www.itl.nist.gov/div898/strd/nls/data/misra1a.shtml
void testNistMisra1a(void )
{
const int n=2 ;
int info;
VectorXd x(n);
/*
* First try
*/
x<< 500 ., 0 .0001 ;
// do the computation
misra1a_functor functor;
LevenbergMarquardt<misra1a_functor> lm(functor);
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 1 );
LM_CHECK_N_ITERS(lm, 19 , 15 );
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1 .2455138894 E-01 );
// check x
VERIFY_IS_APPROX(x[0 ], 2 .3894212918 E+02 );
VERIFY_IS_APPROX(x[1 ], 5 .5015643181 E-04 );
/*
* Second try
*/
x<< 250 ., 0 .0005 ;
// do the computation
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 1 );
LM_CHECK_N_ITERS(lm, 5 , 4 );
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1 .2455138894 E-01 );
// check x
VERIFY_IS_APPROX(x[0 ], 2 .3894212918 E+02 );
VERIFY_IS_APPROX(x[1 ], 5 .5015643181 E-04 );
}
struct hahn1_functor : Functor<double >
{
hahn1_functor(void ) : Functor<double >(7 ,236 ) {}
static const double m_x[236 ];
int operator ()(const VectorXd &b, VectorXd &fvec)
{
static const double m_y[236 ] = { .591 E0 , 1 .547 E0 , 2 .902 E0 , 2 .894 E0 , 4 .703 E0 , 6 .307 E0 , 7 .03 E0 , 7 .898 E0 , 9 .470 E0 , 9 .484 E0 , 10 .072 E0 , 10 .163 E0 , 11 .615 E0 , 12 .005 E0 , 12 .478 E0 , 12 .982 E0 , 12 .970 E0 , 13 .926 E0 , 14 .452 E0 , 14 .404 E0 , 15 .190 E0 , 15 .550 E0 , 15 .528 E0 , 15 .499 E0 , 16 .131 E0 , 16 .438 E0 , 16 .387 E0 , 16 .549 E0 , 16 .872 E0 , 16 .830 E0 , 16 .926 E0 , 16 .907 E0 , 16 .966 E0 , 17 .060 E0 , 17 .122 E0 , 17 .311 E0 , 17 .355 E0 , 17 .668 E0 , 17 .767 E0 , 17 .803 E0 , 17 .765 E0 , 17 .768 E0 , 17 .736 E0 , 17 .858 E0 , 17 .877 E0 , 17 .912 E0 , 18 .046 E0 , 18 .085 E0 , 18 .291 E0 , 18 .357 E0 , 18 .426 E0 , 18 .584 E0 , 18 .610 E0 , 18 .870 E0 , 18 .795 E0 , 19 .111 E0 , .367 E0 , .796 E0 , 0 .892 E0 , 1 .903 E0 , 2 .150 E0 , 3 .697 E0 , 5 .870 E0 , 6 .421 E0 , 7 .422 E0 , 9 .944 E0 , 11 .023 E0 , 11 .87 E0 , 12 .786 E0 , 14 .067 E0 , 13 .974 E0 , 14 .462 E0 , 14 .464 E0 , 15 .381 E0 , 15 .483 E0 , 15 .59 E0 , 16 .075 E0 , 16 .347 E0 , 16 .181 E0 , 16 .915 E0 , 17 .003 E0 , 16 .978 E0 , 17 .756 E0 , 17 .808 E0 , 17 .868 E0 , 18 .481 E0 , 18 .486 E0 , 19 .090 E0 , 16 .062 E0 , 16 .337 E0 , 16 .345 E0 ,
16 .388 E0 , 17 .159 E0 , 17 .116 E0 , 17 .164 E0 , 17 .123 E0 , 17 .979 E0 , 17 .974 E0 , 18 .007 E0 , 17 .993 E0 , 18 .523 E0 , 18 .669 E0 , 18 .617 E0 , 19 .371 E0 , 19 .330 E0 , 0 .080 E0 , 0 .248 E0 , 1 .089 E0 , 1 .418 E0 , 2 .278 E0 , 3 .624 E0 , 4 .574 E0 , 5 .556 E0 , 7 .267 E0 , 7 .695 E0 , 9 .136 E0 , 9 .959 E0 , 9 .957 E0 , 11 .600 E0 , 13 .138 E0 , 13 .564 E0 , 13 .871 E0 , 13 .994 E0 , 14 .947 E0 , 15 .473 E0 , 15 .379 E0 , 15 .455 E0 , 15 .908 E0 , 16 .114 E0 , 17 .071 E0 , 17 .135 E0 , 17 .282 E0 , 17 .368 E0 , 17 .483 E0 , 17 .764 E0 , 18 .185 E0 , 18 .271 E0 , 18 .236 E0 , 18 .237 E0 , 18 .523 E0 , 18 .627 E0 , 18 .665 E0 , 19 .086 E0 , 0 .214 E0 , 0 .943 E0 , 1 .429 E0 , 2 .241 E0 , 2 .951 E0 , 3 .782 E0 , 4 .757 E0 , 5 .602 E0 , 7 .169 E0 , 8 .920 E0 , 10 .055 E0 , 12 .035 E0 , 12 .861 E0 , 13 .436 E0 , 14 .167 E0 , 14 .755 E0 , 15 .168 E0 , 15 .651 E0 , 15 .746 E0 , 16 .216 E0 , 16 .445 E0 , 16 .965 E0 , 17 .121 E0 , 17 .206 E0 , 17 .250 E0 , 17 .339 E0 , 17 .793 E0 , 18 .123 E0 , 18 .49 E0 , 18 .566 E0 , 18 .645 E0 , 18 .706 E0 , 18 .924 E0 , 19 .1 E0 , 0 .375 E0 , 0 .471 E0 , 1 .504 E0 , 2 .204 E0 , 2 .813 E0 , 4 .765 E0 , 9 .835 E0 , 10 .040 E0 , 11 .946 E0 , 12 .596 E0 ,
13 .303 E0 , 13 .922 E0 , 14 .440 E0 , 14 .951 E0 , 15 .627 E0 , 15 .639 E0 , 15 .814 E0 , 16 .315 E0 , 16 .334 E0 , 16 .430 E0 , 16 .423 E0 , 17 .024 E0 , 17 .009 E0 , 17 .165 E0 , 17 .134 E0 , 17 .349 E0 , 17 .576 E0 , 17 .848 E0 , 18 .090 E0 , 18 .276 E0 , 18 .404 E0 , 18 .519 E0 , 19 .133 E0 , 19 .074 E0 , 19 .239 E0 , 19 .280 E0 , 19 .101 E0 , 19 .398 E0 , 19 .252 E0 , 19 .89 E0 , 20 .007 E0 , 19 .929 E0 , 19 .268 E0 , 19 .324 E0 , 20 .049 E0 , 20 .107 E0 , 20 .062 E0 , 20 .065 E0 , 19 .286 E0 , 19 .972 E0 , 20 .088 E0 , 20 .743 E0 , 20 .83 E0 , 20 .935 E0 , 21 .035 E0 , 20 .93 E0 , 21 .074 E0 , 21 .085 E0 , 20 .935 E0 };
// int called=0; printf("call hahn1_functor with iflag=%d, called=%d\n", iflag, called); if (iflag==1) called++;
assert(b.size()==7 );
assert(fvec.size()==236 );
for (int i=0 ; i<236 ; i++) {
double x=m_x[i], xx=x*x, xxx=xx*x;
fvec[i] = (b[0 ]+b[1 ]*x+b[2 ]*xx+b[3 ]*xxx) / (1 .+b[4 ]*x+b[5 ]*xx+b[6 ]*xxx) - m_y[i];
}
return 0 ;
}
int df(const VectorXd &b, MatrixXd &fjac)
{
assert(b.size()==7 );
assert(fjac.rows()==236 );
assert(fjac.cols()==7 );
for (int i=0 ; i<236 ; i++) {
double x=m_x[i], xx=x*x, xxx=xx*x;
double fact = 1 ./(1 .+b[4 ]*x+b[5 ]*xx+b[6 ]*xxx);
fjac(i,0 ) = 1 .*fact;
fjac(i,1 ) = x*fact;
fjac(i,2 ) = xx*fact;
fjac(i,3 ) = xxx*fact;
fact = - (b[0 ]+b[1 ]*x+b[2 ]*xx+b[3 ]*xxx) * fact * fact;
fjac(i,4 ) = x*fact;
fjac(i,5 ) = xx*fact;
fjac(i,6 ) = xxx*fact;
}
return 0 ;
}
};
const double hahn1_functor::m_x[236 ] = { 24 .41 E0 , 34 .82 E0 , 44 .09 E0 , 45 .07 E0 , 54 .98 E0 , 65 .51 E0 , 70 .53 E0 , 75 .70 E0 , 89 .57 E0 , 91 .14 E0 , 96 .40 E0 , 97 .19 E0 , 114 .26 E0 , 120 .25 E0 , 127 .08 E0 , 133 .55 E0 , 133 .61 E0 , 158 .67 E0 , 172 .74 E0 , 171 .31 E0 , 202 .14 E0 , 220 .55 E0 , 221 .05 E0 , 221 .39 E0 , 250 .99 E0 , 268 .99 E0 , 271 .80 E0 , 271 .97 E0 , 321 .31 E0 , 321 .69 E0 , 330 .14 E0 , 333 .03 E0 , 333 .47 E0 , 340 .77 E0 , 345 .65 E0 , 373 .11 E0 , 373 .79 E0 , 411 .82 E0 , 419 .51 E0 , 421 .59 E0 , 422 .02 E0 , 422 .47 E0 , 422 .61 E0 , 441 .75 E0 , 447 .41 E0 , 448 .7 E0 , 472 .89 E0 , 476 .69 E0 , 522 .47 E0 , 522 .62 E0 , 524 .43 E0 , 546 .75 E0 , 549 .53 E0 , 575 .29 E0 , 576 .00 E0 , 625 .55 E0 , 20 .15 E0 , 28 .78 E0 , 29 .57 E0 , 37 .41 E0 , 39 .12 E0 , 50 .24 E0 , 61 .38 E0 , 66 .25 E0 , 73 .42 E0 , 95 .52 E0 , 107 .32 E0 , 122 .04 E0 , 134 .03 E0 , 163 .19 E0 , 163 .48 E0 , 175 .70 E0 , 179 .86 E0 , 211 .27 E0 , 217 .78 E0 , 219 .14 E0 , 262 .52 E0 , 268 .01 E0 , 268 .62 E0 , 336 .25 E0 , 337 .23 E0 , 339 .33 E0 , 427 .38 E0 , 428 .58 E0 , 432 .68 E0 , 528 .99 E0 , 531 .08 E0 , 628 .34 E0 , 253 .24 E0 , 273 .13 E0 , 273 .66 E0 ,
282 .10 E0 , 346 .62 E0 , 347 .19 E0 , 348 .78 E0 , 351 .18 E0 , 450 .10 E0 , 450 .35 E0 , 451 .92 E0 , 455 .56 E0 , 552 .22 E0 , 553 .56 E0 , 555 .74 E0 , 652 .59 E0 , 656 .20 E0 , 14 .13 E0 , 20 .41 E0 , 31 .30 E0 , 33 .84 E0 , 39 .70 E0 , 48 .83 E0 , 54 .50 E0 , 60 .41 E0 , 72 .77 E0 , 75 .25 E0 , 86 .84 E0 , 94 .88 E0 , 96 .40 E0 , 117 .37 E0 , 139 .08 E0 , 147 .73 E0 , 158 .63 E0 , 161 .84 E0 , 192 .11 E0 , 206 .76 E0 , 209 .07 E0 , 213 .32 E0 , 226 .44 E0 , 237 .12 E0 , 330 .90 E0 , 358 .72 E0 , 370 .77 E0 , 372 .72 E0 , 396 .24 E0 , 416 .59 E0 , 484 .02 E0 , 495 .47 E0 , 514 .78 E0 , 515 .65 E0 , 519 .47 E0 , 544 .47 E0 , 560 .11 E0 , 620 .77 E0 , 18 .97 E0 , 28 .93 E0 , 33 .91 E0 , 40 .03 E0 , 44 .66 E0 , 49 .87 E0 , 55 .16 E0 , 60 .90 E0 , 72 .08 E0 , 85 .15 E0 , 97 .06 E0 , 119 .63 E0 , 133 .27 E0 , 143 .84 E0 , 161 .91 E0 , 180 .67 E0 , 198 .44 E0 , 226 .86 E0 , 229 .65 E0 , 258 .27 E0 , 273 .77 E0 , 339 .15 E0 , 350 .13 E0 , 362 .75 E0 , 371 .03 E0 , 393 .32 E0 , 448 .53 E0 , 473 .78 E0 , 511 .12 E0 , 524 .70 E0 , 548 .75 E0 , 551 .64 E0 , 574 .02 E0 , 623 .86 E0 , 21 .46 E0 , 24 .33 E0 , 33 .43 E0 , 39 .22 E0 , 44 .18 E0 , 55 .02 E0 , 94 .33 E0 , 96 .44 E0 , 118 .82 E0 , 128 .48 E0 ,
141 .94 E0 , 156 .92 E0 , 171 .65 E0 , 190 .00 E0 , 223 .26 E0 , 223 .88 E0 , 231 .50 E0 , 265 .05 E0 , 269 .44 E0 , 271 .78 E0 , 273 .46 E0 , 334 .61 E0 , 339 .79 E0 , 349 .52 E0 , 358 .18 E0 , 377 .98 E0 , 394 .77 E0 , 429 .66 E0 , 468 .22 E0 , 487 .27 E0 , 519 .54 E0 , 523 .03 E0 , 612 .99 E0 , 638 .59 E0 , 641 .36 E0 , 622 .05 E0 , 631 .50 E0 , 663 .97 E0 , 646 .9 E0 , 748 .29 E0 , 749 .21 E0 , 750 .14 E0 , 647 .04 E0 , 646 .89 E0 , 746 .9 E0 , 748 .43 E0 , 747 .35 E0 , 749 .27 E0 , 647 .61 E0 , 747 .78 E0 , 750 .51 E0 , 851 .37 E0 , 845 .97 E0 , 847 .54 E0 , 849 .93 E0 , 851 .61 E0 , 849 .75 E0 , 850 .98 E0 , 848 .23 E0};
// http://www.itl.nist.gov/div898/strd/nls/data/hahn1.shtml
void testNistHahn1(void )
{
const int n=7 ;
int info;
VectorXd x(n);
/*
* First try
*/
x<< 10 ., -1 ., .05 , -.00001 , -.05 , .001 , -.000001 ;
// do the computation
hahn1_functor functor;
LevenbergMarquardt<hahn1_functor> lm(functor);
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 1 );
LM_CHECK_N_ITERS(lm, 11 , 10 );
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1 .5324382854 E+00 );
// check x
VERIFY_IS_APPROX(x[0 ], 1 .0776351733 E+00 );
VERIFY_IS_APPROX(x[1 ],-1 .2269296921 E-01 );
VERIFY_IS_APPROX(x[2 ], 4 .0863750610 E-03 );
VERIFY_IS_APPROX(x[3 ],-1 .426264 e-06 ); // shoulde be : -1.4262662514E-06
VERIFY_IS_APPROX(x[4 ],-5 .7609940901 E-03 );
VERIFY_IS_APPROX(x[5 ], 2 .4053735503 E-04 );
VERIFY_IS_APPROX(x[6 ],-1 .2314450199 E-07 );
/*
* Second try
*/
x<< .1 , -.1 , .005 , -.000001 , -.005 , .0001 , -.0000001 ;
// do the computation
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 1 );
LM_CHECK_N_ITERS(lm, 11 , 10 );
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1 .5324382854 E+00 );
// check x
VERIFY_IS_APPROX(x[0 ], 1 .077640 ); // should be : 1.0776351733E+00
VERIFY_IS_APPROX(x[1 ], -0 .1226933 ); // should be : -1.2269296921E-01
VERIFY_IS_APPROX(x[2 ], 0 .004086383 ); // should be : 4.0863750610E-03
VERIFY_IS_APPROX(x[3 ], -1 .426277 e-06 ); // shoulde be : -1.4262662514E-06
VERIFY_IS_APPROX(x[4 ],-5 .7609940901 E-03 );
VERIFY_IS_APPROX(x[5 ], 0 .00024053772 ); // should be : 2.4053735503E-04
VERIFY_IS_APPROX(x[6 ], -1 .231450 e-07 ); // should be : -1.2314450199E-07
}
struct misra1d_functor : Functor<double >
{
misra1d_functor(void ) : Functor<double >(2 ,14 ) {}
static const double x[14 ];
static const double y[14 ];
int operator ()(const VectorXd &b, VectorXd &fvec)
{
assert(b.size()==2 );
assert(fvec.size()==14 );
for (int i=0 ; i<14 ; i++) {
fvec[i] = b[0 ]*b[1 ]*x[i]/(1 .+b[1 ]*x[i]) - y[i];
}
return 0 ;
}
int df(const VectorXd &b, MatrixXd &fjac)
{
assert(b.size()==2 );
assert(fjac.rows()==14 );
assert(fjac.cols()==2 );
for (int i=0 ; i<14 ; i++) {
double den = 1 .+b[1 ]*x[i];
fjac(i,0 ) = b[1 ]*x[i] / den;
fjac(i,1 ) = b[0 ]*x[i]*(den-b[1 ]*x[i])/den/den;
}
return 0 ;
}
};
const double misra1d_functor::x[14 ] = { 77 .6 E0, 114 .9 E0, 141 .1 E0, 190 .8 E0, 239 .9 E0, 289 .0 E0, 332 .8 E0, 378 .4 E0, 434 .8 E0, 477 .3 E0, 536 .8 E0, 593 .1 E0, 689 .1 E0, 760 .0 E0};
const double misra1d_functor::y[14 ] = { 10 .07 E0, 14 .73 E0, 17 .94 E0, 23 .93 E0, 29 .61 E0, 35 .18 E0, 40 .02 E0, 44 .82 E0, 50 .76 E0, 55 .05 E0, 61 .01 E0, 66 .40 E0, 75 .47 E0, 81 .78 E0};
// http://www.itl.nist.gov/div898/strd/nls/data/misra1d.shtml
void testNistMisra1d(void )
{
const int n=2 ;
int info;
VectorXd x(n);
/*
* First try
*/
x<< 500 ., 0 .0001 ;
// do the computation
misra1d_functor functor;
LevenbergMarquardt<misra1d_functor> lm(functor);
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 3 );
LM_CHECK_N_ITERS(lm, 9 , 7 );
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5 .6419295283 E-02 );
// check x
VERIFY_IS_APPROX(x[0 ], 4 .3736970754 E+02 );
VERIFY_IS_APPROX(x[1 ], 3 .0227324449 E-04 );
/*
* Second try
*/
x<< 450 ., 0 .0003 ;
// do the computation
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 1 );
LM_CHECK_N_ITERS(lm, 4 , 3 );
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5 .6419295283 E-02 );
// check x
VERIFY_IS_APPROX(x[0 ], 4 .3736970754 E+02 );
VERIFY_IS_APPROX(x[1 ], 3 .0227324449 E-04 );
}
struct lanczos1_functor : Functor<double >
{
lanczos1_functor(void ) : Functor<double >(6 ,24 ) {}
static const double x[24 ];
static const double y[24 ];
int operator ()(const VectorXd &b, VectorXd &fvec)
{
assert(b.size()==6 );
assert(fvec.size()==24 );
for (int i=0 ; i<24 ; i++)
fvec[i] = b[0 ]*exp(-b[1 ]*x[i]) + b[2 ]*exp(-b[3 ]*x[i]) + b[4 ]*exp(-b[5 ]*x[i]) - y[i];
return 0 ;
}
int df(const VectorXd &b, MatrixXd &fjac)
{
assert(b.size()==6 );
assert(fjac.rows()==24 );
assert(fjac.cols()==6 );
for (int i=0 ; i<24 ; i++) {
fjac(i,0 ) = exp(-b[1 ]*x[i]);
fjac(i,1 ) = -b[0 ]*x[i]*exp(-b[1 ]*x[i]);
fjac(i,2 ) = exp(-b[3 ]*x[i]);
fjac(i,3 ) = -b[2 ]*x[i]*exp(-b[3 ]*x[i]);
fjac(i,4 ) = exp(-b[5 ]*x[i]);
fjac(i,5 ) = -b[4 ]*x[i]*exp(-b[5 ]*x[i]);
}
return 0 ;
}
};
const double lanczos1_functor::x[24 ] = { 0 .000000000000 E+00 , 5 .000000000000 E-02 , 1 .000000000000 E-01 , 1 .500000000000 E-01 , 2 .000000000000 E-01 , 2 .500000000000 E-01 , 3 .000000000000 E-01 , 3 .500000000000 E-01 , 4 .000000000000 E-01 , 4 .500000000000 E-01 , 5 .000000000000 E-01 , 5 .500000000000 E-01 , 6 .000000000000 E-01 , 6 .500000000000 E-01 , 7 .000000000000 E-01 , 7 .500000000000 E-01 , 8 .000000000000 E-01 , 8 .500000000000 E-01 , 9 .000000000000 E-01 , 9 .500000000000 E-01 , 1 .000000000000 E+00 , 1 .050000000000 E+00 , 1 .100000000000 E+00 , 1 .150000000000 E+00 };
const double lanczos1_functor::y[24 ] = { 2 .513400000000 E+00 ,2 .044333373291 E+00 ,1 .668404436564 E+00 ,1 .366418021208 E+00 ,1 .123232487372 E+00 ,9 .268897180037 E-01 ,7 .679338563728 E-01 ,6 .388775523106 E-01 ,5 .337835317402 E-01 ,4 .479363617347 E-01 ,3 .775847884350 E-01 ,3 .197393199326 E-01 ,2 .720130773746 E-01 ,2 .324965529032 E-01 ,1 .996589546065 E-01 ,1 .722704126914 E-01 ,1 .493405660168 E-01 ,1 .300700206922 E-01 ,1 .138119324644 E-01 ,1 .000415587559 E-01 ,8 .833209084540 E-02 ,7 .833544019350 E-02 ,6 .976693743449 E-02 ,6 .239312536719 E-02 };
// http://www.itl.nist.gov/div898/strd/nls/data/lanczos1.shtml
void testNistLanczos1(void )
{
const int n=6 ;
int info;
VectorXd x(n);
/*
* First try
*/
x<< 1 .2 , 0 .3 , 5 .6 , 5 .5 , 6 .5 , 7 .6 ;
// do the computation
lanczos1_functor functor;
LevenbergMarquardt<lanczos1_functor> lm(functor);
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 2 );
LM_CHECK_N_ITERS(lm, 79 , 72 );
// check norm^2
std::cout.precision(30 );
std::cout << lm.fvec.squaredNorm() << "\n" ;
VERIFY(lm.fvec.squaredNorm() <= 1 .4307867721 E-25 );
// check x
VERIFY_IS_APPROX(x[0 ], 9 .5100000027 E-02 );
VERIFY_IS_APPROX(x[1 ], 1 .0000000001 E+00 );
VERIFY_IS_APPROX(x[2 ], 8 .6070000013 E-01 );
VERIFY_IS_APPROX(x[3 ], 3 .0000000002 E+00 );
VERIFY_IS_APPROX(x[4 ], 1 .5575999998 E+00 );
VERIFY_IS_APPROX(x[5 ], 5 .0000000001 E+00 );
/*
* Second try
*/
x<< 0 .5 , 0 .7 , 3 .6 , 4 .2 , 4 ., 6 .3 ;
// do the computation
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 2 );
LM_CHECK_N_ITERS(lm, 9 , 8 );
// check norm^2
VERIFY(lm.fvec.squaredNorm() <= 1 .4307867721 E-25 );
// check x
VERIFY_IS_APPROX(x[0 ], 9 .5100000027 E-02 );
VERIFY_IS_APPROX(x[1 ], 1 .0000000001 E+00 );
VERIFY_IS_APPROX(x[2 ], 8 .6070000013 E-01 );
VERIFY_IS_APPROX(x[3 ], 3 .0000000002 E+00 );
VERIFY_IS_APPROX(x[4 ], 1 .5575999998 E+00 );
VERIFY_IS_APPROX(x[5 ], 5 .0000000001 E+00 );
}
struct rat42_functor : Functor<double >
{
rat42_functor(void ) : Functor<double >(3 ,9 ) {}
static const double x[9 ];
static const double y[9 ];
int operator ()(const VectorXd &b, VectorXd &fvec)
{
assert(b.size()==3 );
assert(fvec.size()==9 );
for (int i=0 ; i<9 ; i++) {
fvec[i] = b[0 ] / (1 .+exp(b[1 ]-b[2 ]*x[i])) - y[i];
}
return 0 ;
}
int df(const VectorXd &b, MatrixXd &fjac)
{
assert(b.size()==3 );
assert(fjac.rows()==9 );
assert(fjac.cols()==3 );
for (int i=0 ; i<9 ; i++) {
double e = exp(b[1 ]-b[2 ]*x[i]);
fjac(i,0 ) = 1 ./(1 .+e);
fjac(i,1 ) = -b[0 ]*e/(1 .+e)/(1 .+e);
fjac(i,2 ) = +b[0 ]*e*x[i]/(1 .+e)/(1 .+e);
}
return 0 ;
}
};
const double rat42_functor::x[9 ] = { 9 .000 E0, 14 .000 E0, 21 .000 E0, 28 .000 E0, 42 .000 E0, 57 .000 E0, 63 .000 E0, 70 .000 E0, 79 .000 E0 };
const double rat42_functor::y[9 ] = { 8 .930 E0 ,10 .800 E0 ,18 .590 E0 ,22 .330 E0 ,39 .350 E0 ,56 .110 E0 ,61 .730 E0 ,64 .620 E0 ,67 .080 E0 };
// http://www.itl.nist.gov/div898/strd/nls/data/ratkowsky2.shtml
void testNistRat42(void )
{
const int n=3 ;
int info;
VectorXd x(n);
/*
* First try
*/
x<< 100 ., 1 ., 0 .1 ;
// do the computation
rat42_functor functor;
LevenbergMarquardt<rat42_functor> lm(functor);
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 1 );
LM_CHECK_N_ITERS(lm, 10 , 8 );
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 8 .0565229338 E+00 );
// check x
VERIFY_IS_APPROX(x[0 ], 7 .2462237576 E+01 );
VERIFY_IS_APPROX(x[1 ], 2 .6180768402 E+00 );
VERIFY_IS_APPROX(x[2 ], 6 .7359200066 E-02 );
/*
* Second try
*/
x<< 75 ., 2 .5 , 0 .07 ;
// do the computation
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 1 );
LM_CHECK_N_ITERS(lm, 6 , 5 );
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 8 .0565229338 E+00 );
// check x
VERIFY_IS_APPROX(x[0 ], 7 .2462237576 E+01 );
VERIFY_IS_APPROX(x[1 ], 2 .6180768402 E+00 );
VERIFY_IS_APPROX(x[2 ], 6 .7359200066 E-02 );
}
struct MGH10_functor : Functor<double >
{
MGH10_functor(void ) : Functor<double >(3 ,16 ) {}
static const double x[16 ];
static const double y[16 ];
int operator ()(const VectorXd &b, VectorXd &fvec)
{
assert(b.size()==3 );
assert(fvec.size()==16 );
for (int i=0 ; i<16 ; i++)
fvec[i] = b[0 ] * exp(b[1 ]/(x[i]+b[2 ])) - y[i];
return 0 ;
}
int df(const VectorXd &b, MatrixXd &fjac)
{
assert(b.size()==3 );
assert(fjac.rows()==16 );
assert(fjac.cols()==3 );
for (int i=0 ; i<16 ; i++) {
double factor = 1 ./(x[i]+b[2 ]);
double e = exp(b[1 ]*factor);
fjac(i,0 ) = e;
fjac(i,1 ) = b[0 ]*factor*e;
fjac(i,2 ) = -b[1 ]*b[0 ]*factor*factor*e;
}
return 0 ;
}
};
const double MGH10_functor::x[16 ] = { 5 .000000 E+01 , 5 .500000 E+01 , 6 .000000 E+01 , 6 .500000 E+01 , 7 .000000 E+01 , 7 .500000 E+01 , 8 .000000 E+01 , 8 .500000 E+01 , 9 .000000 E+01 , 9 .500000 E+01 , 1 .000000 E+02 , 1 .050000 E+02 , 1 .100000 E+02 , 1 .150000 E+02 , 1 .200000 E+02 , 1 .250000 E+02 };
const double MGH10_functor::y[16 ] = { 3 .478000 E+04 , 2 .861000 E+04 , 2 .365000 E+04 , 1 .963000 E+04 , 1 .637000 E+04 , 1 .372000 E+04 , 1 .154000 E+04 , 9 .744000 E+03 , 8 .261000 E+03 , 7 .030000 E+03 , 6 .005000 E+03 , 5 .147000 E+03 , 4 .427000 E+03 , 3 .820000 E+03 , 3 .307000 E+03 , 2 .872000 E+03 };
// http://www.itl.nist.gov/div898/strd/nls/data/mgh10.shtml
void testNistMGH10(void )
{
const int n=3 ;
int info;
VectorXd x(n);
/*
* First try
*/
x<< 2 ., 400000 ., 25000 .;
// do the computation
MGH10_functor functor;
LevenbergMarquardt<MGH10_functor> lm(functor);
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 2 );
LM_CHECK_N_ITERS(lm, 284 , 249 );
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 8 .7945855171 E+01 );
// check x
VERIFY_IS_APPROX(x[0 ], 5 .6096364710 E-03 );
VERIFY_IS_APPROX(x[1 ], 6 .1813463463 E+03 );
VERIFY_IS_APPROX(x[2 ], 3 .4522363462 E+02 );
/*
* Second try
*/
x<< 0 .02 , 4000 ., 250 .;
// do the computation
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 3 );
LM_CHECK_N_ITERS(lm, 126 , 116 );
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 8 .7945855171 E+01 );
// check x
VERIFY_IS_APPROX(x[0 ], 5 .6096364710 E-03 );
VERIFY_IS_APPROX(x[1 ], 6 .1813463463 E+03 );
VERIFY_IS_APPROX(x[2 ], 3 .4522363462 E+02 );
}
struct BoxBOD_functor : Functor<double >
{
BoxBOD_functor(void ) : Functor<double >(2 ,6 ) {}
static const double x[6 ];
int operator ()(const VectorXd &b, VectorXd &fvec)
{
static const double y[6 ] = { 109 ., 149 ., 149 ., 191 ., 213 ., 224 . };
assert(b.size()==2 );
assert(fvec.size()==6 );
for (int i=0 ; i<6 ; i++)
fvec[i] = b[0 ]*(1 .-exp(-b[1 ]*x[i])) - y[i];
return 0 ;
}
int df(const VectorXd &b, MatrixXd &fjac)
{
assert(b.size()==2 );
assert(fjac.rows()==6 );
assert(fjac.cols()==2 );
for (int i=0 ; i<6 ; i++) {
double e = exp(-b[1 ]*x[i]);
fjac(i,0 ) = 1 .-e;
fjac(i,1 ) = b[0 ]*x[i]*e;
}
return 0 ;
}
};
const double BoxBOD_functor::x[6 ] = { 1 ., 2 ., 3 ., 5 ., 7 ., 10 . };
// http://www.itl.nist.gov/div898/strd/nls/data/boxbod.shtml
void testNistBoxBOD(void )
{
const int n=2 ;
int info;
VectorXd x(n);
/*
* First try
*/
x<< 1 ., 1 .;
// do the computation
BoxBOD_functor functor;
LevenbergMarquardt<BoxBOD_functor> lm(functor);
lm.parameters.ftol = 1 .E6*NumTraits<double >::epsilon();
lm.parameters.xtol = 1 .E6*NumTraits<double >::epsilon();
lm.parameters.factor = 10 .;
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 1 );
LM_CHECK_N_ITERS(lm, 31 , 25 );
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1 .1680088766 E+03 );
// check x
VERIFY_IS_APPROX(x[0 ], 2 .1380940889 E+02 );
VERIFY_IS_APPROX(x[1 ], 5 .4723748542 E-01 );
/*
* Second try
*/
x<< 100 ., 0 .75 ;
// do the computation
lm.resetParameters();
lm.parameters.ftol = NumTraits<double >::epsilon();
lm.parameters.xtol = NumTraits<double >::epsilon();
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 1 );
LM_CHECK_N_ITERS(lm, 15 , 14 );
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1 .1680088766 E+03 );
// check x
VERIFY_IS_APPROX(x[0 ], 2 .1380940889 E+02 );
VERIFY_IS_APPROX(x[1 ], 5 .4723748542 E-01 );
}
struct MGH17_functor : Functor<double >
{
MGH17_functor(void ) : Functor<double >(5 ,33 ) {}
static const double x[33 ];
static const double y[33 ];
int operator ()(const VectorXd &b, VectorXd &fvec)
{
assert(b.size()==5 );
assert(fvec.size()==33 );
for (int i=0 ; i<33 ; i++)
fvec[i] = b[0 ] + b[1 ]*exp(-b[3 ]*x[i]) + b[2 ]*exp(-b[4 ]*x[i]) - y[i];
return 0 ;
}
int df(const VectorXd &b, MatrixXd &fjac)
{
assert(b.size()==5 );
assert(fjac.rows()==33 );
assert(fjac.cols()==5 );
for (int i=0 ; i<33 ; i++) {
fjac(i,0 ) = 1 .;
fjac(i,1 ) = exp(-b[3 ]*x[i]);
fjac(i,2 ) = exp(-b[4 ]*x[i]);
fjac(i,3 ) = -x[i]*b[1 ]*exp(-b[3 ]*x[i]);
fjac(i,4 ) = -x[i]*b[2 ]*exp(-b[4 ]*x[i]);
}
return 0 ;
}
};
const double MGH17_functor::x[33 ] = { 0 .000000 E+00 , 1 .000000 E+01 , 2 .000000 E+01 , 3 .000000 E+01 , 4 .000000 E+01 , 5 .000000 E+01 , 6 .000000 E+01 , 7 .000000 E+01 , 8 .000000 E+01 , 9 .000000 E+01 , 1 .000000 E+02 , 1 .100000 E+02 , 1 .200000 E+02 , 1 .300000 E+02 , 1 .400000 E+02 , 1 .500000 E+02 , 1 .600000 E+02 , 1 .700000 E+02 , 1 .800000 E+02 , 1 .900000 E+02 , 2 .000000 E+02 , 2 .100000 E+02 , 2 .200000 E+02 , 2 .300000 E+02 , 2 .400000 E+02 , 2 .500000 E+02 , 2 .600000 E+02 , 2 .700000 E+02 , 2 .800000 E+02 , 2 .900000 E+02 , 3 .000000 E+02 , 3 .100000 E+02 , 3 .200000 E+02 };
const double MGH17_functor::y[33 ] = { 8 .440000 E-01 , 9 .080000 E-01 , 9 .320000 E-01 , 9 .360000 E-01 , 9 .250000 E-01 , 9 .080000 E-01 , 8 .810000 E-01 , 8 .500000 E-01 , 8 .180000 E-01 , 7 .840000 E-01 , 7 .510000 E-01 , 7 .180000 E-01 , 6 .850000 E-01 , 6 .580000 E-01 , 6 .280000 E-01 , 6 .030000 E-01 , 5 .800000 E-01 , 5 .580000 E-01 , 5 .380000 E-01 , 5 .220000 E-01 , 5 .060000 E-01 , 4 .900000 E-01 , 4 .780000 E-01 , 4 .670000 E-01 , 4 .570000 E-01 , 4 .480000 E-01 , 4 .380000 E-01 , 4 .310000 E-01 , 4 .240000 E-01 , 4 .200000 E-01 , 4 .140000 E-01 , 4 .110000 E-01 , 4 .060000 E-01 };
// http://www.itl.nist.gov/div898/strd/nls/data/mgh17.shtml
void testNistMGH17(void )
{
const int n=5 ;
int info;
VectorXd x(n);
/*
* First try
*/
x<< 50 ., 150 ., -100 ., 1 ., 2 .;
// do the computation
MGH17_functor functor;
LevenbergMarquardt<MGH17_functor> lm(functor);
lm.parameters.ftol = NumTraits<double >::epsilon();
lm.parameters.xtol = NumTraits<double >::epsilon();
lm.parameters.maxfev = 1000 ;
info = lm.minimize(x);
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5 .4648946975 E-05 );
// check x
VERIFY_IS_APPROX(x[0 ], 3 .7541005211 E-01 );
VERIFY_IS_APPROX(x[1 ], 1 .9358469127 E+00 );
VERIFY_IS_APPROX(x[2 ], -1 .4646871366 E+00 );
VERIFY_IS_APPROX(x[3 ], 1 .2867534640 E-02 );
VERIFY_IS_APPROX(x[4 ], 2 .2122699662 E-02 );
// check return value
VERIFY_IS_EQUAL(info, 2 );
LM_CHECK_N_ITERS(lm, 602 , 545 );
/*
* Second try
*/
x<< 0 .5 ,1 .5 ,-1 ,0 .01 ,0 .02 ;
// do the computation
lm.resetParameters();
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 1 );
LM_CHECK_N_ITERS(lm, 18 , 15 );
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5 .4648946975 E-05 );
// check x
VERIFY_IS_APPROX(x[0 ], 3 .7541005211 E-01 );
VERIFY_IS_APPROX(x[1 ], 1 .9358469127 E+00 );
VERIFY_IS_APPROX(x[2 ], -1 .4646871366 E+00 );
VERIFY_IS_APPROX(x[3 ], 1 .2867534640 E-02 );
VERIFY_IS_APPROX(x[4 ], 2 .2122699662 E-02 );
}
struct MGH09_functor : Functor<double >
{
MGH09_functor(void ) : Functor<double >(4 ,11 ) {}
static const double _x[11 ];
static const double y[11 ];
int operator ()(const VectorXd &b, VectorXd &fvec)
{
assert(b.size()==4 );
assert(fvec.size()==11 );
for (int i=0 ; i<11 ; i++) {
double x = _x[i], xx=x*x;
fvec[i] = b[0 ]*(xx+x*b[1 ])/(xx+x*b[2 ]+b[3 ]) - y[i];
}
return 0 ;
}
int df(const VectorXd &b, MatrixXd &fjac)
{
assert(b.size()==4 );
assert(fjac.rows()==11 );
assert(fjac.cols()==4 );
for (int i=0 ; i<11 ; i++) {
double x = _x[i], xx=x*x;
double factor = 1 ./(xx+x*b[2 ]+b[3 ]);
fjac(i,0 ) = (xx+x*b[1 ]) * factor;
fjac(i,1 ) = b[0 ]*x* factor;
fjac(i,2 ) = - b[0 ]*(xx+x*b[1 ]) * x * factor * factor;
fjac(i,3 ) = - b[0 ]*(xx+x*b[1 ]) * factor * factor;
}
return 0 ;
}
};
const double MGH09_functor::_x[11 ] = { 4 ., 2 ., 1 ., 5 .E-1 , 2 .5 E-01 , 1 .670000 E-01 , 1 .250000 E-01 , 1 .E-01 , 8 .330000 E-02 , 7 .140000 E-02 , 6 .250000 E-02 };
const double MGH09_functor::y[11 ] = { 1 .957000 E-01 , 1 .947000 E-01 , 1 .735000 E-01 , 1 .600000 E-01 , 8 .440000 E-02 , 6 .270000 E-02 , 4 .560000 E-02 , 3 .420000 E-02 , 3 .230000 E-02 , 2 .350000 E-02 , 2 .460000 E-02 };
// http://www.itl.nist.gov/div898/strd/nls/data/mgh09.shtml
void testNistMGH09(void )
{
const int n=4 ;
int info;
VectorXd x(n);
/*
* First try
*/
x<< 25 ., 39 , 41 .5 , 39 .;
// do the computation
MGH09_functor functor;
LevenbergMarquardt<MGH09_functor> lm(functor);
lm.parameters.maxfev = 1000 ;
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 1 );
LM_CHECK_N_ITERS(lm, 490 , 376 );
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 3 .0750560385 E-04 );
// check x
VERIFY_IS_APPROX(x[0 ], 0 .1928077089 ); // should be 1.9280693458E-01
VERIFY_IS_APPROX(x[1 ], 0 .19126423573 ); // should be 1.9128232873E-01
VERIFY_IS_APPROX(x[2 ], 0 .12305309914 ); // should be 1.2305650693E-01
VERIFY_IS_APPROX(x[3 ], 0 .13605395375 ); // should be 1.3606233068E-01
/*
* Second try
*/
x<< 0 .25 , 0 .39 , 0 .415 , 0 .39 ;
// do the computation
lm.resetParameters();
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 1 );
LM_CHECK_N_ITERS(lm, 18 , 16 );
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 3 .0750560385 E-04 );
// check x
VERIFY_IS_APPROX(x[0 ], 0 .19280781 ); // should be 1.9280693458E-01
VERIFY_IS_APPROX(x[1 ], 0 .19126265 ); // should be 1.9128232873E-01
VERIFY_IS_APPROX(x[2 ], 0 .12305280 ); // should be 1.2305650693E-01
VERIFY_IS_APPROX(x[3 ], 0 .13605322 ); // should be 1.3606233068E-01
}
struct Bennett5_functor : Functor<double >
{
Bennett5_functor(void ) : Functor<double >(3 ,154 ) {}
static const double x[154 ];
static const double y[154 ];
int operator ()(const VectorXd &b, VectorXd &fvec)
{
assert(b.size()==3 );
assert(fvec.size()==154 );
for (int i=0 ; i<154 ; i++)
fvec[i] = b[0 ]* pow(b[1 ]+x[i],-1 ./b[2 ]) - y[i];
return 0 ;
}
int df(const VectorXd &b, MatrixXd &fjac)
{
assert(b.size()==3 );
assert(fjac.rows()==154 );
assert(fjac.cols()==3 );
for (int i=0 ; i<154 ; i++) {
double e = pow(b[1 ]+x[i],-1 ./b[2 ]);
fjac(i,0 ) = e;
fjac(i,1 ) = - b[0 ]*e/b[2 ]/(b[1 ]+x[i]);
fjac(i,2 ) = b[0 ]*e*log(b[1 ]+x[i])/b[2 ]/b[2 ];
}
return 0 ;
}
};
const double Bennett5_functor::x[154 ] = { 7 .447168 E0, 8 .102586 E0, 8 .452547 E0, 8 .711278 E0, 8 .916774 E0, 9 .087155 E0, 9 .232590 E0, 9 .359535 E0, 9 .472166 E0, 9 .573384 E0, 9 .665293 E0, 9 .749461 E0, 9 .827092 E0, 9 .899128 E0, 9 .966321 E0, 10 .029280 E0, 10 .088510 E0, 10 .144430 E0, 10 .197380 E0, 10 .247670 E0, 10 .295560 E0, 10 .341250 E0, 10 .384950 E0, 10 .426820 E0, 10 .467000 E0, 10 .505640 E0, 10 .542830 E0, 10 .578690 E0, 10 .613310 E0, 10 .646780 E0, 10 .679150 E0, 10 .710520 E0, 10 .740920 E0, 10 .770440 E0, 10 .799100 E0, 10 .826970 E0, 10 .854080 E0, 10 .880470 E0, 10 .906190 E0, 10 .931260 E0, 10 .955720 E0, 10 .979590 E0, 11 .002910 E0, 11 .025700 E0, 11 .047980 E0, 11 .069770 E0, 11 .091100 E0, 11 .111980 E0, 11 .132440 E0, 11 .152480 E0, 11 .172130 E0, 11 .191410 E0, 11 .210310 E0, 11 .228870 E0, 11 .247090 E0, 11 .264980 E0, 11 .282560 E0, 11 .299840 E0, 11 .316820 E0, 11 .333520 E0, 11 .349940 E0, 11 .366100 E0, 11 .382000 E0, 11 .397660 E0, 11 .413070 E0, 11 .428240 E0, 11 .443200 E0, 11 .457930 E0, 11 .472440 E0, 11 .486750 E0, 11 .500860 E0, 11 .514770 E0, 11 .528490 E0, 11 .542020 E0, 11 .555380 E0, 11 .568550 E0,
11 .581560 E0, 11 .594420 E0, 11 .607121 E0, 11 .619640 E0, 11 .632000 E0, 11 .644210 E0, 11 .656280 E0, 11 .668200 E0, 11 .679980 E0, 11 .691620 E0, 11 .703130 E0, 11 .714510 E0, 11 .725760 E0, 11 .736880 E0, 11 .747890 E0, 11 .758780 E0, 11 .769550 E0, 11 .780200 E0, 11 .790730 E0, 11 .801160 E0, 11 .811480 E0, 11 .821700 E0, 11 .831810 E0, 11 .841820 E0, 11 .851730 E0, 11 .861550 E0, 11 .871270 E0, 11 .880890 E0, 11 .890420 E0, 11 .899870 E0, 11 .909220 E0, 11 .918490 E0, 11 .927680 E0, 11 .936780 E0, 11 .945790 E0, 11 .954730 E0, 11 .963590 E0, 11 .972370 E0, 11 .981070 E0, 11 .989700 E0, 11 .998260 E0, 12 .006740 E0, 12 .015150 E0, 12 .023490 E0, 12 .031760 E0, 12 .039970 E0, 12 .048100 E0, 12 .056170 E0, 12 .064180 E0, 12 .072120 E0, 12 .080010 E0, 12 .087820 E0, 12 .095580 E0, 12 .103280 E0, 12 .110920 E0, 12 .118500 E0, 12 .126030 E0, 12 .133500 E0, 12 .140910 E0, 12 .148270 E0, 12 .155570 E0, 12 .162830 E0, 12 .170030 E0, 12 .177170 E0, 12 .184270 E0, 12 .191320 E0, 12 .198320 E0, 12 .205270 E0, 12 .212170 E0, 12 .219030 E0, 12 .225840 E0, 12 .232600 E0, 12 .239320 E0, 12 .245990 E0, 12 .252620 E0, 12 .259200 E0, 12 .265750 E0, 12 .272240 E0 };
const double Bennett5_functor::y[154 ] = { -34 .834702 E0 ,-34 .393200 E0 ,-34 .152901 E0 ,-33 .979099 E0 ,-33 .845901 E0 ,-33 .732899 E0 ,-33 .640301 E0 ,-33 .559200 E0 ,-33 .486801 E0 ,-33 .423100 E0 ,-33 .365101 E0 ,-33 .313000 E0 ,-33 .260899 E0 ,-33 .217400 E0 ,-33 .176899 E0 ,-33 .139198 E0 ,-33 .101601 E0 ,-33 .066799 E0 ,-33 .035000 E0 ,-33 .003101 E0 ,-32 .971298 E0 ,-32 .942299 E0 ,-32 .916302 E0 ,-32 .890202 E0 ,-32 .864101 E0 ,-32 .841000 E0 ,-32 .817799 E0 ,-32 .797501 E0 ,-32 .774300 E0 ,-32 .757000 E0 ,-32 .733799 E0 ,-32 .716400 E0 ,-32 .699100 E0 ,-32 .678799 E0 ,-32 .661400 E0 ,-32 .644001 E0 ,-32 .626701 E0 ,-32 .612202 E0 ,-32 .597698 E0 ,-32 .583199 E0 ,-32 .568699 E0 ,-32 .554298 E0 ,-32 .539799 E0 ,-32 .525299 E0 ,-32 .510799 E0 ,-32 .499199 E0 ,-32 .487598 E0 ,-32 .473202 E0 ,-32 .461601 E0 ,-32 .435501 E0 ,-32 .435501 E0 ,-32 .426800 E0 ,-32 .412300 E0 ,-32 .400799 E0 ,-32 .392101 E0 ,-32 .380501 E0 ,-32 .366001 E0 ,-32 .357300 E0 ,-32 .348598 E0 ,-32 .339901 E0 ,-32 .328400 E0 ,-32 .319698 E0 ,-32 .311001 E0 ,-32 .299400 E0 ,-32 .290699 E0 ,-32 .282001 E0 ,-32 .273300 E0 ,-32 .264599 E0 ,-32 .256001 E0 ,-32 .247299 E0
,-32 .238602 E0 ,-32 .229900 E0 ,-32 .224098 E0 ,-32 .215401 E0 ,-32 .203800 E0 ,-32 .198002 E0 ,-32 .189400 E0 ,-32 .183601 E0 ,-32 .174900 E0 ,-32 .169102 E0 ,-32 .163300 E0 ,-32 .154598 E0 ,-32 .145901 E0 ,-32 .140099 E0 ,-32 .131401 E0 ,-32 .125599 E0 ,-32 .119801 E0 ,-32 .111198 E0 ,-32 .105400 E0 ,-32 .096699 E0 ,-32 .090900 E0 ,-32 .088001 E0 ,-32 .079300 E0 ,-32 .073502 E0 ,-32 .067699 E0 ,-32 .061901 E0 ,-32 .056099 E0 ,-32 .050301 E0 ,-32 .044498 E0 ,-32 .038799 E0 ,-32 .033001 E0 ,-32 .027199 E0 ,-32 .024300 E0 ,-32 .018501 E0 ,-32 .012699 E0 ,-32 .004002 E0 ,-32 .001099 E0 ,-31 .995300 E0 ,-31 .989500 E0 ,-31 .983700 E0 ,-31 .977900 E0 ,-31 .972099 E0 ,-31 .969299 E0 ,-31 .963501 E0 ,-31 .957701 E0 ,-31 .951900 E0 ,-31 .946100 E0 ,-31 .940300 E0 ,-31 .937401 E0 ,-31 .931601 E0 ,-31 .925800 E0 ,-31 .922899 E0 ,-31 .917101 E0 ,-31 .911301 E0 ,-31 .908400 E0 ,-31 .902599 E0 ,-31 .896900 E0 ,-31 .893999 E0 ,-31 .888201 E0 ,-31 .885300 E0 ,-31 .882401 E0 ,-31 .876600 E0 ,-31 .873699 E0 ,-31 .867901 E0 ,-31 .862101 E0 ,-31 .859200 E0 ,-31 .856300 E0 ,-31 .850500 E0 ,-31 .844700 E0 ,-31 .841801 E0 ,-31 .838900 E0 ,-31 .833099 E0 ,-31 .830200 E0 ,
-31 .827299 E0 ,-31 .821600 E0 ,-31 .818701 E0 ,-31 .812901 E0 ,-31 .809999 E0 ,-31 .807100 E0 ,-31 .801300 E0 ,-31 .798401 E0 ,-31 .795500 E0 ,-31 .789700 E0 ,-31 .786800 E0 };
// http://www.itl.nist.gov/div898/strd/nls/data/bennett5.shtml
void testNistBennett5(void )
{
const int n=3 ;
int info;
VectorXd x(n);
/*
* First try
*/
x<< -2000 ., 50 ., 0 .8 ;
// do the computation
Bennett5_functor functor;
LevenbergMarquardt<Bennett5_functor> lm(functor);
lm.parameters.maxfev = 1000 ;
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 1 );
LM_CHECK_N_ITERS(lm, 758 , 744 );
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5 .2404744073 E-04 );
// check x
VERIFY_IS_APPROX(x[0 ], -2 .5235058043 E+03 );
VERIFY_IS_APPROX(x[1 ], 4 .6736564644 E+01 );
VERIFY_IS_APPROX(x[2 ], 9 .3218483193 E-01 );
/*
* Second try
*/
x<< -1500 ., 45 ., 0 .85 ;
// do the computation
lm.resetParameters();
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 1 );
LM_CHECK_N_ITERS(lm, 203 , 192 );
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5 .2404744073 E-04 );
// check x
VERIFY_IS_APPROX(x[0 ], -2523 .3007865 ); // should be -2.5235058043E+03
VERIFY_IS_APPROX(x[1 ], 46 .735705771 ); // should be 4.6736564644E+01);
VERIFY_IS_APPROX(x[2 ], 0 .93219881891 ); // should be 9.3218483193E-01);
}
struct thurber_functor : Functor<double >
{
thurber_functor(void ) : Functor<double >(7 ,37 ) {}
static const double _x[37 ];
static const double _y[37 ];
int operator ()(const VectorXd &b, VectorXd &fvec)
{
// int called=0; printf("call hahn1_functor with iflag=%d, called=%d\n", iflag, called); if (iflag==1) called++;
assert(b.size()==7 );
assert(fvec.size()==37 );
for (int i=0 ; i<37 ; i++) {
double x=_x[i], xx=x*x, xxx=xx*x;
fvec[i] = (b[0 ]+b[1 ]*x+b[2 ]*xx+b[3 ]*xxx) / (1 .+b[4 ]*x+b[5 ]*xx+b[6 ]*xxx) - _y[i];
}
return 0 ;
}
int df(const VectorXd &b, MatrixXd &fjac)
{
assert(b.size()==7 );
assert(fjac.rows()==37 );
assert(fjac.cols()==7 );
for (int i=0 ; i<37 ; i++) {
double x=_x[i], xx=x*x, xxx=xx*x;
double fact = 1 ./(1 .+b[4 ]*x+b[5 ]*xx+b[6 ]*xxx);
fjac(i,0 ) = 1 .*fact;
fjac(i,1 ) = x*fact;
fjac(i,2 ) = xx*fact;
fjac(i,3 ) = xxx*fact;
fact = - (b[0 ]+b[1 ]*x+b[2 ]*xx+b[3 ]*xxx) * fact * fact;
fjac(i,4 ) = x*fact;
fjac(i,5 ) = xx*fact;
fjac(i,6 ) = xxx*fact;
}
return 0 ;
}
};
const double thurber_functor::_x[37 ] = { -3 .067 E0, -2 .981 E0, -2 .921 E0, -2 .912 E0, -2 .840 E0, -2 .797 E0, -2 .702 E0, -2 .699 E0, -2 .633 E0, -2 .481 E0, -2 .363 E0, -2 .322 E0, -1 .501 E0, -1 .460 E0, -1 .274 E0, -1 .212 E0, -1 .100 E0, -1 .046 E0, -0 .915 E0, -0 .714 E0, -0 .566 E0, -0 .545 E0, -0 .400 E0, -0 .309 E0, -0 .109 E0, -0 .103 E0, 0 .010 E0, 0 .119 E0, 0 .377 E0, 0 .790 E0, 0 .963 E0, 1 .006 E0, 1 .115 E0, 1 .572 E0, 1 .841 E0, 2 .047 E0, 2 .200 E0 };
const double thurber_functor::_y[37 ] = { 80 .574 E0, 84 .248 E0, 87 .264 E0, 87 .195 E0, 89 .076 E0, 89 .608 E0, 89 .868 E0, 90 .101 E0, 92 .405 E0, 95 .854 E0, 100 .696 E0, 101 .060 E0, 401 .672 E0, 390 .724 E0, 567 .534 E0, 635 .316 E0, 733 .054 E0, 759 .087 E0, 894 .206 E0, 990 .785 E0, 1090 .109 E0, 1080 .914 E0, 1122 .643 E0, 1178 .351 E0, 1260 .531 E0, 1273 .514 E0, 1288 .339 E0, 1327 .543 E0, 1353 .863 E0, 1414 .509 E0, 1425 .208 E0, 1421 .384 E0, 1442 .962 E0, 1464 .350 E0, 1468 .705 E0, 1447 .894 E0, 1457 .628 E0};
// http://www.itl.nist.gov/div898/strd/nls/data/thurber.shtml
void testNistThurber(void )
{
const int n=7 ;
int info;
VectorXd x(n);
/*
* First try
*/
x<< 1000 ,1000 ,400 ,40 ,0 .7 ,0 .3 ,0 .0 ;
// do the computation
thurber_functor functor;
LevenbergMarquardt<thurber_functor> lm(functor);
lm.parameters.ftol = 1 .E4*NumTraits<double >::epsilon();
lm.parameters.xtol = 1 .E4*NumTraits<double >::epsilon();
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 1 );
LM_CHECK_N_ITERS(lm, 39 ,36 );
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5 .6427082397 E+03 );
// check x
VERIFY_IS_APPROX(x[0 ], 1 .2881396800 E+03 );
VERIFY_IS_APPROX(x[1 ], 1 .4910792535 E+03 );
VERIFY_IS_APPROX(x[2 ], 5 .8323836877 E+02 );
VERIFY_IS_APPROX(x[3 ], 7 .5416644291 E+01 );
VERIFY_IS_APPROX(x[4 ], 9 .6629502864 E-01 );
VERIFY_IS_APPROX(x[5 ], 3 .9797285797 E-01 );
VERIFY_IS_APPROX(x[6 ], 4 .9727297349 E-02 );
/*
* Second try
*/
x<< 1300 ,1500 ,500 ,75 ,1 ,0 .4 ,0 .05 ;
// do the computation
lm.resetParameters();
lm.parameters.ftol = 1 .E4*NumTraits<double >::epsilon();
lm.parameters.xtol = 1 .E4*NumTraits<double >::epsilon();
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 1 );
LM_CHECK_N_ITERS(lm, 29 , 28 );
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5 .6427082397 E+03 );
// check x
VERIFY_IS_APPROX(x[0 ], 1 .2881396800 E+03 );
VERIFY_IS_APPROX(x[1 ], 1 .4910792535 E+03 );
VERIFY_IS_APPROX(x[2 ], 5 .8323836877 E+02 );
VERIFY_IS_APPROX(x[3 ], 7 .5416644291 E+01 );
VERIFY_IS_APPROX(x[4 ], 9 .6629502864 E-01 );
VERIFY_IS_APPROX(x[5 ], 3 .9797285797 E-01 );
VERIFY_IS_APPROX(x[6 ], 4 .9727297349 E-02 );
}
struct rat43_functor : Functor<double >
{
rat43_functor(void ) : Functor<double >(4 ,15 ) {}
static const double x[15 ];
static const double y[15 ];
int operator ()(const VectorXd &b, VectorXd &fvec)
{
assert(b.size()==4 );
assert(fvec.size()==15 );
for (int i=0 ; i<15 ; i++)
fvec[i] = b[0 ] * pow(1 .+exp(b[1 ]-b[2 ]*x[i]),-1 ./b[3 ]) - y[i];
return 0 ;
}
int df(const VectorXd &b, MatrixXd &fjac)
{
assert(b.size()==4 );
assert(fjac.rows()==15 );
assert(fjac.cols()==4 );
for (int i=0 ; i<15 ; i++) {
double e = exp(b[1 ]-b[2 ]*x[i]);
double power = -1 ./b[3 ];
fjac(i,0 ) = pow(1 .+e, power);
fjac(i,1 ) = power*b[0 ]*e*pow(1 .+e, power-1 .);
fjac(i,2 ) = -power*b[0 ]*e*x[i]*pow(1 .+e, power-1 .);
fjac(i,3 ) = b[0 ]*power*power*log(1 .+e)*pow(1 .+e, power);
}
return 0 ;
}
};
const double rat43_functor::x[15 ] = { 1 ., 2 ., 3 ., 4 ., 5 ., 6 ., 7 ., 8 ., 9 ., 10 ., 11 ., 12 ., 13 ., 14 ., 15 . };
const double rat43_functor::y[15 ] = { 16 .08 , 33 .83 , 65 .80 , 97 .20 , 191 .55 , 326 .20 , 386 .87 , 520 .53 , 590 .03 , 651 .92 , 724 .93 , 699 .56 , 689 .96 , 637 .56 , 717 .41 };
// http://www.itl.nist.gov/div898/strd/nls/data/ratkowsky3.shtml
void testNistRat43(void )
{
const int n=4 ;
int info;
VectorXd x(n);
/*
* First try
*/
x<< 100 ., 10 ., 1 ., 1 .;
// do the computation
rat43_functor functor;
LevenbergMarquardt<rat43_functor> lm(functor);
lm.parameters.ftol = 1 .E6*NumTraits<double >::epsilon();
lm.parameters.xtol = 1 .E6*NumTraits<double >::epsilon();
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 1 );
LM_CHECK_N_ITERS(lm, 27 , 20 );
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 8 .7864049080 E+03 );
// check x
VERIFY_IS_APPROX(x[0 ], 6 .9964151270 E+02 );
VERIFY_IS_APPROX(x[1 ], 5 .2771253025 E+00 );
VERIFY_IS_APPROX(x[2 ], 7 .5962938329 E-01 );
VERIFY_IS_APPROX(x[3 ], 1 .2792483859 E+00 );
/*
* Second try
*/
x<< 700 ., 5 ., 0 .75 , 1 .3 ;
// do the computation
lm.resetParameters();
lm.parameters.ftol = 1 .E5*NumTraits<double >::epsilon();
lm.parameters.xtol = 1 .E5*NumTraits<double >::epsilon();
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 1 );
LM_CHECK_N_ITERS(lm, 9 , 8 );
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 8 .7864049080 E+03 );
// check x
VERIFY_IS_APPROX(x[0 ], 6 .9964151270 E+02 );
VERIFY_IS_APPROX(x[1 ], 5 .2771253025 E+00 );
VERIFY_IS_APPROX(x[2 ], 7 .5962938329 E-01 );
VERIFY_IS_APPROX(x[3 ], 1 .2792483859 E+00 );
}
struct eckerle4_functor : Functor<double >
{
eckerle4_functor(void ) : Functor<double >(3 ,35 ) {}
static const double x[35 ];
static const double y[35 ];
int operator ()(const VectorXd &b, VectorXd &fvec)
{
assert(b.size()==3 );
assert(fvec.size()==35 );
for (int i=0 ; i<35 ; i++)
fvec[i] = b[0 ]/b[1 ] * exp(-0 .5 *(x[i]-b[2 ])*(x[i]-b[2 ])/(b[1 ]*b[1 ])) - y[i];
return 0 ;
}
int df(const VectorXd &b, MatrixXd &fjac)
{
assert(b.size()==3 );
assert(fjac.rows()==35 );
assert(fjac.cols()==3 );
for (int i=0 ; i<35 ; i++) {
double b12 = b[1 ]*b[1 ];
double e = exp(-0 .5 *(x[i]-b[2 ])*(x[i]-b[2 ])/b12);
fjac(i,0 ) = e / b[1 ];
fjac(i,1 ) = ((x[i]-b[2 ])*(x[i]-b[2 ])/b12-1 .) * b[0 ]*e/b12;
fjac(i,2 ) = (x[i]-b[2 ])*e*b[0 ]/b[1 ]/b12;
}
return 0 ;
}
};
const double eckerle4_functor::x[35 ] = { 400 .0 , 405 .0 , 410 .0 , 415 .0 , 420 .0 , 425 .0 , 430 .0 , 435 .0 , 436 .5 , 438 .0 , 439 .5 , 441 .0 , 442 .5 , 444 .0 , 445 .5 , 447 .0 , 448 .5 , 450 .0 , 451 .5 , 453 .0 , 454 .5 , 456 .0 , 457 .5 , 459 .0 , 460 .5 , 462 .0 , 463 .5 , 465 .0 , 470 .0 , 475 .0 , 480 .0 , 485 .0 , 490 .0 , 495 .0 , 500 .0 };
const double eckerle4_functor::y[35 ] = { 0 .0001575 , 0 .0001699 , 0 .0002350 , 0 .0003102 , 0 .0004917 , 0 .0008710 , 0 .0017418 , 0 .0046400 , 0 .0065895 , 0 .0097302 , 0 .0149002 , 0 .0237310 , 0 .0401683 , 0 .0712559 , 0 .1264458 , 0 .2073413 , 0 .2902366 , 0 .3445623 , 0 .3698049 , 0 .3668534 , 0 .3106727 , 0 .2078154 , 0 .1164354 , 0 .0616764 , 0 .0337200 , 0 .0194023 , 0 .0117831 , 0 .0074357 , 0 .0022732 , 0 .0008800 , 0 .0004579 , 0 .0002345 , 0 .0001586 , 0 .0001143 , 0 .0000710 };
// http://www.itl.nist.gov/div898/strd/nls/data/eckerle4.shtml
void testNistEckerle4(void )
{
const int n=3 ;
int info;
VectorXd x(n);
/*
* First try
*/
x<< 1 ., 10 ., 500 .;
// do the computation
eckerle4_functor functor;
LevenbergMarquardt<eckerle4_functor> lm(functor);
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 1 );
LM_CHECK_N_ITERS(lm, 18 , 15 );
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1 .4635887487 E-03 );
// check x
VERIFY_IS_APPROX(x[0 ], 1 .5543827178 );
VERIFY_IS_APPROX(x[1 ], 4 .0888321754 );
VERIFY_IS_APPROX(x[2 ], 4 .5154121844 E+02 );
/*
* Second try
*/
x<< 1 .5 , 5 ., 450 .;
// do the computation
info = lm.minimize(x);
// check return value
VERIFY_IS_EQUAL(info, 1 );
LM_CHECK_N_ITERS(lm, 7 , 6 );
// check norm^2
VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1 .4635887487 E-03 );
// check x
VERIFY_IS_APPROX(x[0 ], 1 .5543827178 );
VERIFY_IS_APPROX(x[1 ], 4 .0888321754 );
VERIFY_IS_APPROX(x[2 ], 4 .5154121844 E+02 );
}
EIGEN_DECLARE_TEST(NonLinearOptimization)
{
// Tests using the examples provided by (c)minpack
CALL_SUBTEST/*_1*/(testChkder());
CALL_SUBTEST/*_1*/(testLmder1());
CALL_SUBTEST/*_1*/(testLmder());
CALL_SUBTEST/*_2*/(testHybrj1());
CALL_SUBTEST/*_2*/(testHybrj());
CALL_SUBTEST/*_2*/(testHybrd1());
CALL_SUBTEST/*_2*/(testHybrd());
CALL_SUBTEST/*_3*/(testLmstr1());
CALL_SUBTEST/*_3*/(testLmstr());
CALL_SUBTEST/*_3*/(testLmdif1());
CALL_SUBTEST/*_3*/(testLmdif());
// NIST tests, level of difficulty = "Lower"
CALL_SUBTEST/*_4*/(testNistMisra1a());
CALL_SUBTEST/*_4*/(testNistChwirut2());
// NIST tests, level of difficulty = "Average"
CALL_SUBTEST/*_5*/(testNistHahn1());
CALL_SUBTEST/*_6*/(testNistMisra1d());
CALL_SUBTEST/*_7*/(testNistMGH17());
CALL_SUBTEST/*_8*/(testNistLanczos1());
// // NIST tests, level of difficulty = "Higher"
CALL_SUBTEST/*_9*/(testNistRat42());
// CALL_SUBTEST/*_10*/(testNistMGH10());
CALL_SUBTEST/*_11*/(testNistBoxBOD());
// CALL_SUBTEST/*_12*/(testNistMGH09());
CALL_SUBTEST/*_13*/(testNistBennett5());
CALL_SUBTEST/*_14*/(testNistThurber());
CALL_SUBTEST/*_15*/(testNistRat43());
CALL_SUBTEST/*_16*/(testNistEckerle4());
}
/*
* Can be useful for debugging...
printf("info, nfev : %d, %d\n", info, lm.nfev);
printf("info, nfev, njev : %d, %d, %d\n", info, solver.nfev, solver.njev);
printf("info, nfev : %d, %d\n", info, solver.nfev);
printf("x[0] : %.32g\n", x[0]);
printf("x[1] : %.32g\n", x[1]);
printf("x[2] : %.32g\n", x[2]);
printf("x[3] : %.32g\n", x[3]);
printf("fvec.blueNorm() : %.32g\n", solver.fvec.blueNorm());
printf("fvec.blueNorm() : %.32g\n", lm.fvec.blueNorm());
printf("info, nfev, njev : %d, %d, %d\n", info, lm.nfev, lm.njev);
printf("fvec.squaredNorm() : %.13g\n", lm.fvec.squaredNorm());
std::cout << x << std::endl;
std::cout.precision(9);
std::cout << x[0] << std::endl;
std::cout << x[1] << std::endl;
std::cout << x[2] << std::endl;
std::cout << x[3] << std::endl;
*/
Messung V0.5 in Prozent C=87 H=88 G=87
¤ Dauer der Verarbeitung: 0.44 Sekunden
(vorverarbeitet am 2026-06-06)
¤
*© Formatika GbR, Deutschland