Commit 16f452a6 authored by Davis King's avatar Davis King

Setup the eigenvalue_decomposition to use LAPACK

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%403822
parent 03aea106
...@@ -12,6 +12,12 @@ ...@@ -12,6 +12,12 @@
#include <complex> #include <complex>
#include <cmath> #include <cmath>
#ifdef DLIB_USE_LAPACK
#include "lapack/geev.h"
#include "lapack/syev.h"
#include "lapack/syevr.h"
#endif
namespace dlib namespace dlib
{ {
...@@ -171,16 +177,32 @@ namespace dlib ...@@ -171,16 +177,32 @@ namespace dlib
{ {
V = A; V = A;
#ifdef DLIB_USE_LAPACK
matrix<type,0,1,mem_manager_type, layout_type> work;
e = 0;
// I would use syevr but the last time I checked there was a bug in the
// Intel MKL's implementation of syevr.
lapack::syev('V', 'L', V, d, work);
#else
// Tridiagonalize. // Tridiagonalize.
tred2(); tred2();
// Diagonalize. // Diagonalize.
tql2(); tql2();
#endif
} }
else else
{ {
#ifdef DLIB_USE_LAPACK
matrix<type,0,0,mem_manager_type, column_major_layout> temp, vl, vr, work;
temp = A;
lapack::geev('N', 'V', temp, d, e, vl, vr, work);
V = vr;
#else
H = A; H = A;
ort.set_size(n); ort.set_size(n);
// Reduce to Hessenberg form. // Reduce to Hessenberg form.
...@@ -188,6 +210,7 @@ namespace dlib ...@@ -188,6 +210,7 @@ namespace dlib
// Reduce Hessenberg to real Schur form. // Reduce Hessenberg to real Schur form.
hqr2(); hqr2();
#endif
} }
} }
...@@ -222,11 +245,19 @@ namespace dlib ...@@ -222,11 +245,19 @@ namespace dlib
V = A; V = A;
#ifdef DLIB_USE_LAPACK
matrix<type,0,1,mem_manager_type, layout_type> work;
e = 0;
// I would use syevr but the last time I checked there was a bug in the
// Intel MKL's implementation of syevr.
lapack::syev('V', 'L', V, d, work);
#else
// Tridiagonalize. // Tridiagonalize.
tred2(); tred2();
// Diagonalize. // Diagonalize.
tql2(); tql2();
#endif
} }
......
...@@ -632,6 +632,8 @@ namespace dlib ...@@ -632,6 +632,8 @@ namespace dlib
- V*trans(V) should be equal to the identity matrix. That is, all the - V*trans(V) should be equal to the identity matrix. That is, all the
eigenvectors in V should be orthonormal. eigenvectors in V should be orthonormal.
- So A == V*D*trans(V) - So A == V*D*trans(V)
- If DLIB_USE_LAPACK is #defined then this object uses the xSYEV LAPACK
routine.
On the other hand, if A is not symmetric then: On the other hand, if A is not symmetric then:
- Some of the eigenvalues and eigenvectors might be complex numbers. - Some of the eigenvalues and eigenvectors might be complex numbers.
...@@ -642,6 +644,8 @@ namespace dlib ...@@ -642,6 +644,8 @@ namespace dlib
- V*trans(V) won't be equal to the identity matrix but it is usually - V*trans(V) won't be equal to the identity matrix but it is usually
invertible. So A == V*D*inv(V) is usually a valid statement but invertible. So A == V*D*inv(V) is usually a valid statement but
A == V*D*trans(V) won't be. A == V*D*trans(V) won't be.
- If DLIB_USE_LAPACK is #defined then this object uses the xGEEV LAPACK
routine.
!*/ !*/
public: public:
......
...@@ -26,11 +26,6 @@ namespace ...@@ -26,11 +26,6 @@ namespace
dlib::rand::float_1a rnd; dlib::rand::float_1a rnd;
// ----------------------------------------------------------------------------------------
template <typename mat_type>
const matrix<typename mat_type::type> symm(const mat_type& m) { return m*trans(m); }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename type> template <typename type>
...@@ -65,8 +60,8 @@ namespace ...@@ -65,8 +60,8 @@ namespace
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename matrix_type> template <typename matrix_type, typename U>
void test_eigenvalue ( const matrix_type& m) void test_eigenvalue_impl ( const matrix_type& m, const eigenvalue_decomposition<U>& test )
{ {
typedef typename matrix_type::type type; typedef typename matrix_type::type type;
const type eps = 10*max(abs(m))*sqrt(std::numeric_limits<type>::epsilon()); const type eps = 10*max(abs(m))*sqrt(std::numeric_limits<type>::epsilon());
...@@ -74,8 +69,6 @@ namespace ...@@ -74,8 +69,6 @@ namespace
print_spinner(); print_spinner();
eigenvalue_decomposition<matrix_type> test(m);
DLIB_TEST(test.dim() == m.nr()); DLIB_TEST(test.dim() == m.nr());
// make sure all the various ways of asking for the eigenvalues are actually returning a // make sure all the various ways of asking for the eigenvalues are actually returning a
...@@ -128,6 +121,18 @@ namespace ...@@ -128,6 +121,18 @@ namespace
} }
} }
// ----------------------------------------------------------------------------------------
template <typename matrix_type>
void test_eigenvalue ( const matrix_type& m )
{
eigenvalue_decomposition<matrix_type> test(m);
test_eigenvalue_impl(m, test);
eigenvalue_decomposition<matrix_type> test_symm(make_symmetric(m));
test_eigenvalue_impl(make_symmetric(m), test_symm);
}
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
void matrix_test_double() void matrix_test_double()
...@@ -143,14 +148,6 @@ namespace ...@@ -143,14 +148,6 @@ namespace
test_eigenvalue(10*randm<double,1,1>()); test_eigenvalue(10*randm<double,1,1>());
test_eigenvalue(10*randm<double,2,2>()); test_eigenvalue(10*randm<double,2,2>());
test_eigenvalue(10*randm<double,3,3>()); test_eigenvalue(10*randm<double,3,3>());
test_eigenvalue(10*symm(randm<double>(1,1)));
test_eigenvalue(10*symm(randm<double>(2,2)));
test_eigenvalue(10*symm(randm<double>(3,3)));
test_eigenvalue(10*symm(randm<double>(4,4)));
test_eigenvalue(10*symm(randm<double>(15,15)));
test_eigenvalue(10*symm(randm<double>(150,150)));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -168,13 +165,6 @@ namespace ...@@ -168,13 +165,6 @@ namespace
test_eigenvalue(10*randm<float,1,1>()); test_eigenvalue(10*randm<float,1,1>());
test_eigenvalue(10*randm<float,2,2>()); test_eigenvalue(10*randm<float,2,2>());
test_eigenvalue(10*randm<float,3,3>()); test_eigenvalue(10*randm<float,3,3>());
test_eigenvalue(10*symm(randm<float>(1,1)));
test_eigenvalue(10*symm(randm<float>(2,2)));
test_eigenvalue(10*symm(randm<float>(3,3)));
test_eigenvalue(10*symm(randm<float>(4,4)));
test_eigenvalue(10*symm(randm<float>(15,15)));
test_eigenvalue(10*symm(randm<float>(50,50)));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment