core/vnl/algo/vnl_sparse_symmetric_eigensystem.h
Go to the documentation of this file.
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_