/vol/vipdata/irtk/contrib++/include/irtkEigenAnalysis.h

00001 /*=========================================================================
00002 
00003   Library   : Image Registration Toolkit (IRTK)
00004   Module    : $Id: irtkEigenAnalysis.h 2 2008-12-23 12:40:14Z dr $
00005   Copyright : Imperial College, Department of Computing
00006               Visual Information Processing (VIP), 2008 onwards
00007   Date      : $Date: 2008-12-23 12:40:14 +0000 (Tue, 23 Dec 2008) $
00008   Version   : $Revision: 2 $
00009   Changes   : $Author: dr $
00010 
00011 =========================================================================*/
00012 
00013 #ifndef IRTKEIGENANALYSIS_H
00014 
00015 #define IRTKEIGENANALYSIS_H
00016 
00017 #include <irtkImage.h>
00018 
00019 class irtkEigenAnalysis
00020 {
00021 public:
00022   irtkEigenAnalysis (int _size);
00023   ~irtkEigenAnalysis ();
00024 
00025   // set the matrix for eigensolving
00026   float& Matrix (int row, int col) {
00027     return mat[row][col];
00028   }
00029   irtkEigenAnalysis& Matrix (float** inmat);
00030 
00031   // get the results of eigensolving
00032   float Eigenvalue (int d) {
00033     return diag[d];
00034   }
00035   float Eigenvector (int row, int col) {
00036     return mat[row][col];
00037   }
00038   const float* Eigenvalue () {
00039     return diag;
00040   }
00041   const float** Eigenvector () {
00042     return (const float**) mat;
00043   }
00044 
00045   // solve eigensystem
00046   void EigenStuff2 ();  // uses TriDiagonal2
00047   void EigenStuff3 ();  // uses TriDiagonal3
00048   void EigenStuff4 ();  // uses TriDiagonal4
00049   void EigenStuffN ();  // uses TriDiagonalN
00050   void EigenStuff  ();  // uses switch statement
00051 
00052   // solve eigensystem, use decreasing sort on eigenvalues
00053   void DecrSortEigenStuff2 ();
00054   void DecrSortEigenStuff3 ();
00055   void DecrSortEigenStuff4 ();
00056   void DecrSortEigenStuffN ();
00057   void DecrSortEigenStuff  ();
00058 
00059   // solve eigensystem, use increasing sort on eigenvalues
00060   void IncrSortEigenStuff2 ();
00061   void IncrSortEigenStuff3 ();
00062   void IncrSortEigenStuff4 ();
00063   void IncrSortEigenStuffN ();
00064   void IncrSortEigenStuff  ();
00065 
00066   // solve eigensystem, use decreasing sort on eigenvalues
00067   void DecrMagSortEigenStuff2 ();
00068   void DecrMagSortEigenStuff3 ();
00069   void DecrMagSortEigenStuff4 ();
00070   void DecrMagSortEigenStuffN ();
00071   void DecrMagSortEigenStuff  ();
00072 
00073   // solve eigensystem, use increasing sort on eigenvalues
00074   void IncrMagSortEigenStuff2 ();
00075   void IncrMagSortEigenStuff3 ();
00076   void IncrMagSortEigenStuff4 ();
00077   void IncrMagSortEigenStuffN ();
00078   void IncrMagSortEigenStuff  ();
00079 
00080   // debugging output?
00081   float& Tdiag (int i) {
00082     return diag[i];
00083   }
00084   float& Tsubdiag (int i) {
00085     return subd[i];
00086   }
00087   void Reduce () {
00088     TridiagonalN(size,mat,diag,subd);
00089   }
00090 
00091 private:
00092   int size;
00093   float** mat;
00094   float* diag;
00095   float* subd;
00096 
00097   // Householder reduction to tridiagonal form
00098   void Tridiagonal2 (float** mat, float* diag, float* subd);
00099   void Tridiagonal3 (float** mat, float* diag, float* subd);
00100   void Tridiagonal4 (float** mat, float* diag, float* subd);
00101   void TridiagonalN (int n, float** mat, float* diag, float* subd);
00102 
00103   // QL algorithm with implicit shifting, applies to tridiagonal matrices
00104   void QLAlgorithm (int n, float* diag, float* subd, float** mat);
00105 
00106   // sort eigenvalues from largest to smallest
00107   void DecreasingSort (int n, float* eigval, float** eigvec);
00108 
00109   // sort eigenvalues from smallest to largest
00110   void IncreasingSort (int n, float* eigval, float** eigvec);
00111 
00112   // sort eigenvalues from largest to smallest (in magnitude)
00113   void DecreasingMagnitudeSort (int n, float* eigval, float** eigvec);
00114 
00115   // sort eigenvalues from smallest to largest (in magnitude)
00116   void IncreasingMagnitudeSort (int n, float* eigval, float** eigvec);
00117 
00118 // error handling
00119 public:
00120   static int verbose;
00121   static unsigned error;
00122   static void Report (ostream& ostr);
00123 private:
00124   static const unsigned invalid_size;
00125   static const unsigned allocation_failed;
00126   static const unsigned ql_exceeded;
00127   static const char* message[3];
00128   static int Number (unsigned single_error);
00129   static void Report (unsigned single_error);
00130 };
00131 
00132 
00133 class irtkEigenAnalysisD
00134 {
00135 public:
00136   irtkEigenAnalysisD (int _size);
00137   ~irtkEigenAnalysisD ();
00138 
00139   // set the matrix for eigensolving
00140   double& Matrix (int row, int col) {
00141     return mat[row][col];
00142   }
00143   irtkEigenAnalysisD& Matrix (double** inmat);
00144 
00145   // get the results of eigensolving
00146   double Eigenvalue (int d) {
00147     return diag[d];
00148   }
00149   double Eigenvector (int row, int col) {
00150     return mat[row][col];
00151   }
00152   const double* Eigenvalue () {
00153     return diag;
00154   }
00155   const double** Eigenvector () {
00156     return (const double**) mat;
00157   }
00158 
00159   // solve eigensystem
00160   void EigenStuff2 ();  // uses TriDiagonal2
00161   void EigenStuff3 ();  // uses TriDiagonal3
00162   void EigenStuff4 ();  // uses TriDiagonal4
00163   void EigenStuffN ();  // uses TriDiagonalN
00164   void EigenStuff  ();  // uses switch statement
00165 
00166   // solve eigensystem, use decreasing sort on eigenvalues
00167   void DecrSortEigenStuff2 ();
00168   void DecrSortEigenStuff3 ();
00169   void DecrSortEigenStuff4 ();
00170   void DecrSortEigenStuffN ();
00171   void DecrSortEigenStuff  ();
00172 
00173   // solve eigensystem, use increasing sort on eigenvalues
00174   void IncrSortEigenStuff2 ();
00175   void IncrSortEigenStuff3 ();
00176   void IncrSortEigenStuff4 ();
00177   void IncrSortEigenStuffN ();
00178   void IncrSortEigenStuff  ();
00179 
00180   // solve eigensystem, use decreasing sort on eigenvalues
00181   void DecrMagSortEigenStuff2 ();
00182   void DecrMagSortEigenStuff3 ();
00183   void DecrMagSortEigenStuff4 ();
00184   void DecrMagSortEigenStuffN ();
00185   void DecrMagSortEigenStuff  ();
00186 
00187   // solve eigensystem, use increasing sort on eigenvalues
00188   void IncrMagSortEigenStuff2 ();
00189   void IncrMagSortEigenStuff3 ();
00190   void IncrMagSortEigenStuff4 ();
00191   void IncrMagSortEigenStuffN ();
00192   void IncrMagSortEigenStuff  ();
00193 
00194   // debugging output?
00195   double& Tdiag (int i) {
00196     return diag[i];
00197   }
00198   double& Tsubdiag (int i) {
00199     return subd[i];
00200   }
00201   void Reduce () {
00202     TridiagonalN(size,mat,diag,subd);
00203   }
00204 
00205 private:
00206   int size;
00207   double** mat;
00208   double* diag;
00209   double* subd;
00210 
00211   // Householder reduction to tridiagonal form
00212   void Tridiagonal2 (double** mat, double* diag, double* subd);
00213   void Tridiagonal3 (double** mat, double* diag, double* subd);
00214   void Tridiagonal4 (double** mat, double* diag, double* subd);
00215   void TridiagonalN (int n, double** mat, double* diag, double* subd);
00216 
00217   // QL algorithm with implicit shifting, applies to tridiagonal matrices
00218   void QLAlgorithm (int n, double* diag, double* subd, double** mat);
00219 
00220   // sort eigenvalues from largest to smallest
00221   void DecreasingSort (int n, double* eigval, double** eigvec);
00222 
00223   // sort eigenvalues from smallest to largest
00224   void IncreasingSort (int n, double* eigval, double** eigvec);
00225 
00226   // sort eigenvalues from largest to smallest (in magnitude)
00227   void DecreasingMagnitudeSort (int n, double* eigval, double** eigvec);
00228 
00229   // sort eigenvalues from smallest to largest (in magnitude)
00230   void IncreasingMagnitudeSort (int n, double* eigval, double** eigvec);
00231 // error handling
00232 public:
00233   static int verbose;
00234   static unsigned error;
00235   static void Report (ostream& ostr);
00236 private:
00237   static const unsigned invalid_size;
00238   static const unsigned allocation_failed;
00239   static const unsigned ql_exceeded;
00240   static const char* message[3];
00241   static int Number (unsigned single_error);
00242   static void Report (unsigned single_error);
00243 };
00244 #endif