/vol/vipdata/irtk/geometry++/include/irtkMatrix.h

00001 /*=========================================================================
00002 
00003   Library   : Image Registration Toolkit (IRTK)
00004   Module    : $Id: irtkMatrix.h 6 2009-01-23 13:44:31Z DR $
00005   Copyright : Imperial College, Department of Computing
00006               Visual Information Processing (VIP), 2008 onwards
00007   Date      : $Date: 2009-01-23 13:44:31 +0000 (Fri, 23 Jan 2009) $
00008   Version   : $Revision: 6 $
00009   Changes   : $Author: DR $
00010 
00011 =========================================================================*/
00012 
00013 #ifndef _IRTKMATRIX_H
00014 
00015 #define _IRTKMATRIX_H
00016 
00017 #ifdef USE_VXL
00018 #include <vnl/vnl_matrix.h>
00019 #endif
00020 
00027 class irtkMatrix : public irtkObject
00028 {
00029 
00030 protected:
00031 
00033   int _rows;
00034 
00036   int _cols;
00037 
00039   double **_matrix;
00040 
00041 public:
00042 
00044   irtkMatrix();
00045 
00047   irtkMatrix(int, int);
00048 
00050   irtkMatrix(const irtkMatrix &);
00051 
00053   ~irtkMatrix();
00054 
00056   void Initialize(int, int);
00057 
00058   //
00059   // Matrix access functions
00060   //
00061 
00063   int Rows() const;
00064 
00066   int Cols() const;
00067 
00069   void   Put(int, int, double);
00070 
00072   double Get(int, int) const;
00073 
00074   //
00075   // Operators for matrix access
00076   //
00077 
00079   double& operator()(int, int);
00080 
00082   double  operator()(int, int) const;
00083 
00085   irtkMatrix  operator()(int, int, int, int);
00086 
00088   void    operator()(irtkMatrix &, int, int);
00089 
00090   //
00091   // Matrix operators for doubles
00092   //
00093 
00095   irtkMatrix& operator-=(const double&);
00096 
00098   irtkMatrix& operator+=(const double&);
00099 
00101   irtkMatrix& operator*=(const double&);
00102 
00104   irtkMatrix& operator/=(const double&);
00105 
00107   irtkMatrix  operator- (const double&);
00108 
00110   irtkMatrix  operator+ (const double&);
00111 
00113   irtkMatrix  operator* (const double&);
00114 
00116   irtkMatrix  operator/ (const double&);
00117 
00118   //
00119   // Matrix operators for matrices
00120   //
00121 
00123   irtkMatrix& operator =(const irtkMatrix&);
00124 
00126   irtkMatrix& operator-=(const irtkMatrix&);
00127 
00129   irtkMatrix& operator+=(const irtkMatrix&);
00130 
00132   irtkMatrix& operator*=(const irtkMatrix&);
00133 
00135   irtkMatrix  operator- (const irtkMatrix&);
00136 
00138   irtkMatrix  operator+ (const irtkMatrix&);
00139 
00141   irtkMatrix  operator* (const irtkMatrix&);
00142 
00144   irtkMatrix  operator! (void);
00145 
00147   irtkMatrix  operator~ (void);
00148 
00150   int operator==(const irtkMatrix &);
00151 
00152   // Matrix exponential via Pade approximation.
00153   // See Golub and Van Loan, Matrix Computations, Algorithm 11.3-1.
00154   friend irtkMatrix expm(irtkMatrix);
00155 
00156   // Matrix logarithm.
00157   friend irtkMatrix logm(irtkMatrix);
00158 
00159   // Matrix square root.
00160   friend irtkMatrix sqrtm(irtkMatrix);
00161 
00162   friend irtkMatrix FrechetMean(irtkMatrix *, int, int = 10);
00163 
00164   friend irtkMatrix FrechetMean(irtkMatrix *, double *, int, int = 10);
00165 
00166 #ifndef USE_STL
00168   int operator!=(const irtkMatrix &);
00169 #endif
00170 
00171   //
00172   // Matrix functions
00173   //
00174 
00176   double Norm(void) const;
00177 
00178   // The infinity norm is the maximum of the absolute value row sums.
00179   double InfinityNorm(void) const;
00180 
00182   double Det() const;
00183 
00185   void   SVD(irtkMatrix &, irtkVector &, irtkMatrix &) const;
00186 
00188   void   Ident();
00189 
00191   bool IsIdentity() const;
00192 
00194   void   Invert();
00195 
00197   void   Transpose();
00198 
00200   void   Eigenvalues(irtkMatrix &, irtkVector &);
00201 
00203   void   LeastSquaresFit(const irtkVector &, irtkVector &);
00204 
00205   //
00206   // Matrix in- and output
00207   //
00208 
00210   friend ostream& operator<< (ostream&, const irtkMatrix&);
00211 
00213   friend istream& operator>> (istream&, irtkMatrix&);
00214 
00216   void Print();
00217 
00219   void Read (char *);
00220 
00222   void Write(char *);
00223 
00225   void Import (char *, int, int);
00226 
00227 #ifdef USE_VXL
00228 
00230   template <class T> void Matrix2Vnl(vnl_matrix<T> *m) const;
00231 
00233   template <class T> void Vnl2Matrix(vnl_matrix<T> *m);
00234 
00235 #else
00236 
00238   void Matrix2NR(float **) const;
00239   void Matrix2NR(double **) const;
00240 
00242   void NR2Matrix(float **);
00243   void NR2Matrix(double **);
00244 
00245   //
00246   // Matrix operators for vectors
00247   //
00248 
00250   irtkVector  operator* (const irtkVector&);
00251 
00252 #endif
00253 };
00254 
00255 //
00256 // Access operators
00257 //
00258 
00259 inline int irtkMatrix::Rows() const
00260 {
00261   return _rows;
00262 }
00263 
00264 inline int irtkMatrix::Cols() const
00265 {
00266   return _cols;
00267 }
00268 
00269 inline void irtkMatrix::Put(int rows, int cols, double matrix)
00270 {
00271 #ifdef NO_BOUNDS
00272   _matrix[cols][rows] = matrix;
00273 #else
00274   if ((rows >= 0) && (rows < _rows) && (cols >= 0) && (cols < _cols)) {
00275     _matrix[cols][rows] = matrix;
00276   } else {
00277     cout << "irtkMatrix::Put: parameter out of range\n";
00278   }
00279 #endif
00280 }
00281 
00282 inline double irtkMatrix::Get(int rows, int cols) const
00283 {
00284 #ifdef NO_BOUNDS
00285   return _matrix[cols][rows];
00286 #else
00287   if ((rows >= 0) && (rows < _rows) && (cols >= 0) && (cols < _cols)) {
00288     return _matrix[cols][rows];
00289   } else {
00290     cout << "irtkMatrix::Get: parameter out of range\n";
00291     return 0;
00292   }
00293 #endif
00294 }
00295 
00296 inline double &irtkMatrix::operator()(int rows, int cols)
00297 {
00298 #ifdef NO_BOUNDS
00299   return _matrix[cols][rows];
00300 #else
00301   if ((rows >= 0) && (rows < _rows) && (cols >= 0) && (cols < _cols)) {
00302     return _matrix[cols][rows];
00303   } else {
00304     cout << "irtkMatrix::operator(): parameter out of range\n";
00305     return _matrix[0][0];
00306   }
00307 #endif
00308 }
00309 
00310 inline double irtkMatrix::operator()(int rows, int cols) const
00311 {
00312 #ifdef NO_BOUNDS
00313   return _matrix[cols][rows];
00314 #else
00315   if ((rows >= 0) && (rows < _rows) && (cols >= 0) && (cols < _cols)) {
00316     return _matrix[cols][rows];
00317   } else {
00318     cout << "irtkMatrix::operator(): parameter out of range\n";
00319     return 0;
00320   }
00321 #endif
00322 }
00323 
00324 //
00325 // Matrix operators for doubles
00326 //
00327 
00328 inline irtkMatrix& irtkMatrix::operator-=(const double &x)
00329 {
00330   int i, j;
00331 
00332   for (j = 0; j < _cols; j++) {
00333     for (i = 0; i < _rows; i++) {
00334       _matrix[j][i] -= x;
00335     }
00336   }
00337   return *this;
00338 }
00339 
00340 inline irtkMatrix& irtkMatrix::operator+=(const double &x)
00341 {
00342   int i, j;
00343 
00344   for (j = 0; j < _cols; j++) {
00345     for (i = 0; i < _rows; i++) {
00346       _matrix[j][i] += x;
00347     }
00348   }
00349   return *this;
00350 }
00351 
00352 inline irtkMatrix& irtkMatrix::operator*=(const double &x)
00353 {
00354   int i, j;
00355 
00356   for (j = 0; j < _cols; j++) {
00357     for (i = 0; i < _rows; i++) {
00358       _matrix[j][i] *= x;
00359     }
00360   }
00361   return *this;
00362 }
00363 
00364 inline irtkMatrix& irtkMatrix::operator/=(const double &x)
00365 {
00366   int i, j;
00367 
00368   for (j = 0; j < _cols; j++) {
00369     for (i = 0; i < _rows; i++) {
00370       _matrix[j][i] /= x;
00371     }
00372   }
00373   return *this;
00374 }
00375 
00376 inline irtkMatrix irtkMatrix::operator-(const double &x)
00377 {
00378   int i, j;
00379   irtkMatrix m;
00380 
00381   m = *this;
00382   for (j = 0; j < _cols; j++) {
00383     for (i = 0; i < m._rows; i++) {
00384       m._matrix[j][i] = _matrix[j][i] - x;
00385     }
00386   }
00387   return m;
00388 }
00389 
00390 inline irtkMatrix irtkMatrix::operator+(const double &x)
00391 {
00392   int i, j;
00393   irtkMatrix m;
00394 
00395   m = *this;
00396   for (j = 0; j < _cols; j++) {
00397     for (i = 0; i < m._rows; i++) {
00398       m._matrix[j][i] = _matrix[j][i] + x;
00399     }
00400   }
00401   return m;
00402 }
00403 
00404 inline irtkMatrix irtkMatrix::operator*(const double &x)
00405 {
00406   int i, j;
00407   irtkMatrix m;
00408 
00409   m = *this;
00410   for (j = 0; j < _cols; j++) {
00411     for (i = 0; i < m._rows; i++) {
00412       m._matrix[j][i] = _matrix[j][i] * x;
00413     }
00414   }
00415   return m;
00416 }
00417 
00418 inline irtkMatrix irtkMatrix::operator/(const double &x)
00419 {
00420   int i, j;
00421   irtkMatrix m;
00422 
00423   m = *this;
00424   for (j = 0; j < _cols; j++) {
00425     for (i = 0; i < m._rows; i++) {
00426       m._matrix[j][i] = _matrix[j][i] / x;
00427     }
00428   }
00429   return m;
00430 }
00431 
00432 //
00433 // Matrix operators for matrices
00434 //
00435 
00436 inline int irtkMatrix::operator==(const irtkMatrix& m)
00437 {
00438   int i, j;
00439 
00440   if ((m._rows != _rows) || (m._cols != _cols)) return 0;
00441   for (j = 0; j < _cols; j++) {
00442     for (i = 0; i < m._rows; i++) {
00443       if (m._matrix[j][i] != _matrix[j][i]) return 0;
00444     }
00445   }
00446   return 1;
00447 }
00448 
00449 #ifndef USE_STL
00450 inline int irtkMatrix::operator!=(const irtkMatrix& m)
00451 {
00452   return !(*this == m);
00453 }
00454 #endif
00455 
00456 inline double irtkMatrix::Norm(void) const
00457 {
00458   int i, j;
00459   double norm = 0;
00460 
00461   // The norm of a matrix M is defined as trace(M * M~)
00462   for (j = 0; j < _cols; j++) {
00463     for (i = 0; i < _rows; i++) {
00464       norm += _matrix[j][i]*_matrix[j][i];
00465     }
00466   }
00467   return sqrt(norm);
00468 }
00469 
00470 inline double irtkMatrix::InfinityNorm(void) const
00471 {
00472   int i, j;
00473   double normInf = -1.0 * DBL_MAX;
00474   double sum;
00475 
00476   for (i = 0; i < _rows; ++i) {
00477     sum = 0;
00478     for (j = 0; j < _cols; ++j) {
00479       sum += abs(_matrix[j][i]);
00480     }
00481     if (sum > normInf)
00482       normInf = sum;
00483   }
00484   return normInf;
00485 }
00486 
00487 
00488 #endif
00489 
00490