31 #include <bias_config.h>
32 #include <MathAlgo/SVD.hh>
33 #include <MathAlgo/SVD3x3.hh>
34 #include <Base/Math/Random.hh>
35 #include <Base/Math/Matrix3x3.hh>
36 #include <Base/Debug/TimeMeasure.hh>
41 #define MAX_PRINT_SIZE 8
43 int main(
int argc,
char **argv)
49 bool useOpenCV =
false;
51 useOpenCV = (atoi(argv[2]) != 0);
53 cout <<
"Usage : ExampleSVD [<matrix size>] [<use OpenCV?>]" << endl << endl;
58 #ifdef BIAS_HAVE_OPENCV
59 cout << endl <<
"Using OpenCV singular value decomposition" << endl;
61 cout <<
"BIAS does not support OpenCV, using LAPACK SVD instead" << endl;
65 cout << endl <<
"Using LAPACK singular value decomposition" << endl;
67 double errorThreshold = 1e-6 * size * size;
71 cout << endl <<
"1.) Compute SVD for random " << size <<
"x" << size <<
" matrix" << endl;
79 for (
int i = 0; i < size; i++)
80 for (
int j = 0; j < size; j++)
82 if (size <= MAX_PRINT_SIZE)
83 M.PrintPretty(cout,
"M");
92 for (
int k = 0; k < numRepeats; k++)
97 for (
int k = 0; k < numRepeats; k++)
98 #ifdef BIAS_HAVE_OPENCV
108 if (size <= MAX_PRINT_SIZE)
116 if (size <= MAX_PRINT_SIZE)
117 cout << endl <<
"SVD S = " << svd.
GetS() << endl;
120 cout << endl <<
"SVD3x3 S = " << svd3x3.
GetS() << endl
121 << endl <<
"diff. S = " << dS << endl;
124 if (size <= MAX_PRINT_SIZE)
133 for (
int i = 0; i < size; i++)
134 S[i][i] = svd.
GetS()[i];
136 cout << endl <<
"SVD |M - U*S*VT| = " << dM.
NormL2() << endl;
137 if (dM.
NormL2() > errorThreshold) {
138 BIASERR(
"SVD failed!");
142 for (
int i = 0; i < size; i++)
143 S[i][i] = svd3x3.
GetS()[i];
144 dM = M - svd3x3.
GetU() * S * svd3x3.
GetVT();
145 cout << endl <<
"SVD3x3 |M - U*S*VT| = " << dM.
NormL2() << endl;
146 if (dM.
NormL2() > errorThreshold) {
147 BIASERR(
"SVD3x3 failed!");
148 if (size <= MAX_PRINT_SIZE)
153 cout << endl <<
"SVD time = " << (0.001 * timer.
GetRealTime()) / numRepeats <<
" ms";
155 cout << endl <<
"SVD3x3 time = " << (0.001 * timer3x3.
GetRealTime()) / numRepeats <<
" ms";
160 cout << endl << endl <<
"2.) Invert matrix with SVD" << endl;
164 #ifdef BIAS_HAVE_OPENCV
173 cout << endl <<
"SVD |M*inv(M) - I| = " << dM.
NormL2() << endl;
174 if (dM.
NormL2() > errorThreshold) {
175 BIASERR(
"Matrix inversion with SVD failed!");
176 if (size <= MAX_PRINT_SIZE)
182 cout << endl <<
"SVD3x3 |M*inv(M) - I| = " << dM.
NormL2() << endl;
183 if (dM.
NormL2() > errorThreshold) {
184 BIASERR(
"Matrix inversion with SVD3x3 failed!");
191 cout << endl << endl <<
"3.) Compute matrix square root with SVD" << endl;
194 if (size <= MAX_PRINT_SIZE)
198 if (size <= MAX_PRINT_SIZE)
200 dM = MTM - (sqrtMTM * sqrtMTM);
201 cout << endl <<
"SVD |MT*M - sqrt(MT*M)^2| = " << dM.
NormL2() << endl;
202 if (dM.
NormL2() > errorThreshold) {
203 BIASERR(
"Matrix square root failed!");
204 if (size <= MAX_PRINT_SIZE)
208 sqrtMTM = svd3x3.
Sqrt(MTM);
210 dM = MTM - (sqrtMTM * sqrtMTM);
211 cout << endl <<
"SVD3x3 |MT*M - sqrt(MT*M)^2| = " << dM.
NormL2() << endl;
212 if (dM.
NormL2() > errorThreshold) {
213 BIASERR(
"Matrix square root failed!");
std::ostream & PrintPretty(std::ostream &s, const std::string &name="", const int width=8, const bool alignLeft=true) const
computes and holds the singular value decomposition of a rectangular (not necessarily quadratic) Matr...
int Compute(const Matrix< double > &M, double ZeroThreshold=DEFAULT_DOUBLE_ZERO_THRESHOLD)
set a new matrix and compute its decomposition.
int Compute(const Matrix< double > &M, double ZeroThreshold=DEFAULT_DOUBLE_ZERO_THRESHOLD)
set a new matrix and compute its decomposition.
double GetUniformDistributed(const double min, const double max)
on succesive calls return uniform distributed random variable between min and max ...
double NormL2() const
Return the L2 norm: a^2 + b^2 + c^2 + ...
Matrix< double > InvertOpenCV(const Matrix< double > &A)
Calculates new inverse with OpenCV cvInvert.
singular value decomposition for 3x3 matrices
const Matrix< double > & GetVT() const
return VT (=transposed(V))
const Vector< double > & GetS() const
return S which is a vector of the singular values of A in descending order.
double GetRealTime() const
return real time (=wall time clock) in usec JW For Win32: real-time is measured differently from user...
int ComputeOpenCV(const Matrix< double > &M, double ZeroThreshold=DEFAULT_DOUBLE_ZERO_THRESHOLD)
Use OpenCV for decomposition as Lapack frequently leads to crashes under windows. ...
const Matrix< double > & GetU() const
return U U is a m x m orthogonal matrix
Matrix< double > Invert()
returns pseudoinverse of A = U * S * V^T A^+ = V * S^+ * U^T
Matrix< double > Sqrt()
returns the square root of a symmetric positive definite matrix M A = sqrt(M) = U * sqrt(S) * V_T...
class for producing random numbers from different distributions
class TimeMeasure contains functions for timing real time and cpu time.