bazar  1.3.1
ls_step_solver.cpp
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 #include <iostream>
22 #include "ls_step_solver.h"
23 using namespace std;
24 
25 #ifdef WIN32
26 #include <float.h>
27 static inline int finite(double d) { return _finite(d); }
28 #endif
29 
30 ls_step_solver::ls_step_solver(int state_size, int maximum_scalar_measure_number)
31 {
32  this->maximum_scalar_measure_number = maximum_scalar_measure_number;
33 
34  M_copy = cvCreateMat(maximum_scalar_measure_number, state_size, CV_64F);
35  M1 = new double[maximum_scalar_measure_number];
36  M2 = new double[maximum_scalar_measure_number];
37  b_copy = new double[maximum_scalar_measure_number];
38 }
39 
41 {
42  delete[] M1;
43  delete[] M2;
44  delete[] b_copy;
45  if (M_copy) cvReleaseMat(&M_copy);
46 }
47 
48 void ls_step_solver::resize(int state_size, int maximum_scalar_measure_number)
49 {
50  if (maximum_scalar_measure_number > M_copy->rows ||
51  state_size > M_copy->cols) {
52  cvReleaseMat(&M_copy);
53  delete[] M1;
54  delete[] M2;
55  delete[] b_copy;
56 
57  this->maximum_scalar_measure_number = maximum_scalar_measure_number;
58  M_copy = cvCreateMat(maximum_scalar_measure_number, state_size, CV_64F);
59  M1 = new double[maximum_scalar_measure_number];
60  M2 = new double[maximum_scalar_measure_number];
61  b_copy = new double[maximum_scalar_measure_number];
62  }
63 }
64 
65 bool ls_step_solver::qr_solve(CvMat * M, CvMat * b, CvMat * X)
66 {
67 #ifndef SORRY_VINCENT_Y_A_UN_BUG
68  return cvSolve(M, b, X, CV_LU) != 0;
69 #else
70  int nr = M->rows;
71  int nc = M->cols;
72  int Mnc = M_copy->cols;
73 
74  assert(M_copy->rows == maximum_scalar_measure_number);
75  assert(M->cols == M_copy->cols);
76  assert(M->rows <= M_copy->rows);
77  CvMat subM;
78  cvGetSubRect(M_copy, &subM, cvRect(0,0,M->cols, M->rows));
79  cvCopy(M, &subM);
80  /*
81  // copy M -> M_copy
82  for(int i = 0; i < nr; i++)
83  {
84  double * pM = M->data.db + i * nc;
85  double * pMc = M_copy->data.db + i * Mnc;
86 
87  for(int j = 0; j < nc; j++)
88  pMc[j] = pM[j];
89  }
90  */
91 
92  assert(nc <= maximum_scalar_measure_number);
93  assert(nr <= maximum_scalar_measure_number);
94 
95  // Decomposition QR:
96  double * pM = M_copy->data.db;
97 
98  bool singular = false;
99  double * ppMkk = pM;
100  for(int k = 0; k < nc; k++)
101  {
102  double * ppMik = ppMkk;
103  double eta = fabs(*ppMik);
104  for(int i = k + 1; i < nr; i++)
105  {
106  double elt = fabs(*ppMik);
107  if (eta < elt) eta = elt;
108  ppMik += Mnc;
109  }
110 
111  if (eta == 0)
112  {
113  M1[k] = M2[k] = 0;
114  singular = true;
115  }
116  else
117  {
118  double sum = 0;
119  double inv_eta = 1. / eta;
120  double * ppMik = ppMkk;
121  for(int i = k; i < nr; i++)
122  {
123  *ppMik *= inv_eta;
124  sum += *ppMik * *ppMik;
125  ppMik += Mnc;
126  }
127  double sigma = sqrt(sum);
128  if (*ppMkk < 0)
129  sigma = -sigma;
130  *ppMkk += sigma;
131  M1[k] = sigma * *ppMkk;
132  M2[k] = -eta * sigma;
133  for(int j = k + 1; j < nc; j++)
134  {
135  double sum = 0;
136  double * ppMik = ppMkk;
137  int Djk = j - k;
138  for(int i = k; i < nr; i++)
139  {
140  sum += *ppMik * ppMik[Djk];
141  ppMik += Mnc;
142  }
143  double tau = sum / M1[k];
144  ppMik = ppMkk;
145  for(int i = k; i < nr; i++)
146  {
147  ppMik[Djk] -= tau * *ppMik;
148  ppMik += Mnc;
149  }
150  }
151  }
152  ppMkk += Mnc + 1;
153  }
154 
155  assert(M_copy->rows == maximum_scalar_measure_number);
156 
157  // b_copy <- Qt b
158  for(int i = 0; i < nr; i++)
159  b_copy[i] = b->data.db[i];
160  double * ppMjj = pM;
161  for(int j = 0; j < nc; j++)
162  {
163  double tau = 0;
164  double * ppMij = ppMjj;
165  for(int i = j; i < nr; i++)
166  {
167  tau += *ppMij * b_copy[i];
168  ppMij += Mnc;
169  }
170  tau /= M1[j];
171  ppMij = ppMjj;
172  for(int i = j; i < nr; i++)
173  {
174  b_copy[i] -= tau * *ppMij;
175  ppMij += Mnc;
176  }
177  ppMjj += Mnc + 1;
178  }
179 
180  assert(M_copy->rows == maximum_scalar_measure_number);
181 
182  // X = R-1 b
183  double * p_X = X->data.db;
184  p_X[nc - 1] = b_copy[nc - 1] / M2[nc - 1];
185  if (!finite(p_X[nc-1])) return false;
186  for(int i = nc - 2; i >= 0; i--)
187  {
188  double sum = 0;
189  double * ppMij = pM + i * Mnc + (i + 1);
190 
191  for(int j = i + 1; j < nc; j++)
192  {
193  sum += *ppMij * p_X[j];
194  ppMij++;
195  }
196  p_X[i] = (b_copy[i] - sum) / M2[i];
197  if (!finite(p_X[i])) return false;
198  }
199  assert(M_copy->rows == maximum_scalar_measure_number);
200  return true;
201 #endif
202 }