ViSP  2.8.0
vpMatrix_lu.cpp
1 /****************************************************************************
2  *
3  * $Id: vpMatrix_lu.cpp 4056 2013-01-05 13:04:42Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2013 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Matrix LU decomposition.
36  *
37  * Authors:
38  * Eric Marchand
39  *
40  *****************************************************************************/
41 
42 #include <visp/vpConfig.h>
43 
44 #ifndef DOXYGEN_SHOULD_SKIP_THIS
45 
46 #include <visp/vpMatrix.h>
47 #include <visp/vpMath.h>
48 #include <visp/vpColVector.h>
49 
50 // Exception
51 #include <visp/vpException.h>
52 #include <visp/vpMatrixException.h>
53 
54 // Debug trace
55 #include <visp/vpDebug.h>
56 
57 #include <cmath> // std::fabs
58 #include <limits> // numeric_limits
59 
60 #define TINY 1.0e-20;
61 
62 
63 /*--------------------------------------------------------------------
64  LU Decomposition related functions
65 -------------------------------------------------------------------- */
66 
85 void
86 vpMatrix::LUDcmp(unsigned int *perm, int& d)
87 {
88  unsigned int n = rowNum;
89 
90  unsigned int i,imax=0,j,k;
91  double big,dum,sum,temp;
92  vpColVector vv(n);
93 
94  d=1;
95  for (i=0;i<n;i++) {
96  big=0.0;
97  for (j=0;j<n;j++)
98  if ((temp=fabs(rowPtrs[i][j])) > big) big=temp;
99  //if (big == 0.0)
100  if (std::fabs(big) <= std::numeric_limits<double>::epsilon())
101  {
102  vpERROR_TRACE("Singular vpMatrix in LUDcmp") ;
104  "\n\t\tSingular vpMatrix in LUDcmp")) ;
105  }
106  vv[i]=1.0/big;
107  }
108  for (j=0;j<n;j++) {
109  for (i=0;i<j;i++) {
110  sum=rowPtrs[i][j];
111  for (k=0;k<i;k++) sum -= rowPtrs[i][k]*rowPtrs[k][j];
112  rowPtrs[i][j]=sum;
113  }
114  big=0.0;
115  for (i=j;i<n;i++) {
116  sum=rowPtrs[i][j];
117  for (k=0;k<j;k++)
118  sum -= rowPtrs[i][k]*rowPtrs[k][j];
119  rowPtrs[i][j]=sum;
120  if ( (dum=vv[i]*fabs(sum)) >= big) {
121  big=dum;
122  imax=i;
123  }
124  }
125  if (j != imax) {
126  for (k=0;k<n;k++) {
127  dum=rowPtrs[imax][k];
128  rowPtrs[imax][k]=rowPtrs[j][k];
129  rowPtrs[j][k]=dum;
130  }
131  d *= -1;
132  vv[imax]=vv[j];
133  }
134  perm[j]=imax;
135  //if (rowPtrs[j][j] == 0.0)
136  if (std::fabs(rowPtrs[j][j]) <= std::numeric_limits<double>::epsilon())
137  rowPtrs[j][j]=TINY;
138  if (j != n) {
139  dum=1.0/(rowPtrs[j][j]);
140  for (i=j+1;i<n;i++) rowPtrs[i][j] *= dum;
141  }
142  }
143 }
144 
145 #undef TINY
146 
166 void vpMatrix::LUBksb(unsigned int *perm, vpColVector& b)
167 {
168  unsigned int n = rowNum;
169 
170  unsigned int ii=0;
171  unsigned int ip;
172  double sum;
173  bool flag = false;
174  unsigned int i;
175 
176  for (i=0;i<n;i++) {
177  ip=perm[i];
178  sum=b[ip];
179  b[ip]=b[i];
180  if (flag) {
181  for (unsigned int j=ii;j<=i-1;j++) sum -= rowPtrs[i][j]*b[j];
182  }
183  //else if (sum) {
184  else if (std::fabs(sum) > std::numeric_limits<double>::epsilon()) {
185  ii=i;
186  flag = true;
187  }
188  b[i]=sum;
189  }
190  // for (int i=n-1;i>=0;i--) {
191  // sum=b[i];
192  // for (int j=i+1;j<n;j++) sum -= rowPtrs[i][j]*b[j];
193  // b[i]=sum/rowPtrs[i][i];
194  // }
195  i=n;
196  do {
197  i --;
198 
199  sum=b[i];
200  for (unsigned int j=i+1;j<n;j++) sum -= rowPtrs[i][j]*b[j];
201  b[i]=sum/rowPtrs[i][i];
202  } while(i != 0);
203 }
204 #endif // doxygen should skip this
205 
235 vpMatrix
237 {
238  unsigned int i,j;
239 
240  if ( rowNum != colNum)
241  {
242  vpERROR_TRACE("\n\t\tCannot invert a non-square vpMatrix") ;
244  "Cannot invert a non-square vpMatrix")) ;
245  }
246 
248  vpMatrix V(rowNum, rowNum);
249  vpColVector W(rowNum);
250 
251  for (i=0; i<rowNum; i++) {
252  for (j=0; j<rowNum; j++) {
253  B[i][j] = (i == j) ? 1 : 0;
254  }
255  }
256 
257  vpMatrix A(rowNum, rowNum);
258  A = *this;
259 
260  unsigned int *perm = new unsigned int[rowNum];
261  int p;
262 
263  A.LUDcmp(perm, p);
264 
265  vpColVector c_tmp(rowNum) ;
266  for (j=1; j<=rowNum; j++)
267  {
268  c_tmp =0 ; c_tmp[j-1] = 1 ;
269  A.LUBksb(perm, c_tmp);
270  for (unsigned int k=0 ; k < c_tmp.getRows() ; k++)
271  B[k][j-1] = c_tmp[k] ;
272  }
273  delete [] perm;
274  return B;
275 }
276 
Definition of the vpMatrix class.
Definition: vpMatrix.h:96
#define vpERROR_TRACE
Definition: vpDebug.h:379
double ** rowPtrs
address of the first element of each rows
Definition: vpMatrix.h:119
unsigned int rowNum
number of rows
Definition: vpMatrix.h:110
Class that provides a data structure for the column vectors as well as a set of operations on these v...
Definition: vpColVector.h:72
vpMatrix inverseByLU() const
error that can be emited by the vpMatrix class and its derivates
unsigned int colNum
number of columns
Definition: vpMatrix.h:112
unsigned int getRows() const
Return the number of rows of the matrix.
Definition: vpMatrix.h:157