TooN
wls.h
1 // -*- c++ -*-
2 
3 // Copyright (C) 2005,2009 Tom Drummond (twd20@cam.ac.uk)
4 
5 //All rights reserved.
6 //
7 //Redistribution and use in source and binary forms, with or without
8 //modification, are permitted provided that the following conditions
9 //are met:
10 //1. Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 //2. Redistributions in binary form must reproduce the above copyright
13 // notice, this list of conditions and the following disclaimer in the
14 // documentation and/or other materials provided with the distribution.
15 //
16 //THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
17 //AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 //IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 //ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
20 //LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 //CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 //SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 //INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 //CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 //ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 //POSSIBILITY OF SUCH DAMAGE.
27 
28 #ifndef TOON_INCLUDE_WLS_H
29 #define TOON_INCLUDE_WLS_H
30 
31 #include <TooN/TooN.h>
32 #include <TooN/Cholesky.h>
33 #include <TooN/helpers.h>
34 
35 #include <cmath>
36 
37 namespace TooN {
38 
44 template <int Size=Dynamic, class Precision=DefaultPrecision,
45  template<int DecompSize, class DecompPrecision> class Decomposition = Cholesky>
46 class WLS {
47 public:
48 
50  WLS(int size=0) :
51  my_C_inv(size,size),
52  my_vector(size),
53  my_decomposition(size),
54  my_mu(size)
55  {
56  clear();
57  }
58 
60  void clear(){
61  my_C_inv = Zeros;
62  my_vector = Zeros;
63  }
64 
68  void add_prior(Precision val){
69  for(int i=0; i<my_C_inv.num_rows(); i++){
70  my_C_inv(i,i)+=val;
71  }
72  }
73 
77  template<class B2>
79  SizeMismatch<Size,Size>::test(my_C_inv.num_rows(), v.size());
80  for(int i=0; i<my_C_inv.num_rows(); i++){
81  my_C_inv(i,i)+=v[i];
82  }
83  }
84 
88  template<class B2>
90  my_C_inv+=m;
91  }
92 
97  template<class B2, class P2>
98  inline void add_mJ(Precision m, const Vector<Size, P2, B2>& J, Precision weight = 1) {
99 
100  //Upper right triangle only, for speed
101  for(int r=0; r < my_C_inv.num_rows(); r++)
102  {
103  double Jw = weight * J[r];
104  my_vector[r] += m * Jw;
105  for(int c=r; c < my_C_inv.num_rows(); c++)
106  my_C_inv[r][c] += Jw * J[c];
107  }
108  }
109 
114  template<class VB, int S2, class B2>
115  inline void add_mJ(const Vector<S2, Precision, VB>& m, const Matrix<S2,Size, Precision, B2>& J, Precision weight = 1) {
116 
117  SizeMismatch<S2,S2>::test(m.size(), J.num_rows());
118  for(int r=0; r < J.num_rows(); r++)
119  add_mJ(m[r], J[r], weight);
120 
121  }
122 
127  template<int N, class B1, class B2, class B3>
128  inline void add_mJ(const Vector<N,Precision,B1>& m,
130  const Matrix<N,N,Precision,B3>& invcov){
131  const Matrix<Size,N,Precision> temp = J * invcov;
132  my_C_inv += temp * J.T();
133  my_vector += temp * m;
134  }
135 
140  template<int N, class B1, class B2, class B3>
141  inline void add_mJ_rows(const Vector<N,Precision,B1>& m,
143  const Matrix<N,N,Precision,B3>& invcov){
144  const Matrix<Size,N,Precision> temp = J.T() * invcov;
145  my_C_inv += temp * J;
146  my_vector += temp * m;
147  }
148 
154  template<int N, typename B1>
155  inline void add_sparse_mJ(const Precision m,
156  const Vector<N,Precision,B1>& J1, const int index1,
157  const Precision weight = 1){
158  //Upper right triangle only, for speed
159  for(int r=0; r < J1.size(); r++)
160  {
161  double Jw = weight * J1[r];
162  my_vector[r+index1] += m * Jw;
163  for(int c = r; c < J1.size(); c++)
164  my_C_inv[r+index1][c+index1] += Jw * J1[c];
165  }
166  }
167 
173  template<int N, int S1, class P1, class P2, class P3, class B1, class B2, class B3>
174  inline void add_sparse_mJ_rows(const Vector<N,P1,B1>& m,
175  const Matrix<N,S1,P2,B2>& J1, const int index1,
176  const Matrix<N,N,P3,B3>& invcov){
177  const Matrix<S1,N,Precision> temp1 = J1.T() * invcov;
178  const int size1 = J1.num_cols();
179  my_C_inv.slice(index1, index1, size1, size1) += temp1 * J1;
180  my_vector.slice(index1, size1) += temp1 * m;
181  }
182 
190  template<int N, int S1, int S2, class B1, class B2, class B3, class B4>
192  const Matrix<N,S1,Precision,B2>& J1, const int index1,
193  const Matrix<N,S2,Precision,B3>& J2, const int index2,
194  const Matrix<N,N,Precision,B4>& invcov){
195  const Matrix<S1,N,Precision> temp1 = J1.T() * invcov;
196  const Matrix<S2,N,Precision> temp2 = J2.T() * invcov;
197  const Matrix<S1,S2,Precision> mixed = temp1 * J2;
198  const int size1 = J1.num_cols();
199  const int size2 = J2.num_cols();
200  my_C_inv.slice(index1, index1, size1, size1) += temp1 * J1;
201  my_C_inv.slice(index2, index2, size2, size2) += temp2 * J2;
202  my_C_inv.slice(index1, index2, size1, size2) += mixed;
203  my_C_inv.slice(index2, index1, size2, size1) += mixed.T();
204  my_vector.slice(index1, size1) += temp1 * m;
205  my_vector.slice(index2, size2) += temp2 * m;
206  }
207 
210  void compute(){
211 
212  //Copy the upper right triangle to the empty lower-left.
213  for(int r=1; r < my_C_inv.num_rows(); r++)
214  for(int c=0; c < r; c++)
215  my_C_inv[r][c] = my_C_inv[c][r];
216 
217  my_decomposition.compute(my_C_inv);
218  my_mu=my_decomposition.backsub(my_vector);
219  }
220 
223  void operator += (const WLS& meas){
224  my_vector+=meas.my_vector;
225  my_C_inv += meas.my_C_inv;
226  }
227 
231  const Matrix<Size,Size,Precision>& get_C_inv() const {return my_C_inv;}
232  Vector<Size,Precision>& get_mu(){return my_mu;}
233  const Vector<Size,Precision>& get_mu() const {return my_mu;}
234  Vector<Size,Precision>& get_vector(){return my_vector;}
235  const Vector<Size,Precision>& get_vector() const {return my_vector;}
236  Decomposition<Size,Precision>& get_decomposition(){return my_decomposition;}
237  const Decomposition<Size,Precision>& get_decomposition() const {return my_decomposition;}
238 
239 
240 private:
242  Vector<Size,Precision> my_vector;
243  Decomposition<Size,Precision> my_decomposition;
245 
246  // comment out to allow bitwise copying
247  // WLS( WLS& copyof );
248  // int operator = ( WLS& copyof );
249 };
250 
251 }
252 
253 #endif
void add_prior(const Vector< Size, Precision, B2 > &v)
Applies a regularisation term with a different strength for each parameter value. ...
Definition: wls.h:78
void add_sparse_mJ_rows(const Vector< N, Precision, B1 > &m, const Matrix< N, S1, Precision, B2 > &J1, const int index1, const Matrix< N, S2, Precision, B3 > &J2, const int index2, const Matrix< N, N, Precision, B4 > &invcov)
Add multiple measurements at once with a sparse Jacobian (much, much more efficiently) ...
Definition: wls.h:191
Decomposition< Size, Precision > & get_decomposition()
Return the decomposition object used to compute .
Definition: wls.h:236
Matrix< Size, Size, Precision > & get_C_inv()
Returns the inverse covariance matrix.
Definition: wls.h:229
Pretty generic SFINAE introspection generator.
Definition: vec_test.cc:21
A vector.
Definition: vector.hh:126
Vector< Size, Precision > & get_vector()
Returns the vector .
Definition: wls.h:234
void add_prior(Precision val)
Applies a constant regularisation term.
Definition: wls.h:68
A matrix.
Definition: matrix.hh:105
void operator+=(const WLS &meas)
Combine measurements from two WLS systems.
Definition: wls.h:223
Vector< Size, Precision > & get_mu()
Returns the update. With no prior, this is the result of .
Definition: wls.h:232
const Vector< Size, Precision > & get_vector() const
Returns the vector .
Definition: wls.h:235
void add_mJ_rows(const Vector< N, Precision, B1 > &m, const Matrix< N, Size, Precision, B2 > &J, const Matrix< N, N, Precision, B3 > &invcov)
Add multiple measurements at once (much more efficiently)
Definition: wls.h:141
const Decomposition< Size, Precision > & get_decomposition() const
Return the decomposition object used to compute .
Definition: wls.h:237
void add_sparse_mJ(const Precision m, const Vector< N, Precision, B1 > &J1, const int index1, const Precision weight=1)
Add a single measurement at once with a sparse Jacobian (much, much more efficiently) ...
Definition: wls.h:155
WLS(int size=0)
Default constructor or construct with the number of dimensions for the Dynamic case.
Definition: wls.h:50
void clear()
Clear all the measurements and apply a constant regularisation term.
Definition: wls.h:60
void add_sparse_mJ_rows(const Vector< N, P1, B1 > &m, const Matrix< N, S1, P2, B2 > &J1, const int index1, const Matrix< N, N, P3, B3 > &invcov)
Add multiple measurements at once with a sparse Jacobian (much, much more efficiently) ...
Definition: wls.h:174
void add_mJ(Precision m, const Vector< Size, P2, B2 > &J, Precision weight=1)
Add a single measurement.
Definition: wls.h:98
void add_mJ(const Vector< N, Precision, B1 > &m, const Matrix< Size, N, Precision, B2 > &J, const Matrix< N, N, Precision, B3 > &invcov)
Add multiple measurements at once (much more efficiently)
Definition: wls.h:128
void compute()
Process all the measurements and compute the weighted least squares set of parameter values stores th...
Definition: wls.h:210
const Matrix< Size, Size, Precision > & get_C_inv() const
Returns the inverse covariance matrix.
Definition: wls.h:231
const Vector< Size, Precision > & get_mu() const
Returns the update. With no prior, this is the result of .
Definition: wls.h:233
Definition: size_mismatch.hh:103
double DefaultPrecision
All TooN classes default to using this precision for computations and storage.
Definition: TooN.h:315
void add_mJ(const Vector< S2, Precision, VB > &m, const Matrix< S2, Size, Precision, B2 > &J, Precision weight=1)
Add a several measurements measurement.
Definition: wls.h:115
void add_prior(const Matrix< Size, Size, Precision, B2 > &m)
Applies a whole-matrix regularisation term.
Definition: wls.h:89
Performs Gauss-Newton weighted least squares computation.
Definition: wls.h:46