00001 // This is core/vnl/algo/vnl_sparse_symmetric_eigensystem.h 00002 #ifndef vnl_sparse_symmetric_eigensystem_h_ 00003 #define vnl_sparse_symmetric_eigensystem_h_ 00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE 00005 #pragma interface 00006 #endif 00007 //: 00008 // \file 00009 // \brief Find the eigenvalues of a sparse symmetric matrix 00010 // \author Rupert W. Curwen, GE CR&D 00011 // \date 20 Oct 98 00012 // 00013 // \verbatim 00014 // Modifications 00015 // 28 Mar 2001: dac (Manchester) - tidied up documentation 00016 // 17 Dec 2010: Michael Bowers - added generalized sparse symmetric eigensystem 00017 // solver (see 2nd CalculateNPairs() method) 00018 // \endverbatim 00019 00020 #include <vnl/vnl_sparse_matrix.h> 00021 #include <vcl_vector.h> 00022 00023 //: Find the eigenvalues of a sparse symmetric matrix 00024 // Solve the standard eigenproblem $A x = \lambda x$, or the 00025 // generalized eigenproblem of $A x = \lambda B x$, where 00026 // $A$ symmetric and sparse and, optionally, B sparse, symmetric, 00027 // and positive definite. The block Lanczos algorithm is used to allow the 00028 // recovery of a number of eigenvalue/eigenvector pairs from either 00029 // end of the spectrum, to a required accuracy. 00030 // 00031 // Uses the dnlaso routine from the LASO package of netlib for 00032 // solving the standard case. 00033 // Uses the dsaupd routine from the ARPACK package of netlib for 00034 // solving the generalized case. 00035 00036 class vnl_sparse_symmetric_eigensystem 00037 { 00038 public: 00039 vnl_sparse_symmetric_eigensystem(); 00040 ~vnl_sparse_symmetric_eigensystem(); 00041 00042 // Find n eigenvalue/eigenvectors of the eigenproblem A * x = lambda * x. 00043 // If smallest is true, will calculate the n smallest eigenpairs, 00044 // else the n largest. 00045 int CalculateNPairs(vnl_sparse_matrix<double>& M, int n, 00046 bool smallest = true, long nfigures = 10); 00047 00048 // Find n eigenvalue/eigenvectors of the eigenproblem A * x = lambda * B * x. 00049 // !smallest and !magnitude - compute the N largest (algebraic) eigenvalues 00050 // smallest and !magnitude - compute the N smallest (algebraic) eigenvalues 00051 // !smallest and magnitude - compute the N largest (magnitude) eigenvalues 00052 // smallest and magnitude - compute the nev smallest (magnitude) eigenvalues 00053 // set sigma for shift/invert method 00054 int CalculateNPairs(vnl_sparse_matrix<double>& A, vnl_sparse_matrix<double>& B, int nEV, 00055 double tolerance = 0, int numberLanczosVecs = 0, 00056 bool smallest = false, bool magnitude = true, 00057 int maxIterations = 0, 00058 double sigma = 0.0); 00059 00060 // Recover specified eigenvector after computation. The argument 00061 // must be less than the requested number of eigenvectors. 00062 vnl_vector<double> get_eigenvector(int i) const; 00063 double get_eigenvalue(int i) const; 00064 00065 // Used as a callback in solving. 00066 int CalculateProduct(int n, int m, const double* p, double* q); 00067 int SaveVectors(int n, int m, const double* q, int base); 00068 int RestoreVectors(int n, int m, double* q, int base); 00069 00070 protected: 00071 int nvalues; // this is the size of the next two arrays. 00072 vnl_vector<double> * vectors; // eigenvectors 00073 double * values; // eigenvalues 00074 00075 // Matrix A of A*x = lambda*x (or lambda*B*x) 00076 vnl_sparse_matrix<double> * mat; 00077 // Matrix B of A*x = lambda*B*x 00078 vnl_sparse_matrix<double> * Bmat; 00079 00080 vcl_vector<double*> temp_store; 00081 }; 00082 00083 #endif // vnl_sparse_symmetric_eigensystem_h_