TooN
irls.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 
29 #ifndef __IRLS_H
30 #define __IRLS_H
31 
32 #include <TooN/wls.h>
33 #include <cassert>
34 #include <cmath>
35 
36 namespace TooN {
37 
42  template<typename Precision>
43  struct RobustI {
44  void set_sd(Precision x){ sd_inlier = x;}
45  double sd_inlier;
46  inline Precision reweight(Precision x) {return 1/(sd_inlier+fabs(x));}
47  inline Precision true_scale(Precision x) {return reweight(x) - fabs(x)*reweight(x)*reweight(x);}
48  inline Precision objective(Precision x) {return fabs(x) + sd_inlier*::log(sd_inlier*reweight(x));}
49  };
50 
55  template<typename Precision>
56  struct RobustII {
57  void set_sd(Precision x){ sd_inlier = x*x;}
58  Precision sd_inlier;
59  inline Precision reweight(Precision d){return 1/(sd_inlier+d*d);}
60  inline Precision true_scale(Precision d){return d - 2*d*reweight(d);}
61  inline Precision objective(Precision d){return 0.5 * ::log(1 + d*d/sd_inlier);}
62  };
63 
68  template<typename Precision>
69  struct ILinear {
70  void set_sd(Precision){}
71  inline Precision reweight(Precision){return 1;}
72  inline Precision true_scale(Precision){return 1;}
73  inline Precision objective(Precision d){return d*d;}
74  };
75 
81  template<typename Precision>
82  struct RobustIII {
83 
84  void set_sd(Precision x){ sd_inlier = x*x;}
85  Precision sd_inlier;
86  Precision reweight(Precision x) const
88  {
89  double d = (1 + x*x/sd_inlier);
90  return 1/(d*d);
91  }
93  Precision objective(Precision x) const
94  {
95  return x*x / (2*(1 + x*x/sd_inlier));
96  }
97  };
98 
104  template <int Size, typename Precision, template <typename RWPrecision> class Reweight>
105  class IRLS
106  : public Reweight<Precision>,
107  public WLS<Size,Precision>
108  {
109  public:
110  IRLS(int size=Size):
111  WLS<Size,Precision>(size),
112  my_true_C_inv(Zeros(size))
113  {
114  my_residual=0;
115  }
116 
117  template<int Size2, typename Precision2, typename Base2>
118  inline void add_mJ(Precision m, const Vector<Size2,Precision2,Base2>& J) {
119  SizeMismatch<Size,Size2>::test(my_true_C_inv.num_rows(), J.size());
120 
121  Precision scale = Reweight<Precision>::reweight(m);
122  Precision ts = Reweight<Precision>::true_scale(m);
123  my_residual += Reweight<Precision>::objective(m);
124 
125  WLS<Size>::add_mJ(m,J,scale);
126 
127  Vector<Size,Precision> scaledm(m*ts);
128 
129  my_true_C_inv += scaledm.as_col() * scaledm.as_row();
130 
131  }
132 
133  void operator += (const IRLS& meas){
134  WLS<Size>::operator+=(meas);
135  my_true_C_inv += meas.my_true_C_inv;
136  }
137 
138 
139  Matrix<Size,Size,Precision>& get_true_C_inv() {return my_true_C_inv;}
140  const Matrix<Size,Size,Precision>& get_true_C_inv()const {return my_true_C_inv;}
141 
142  Precision get_residual() {return my_residual;}
143 
144  void clear(){
146  my_residual=0;
147  my_true_C_inv = Zeros;
148  }
149 
150  private:
151 
152  Precision my_residual;
153 
154  Matrix<Size,Size,Precision> my_true_C_inv;
155 
156  // comment out to allow bitwise copying
157  IRLS( IRLS& copyof );
158  int operator = ( IRLS& copyof );
159  };
160 
161 }
162 
163 #endif
Precision sd_inlier
The inlier standard deviation squared, .
Definition: irls.h:58
Precision objective(Precision d)
Returns .
Definition: irls.h:61
Precision true_scale(Precision x)
Returns .
Definition: irls.h:47
Matrix< R, C, P > log(const Matrix< R, C, P, B > &m)
computes the matrix logarithm of a matrix m using the inverse scaling and squaring method...
Definition: helpers.h:373
Pretty generic SFINAE introspection generator.
Definition: vec_test.cc:21
A vector.
Definition: vector.hh:126
void set_sd(Precision x)
Set the noise standard deviation.
Definition: irls.h:84
Robust reweighting (type I) for IRLS.
Definition: irls.h:43
Precision objective(Precision x)
Returns .
Definition: irls.h:48
void operator+=(const WLS &meas)
Combine measurements from two WLS systems.
Definition: wls.h:223
Precision reweight(Precision)
Returns .
Definition: irls.h:71
void set_sd(Precision)
Set the noise standard deviation (does nothing).
Definition: irls.h:70
Performs iterative reweighted least squares.
Definition: irls.h:105
Precision true_scale(Precision)
Returns .
Definition: irls.h:72
void clear()
Clear all the measurements and apply a constant regularisation term.
Definition: wls.h:60
void add_mJ(Precision m, const Vector< Size, P2, B2 > &J, Precision weight=1)
Add a single measurement.
Definition: wls.h:98
void set_sd(Precision x)
Set the noise standard deviation.
Definition: irls.h:44
A reweighting class representing no reweighting in IRLS.
Definition: irls.h:69
Precision true_scale(Precision d)
Returns .
Definition: irls.h:60
Robust reweighting (type II) for IRLS.
Definition: irls.h:56
Precision reweight(Precision d)
Returns .
Definition: irls.h:59
Definition: size_mismatch.hh:103
double sd_inlier
The inlier standard deviation, .
Definition: irls.h:45
Precision sd_inlier
Inlier standard deviation squared.
Definition: irls.h:85
A reweighting class where the objective function tends to a fixed value, rather than infinity...
Definition: irls.h:82
void set_sd(Precision x)
Set the noise standard deviation.
Definition: irls.h:57
Precision reweight(Precision x)
Returns .
Definition: irls.h:46
Precision objective(Precision d)
Returns .
Definition: irls.h:73
Performs Gauss-Newton weighted least squares computation.
Definition: wls.h:46