SLAMflex SE  0.1.0
SLAMflex provides detection and tracking of dominant planes for smartphone devices. This plane can then be used to show AR content relative to the plane orientation. The detection of plane is performed in the field of view of the smartphone camera. In subsequent frames it is tracked. The interface returns the plane position and orientation.
Cholesky.h
Go to the documentation of this file.
1 // -*- c++ -*-
2 
3 // Copyright (C) 2009 Tom Drummond (twd20@cam.ac.uk)
4 //
5 // This file is part of the TooN Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 // USA.
20 
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
29 
30 
31 #ifndef TOON_INCLUDE_CHOLESKY_H
32 #define TOON_INCLUDE_CHOLESKY_H
33 
34 #include "TooN.h"
35 
36 namespace TooN {
37 
38 
68 template <int Size=Dynamic, class Precision=DefaultPrecision>
69 class Cholesky {
70 public:
72 
76  template<class P2, class B2>
78  : my_cholesky(m) {
79  SizeMismatch<Size,Size>::test(m.num_rows(), m.num_cols());
80  do_compute();
81  }
82 
84  Cholesky(int size) : my_cholesky(size,size) {}
85 
86 
89  template<class P2, class B2> void compute(const Matrix<Size, Size, P2, B2>& m){
90  SizeMismatch<Size,Size>::test(m.num_rows(), m.num_cols());
91  SizeMismatch<Size,Size>::test(m.num_rows(), my_cholesky.num_rows());
92  my_cholesky=m;
93  do_compute();
94  }
95 
96  private:
97  void do_compute() {
98  int size=my_cholesky.num_rows();
99  for(int col=0; col<size; col++){
100  Precision inv_diag = 1;
101  for(int row=col; row < size; row++){
102  // correct for the parts of cholesky already computed
103  Precision val = my_cholesky(row,col);
104  for(int col2=0; col2<col; col2++){
105  // val-=my_cholesky(col,col2)*my_cholesky(row,col2)*my_cholesky(col2,col2);
106  val-=my_cholesky(col2,col)*my_cholesky(row,col2);
107  }
108  if(row==col){
109  // this is the diagonal element so don't divide
110  my_cholesky(row,col)=val;
111  inv_diag=1/val;
112  } else {
113  // cache the value without division in the upper half
114  my_cholesky(col,row)=val;
115  // divide my the diagonal element for all others
116  my_cholesky(row,col)=val*inv_diag;
117  }
118  }
119  }
120  }
121  public:
122 
125  template<int Size2, class P2, class B2>
127  int size=my_cholesky.num_rows();
128  SizeMismatch<Size,Size2>::test(size, v.size());
129 
130  // first backsub through L
131  Vector<Size, Precision> y(size);
132  for(int i=0; i<size; i++){
133  Precision val = v[i];
134  for(int j=0; j<i; j++){
135  val -= my_cholesky(i,j)*y[j];
136  }
137  y[i]=val;
138  }
139 
140  // backsub through diagonal
141  for(int i=0; i<size; i++){
142  y[i]/=my_cholesky(i,i);
143  }
144 
145  // backsub through L.T()
146  Vector<Size,Precision> result(size);
147  for(int i=size-1; i>=0; i--){
148  Precision val = y[i];
149  for(int j=i+1; j<size; j++){
150  val -= my_cholesky(j,i)*result[j];
151  }
152  result[i]=val;
153  }
154 
155  return result;
156  }
157 
160  template<int Size2, int C2, class P2, class B2>
162  int size=my_cholesky.num_rows();
163  SizeMismatch<Size,Size2>::test(size, m.num_rows());
164 
165  // first backsub through L
166  Matrix<Size, C2, Precision> y(size, m.num_cols());
167  for(int i=0; i<size; i++){
168  Vector<C2, Precision> val = m[i];
169  for(int j=0; j<i; j++){
170  val -= my_cholesky(i,j)*y[j];
171  }
172  y[i]=val;
173  }
174 
175  // backsub through diagonal
176  for(int i=0; i<size; i++){
177  y[i]*=(1/my_cholesky(i,i));
178  }
179 
180  // backsub through L.T()
181  Matrix<Size,C2,Precision> result(size, m.num_cols());
182  for(int i=size-1; i>=0; i--){
183  Vector<C2,Precision> val = y[i];
184  for(int j=i+1; j<size; j++){
185  val -= my_cholesky(j,i)*result[j];
186  }
187  result[i]=val;
188  }
189  return result;
190  }
191 
192 
195  // easy way to get inverse - could be made more efficient
198  return backsub(I);
199  }
200 
202  Precision determinant(){
203  Precision answer=my_cholesky(0,0);
204  for(int i=1; i<my_cholesky.num_rows(); i++){
205  answer*=my_cholesky(i,i);
206  }
207  return answer;
208  }
209 
210  template <int Size2, typename P2, typename B2>
211  Precision mahalanobis(const Vector<Size2, P2, B2>& v) const {
212  return v * backsub(v);
213  }
214 
217  my_cholesky.num_rows());
218  m=Identity;
219  for (int i=1;i<my_cholesky.num_rows();i++) {
220  for (int j=0;j<i;j++) {
221  m(i,j)=my_cholesky(i,j);
222  }
223  }
224  return m;
225  }
226 
229  my_cholesky.num_rows());
230  m=Zeros;
231  for (int i=0;i<my_cholesky.num_rows();i++) {
232  m(i,i)=my_cholesky(i,i);
233  }
234  return m;
235  }
236 
239  my_cholesky.num_rows());
240  m=Zeros;
241  for (int j=0;j<my_cholesky.num_cols();j++) {
242  Precision sqrtd=sqrt(my_cholesky(j,j));
243  m(j,j)=sqrtd;
244  for (int i=j+1;i<my_cholesky.num_rows();i++) {
245  m(i,j)=my_cholesky(i,j)*sqrtd;
246  }
247  }
248  return m;
249  }
250 
251 private:
253 };
254 
255 
256 }
257 
258 #endif
Precision mahalanobis(const Vector< Size2, P2, B2 > &v) const
Definition: Cholesky.h:211
static Operator< Internal::Identity< Internal::One > > Identity
Definition: objects.h:748
Vector< Size, Precision > backsub(const Vector< Size2, P2, B2 > &v) const
Definition: Cholesky.h:126
Matrix< Size, C2, Precision > backsub(const Matrix< Size2, C2, P2, B2 > &m) const
Definition: Cholesky.h:161
Matrix< Size, Size, Precision > get_L() const
Definition: Cholesky.h:237
Everything lives inside this namespace.
Definition: allocator.hh:48
static void test(int s1, int s2)
Matrix< Size, Size, Precision > get_inverse()
Definition: Cholesky.h:196
Cholesky(const Matrix< Size, Size, P2, B2 > &m)
Definition: Cholesky.h:77
Matrix< Size, Size, Precision > get_unscaled_L() const
Definition: Cholesky.h:215
Matrix< Size, Size, Precision > get_D() const
Definition: Cholesky.h:227
Cholesky(int size)
Constructor for Size=Dynamic.
Definition: Cholesky.h:84
Precision determinant()
Compute the determinant.
Definition: Cholesky.h:202
void do_compute()
Definition: Cholesky.h:97
void compute(const Matrix< Size, Size, P2, B2 > &m)
Definition: Cholesky.h:89
static Operator< Internal::Zero > Zeros
Definition: objects.h:727
Matrix< Size, Size, Precision > my_cholesky
Definition: Cholesky.h:252