Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
SVD3x3.hh
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 #ifndef __SVD3x3_hh__
26 #define __SVD3x3_hh__
27 
28 #include "SVD.hh"
29 
30 namespace BIAS {
31  /** @class SVD3x3
32  @ingroup g_mathalgo
33  @brief singular value decomposition for 3x3 matrices
34 
35  koeser: There is an example matrix
36  F[0][0] =0.00075284066373225704;
37  F[0][1] =-0.099906426438442303;
38  F[0][2] =0.16267766990357244;
39  F[1][0] =0.10333163045064053;
40  F[1][1] =0.0014727467665194025;
41  F[1][2] =0.6803859609102173;
42  F[2][0] =-0.16234020366691171;
43  F[2][1] =-0.68087420277635458;
44  F[2][2] =0.0021896762792443826;
45  where the svd fails (at least) on p4 systems with gcc 3.3.1 and 3.3.3
46  with -O3 (independent of march-flag), but where it does not fail with O2.
47  SVD3x3 is implemented as an algorithm, which computes each singular value
48  and corresponding vector by iterating until some error measure e becomes
49  small compared to a reference value ref:
50  if (ref+e==ref) then converged=true;
51  With O3 this condition never becomes true for the second singular value,
52  because the difference of lhs and rhs stays at 1e-18, while in O2
53  this converges after two iterations to zero.
54  We have problems here in the order of machine precision, the question is
55  now whether this different behaviour of O2 and O3 is due to a compiler
56  error or an algorithmic weakness.
57  When tracing back the two execution branches of ExampleSVD3x3 (O2 and
58  O3), which uses the above matrix one finds that in the very beginning,
59  s and a[k][i] are absolutely the same before the line:
60  s += a[k][i]*a[k][i];
61  and after this line s differs by the last digit. Such effects sum up and
62  result in the failing of the convergence of the SVD.
63  Debugging in O3 is complicated because every cout causes a side-effect
64  and changes execution order and results, so I found that even adding one
65  simple cout at some line made the algorithm converge for that example.
66 
67  In my opinion this means that the svd algorihtm makes some convergence
68  assumptions about values in the order of machine precision which are not
69  always fulfilled, therefore it does not converge. This is just one
70  example which happens with O3 but there may also be one for O2, which we
71  have not found ? It may however also be an optimization "error" of gcc.
72 
73  @author woelk 08/2004 */
74  class BIASMathAlgo_EXPORT SVD3x3 : public SVD
75  {
76  public:
77  SVD3x3();
78 
79  /** constructor
80  solve the general eigenproblem of the rectangular matrix M
81  @author woelk 07/2004
82  @bug does not always converge when general svd does **/
83  SVD3x3(const Matrix <double> & M,
84  double ZeroThreshold = DEFAULT_DOUBLE_ZERO_THRESHOLD );
85 
86  inline virtual ~SVD3x3() {};
87 
88  /** set a new matrix and compute its decomposition.
89  solves the general eigenproblem of the rectangular matrix M
90  @bug does not always converge when general svd does
91  @author woelk 07/2004 **/
92  int Compute(const Matrix<double>& M,
93  double ZeroThreshold=DEFAULT_DOUBLE_ZERO_THRESHOLD);
94 
95  protected:
96  // swaps two singular values in S_ and the according columns/rows in V_/U_
97  inline void _Swap(int a, int b)
98  {
99  double tmp;
100  // swap singular values
101  tmp=S_[a]; S_[a]=S_[b]; S_[b]=tmp;
102  // swap rows in VT_
103  tmp=VT_[a][0]; VT_[a][0]=VT_[b][0]; VT_[b][0]=tmp;
104  tmp=VT_[a][1]; VT_[a][1]=VT_[b][1]; VT_[b][1]=tmp;
105  tmp=VT_[a][2]; VT_[a][2]=VT_[b][2]; VT_[b][2]=tmp;
106  // swap columns in U_
107  tmp=U_[0][a]; U_[0][a]=U_[0][b]; U_[0][b]=tmp;
108  tmp=U_[1][a]; U_[1][a]=U_[1][b]; U_[1][b]=tmp;
109  tmp=U_[2][a]; U_[2][a]=U_[2][b]; U_[2][b]=tmp;
110  }
111  };
112 
113 
114 } // namespace
115 
116 
117 #endif // __SVD3x3_hh__
computes and holds the singular value decomposition of a rectangular (not necessarily quadratic) Matr...
Definition: SVD.hh:92
void _Swap(int a, int b)
Definition: SVD3x3.hh:97
singular value decomposition for 3x3 matrices
Definition: SVD3x3.hh:74
virtual ~SVD3x3()
Definition: SVD3x3.hh:86