KJB
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsl_multifit.h
Go to the documentation of this file.
1 /* $Id: gsl_multifit.h 14889 2013-07-10 20:48:10Z predoehl $ */
2 /* {{{=========================================================================== *
3  |
4  | Copyright (c) 1994-2011 by Kobus Barnard (author)
5  |
6  | Personal and educational use of this code is granted, provided that this
7  | header is kept intact, and that the authorship is not misrepresented, that
8  | its use is acknowledged in publications, and relevant papers are cited.
9  |
10  | For other use contact the author (kobus AT cs DOT arizona DOT edu).
11  |
12  | Please note that the code in this file has not necessarily been adequately
13  | tested. Naturally, there is no guarantee of performance, support, or fitness
14  | for any particular task. Nonetheless, I am interested in hearing about
15  | problems that you encounter.
16  |
17  | Author: Kyle Simek
18  * =========================================================================== }}}*/
19 
20 // vim: tabstop=4 shiftwidth=4 foldmethod=marker
21 
22 #ifndef KJB_CPP_GSL_MULTIFIT_H
23 #define KJB_CPP_GSL_MULTIFIT_H
24 
38 #include <l_cpp/l_exception.h>
39 #include <gsl_cpp/gsl_util.h>
40 #include <gsl_cpp/gsl_vector.h>
41 #include <boost/function/function1.hpp>
42 
43 #ifdef KJB_HAVE_GSL
44 #include <gsl/gsl_multifit_nlin.h>
45 #else
46 #warning "Gnu Scientific Library is absent, yet essential to this program."
47 
48 /*
49  * Here is some fakery to make client programs compile even when GSL is absent.
50  */
53 struct gsl_matrix {};
54 #define gsl_multifit_fdfsolver_lmsder ((void*)0)
55 #define gsl_multifit_fdfsolver_lmder ((void*)0)
56 #define gsl_multifit_fdfsolver_alloc(x,z) 0
57 #define gsl_set_error_handler_off() (0)
59  double (*f)( const gsl_vector*, void* , gsl_vector * );
60  void (*df)( const gsl_vector*, void*, gsl_matrix* );
61  void (*fdf)( const gsl_vector*, void*, gsl_vector*, gsl_matrix* );
62  int n;
63  size_t p;
64  void *params;
65 };
66 
68 typedef void gsl_multifit_fsolver;
69 // #define gsl_multifit_fsolver_nmsimplex2 ((void*)0)
70 #define gsl_multifit_fsolver_alloc(x,z) 0
71 //struct gsl_multifit_function {
72 // size_t n; void *params;
73 // double (*f)( const gsl_vector*, void* );
74 //};
75 
76 #endif
77 
78 
79 namespace kjb {
80 
82 
83 #ifdef KJB_HAVE_GSL
84 
89  struct basic_Gsl_multifit_fdf {
91  size_t dim;
92  size_t num_obs;
93 
94  basic_Gsl_multifit_fdf(
95  const gsl_multifit_fdfsolver_type* type,
96  size_t n,
97  size_t p
98  )
99  : p( (n>0 && p>0) ? gsl_multifit_fdfsolver_alloc(type, n, p) : 00 ),
100  dim( p ),
101  num_obs( n )
102  {
103  ETX_2( 0 == n, "basic_Gsl_multifit_fdf(): zero observations" );
104  ETX_2( 0 == p, "basic_Gsl_multifit_fdf(): Zero dimensions" );
105  ETX_2( 00 == p, "basic_Gsl_multifit_fdf(): Memory alloc failed" );
106  }
107 
108  ~basic_Gsl_multifit_fdf()
109  {
110  gsl_multifit_fdfsolver_free( p );
111  }
112 
113  void swap( basic_Gsl_multifit_fdf& that )
114  {
115  using std::swap;
116  swap( p, that.p );
117  }
118 
119  private:
120  // this class is not copyable, nor assignable, nor has a default ctor.
121  basic_Gsl_multifit_fdf( const basic_Gsl_multifit_fdf& );
122  basic_Gsl_multifit_fdf();
123  basic_Gsl_multifit_fdf& operator=( const basic_Gsl_multifit_fdf& );
124  };
125 
126  basic_Gsl_multifit_fdf m_fit;
127 #endif
128 
129  bool m_verbose;
130 
131  boost::function1<double, const gsl_vector*> boost_f_;
132  bool m_initialized;
133 
134  mutable Gsl_Vector* m_gradient;
135 
136 public:
139  const gsl_multifit_fdfsolver_type* type,
141  const gsl_vector* x0,
142  size_t data_count,
143  bool verbosity = true
144  )
145 #ifdef KJB_HAVE_GSL
146  : m_fit( type, data_count, x0 ? x0 -> size : 0 ),
147  m_verbose( verbosity ),
148  m_initialized(false),
149  m_gradient(NULL)
150  {
151  if(x0->size != f->p)
152  {
154  }
155 
156  initialize(f, x0);
157  }
158 #else
159  {
160  KJB_THROW_2( Missing_dependency, "GNU GSL" );
161  }
162 #endif
163 
165  size_t data_count,
166  size_t size,
168 #ifdef KJB_HAVE_GSL
169  : m_fit( type, data_count, size),
170  m_verbose( false ),
171  m_initialized(false),
172  m_gradient(NULL)
173  {}
174 #else
175  {
176  KJB_THROW_2( Missing_dependency, "GNU GSL" );
177  }
178 #endif
179 
181  {
182  delete m_gradient;
183  }
184 
187  const gsl_vector* x0
188  )
189  {
190 #ifdef KJB_HAVE_GSL
191  GSL_ETX( gsl_multifit_fdfsolver_set( m_fit.p, f, x0 ) );
192  m_initialized = true;
193 #endif
194  }
195 
196  size_t dim() const
197  {
198 #ifdef KJB_HAVE_GSL
199  return m_fit.dim;
200 #endif
201  }
202 
203  size_t num_observations() const
204  {
205 #ifdef KJB_HAVE_GSL
206  return m_fit.num_obs;
207 #endif
208  }
209 
218  int iterate()
219  {
220 #ifdef KJB_HAVE_GSL
221  if(!m_initialized)
222  {
223  KJB_THROW_2(Runtime_error, "Solver not initialized");
224  }
225 
226  int rc = gsl_multifit_fdfsolver_iterate( m_fit.p );
227  if (m_verbose) gsl_iterate_EPE(rc);
228  return rc;
229 #endif
230  }
231 
234  {
235 #ifdef KJB_HAVE_GSL
236  return gsl_multifit_fdfsolver_position( m_fit.p );
237 #endif
238  }
239 
241  {
242 #ifdef KJB_HAVE_GSL
243  return m_fit.p->J;
244 #endif
245  }
246 
247 
249  const gsl_vector* min() const
250  {
251 #ifdef KJB_HAVE_GSL
252  return m_fit.p->f;
253 #endif
254  }
255 
260  int test_delta( double epsabs, double epsrel) const
261  {
262 #ifdef KJB_HAVE_GSL
263 
264  return gsl_multifit_test_delta( m_fit.p->dx, m_fit.p->x, epsabs, epsrel );
265 #endif
266  }
267 
272  int test_gradient( double epsabs = 1e-6) const
273  {
274 #ifdef KJB_HAVE_GSL
275  if(m_gradient == NULL)
276  m_gradient = new Gsl_Vector(dim());
277 
278  gsl_multifit_gradient(m_fit.p->J, m_fit.p->f, *m_gradient);
279  return gsl_multifit_test_gradient(*m_gradient, epsabs);
280 #endif
281  }
282 
290  void swap( Gsl_multifit_fdf& that )
291  {
292 #ifdef KJB_HAVE_GSL
293  if ( this == &that )
294  {
295  return;
296  }
297  m_fit.swap( that.m_fit );
298 
299  using std::swap;
300  swap( m_verbose, that.m_verbose );
301  swap( m_gradient, that.m_gradient );
302 #endif
303  }
304 
311  bool verbosity( bool v )
312  {
313  bool oldv = m_verbose;
314  m_verbose = v;
315  return oldv;
316  }
317 
321  bool verbosity( )
322  {
323  return m_verbose;
324  }
325 };
326 
327 } // namespace kjb
328 
329 #endif
Definition: gsl_vector.h:35
size_t size
Definition: gsl_vector.h:36
bool verbosity()
Definition: gsl_multifit.h:321
gsl_vector * position() const
query the current best argfit of the solver
Definition: gsl_multifit.h:233
double * p
Definition: gsl_vector.h:36
size_t num_observations() const
Definition: gsl_multifit.h:203
Object thrown when an argument is of the wrong size or dimensions.
Definition: l_exception.h:426
void gsl_multifit_fdfsolver
Definition: gsl_multifit.h:52
#define gsl_multifit_fdfsolver_lmsder
Definition: gsl_multifit.h:54
int n
Definition: gsl_multifit.h:62
int iterate()
Perform one iteration of the solver.
Definition: gsl_multifit.h:218
#define KJB_THROW(ex)
Definition: l_exception.h:46
GSL utility stuff to help those using the C++ wrapper on GSL code.
bool verbosity(bool v)
Alter the verbosity attribute of the object.
Definition: gsl_multifit.h:311
void gsl_multifit_fsolver
Definition: gsl_multifit.h:68
Gsl_multifit_fdf(size_t data_count, size_t size, const gsl_multifit_fdfsolver_type *type=gsl_multifit_fdfsolver_lmsder)
Definition: gsl_multifit.h:164
void gsl_iterate_EPE(int gsl_error_code)
On error, print a GSL iteration error message (like EPE)
Definition: gsl_util.cpp:40
Definition: gsl_multifit.h:81
#define GSL_ETX(gsl_expr)
Definition: gsl_util.h:37
double(* f)(const gsl_vector *, void *, gsl_vector *)
Definition: gsl_multifit.h:59
Gsl_multifit_fdf(const gsl_multifit_fdfsolver_type *type, gsl_multifit_function_fdf *f, const gsl_vector *x0, size_t data_count, bool verbosity=true)
TODO: document.
Definition: gsl_multifit.h:138
void swap(Gsl_multifit_fdf &that)
Swap the contents of this solver and another (fast).
Definition: gsl_multifit.h:290
RAII wrapper for GSL vector objects.
Definition: gsl_vector.h:78
#define KJB_THROW_2(ex, msg)
Definition: l_exception.h:48
~Gsl_multifit_fdf()
Definition: gsl_multifit.h:180
void swap(kjb::Gsl_Multimin_fdf &m1, kjb::Gsl_Multimin_fdf &m2)
Swap two wrapped multimin objects.
Definition: gsl_multimin.h:693
#define ETX_2(a, msg)
Definition: l_exception.h:78
C++ wrapper on GSL vector class to prevent resource leaks.
Definition: gsl_multifit.h:58
int test_gradient(double epsabs=1e-6) const
Definition: gsl_multifit.h:272
void gsl_multifit_fsolver_type
Definition: gsl_multifit.h:67
void(* fdf)(const gsl_vector *, void *, gsl_vector *, gsl_matrix *)
Definition: gsl_multifit.h:61
void initialize(gsl_multifit_function_fdf *f, const gsl_vector *x0)
Definition: gsl_multifit.h:185
gsl_matrix * jacobian() const
Definition: gsl_multifit.h:240
void gsl_multifit_fdfsolver_type
Definition: gsl_multifit.h:51
#define gsl_multifit_fdfsolver_alloc(x, z)
Definition: gsl_multifit.h:56
Support for error handling exception classes in libKJB.
Object thrown when a program lacks required resources or libraries.
Definition: l_exception.h:539
Definition: gsl_multifit.h:53
int test_delta(double epsabs, double epsrel) const
Definition: gsl_multifit.h:260
size_t p
Definition: gsl_multifit.h:63
size_t dim() const
Definition: gsl_multifit.h:196
Object thrown when computation fails somehow during execution.
Definition: l_exception.h:321
void * params
Definition: gsl_multifit.h:64
void(* df)(const gsl_vector *, void *, gsl_matrix *)
Definition: gsl_multifit.h:60
const gsl_vector * min() const
query the current best min value of the function to be minimized
Definition: gsl_multifit.h:249