mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
levmarInterface.hpp
Go to the documentation of this file.
1 /** \file levmarInterface.hpp
2  * \author Jared R. Males
3  * \brief A c++ interface to the templatized levmar minimization routines..
4  * \ingroup fitting_files
5  *
6  */
7 
8 //***********************************************************************//
9 // Copyright 2015, 2016, 2017 Jared R. Males (jaredmales@gmail.com)
10 //
11 // This file is part of mxlib.
12 //
13 // mxlib is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation, either version 3 of the License, or
16 // (at your option) any later version.
17 //
18 // mxlib is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 // GNU General Public License for more details.
22 //
23 // You should have received a copy of the GNU General Public License
24 // along with mxlib. If not, see <http://www.gnu.org/licenses/>.
25 //***********************************************************************//
26 
27 #ifndef levmarInterface_hpp
28 #define levmarInterface_hpp
29 
30 #include <iostream>
31 
32 #include "../../mxlib.hpp"
33 
34 #include "templateLevmar.hpp"
35 #include "../../sys/timeUtils.hpp"
36 
37 
38 namespace mx
39 {
40 namespace math
41 {
42 namespace fit
43 {
44 
45 //Forwards
46 template <typename T>
47 struct hasJacobian;
48 
49 ///A templatized interface to the levmar package
50 /** Requires a fitter class, which conforms to one of the following minimum specifications.
51  * To use the finite difference jacobian calculation:
52  * \code
53  * //This will cause the levmar_dif routine to be used
54  * template<typename _realT>
55  * struct dif_fitter
56  * {
57  * typedef _realT realT; //required
58  *
59  * static void func(realT *p, realT *hx, int m, int n, void *adata)
60  * {
61  * //do stuff here . . .
62  * }
63  * };
64  * \endcode
65  * If you wish to provide your own jacobian:
66  * \code
67  * //This will cause the levmar_der routine to be used
68  * template<typename _realT>
69  * struct der_fitter
70  * {
71  * typedef _realT realT; //required
72  *
73  * typdef bool hasJacobian; //this signals that jacf exists and should be used.
74  *
75  * static void func(realT *p, realT *hx, int m, int n, void *adata)
76  * {
77  * //do stuff here . . .
78  * }
79  *
80  * // This is the jacobian.
81  * static void jacf(realT *p, realT *j, int m, int n, void *adata)
82  * {
83  * //do stuff here . . .
84  * }
85  *
86  * };
87  *
88  * \endcode
89  *
90  * Note that if your fitter has a jacobian function (jacf), you must define
91  * \code
92  * typedef bool hasJacobian;
93  * \endcode
94  * for it to be used.
95  *
96  * \tparam fitterT a class with at least the minimum interface described above.
97  *
98  * \ingroup fitting
99  */
100 template<class fitterT>
102 {
103 
104 public:
105 
106  typedef typename fitterT::realT realT;
107 
108 
109 protected:
110  realT *p; ///< Parameter array. On input is the initial estimates. On output has the estimated solution.
111  realT *init_p; ///< Parameter array on input, saved for comparison.
112 
113  int m; ///< Parameter vector dimension (i.e. number of unknowns)
114  bool own_p; ///< Flag indicating whether the p array is owned by this object (for de-allocation).
115 
116  int itmax; ///< Maximum number of iterations, default is 100
117 
118 public:
119  realT *x; ///< I: measurement vector. NULL implies a zero vector
120 
121  int n; ///< I: measurement vector dimension
122 
123 
124 
125  /// Options passed to the minimization routines. See \ref set_opts for details.
126  realT opts[LM_OPTS_SZ];
127 
128  /// Information regarding the minimization.
129  /** See the levmar source code for documentation. These fields are accessed by
130  * \ref get_initial_norm, \ref get_final_norm, \ref get_iterations, \ref get_reason_code,
131  * \ref get_reason_string, \ref get_fevals, \ref get_jevals, \ref get_nlinsys
132  */
133  realT info[LM_INFO_SZ];
134 
135  /// Elapsed time of the fitting procedure
136  double deltaT;
137 
138  /// Working memory passed to the levmar routines.
139  /** From the levmar documentation: at least LM_DER/DIF_WORKSZ() reals large, allocated if NULL
140  * Here this is always allocated by a call to \ref allocate_work.
141  */
142  realT *work;
143 
144  ///The current size of the work array
145  int work_sz;
146 
147  ///Covariance matrix corresponding to LS solution; mxm.
148  /** Here this is allocated to size m-x-m by allocate_work, but if you don't want it
149  * allcoated and calculated
150  * set \ref getCovar to false and NULL will be passed.
151  */
152  realT *covar;
153 
154  ///The current size of the covar array
155  int covar_sz;
156 
157  ///Controls whether the covar array is allocated.
158  bool getCovar;
159 
160  ///Pointer to possibly additional data, passed uninterpreted to func & jacf.
161  /** Set to NULL if not needed.
162  */
163  void *adata;
164 
165 private:
166  ///Initialization common to all constructors
167  void initialize();
168 
169 public:
170 
171  /// Default constructor.
172  /** With this constructor, you must set the parameter, data, and adata before calling fit().
173  */
175 
176  /// Setup constructor
177  /** with this constructor fit() will work immediately.
178  *
179  */
180  levmarInterface( realT *i_p, ///< [in] pointer to the initial parameter guess
181  realT *i_x, ///< [in] pointer to the data (can be NULL)
182  int i_m, ///< [in] the size of i_p
183  int i_n, ///< [in] the size of i_x
184  void *i_adata ///< [in] pointer to auxiliary data (can be NULL)
185  );
186 
187  ///Destructor
188  /** Frees the work and covar matrices.
189  */
191 
192  ///Set number of parameters, but don't allocate
193  void nParams(int i_m /**< [in] the number of parameters */);
194 
195  ///Get the current number of parameters
196  /** \returns the current number of parameters (m)
197  */
198  int nParams();
199 
200  ///Allocate parameters array based on previous call to \ref nParams
202 
203  ///Set number of parameters and allocate
204  void allocate_params(int i_m);
205 
206  ///Point the parameter pointer at an externally allocated array
207  void point_params(realT * i_p);
208 
209  ///Point the parameter pointer at an externally allocated array
210  void point_params(realT * i_p, int i_m);
211 
212  ///Copy parameters to the parameter array
213  /** This assumes that either the array was allocated (i.e. with \ref allocate_params) or
214  * that \ref point_params has been called
215  */
216  void set_params(realT * i_p);
217 
218  ///Get current pointer array address
219  realT * get_params();
220 
221 
222  ///Set the maximum number of iterations
223  /** Sets itmax. Initialization default is itmax = 100
224  *
225  * \param i_itmax the new value of itmax to set
226  */
227  void set_itmax(int i_itmax);
228 
229  ///Get the maximum number of iterations
230  int get_itmax();
231 
232  ///Allocate the work and covar matrices
233  /** Uses a function object specialized for whether or not there is a jacobian
234  * to determine the size of work.
235  */
237 
238  ///Set one of the minimization options to val
239  /** The options correspond to:
240  *
241  * 0: the scale factor of the initial \f$ \mu \f$
242  *
243  * 1: \f$ \epsilon_1 \f$ Stopping threshold for ||J^T e||_inf
244  *
245  * 2: \f$ \epsilon_1 \f$ Stopping threshold for ||Dp||_2
246  *
247  * 3: \f$ \epsilon_1 \f$ Stopping threshold for ||e||_2
248  *
249  * 4: \f$ \Delta_{diff}\f$ Stepsize for finite differences
250  *
251  * \param n is the option number
252  * \param val is the value to set
253  */
254  void set_opts(int n, realT val);
255 
256  ///Set one or all of the minimization options to the default.
257  /** See \ref set_opts for discription of the options.
258  *
259  * \param n the option number. Pass -1 to set all options to defaults.
260  */
261  void set_opts_default(int n = -1);
262 
263  ///Get the current value of an option.
264  /** See \ref set_opts for a description of the options
265  *
266  * \param n the option number
267  */
268  realT get_opts(int n);
269 
270  ///Perform the fit
271  /** This calls \ref allocate_work, and then dispatches the levmar routine appropriate for fitterT.
272  */
273  int fit();
274 
275  ///Returns the L2-norm before minimization occurs
277 
278  ///Returns the L2-norm at the end of the minimization
279  realT get_final_norm();
280 
281  ///Get the number of iterations taken during the minimization
283 
284  ///Get a code specifying the reason minimization terminated.
286 
287  ///Get the descriptive string describing the reason minimization terminated.
288  std::string get_reason_string();
289 
290  ///Get the number of function evaluations during the minimization
291  int get_fevals();
292 
293  ///Get the number of jacobian evaluations during the minimization
294  int get_jevals();
295 
296  ///Get the number of linear system solutions during the minimization
297  int get_nlinsys();
298 
299  ///Get the elapsed time of the fit
300  double get_deltaT()
301  {
302  return deltaT;
303  }
304 
305  //Status reports
306 
307  ///Output current parameters to a stream
308  /** Prints a formatted list of all current fit parameters.
309  *
310  * \tparam iosT is a std::ostream-like type.
311  * \tparam comment is a comment character to start each line. Can be '\0'.
312  */
313  template<typename iosT, char comment='#'>
314  iosT & dumpParameters( iosT & ios /**< [in] a std::ostream-like stream. */);
315 
316  ///Dump the parameter vector to stdout.
317  /**
318  * \tparam comment is a comment character to start each line. Can be '\0'.
319  */
320  template<char comment='#'>
321  std::ostream & dumpParameters();
322 
323  ///Output current parameters to a stream
324  /** Prints a formatted list of all current fit parameters.
325  *
326  * \tparam iosT is a std::ostream-like type.
327  * \tparam comment is a comment character to start each line. Can be '\0'.
328  */
329  template<typename iosT, char comment='#'>
330  iosT & dumpReport( iosT & ios, ///< [in] a std::ostream-like stream.
331  bool dumpParams = true ///< [in] [optional] whether or not to dump the parameters.
332  );
333 
334  ///Dump a status report to stdout
335  /**
336  * \tparam comment is a comment character to start each line. Can be '\0'.
337  */
338  template<char comment='#'>
339  std::ostream & dumpReport( bool dumpParams = true /**< [in] [optional] whether or not to dump the parameters.*/);
340 
341 };
342 
343 template<class fitterT>
345 {
346  p=0;
347  own_p = false;
348 
349  init_p = 0;
350 
351  m=0;
352 
353  x=0;
354  n=0;
355  set_opts_default(-1);//set all opts to defaults.
356  work=0;
357  work_sz = 0;
358  covar=0;
359  covar_sz = 0;
360  getCovar = true;
361  adata=0;
362 
363  for(int i=0;i<LM_INFO_SZ; ++i) info[i] = 0;
364  deltaT = 0;
365 
366  itmax = 100;
367 }
368 
369 template<class fitterT>
371 {
372  initialize();
373 }
374 
375 template<class fitterT>
376 levmarInterface<fitterT>::levmarInterface(typename fitterT::realT *i_p,
377  typename fitterT::realT *i_x,
378  int i_m,
379  int i_n,
380  void * i_adata)
381 {
382  initialize();
383 
384  p = i_p;
385  x = i_x;
386  m = i_m;
387  n = i_n;
388  adata = i_adata;
389 }
390 
391 template<class fitterT>
393 {
394  if(p && own_p) free(p);
395 
396  if(init_p) free(init_p);
397 
398  if(work) free(work);
399 
400  if(covar) free(covar);
401 }
402 
403 template<class fitterT>
405 {
406  //If we own and have allocated p, then de-alloc
407  if(p && own_p)
408  {
409  free(p);
410  p = 0;
411  }
412 
413  m = i_m;
414 
415  //Also allocate the init_p storage for initial guess
416  if( init_p)
417  {
418  free(init_p);
419  }
420 
421  init_p = (typename fitterT::realT *) malloc(sizeof(typename fitterT::realT) * m);
422 
423 }
424 
425 template<class fitterT>
427 {
428  return m;
429 }
430 
431 
432 template<class fitterT>
434 {
435  if(p && own_p)
436  {
437  free(p);
438  }
439 
440  p = (typename fitterT::realT *) malloc(sizeof(typename fitterT::realT) * m);
441 
442  own_p = true;
443 }
444 
445 template<class fitterT>
447 {
448  nParams(i_m);
449 
450  allocate_params();
451 }
452 
453 template<class fitterT>
455 {
456  if(p && own_p)
457  {
458  free(p);
459  }
460 
461  p = i_p;
462 }
463 
464 
465 template<class fitterT>
466 void levmarInterface<fitterT>::point_params(realT * i_p, int i_m)
467 {
468  nParams(i_m);
469  point_params(i_p);
470 }
471 
472 template<class fitterT>
474 {
475  itmax = i_itmax;
476 }
477 
478 template<class fitterT>
480 {
481  return itmax;
482 }
483 
484 template<class fitterT>
485 typename fitterT::realT * levmarInterface<fitterT>::get_params()
486 {
487  return p;
488 }
489 
490 template<class fitterT>
492 {
493  for(int i=0;i<m;i++) p[i] = i_p[i];
494 }
495 
496 
497 //Functor which is used by allocate() if hasJacobian is false
498 template<class fitterT, bool jacf = hasJacobian<fitterT>::value>
499 struct levmar_allocate_size
500 {
501  typedef typename fitterT::realT realT;
502 
503  int operator()(int m, int n)
504  {
505  return LM_DIF_WORKSZ(m,n);
506  }
507 };
508 
509 //Functor which is used by allocate() if hasJacobian is true
510 template<class fitterT>
511 struct levmar_allocate_size<fitterT, true>
512 {
513  typedef typename fitterT::realT realT;
514 
515  int operator()(int m, int n)
516  {
517  return LM_DER_WORKSZ(m,n);
518  }
519 };
520 
521 template<class fitterT>
523 {
524  //Create function object to get allocation size, which depends on whether there is Jacobian.
525  levmar_allocate_size<fitterT> alloc_sz;
526 
527  if(work_sz < alloc_sz(m,n) || !work)
528  {
529  if(work) free(work);
530 
531  work_sz = alloc_sz(m,n);
532  work = (realT *) malloc( work_sz * sizeof(realT));
533  }
534 
535  //Allocate if covar is desired and unallocated.
536  if(getCovar)
537  {
538  if(covar_sz < m*m || !covar)
539  {
540  if(covar) free(covar);
541 
542  covar_sz = m*m;
543  covar = (realT *) malloc(covar_sz * sizeof(realT));
544  }
545  }
546  else
547  {
548  //If covar is not desired, de-allocate if allocated before.
549  if(covar) free(covar);
550  covar = 0;
551  }
552 }
553 
554 
555 template<class fitterT>
557 {
558  opts[n] = val;
559 }
560 
561 
562 template<class fitterT>
564 {
565  //See the source in lm_core.c
566 
567  if(n == 0 || n == -1)
568  {
569  opts[0] = LM_INIT_MU;
570  }
571 
572  if(n > 0 && n < 4)
573  {
574  opts[n] = LM_STOP_THRESH;
575  }
576  else if(n == -1)
577  {
578  opts[1] = LM_STOP_THRESH;
579  opts[2] = LM_STOP_THRESH;
580  opts[3] = LM_STOP_THRESH;
581  }
582 
583  if(n == 4 || n == -1)
584  {
585  opts[4] = LM_DIFF_DELTA;
586  }
587 }
588 
589 template<class fitterT>
590 typename fitterT::realT levmarInterface<fitterT>::get_opts(int n)
591 {
592  return opts[n];
593 }
594 
595 //Functor which is used by fit() if hasJacobian is false
596 template<class fitterT, bool jacf = hasJacobian<fitterT>::value>
597 struct do_levmar
598 {
599  typedef typename fitterT::realT realT;
600 
601  int operator()(realT *p,
602  realT *x,
603  int m,
604  int n,
605  int itmax,
606  realT *opts,
607  realT *info,
608  realT *work,
609  realT *covar,
610  void *adata)
611  {
612  return levmar_dif<realT>( &fitterT::func, p, x, m, n, itmax, opts, info, work, covar, adata);
613  }
614 };
615 
616 //Functor which is used by fit() if hasJacobian is true
617 template<class fitterT>
618 struct do_levmar<fitterT, true>
619 {
620  typedef typename fitterT::realT realT;
621 
622  int operator()(realT *p,
623  realT *x,
624  int m,
625  int n,
626  int itmax,
627  realT *opts,
628  realT *info,
629  realT *work,
630  realT *covar,
631  void *adata)
632  {
633  return levmar_der<realT>( &fitterT::func, &fitterT::jacf, p, x, m, n, itmax, opts, info, work, covar, adata);
634  }
635 };
636 
637 
638 template<class fitterT>
640 {
641  realT * _opts;
642 
643  allocate_work();
644 
645  if(opts[0] == 0) _opts= 0;
646  else _opts = opts;
647 
648  //These may not be updated by the levmar library
649  info[8] = 0;
650  info[9] = 0;
651 
652 
653  if( !init_p)
654  {
655  init_p = (typename fitterT::realT *) malloc(sizeof(typename fitterT::realT) * m);
656  }
657 
658  for(int i = 0; i < m; ++i) init_p[i] = p[i];
659 
660  double t0 = sys::get_curr_time();
661 
662  //Create one of the above functors, which depends on whether fitterT has a Jacobian.
663  do_levmar<fitterT> fitter;
664 
665  fitter(p,x,m,n,itmax,_opts,info,work,covar,adata);
666 
667  deltaT = sys::get_curr_time() - t0;
668 
669  return 0;
670 }
671 
672 
673 
674 template<class fitterT>
676 {
677  return info[0];
678 }
679 
680 template<class fitterT>
682 {
683  return info[1];
684 }
685 
686 template<class fitterT>
688 {
689  return (int) info[5];
690 }
691 
692 template<class fitterT>
694 {
695  return (int) info[6];
696 }
697 
698 template<class fitterT>
700 {
701  return (int) info[7];
702 }
703 
704 template<class fitterT>
706 {
707  return (int) info[8];
708 }
709 
710 template<class fitterT>
712 {
713  return (int) info[9];
714 }
715 
716 template<class fitterT>
718 {
719  switch(get_reason_code())
720  {
721  case 1:
722  return "stopped by small gradient J^T e";
723  break;
724  case 2:
725  return "stopped by small Dp";
726  break;
727  case 3:
728  return "stopped by itmax";
729  break;
730  case 4:
731  return "singular matrix. Restart from current p with increased mu";
732  break;
733  case 5:
734  return "no further error reduction is possible. Restart with increased mu";
735  break;
736  case 6:
737  return "stopped by small ||e||_2";
738  break;
739  case 7:
740  return "stopped by invalid (i.e. NaN or Inf) \"func\" values. This is a user error";
741  break;
742  default:
743  return "unknown reason code";
744  }
745 
746 }
747 
748 template<class fitterT>
749 template<typename iosT, char comment>
751 {
752  //This causes the stream to not output a '\0'
753  char c[] = {comment, '\0'};
754 
755  ios << c << "Current parameters (initial):\n";
756  for(int i=0;i<m;i++)
757  {
758  ios << c;
759  ios << "p[" << i << "] = " << p[i] << " (" << init_p[i] << ")\n";
760  }
761 
762  return ios;
763 }
764 
765 template<class fitterT>
766 template<char comment>
768 {
769  return dumpParameters<std::ostream,comment>(std::cout);
770 }
771 
772 template<class fitterT>
773 template<typename iosT, char comment>
775  bool dumpParams
776  )
777 {
778  char c[] = {comment, '\0'}; //So a '\0' won't be written to stream.
779 
780  ios << c << "--------------------------------------\n";
781  ios << c << "mx::math::fit::levmarInterface Results \n";
782  ios << c << "--------------------------------------\n";
783  if(dumpParams) dumpParameters<iosT,comment>(ios);
784  ios << c << "Reason for termination: " << get_reason_string() << "\n";
785  ios << c << "Initial norm: " << get_initial_norm() << "\n";
786  ios << c << "Final norm: " << get_final_norm() << "\n";
787  ios << c << "Number of iterations: " << get_iterations() << "\n";
788  ios << c << "Function evals: " << get_fevals() << "\n";
789  ios << c << "Jacobian evals: " << get_jevals() << "\n";
790  ios << c << "Elapsed time: " << get_deltaT() << " secs\n";
791  dumpGitStatus<iosT,comment>(ios);
792  return ios;
793 
794 }
795 
796 template<class fitterT>
797 template<char comment>
798 std::ostream & levmarInterface<fitterT>::dumpReport( bool dumpParams )
799 {
800  return dumpReport<std::ostream, comment>(std::cout);
801 
802 }
803 
804 
805 ///Test whether a function type has a Jacobian function by testing whether it has a typedef of "hasJacobian"
806 /** Used for compile-time determination of whether the fitter has a Jacobian.
807  *
808  * \ingroup fitting
809  */
810 template <typename T>
811 struct hasJacobian //This was taken directly from the example at http://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error
812 {
813  // Types "yes" and "no" are guaranteed to have different sizes,
814  // specifically sizeof(yes) == 1 and sizeof(no) == 2.
815  typedef char yes[1];
816  typedef char no[2];
817 
818  template <typename fitterT>
819  static yes& test(typename fitterT::hasJacobian*);
820 
821  template <typename>
822  static no& test(...);
823 
824  /// If hasJacobian<fitterT>::value == true, then fitterT has a Jacobian and the appropriate levmar routines are used.
825  /// If ::value == false, then the numerical derivatives are calculated.
826  // If the "sizeof" of the result of calling test<T>(0) would be equal to sizeof(yes),
827  // the first overload worked and T has a nested type named "hasJacobian".
828  static const bool value = sizeof(test<T>(0)) == sizeof(yes);
829 };
830 
831 ///Wrapper for a native array to pass to \ref levmarInterface
832 /**
833  * \ingroup fitting
834  */
835 template<typename realT>
836 struct array2Fit
837 {
838  realT * data {0}; ///Pointer to the array
839  size_t nx {0}; ///X dimension of the array
840  size_t ny {0}; ///Y dimension of the array
841 };
842 
843 
844 } //namespace fit
845 } //namespace math
846 } //namespace mx
847 
848 #endif //levmarInterface_hpp
849 
A templatized interface to the levmar package.
realT info[LM_INFO_SZ]
Information regarding the minimization.
void point_params(realT *i_p, int i_m)
Point the parameter pointer at an externally allocated array.
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.
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.
std::ostream & dumpReport(bool dumpParams=true)
Dump a status report to stdout.
realT * init_p
Parameter array on input, saved for comparison.
levmarInterface(realT *i_p, realT *i_x, int i_m, int i_n, void *i_adata)
Setup constructor.
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)
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.
void allocate_params(int i_m)
Set number of parameters and allocate.
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.
constexpr units::realT c()
The speed of light.
Definition: constants.hpp:60
typeT get_curr_time(timespec &tsp)
Get the current system time in seconds.
Definition: timeUtils.hpp:63
The mxlib c++ namespace.
Definition: mxError.hpp:107
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..