CEDRIC  Revision_backup-2009-02
Lanczos.h
Go to the documentation of this file.
1 #ifndef REDUKT_LANCZOS_H
2 #define REDUKT_LANCZOS_H
3 
4 
5 #include <ietl/interface/ublas.h>
6 #include <ietl/vectorspace.h>
7 #include <ietl/lanczos.h>
8 #include <ietl/iteration.h>
9 
10 #include <boost/random.hpp>
11 #include <boost/limits.hpp>
12 
13 #include <vector>
14 #include <algorithm> // for swap()
15 #include <limits>
16 #include <cmath>
17 
18 #include <iostream>
19 #include <iomanip>
20 
21 #include <assert.h>
22 
23 
24 #include <boost/numeric/ublas/io.hpp>
25 
26 
28 template<class Matrix,class Vector>
29 class Lanczos
30 {
31 public:
32  typedef ietl::vectorspace<Vector> Vectorspace;
33  typedef boost::lagged_fibonacci607 RandGen;
34 
36  Lanczos( const Matrix& mat, int k )
37  {
38  assert( mat.size1() == mat.size2() );
39  int N = mat.size1();
40 
41  //
42  // Compute eigenvalues
43  //
44 
45  Vectorspace vec(N);
46  RandGen gen;
47  ietl::lanczos<Matrix,Vectorspace> lanczos( mat, vec );
48 
49  double rel_tol = 500*std::numeric_limits<double>::epsilon();
50  double abs_tol = std::pow(std::numeric_limits<double>::epsilon(),2./3);
51  int max_iter = 2*N;
52 
53  ietl::lanczos_iteration_nhighest<double> iter( max_iter, k, rel_tol, abs_tol );
54 
55  std::cout << "Starting Lanczos calculation of " << k << " highest eigenvalues with " << max_iter << " max.iterations" << std::endl;
56  try
57  {
58  lanczos.calculate_eigenvalues( iter, gen );
59  eigen = lanczos.eigenvalues();
60  multi = lanczos.multiplicities();
61  err = lanczos.errors();
62  }
63  catch( std::runtime_error& e )
64  {
65  std::cout << e.what() << std::endl;
66 
67  // Printing eigenvalues with error & multiplicities:
68  std::cout << "# eigenvalue error multiplicity\n";
69  std::cout.precision(10);
70  for( unsigned int i=0; i < eigen.size(); ++i )
71  std::cout << i << "\t" << eigen[i] << "\t" << err[i] << "\t"
72  << multi[i] << "\n";
73 
74  throw std::runtime_error("Problems with ietl lanczos algorithm occured during eigenvalue computation");
75  }
76 
77  std::cout << "Lanczos eigenvalue calculation finished" << std::endl;
78 
79  // computed eigenvalues are stored ascending
80  std::cout << "Lanczos reordering eigenvalues descending " << std::flush;
81  for( unsigned int i=0; i < eigen.size()/2; ++i )
82  std::swap( eigen[i], eigen[eigen.size()-i-1] );
83  std::cout << "done" << std::endl;
84 
85 
86  //
87  // Compute eigenvectors
88  //
89 
90  std::cout << "Starting Lanczos calculation of eigenvectors" << std::endl;
91  try
92  {
93  lanczos.eigenvectors( eigen.begin(), eigen.begin() + k,
94  std::back_inserter(eigenvectors),
95  info,
96  gen );
97  }
98  catch( std::runtime_error& e )
99  {
100  std::cout << e.what() << std::endl;
101  throw std::runtime_error("Problems with ietl lanczos algorithm occured during eigenvector computation");
102  }
103  std::cout << "Lanczos eigenvector calculation finished" << std::endl;
104  }
105 
106  void printInfo()
107  {
108  // Printing eigenvalues with error & multiplicities:
109  std::cout << "# eigenvalue error multiplicity\n";
110  std::cout.precision(10);
111  for( unsigned int i=0; i < eigen.size(); ++i )
112  std::cout << i << "\t" << eigen[i] << "\t" << err[i] << "\t"
113  << multi[i] << "\n";
114 
115  // Print eigenvectors
116  for( unsigned int i=0; i < eigenvectors.size(); ++i )
117  std::cout << "Eigenvector " << i << " = " << eigenvectors[i] << std::endl;
118 
119  std::cout << std::endl;
120  std::cout << " Information about the eigen vectors computations:\n\n";
121  for(int i = 0; i < info.size(); i++)
122  {
123  std::cout << " m1(" << i+1 << "): " << info.m1(i) << ", m2(" << i+1 << "): "
124  << info.m2(i) << ", ma(" << i+1 << "): " << info.ma(i) << " eigenvalue("
125  << i+1 << "): " << info.eigenvalue(i) << " residual(" << i+1 << "): "
126  << info.residual(i) << " error_info(" << i+1 << "): "
127  << info.error_info(i) << std::endl << std::endl;
128  }
129  }
130 
131  const Vector& getEigenvector( unsigned int i ) const
132  {
133  assert( i < eigenvectors.size() );
134  return eigenvectors[i];
135  }
136 
137  double getEigenvalue( unsigned int i ) const
138  {
139  assert( i < eigenvectors.size() );
140  return eigen[i];
141  }
142 
143 private:
144  std::vector<double> eigen; // eigenvalues
145  std::vector<int> multi; // multiplicities
146  std::vector<double> err; // error
147 
148  std::vector<Vector> eigenvectors; // eigenvectors
149  ietl::Info<double> info; // (m1, m2, ma, eigenvalue, residual, status).
150 };
151 
152 #endif // REDUKT_LANCZOS_H
Lanczos(const Matrix &mat, int k)
Compute k greatest eigenvalues and eigenvectors of symmetric Matrix mat.
Definition: Lanczos.h:36
const Vector & getEigenvector(unsigned int i) const
Definition: Lanczos.h:131
ietl::vectorspace< Vector > Vectorspace
Definition: Lanczos.h:32
boost::lagged_fibonacci607 RandGen
Definition: Lanczos.h:33
double getEigenvalue(unsigned int i) const
Definition: Lanczos.h:137
Compute k greatest eigenvectors of a Matrix.
Definition: Lanczos.h:29
void printInfo()
Definition: Lanczos.h:106