27#ifndef levmarInterface_hpp
28#define levmarInterface_hpp
114template <
class fitterT>
119 typedef typename fitterT::realT realT;
321 template <
typename iosT,
char comment = '#'>
328 template <
char comment = '#'>
337 template <
typename iosT,
char comment = '#'>
339 bool dumpParams =
true
346 template <
char comment = '#'>
347 std::ostream &
dumpReport(
bool dumpParams =
true );
350template <
class fitterT>
351void levmarInterface<fitterT>::initialize()
362 set_opts_default( -1 );
370 for(
int i = 0; i < LM_INFO_SZ; ++i )
377template <
class fitterT>
383template <
class fitterT>
385 typename fitterT::realT *i_p,
typename fitterT::realT *i_x,
int i_m,
int i_n,
void *i_adata )
396template <
class fitterT>
412template <
class fitterT>
430 init_p = (
typename fitterT::realT *)malloc(
sizeof(
typename fitterT::realT ) *
m );
433template <
class fitterT>
439template <
class fitterT>
447 p = (
typename fitterT::realT *)malloc(
sizeof(
typename fitterT::realT ) *
m );
452template <
class fitterT>
460template <
class fitterT>
471template <
class fitterT>
478template <
class fitterT>
484template <
class fitterT>
490template <
class fitterT>
496template <
class fitterT>
499 for(
int i = 0; i <
m; i++ )
504template <class fitterT, bool jacf = hasJacobian<fitterT>::value>
505struct levmar_allocate_size
507 typedef typename fitterT::realT realT;
509 int operator()(
int m,
int n )
511 return LM_DIF_WORKSZ( m, n );
516template <
class fitterT>
517struct levmar_allocate_size<fitterT, true>
519 typedef typename fitterT::realT realT;
521 int operator()(
int m,
int n )
523 return LM_DER_WORKSZ( m, n );
527template <
class fitterT>
531 levmar_allocate_size<fitterT> alloc_sz;
539 work = (realT *)malloc(
work_sz *
sizeof( realT ) );
563template <
class fitterT>
569template <
class fitterT>
574 if(
n == 0 ||
n == -1 )
576 opts[0] = LM_INIT_MU;
581 opts[
n] = LM_STOP_THRESH;
585 opts[1] = LM_STOP_THRESH;
586 opts[2] = LM_STOP_THRESH;
587 opts[3] = LM_STOP_THRESH;
590 if(
n == 4 ||
n == -1 )
592 opts[4] = LM_DIFF_DELTA;
596template <
class fitterT>
603template <class fitterT, bool jacf = hasJacobian<fitterT>::value>
606 typedef typename fitterT::realT realT;
609 realT *p, realT *x,
int m,
int n,
int itmax, realT *opts, realT *info, realT *work, realT *covar,
void *adata )
611 return levmar_dif<realT>( &fitterT::func, p, x, m, n, itmax, opts, info, work, covar, adata );
616template <
class fitterT>
617struct do_levmar<fitterT, true>
619 typedef typename fitterT::realT realT;
622 realT *p, realT *x,
int m,
int n,
int itmax, realT *opts, realT *info, realT *work, realT *covar,
void *adata )
624 return levmar_der<realT>( &fitterT::func, &fitterT::jacf, p, x, m, n, itmax, opts, info, work, covar, adata );
628template <
class fitterT>
646 init_p = (
typename fitterT::realT *)malloc(
sizeof(
typename fitterT::realT ) *
m );
649 for(
int i = 0; i <
m; ++i )
657 do_levmar<fitterT> fitter;
666template <
class fitterT>
672template <
class fitterT>
678template <
class fitterT>
684template <
class fitterT>
690template <
class fitterT>
696template <
class fitterT>
702template <
class fitterT>
708template <
class fitterT>
714 return "stopped by small gradient J^T e";
717 return "stopped by small Dp";
720 return "stopped by itmax";
723 return "singular matrix. Restart from current p with increased mu";
726 return "no further error reduction is possible. Restart with increased mu";
729 return "stopped by small ||e||_2";
732 return "stopped by invalid (i.e. NaN or Inf) \"func\" values. This is a user error";
735 return "unknown reason code";
739template <
class fitterT>
740template <
typename iosT,
char comment>
744 char c[] = { comment,
'\0' };
746 ios << c <<
"Current parameters (initial):\n";
747 for(
int i = 0; i <
m; i++ )
750 ios <<
"p[" << i <<
"] = " <<
p[i] <<
" (" <<
init_p[i] <<
")\n";
756template <
class fitterT>
757template <
char comment>
763template <
class fitterT>
764template <
typename iosT,
char comment>
767 char c[] = { comment,
'\0' };
769 ios << c <<
"--------------------------------------\n";
770 ios << c <<
"mx::math::fit::levmarInterface Results \n";
771 ios << c <<
"--------------------------------------\n";
778 ios << c <<
"Function evals: " <<
get_fevals() <<
"\n";
779 ios << c <<
"Jacobian evals: " <<
get_jevals() <<
"\n";
780 ios << c <<
"Elapsed time: " <<
get_deltaT() <<
" secs\n";
785template <
class fitterT>
786template <
char comment>
806 template <
typename fitterT>
807 static yes &test(
typename fitterT::hasJacobian * );
810 static no &test( ... );
816 static const bool value =
sizeof( test<T>( 0 ) ) ==
sizeof( yes );
823template <
typename realT>
realT info[LM_INFO_SZ]
Information regarding the minimization.
void set_params(realT *i_p)
Copy parameters to the parameter array.
realT * covar
Covariance matrix corresponding to LS solution; mxm.
int itmax
Maximum number of iterations, default is 100.
void nParams(int i_m)
Set number of parameters, but don't allocate.
realT * x
I: measurement vector. NULL implies a zero vector.
realT get_final_norm()
Returns the L2-norm at the end of the minimization.
void set_opts(int n, realT val)
Set one of the minimization options to val.
int fit()
Perform the fit.
std::string get_reason_string()
Get the descriptive string describing the reason minimization terminated.
realT get_initial_norm()
Returns the L2-norm before minimization occurs.
void allocate_params()
Allocate parameters array based on previous call to nParams.
iosT & dumpReport(iosT &ios, bool dumpParams=true)
Output current parameters to a stream.
int get_reason_code()
Get a code specifying the reason minimization terminated.
realT * init_p
Parameter array on input, saved for comparison.
int get_jevals()
Get the number of jacobian evaluations during the minimization.
void set_opts_default(int n=-1)
Set one or all of the minimization options to the default.
iosT & dumpParameters(iosT &ios)
Output current parameters to a stream.
int m
Parameter vector dimension (i.e. number of unknowns).
~levmarInterface()
Destructor.
realT * p
Parameter array. On input is the initial estimates. On output has the estimated solution.
realT get_opts(int n)
Get the current value of an option.
void allocate_work()
Allocate the work and covar matrices.
double deltaT
Elapsed time of the fitting procedure.
int n
I: measurement vector dimension.
int get_nlinsys()
Get the number of linear system solutions during the minimization.
std::ostream & dumpParameters()
Dump the parameter vector to stdout.
realT opts[LM_OPTS_SZ]
Options passed to the minimization routines. See set_opts for details.
int get_fevals()
Get the number of function evaluations during the minimization.
realT * get_params()
Get current pointer array address.
realT * work
Working memory passed to the levmar routines.
void point_params(realT *i_p)
Point the parameter pointer at an externally allocated array.
int nParams()
Get the current number of parameters.
double get_deltaT()
Get the elapsed time of the fit.
levmarInterface()
Default constructor.
void * adata
Pointer to possibly additional data, passed uninterpreted to func & jacf.
bool own_p
Flag indicating whether the p array is owned by this object (for de-allocation).
void set_itmax(int i_itmax)
Set the maximum number of iterations.
int covar_sz
The current size of the covar array.
int get_iterations()
Get the number of iterations taken during the minimization.
int work_sz
The current size of the work array.
bool getCovar
Controls whether the covar array is allocated.
int get_itmax()
Get the maximum number of iterations.
typeT get_curr_time()
Get the current system time in seconds.
Declarations of some libarary wide utilities.
iosT & dumpGitStatus(iosT &ios, const std::string &repoName, const std::string &branch, const std::string &sha1, const bool &modified, const std::string §ion="")
Dump the git status of a repository to a stream.
Wrapper for a native array to pass to levmarInterface.
size_t ny
X dimension of the array.
size_t nx
Pointer to the array.
Test whether a function type has a Jacobian function by testing whether it has a typedef of "hasJacob...
Templatized wrappers to the levmar minimization routines..
Utilities for working with time.