vnl_sparse_lm.h
Go to the documentation of this file.
1 // This is core/vnl/algo/vnl_sparse_lm.h
2 #ifndef vnl_sparse_lm_h_
3 #define vnl_sparse_lm_h_
4 //:
5 // \file
6 // \brief Sparse Levenberg Marquardt nonlinear least squares
7 // \author Matt Leotta (Brown)
8 // \date April 14, 2005
9 //
10 // \verbatim
11 // Modifications
12 // Mar 15, 2010 MJL - Modified to handle 'c' parameters (globals)
13 // \endverbatim
14 //
15 
16 #include <iosfwd>
17 #include <vector>
18 #ifdef _MSC_VER
19 # include <vcl_msvc_warnings.h>
20 #endif
21 #include <vnl/vnl_vector.h>
22 #include <vnl/vnl_matrix.h>
24 
25 #include <vnl/algo/vnl_algo_export.h>
26 
28 
29 //: Sparse Levenberg Marquardt nonlinear least squares
30 // Unlike vnl_levenberg_marquardt this does not use the MINPACK routines.
31 // This class implements sparse Levenberg Marquardt as described in
32 // the Hartley and Zisserman "Multiple View Geometry" book and further
33 // described in a technical report on sparse bundle adjustment available
34 // at http://www.ics.forth.gr/~lourakis/sba
35 class VNL_ALGO_EXPORT vnl_sparse_lm : public vnl_nonlinear_minimizer
36 {
37  public:
38 
39  //: Initialize with the function object that is to be minimized.
41 
42  //: Destructor
43  ~vnl_sparse_lm() override;
44 
45  //: Minimize the function supplied in the constructor until convergence or failure.
46  // On return, a, b, and c are such that f(a,b,c) is the lowest value achieved.
47  // Returns true for convergence, false for failure.
48  // If use_gradient is set to false, a finite difference approximation will be used,
49  // even if the Jacobian functions have been provided.
50  // If use_weights is set to false, weights will not be computed even if a
51  // weighting function has been provided.
52  bool minimize(vnl_vector<double>& a,
55  bool use_gradient = true,
56  bool use_weights = true);
57 
58  // Coping with failure-------------------------------------------------------
59 
60  //: Provide an ASCII diagnosis of the last minimization on std::ostream.
61  void diagnose_outcome(/*std::cerr*/) const;
62  void diagnose_outcome(std::ostream&) const;
63 
64  //: Return J'*J computed at last minimum.
65  // it is an approximation of inverse of covariance
66  vnl_matrix<double> const& get_JtJ();
67 
68  //: Access the final weights after optimization
69  const vnl_vector<double>& get_weights() const { return weights_; }
70 
71 protected:
72 
73  //: used to compute the initial damping
74  double tau_;
75  //: the function to minimize
77 
79  bool set_covariance_; // Set if covariance_ holds J'*J
80 
81  void init(vnl_sparse_lst_sqr_function* f);
82 
83 private:
84 
85  //: allocate matrix memory by setting all the matrix sizes
86  void allocate_matrices();
87 
88  //: check vector sizes and verify that they match the problem size
89  bool check_vector_sizes(vnl_vector<double> const& a,
90  vnl_vector<double> const& b,
91  vnl_vector<double> const& c);
92 
93  //: compute the blocks making up the the normal equations: Jt J d = Jt e
94  void compute_normal_equations();
95 
96  //: extract the vector on the diagonal of Jt J
97  vnl_vector<double> extract_diagonal() const;
98 
99  //: set the vector on the diagonal of Jt J
100  void set_diagonal(const vnl_vector<double>& diag);
101 
102  //: compute all inv(Vi) and Yij
103  void compute_invV_Y();
104 
105  //: compute Z and Sa
106  void compute_Z_Sa(vnl_matrix<double>& Sa);
107 
108  //: compute Ma
109  void compute_Ma(const vnl_matrix<double>& H);
110 
111  //: compute Mb
112  void compute_Mb();
113 
114  //: solve for dc
115  void solve_dc(vnl_vector<double>& dc);
116 
117  //: compute sea using ea, Z, dc, Y, and eb
118  void compute_sea(vnl_vector<double> const& dc,
119  vnl_vector<double>& sea);
120 
121  //: compute Sa and sea
122  // only used when size_c_ == 0
123  void compute_Sa_sea(vnl_matrix<double>& Sa, vnl_vector<double>& sea);
124 
125  //: back solve to find db using da and dc
126  void backsolve_db(vnl_vector<double> const& da,
127  vnl_vector<double> const& dc,
128  vnl_vector<double>& db);
129 
130  const int num_a_;
131  const int num_b_;
132  const int num_e_;
133  const int num_nz_;
134 
135  const int size_a_;
136  const int size_b_;
137  const int size_c_;
138  const int size_e_;
139 
140  //: Storage for each of the Jacobians A_ij, B_ij, and C_ij
141  std::vector<vnl_matrix<double> > A_;
142  std::vector<vnl_matrix<double> > B_;
143  std::vector<vnl_matrix<double> > C_;
144 
145  //: Storage for normal equation blocks
146  // diagonals of JtJ
147  std::vector<vnl_matrix<double> > U_;
148  std::vector<vnl_matrix<double> > V_;
150  // off-diagonals of JtJ
151  std::vector<vnl_matrix<double> > W_;
152  std::vector<vnl_matrix<double> > R_;
153  std::vector<vnl_matrix<double> > Q_;
154  // vectors Jte
158 
159  // Storage for residual vector
161 
162  // Storage for weight vector
164 
165  // Storage for intermediate results
166  std::vector<vnl_matrix<double> > inv_V_;
167  std::vector<vnl_matrix<double> > Y_;
168  std::vector<vnl_matrix<double> > Z_;
169  std::vector<vnl_matrix<double> > Ma_;
170  std::vector<vnl_matrix<double> > Mb_;
171 
172 };
173 
174 
175 #endif // vnl_sparse_lm_h_
const int num_e_
const int size_b_
std::vector< vnl_matrix< double > > inv_V_
Sparse Levenberg Marquardt nonlinear least squares.
Definition: vnl_sparse_lm.h:35
An ordinary mathematical matrix.
vnl_sparse_lst_sqr_function * f_
the function to minimize.
Definition: vnl_sparse_lm.h:76
vnl_vector< double > ec_
vnl_matrix< double > T_
std::vector< vnl_matrix< double > > W_
vnl_matrix< double > inv_covar_
Definition: vnl_sparse_lm.h:78
const int num_nz_
std::vector< vnl_matrix< double > > B_
std::vector< vnl_matrix< double > > C_
const int size_a_
const int size_c_
Abstract base for sparse least squares functions.
vnl_vector< double > eb_
vnl_nonlinear_minimizer is a base class for nonlinear optimization.
const int num_a_
const int num_b_
std::vector< vnl_matrix< double > > Ma_
vnl_vector< double > ea_
std::vector< vnl_matrix< double > > Mb_
std::vector< vnl_matrix< double > > A_
Storage for each of the Jacobians A_ij, B_ij, and C_ij.
Base class for nonlinear optimization.
std::vector< vnl_matrix< double > > V_
std::vector< vnl_matrix< double > > R_
double tau_
used to compute the initial damping.
Definition: vnl_sparse_lm.h:74
vnl_vector< double > e_
std::vector< vnl_matrix< double > > Y_
std::vector< vnl_matrix< double > > Q_
const int size_e_
std::vector< vnl_matrix< double > > Z_
const vnl_vector< double > & get_weights() const
Access the final weights after optimization.
Definition: vnl_sparse_lm.h:69
vnl_vector< double > weights_
bool set_covariance_
Definition: vnl_sparse_lm.h:79
std::vector< vnl_matrix< double > > U_
Storage for normal equation blocks.