bazar  1.3.1
ls_minimizer2.h
Go to the documentation of this file.
1 /*
2 Copyright 2005, 2006 Computer Vision Lab,
3 Ecole Polytechnique Federale de Lausanne (EPFL), Switzerland.
4 All rights reserved.
5 
6 This file is part of BazAR.
7 
8 BazAR is free software; you can redistribute it and/or modify it under the
9 terms of the GNU General Public License as published by the Free Software
10 Foundation; either version 2 of the License, or (at your option) any later
11 version.
12 
13 BazAR is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
15 PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License along with
18 BazAR; if not, write to the Free Software Foundation, Inc., 51 Franklin
19 Street, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21 #ifndef LS_MINIMIZER2_H
22 #define LS_MINIMIZER2_H
23 
24 // windef.h sometimes defines max. We do not want it. NOMINMAX
25 #ifdef max
26 #undef max
27 #endif
28 
29 #include <limits>
30 #include <vector>
31 #include <cxcore.h>
32 #include "ls_step_solver.h"
33 
34 
40 {
41 public:
42 
43  typedef double flt_t;
44  typedef void (*callback_function)(flt_t * state, void ** user_data);
45 
46  ls_minimizer2(int state_size=0);
48 
49  enum {MAX_B_SIZE = 4};
50 
56  struct observation
57  {
58  virtual ~observation(){}
60  void set_default_values(void) {
61  c_max = squared_c = std::numeric_limits<flt_t>::max();
62  c_min = -std::numeric_limits<flt_t>::max();
63  confidence = 1.;
64  weight = 1.;
65  sqrt_weight = 1.;
66  ground_truth_outlier = false;
67  delete_me=false;
68  array_delete_me=false;
69  }
70  void set_weight(flt_t w) { weight =w; sqrt_weight = w*w; }
74  flt_t *b;
76  virtual flt_t residual(const flt_t *computed_b) const;
77  virtual int get_nb_measures() const=0;
78  virtual void eval_func(const flt_t *state, flt_t *b, flt_t *J, void **user_data) const =0;
79  bool operator < (const observation &a) const { return confidence > a.confidence; }
80  };
81 
83  typedef void (*func_nn_ptr)(const flt_t *state, const flt_t *data, int data_size,
84  flt_t *b, flt_t *J, void **user_data);
85 
87  template <int nb_data, int nb_obs>
89  flt_t data[nb_data];
90  flt_t y[nb_obs];
91 
93 
94  observation_nn(func_nn_ptr eval, const flt_t *d, const flt_t *b) {
95  f = eval;
96  memcpy(data, d, nb_data*sizeof(flt_t));
97  memcpy(y, b, nb_obs*sizeof(flt_t));
98  this->b = &y[0];
99  }
100  virtual ~observation_nn(){}
101  virtual int get_nb_measures() const {return nb_obs;}
102  virtual void eval_func(const flt_t *state, flt_t *b, flt_t *J, void **user_data) const {
103  f(state, data, nb_data, b, J, user_data);
104  }
105  virtual flt_t residual(const flt_t *computed_b) const {
106  flt_t r=0;
107  for (int i=0; i<nb_obs; i++) {
108  flt_t d = computed_b[i] - y[i];
109  r += d*d;
110  }
111  return r;
112  }
113  };
114 
116  void set_state_size(int size);
117 
121  void set_scales(flt_t * scales);
123 
129  void set_verbose_level(int vl);
130 
134  void set_user_data(int slot_index, void * ptr);
135 
137  void reset_observations(void);
138 
140  void erase_observations(int a, int b=-1);
141 
142  void add_observation(observation *obs, bool to_delete, bool to_array_delete);
143 
144  void add_observation_2data_1measure(func_nn_ptr f, const flt_t data[2], const flt_t goal);
145  void add_observation_3data_1measure(func_nn_ptr f, const flt_t data[3], const flt_t goal);
146  void add_observation_2data_2measures(func_nn_ptr f, const flt_t data[2], const flt_t goal[2]);
147  void add_observation_3data_2measures(func_nn_ptr f, const flt_t data[3], const flt_t goal[2]);
148 
151 
154 
159  void set_default_c(flt_t c);
160 
165 
167  void set_last_observation_c_max_c_min(flt_t c_max, flt_t c_min);
168 
170  void set_last_observation_weight(flt_t weight);
171 
173  void set_last_observation_confidence(flt_t confidence);
174 
177 
178  // ALGORITHMS:
179  // Steepest descent:
180  int minimize_using_steepest_descent_from(flt_t * initial_state);
181 
183  int minimize_using_levenberg_marquardt_from(flt_t * initial_state);
184  void lm_set_max_iterations(int it);
186  void lm_set_max_failures_in_a_row(int f);
188  void lm_set_tol_cos(flt_t t);
189 
191 
192  // Gauss-Newton:
193  bool minimize_using_gauss_newton_from(flt_t * initial_state);
194 
196  int minimize_using_dogleg_from(flt_t * initial_state);
197 
201  int minimize_using_cattail_from(flt_t * initial_state);
202  void ct_set_max_iterations(int it) {ct_max_iterations = it; }
203  void set_line_search_parameters(flt_t lambda0, flt_t k_rough, flt_t k_fine);
204 
205  // Prosac
206  typedef bool (*sample_consensus_func)(flt_t *computed_state, observation **obs, int nobs, void **user_data);
207  flt_t minimize_using_prosac(sample_consensus_func f, int nb_samples, int min_number_of_inliers, int max_number_of_iterations);
208 
209  // Julien' method
210  flt_t minimize_using_julien_method_from(const flt_t * state, int nb_steps, int nb_iterations_per_step);
211 
212  // DEBUGGING:
216  void check_jacobians_around(flt_t * state, flt_t state_step);
217 
218  // Comparing with ground truth:
220  void set_ground_truth(flt_t * state);
223 
224  void reserve(int max_obs) {
225  alloc_matrices(max_obs);
226  }
227 
228 private:
229  void set_default_values(void);
230  void free_all();
231  int real_J_size;
232  void alloc_matrices(int maximum_scalar_measure_number);
233  void free_matrices();
234 public:
235  int count_measures();
236 private:
237  inline flt_t rho(flt_t x2, flt_t c2) { return (x2 < c2) ? x2 : c2; }
238  flt_t build_eps(flt_t * state, flt_t current_best_residual = std::numeric_limits<flt_t>::max(),
239  bool outliers_in_residual=true);
240  int nb_inliers;
241  bool build_J(flt_t * state);
242  bool build_J_and_eps(flt_t * state);
243  bool build_J_and_stuff(flt_t * state);
244  flt_t compute_residual(flt_t * state, bool display = false);
245  // !!! CALL new_iteration_callback function before calling residual !!!
246  flt_t residual(flt_t * state);
247 
248  flt_t build_eps_return_inlier_residual(flt_t * state, flt_t current_best_residual = std::numeric_limits<flt_t>::max());
249  flt_t inlier_residual(flt_t * state, flt_t current_best_residual);
250 
251  void show_state(int vl, flt_t * state, flt_t r);
252 
253  void set_current_c_s(flt_t k = -1.);
254 
255  flt_t * new_state, * best_state, * scales;
256  int state_size;
257 
258  flt_t default_squared_c;
259 
261  typedef std::vector<observation *> observation_vector;
262 
264  observation_vector observations;
265 
266  CvMat * J, *newJ, * eps, * eps_previous;
267  CvMat * Jt, * JtJ, * Jteps, * ds, * Jds, * aug_JtJ;
268  ls_step_solver * step_solver;
269  callback_function new_iteration_callback;
270  callback_function state_change_callback;
271  void set_new_state(const flt_t *new_state);
272 
273 public:
275 
276 private:
277  void * user_data[10];
278 
279  // Algorithm specific data:
280  // Levenberg-Marquardt
281 public:
286 private:
287 
288  // Dog leg:
289  flt_t dl_update_Delta(flt_t rho, flt_t Delta, flt_t rho_min, flt_t rho_max);
290  flt_t dl_tol_cos;
291  CvMat * dl_delta_diff, * dl_delta_dl, * dl_delta_sd, * dl_delta_gn;
292  CvMat * JtJdelta, * JJteps;
293 
294  // Cat tail:
295  bool line_search(CvMat * dir, flt_t lambda_min, flt_t lambda_max, flt_t current_residual, flt_t & new_residual, flt_t & new_lambda);
296  CvMat * ct_delta_gn, * ct_delta_sd;
297  int ct_max_iterations;
298  flt_t ct_k_rough, ct_k_fine, ct_lambda0;
299 
300  // Prosac:
301  bool pick_random_indices(int *idx, int nb, int max_index);
302 
303  // Julien' method:
304  bool inside_julien_method;
305 
306  // For debugging:
307 public:
309 private:
310  flt_t * ground_truth_state;
311 };
312 
313 #endif // LS_MINIMIZER_H