Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members

stat_matrix.h

Go to the documentation of this file.
00001 // -*-c++-*-
00002 #ifndef IG_STAT_MATRIX_H
00003 #define IG_STAT_MATRIX_H
00004 
00005 // $Id: stat_matrix.h,v 1.1.2.12 2005/07/02 15:41:46 hkuiper Exp $
00006 
00007 // CwMtx matrix and vector math library
00008 // Copyright (C) 1999-2001  Harry Kuiper
00009 // Copyright (C) 2000  Will DeVore (template conversion)
00010 
00011 // This library is free software; you can redistribute it and/or
00012 // modify it under the terms of the GNU Lesser General Public
00013 // License as published by the Free Software Foundation; either
00014 // version 2 of the License, or (at your option) any later version.
00015 
00016 // This library is distributed in the hope that it will be useful,
00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019 // Lesser General Public License for more details.
00020 
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License along with this library; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00024 // USA
00025 
00026 #include <iostream>
00027 
00028 // CWMatrix class
00029 
00030 // This library was designed to mirror as closely as possible the
00031 // notation used in mathematical writing. A matrix is indexed:
00032 // matMatrixName[row][col].
00033 
00034 // CAUTION!!!
00035 
00036 // This matrix library was implemented with emphasis on
00037 // speed. Consequently no attempts were made to trap and report
00038 // errors. It is left entirely to the user to write code that does not
00039 // cause errors within the matrix routines.
00040 
00041 namespace CwMtx
00042 {
00043   using std::ostream;
00044   
00045   // forward declarations
00046 
00047   template <unsigned r, unsigned c, class T>
00048   class CWTSMatrix;
00049 
00050   template <unsigned r, class T>
00051   class CWTSSquareMatrix;
00052 
00053   template <unsigned r, class T>
00054   class CWTSVector;
00055 
00056   template <class T>
00057   class CWTSSpaceVector;
00058 
00059   template <class T>
00060   class CWTSQuaternion;
00061 
00062   // Template classes that create zero "objects".
00063 
00064   template <class T>
00065   class CWTSZero
00066   {
00067   public:
00068     operator T() { return 0; }
00069   };
00070 
00071   template <unsigned r, unsigned c, class T>
00072   class CWTSZero< CWTSMatrix<r, c, T> >:
00073     public CWTSMatrix<r, c, T>
00074   {
00075   public:
00076     CWTSZero() { fill(CWTSZero<T>()); }
00077   };
00078 
00079   template <unsigned r, class T>
00080   class CWTSZero< CWTSSquareMatrix<r, T> >:
00081     public CWTSSquareMatrix<r, T>
00082   {
00083   public:
00084     CWTSZero() { fill(CWTSZero<T>()); }
00085   };
00086 
00087   template <unsigned r, class T>
00088   class CWTSZero< CWTSVector<r, T> >:
00089     public CWTSVector<r, T>
00090   {
00091   public:
00092     CWTSZero() { fill(CWTSZero<T>()); }
00093   };
00094 
00095   template <class T>
00096   class CWTSZero< CWTSSpaceVector<T> >:
00097     public CWTSSpaceVector<T>
00098   {
00099   public:
00100     CWTSZero() { fill(CWTSZero<T>()); }
00101   };
00102 
00103   template <class T>
00104   class CWTSZero< CWTSQuaternion<T> >:
00105     public CWTSQuaternion<T>
00106   {
00107   public:
00108     CWTSZero() { fill(CWTSZero<T>()); }
00109   };
00110 
00111   // Template classes that create unity "objects".
00112 
00113   template <class T>
00114   class CWTSUnity
00115   {
00116   public:
00117     operator T() { return 1; }
00118   };
00119 
00120   // NOTE: Only a matrix with an equal number of rows and columns can
00121   // be a unity matrix.
00122   template <unsigned r, class T>
00123   class CWTSUnity< CWTSMatrix<r, r, T> >:
00124     public CWTSSquareMatrix<r, T>
00125   {
00126   public:
00127     CWTSUnity() { this->makeUnity(); }
00128   };
00129 
00130   template <unsigned r, class T>
00131   class CWTSUnity< CWTSSquareMatrix<r, T> >:
00132     public CWTSSquareMatrix<r, T>
00133   {
00134   public:
00135     CWTSUnity() { this->makeUnity(); }
00136   };
00137 
00138   template <class T>
00139   class CWTSUnity< CWTSQuaternion<T> >:
00140     public CWTSQuaternion<T>
00141   {
00142   public:
00143     CWTSUnity()
00144     {
00145       (*this)[0] = (*this)[1] = (*this)[2] = CWTSZero<T>();
00146       (*this)[3] = CWTSUnity<T>();
00147     }
00148   };
00149 
00150   // This template defaults to double. Most of the time this template
00151   // will be working with math functions that only work with
00152   // doubles. For example, the transcendental function sin(x) takes
00153   // and returns a double which would force the compiler to convert
00154   // back and forth from some other data type to a double.
00155 
00156   // prefix mat
00157   template <unsigned r, unsigned c, class T = double>
00158   class CWTSMatrix
00159   {
00160   public:
00161     typedef T element;
00162 
00163     CWTSMatrix() {}
00164     CWTSMatrix(const CWTSMatrix &);
00165 
00166     ~CWTSMatrix() {}
00167 
00168     unsigned getRows() const { return r; }
00169     unsigned getCols() const { return c; }
00170 
00171     // basic matrix operations
00172 
00173     // returns a row of modifyable elements
00174     T* operator [](unsigned irow) { return m_rgrow[irow]; }
00175     // returns a row of non-modifyable elements
00176     const T* operator [](unsigned irow) const { return m_rgrow[irow]; }
00177 
00178     CWTSMatrix operator +(const CWTSMatrix &) const;
00179     CWTSMatrix operator -(const CWTSMatrix &) const;
00180     CWTSMatrix operator -() const;
00181     CWTSMatrix operator *(const T &) const;
00182     CWTSMatrix operator /(const T &value) const;
00183 
00184     // not inherited
00185     CWTSMatrix & operator =(const CWTSMatrix &);
00186     CWTSMatrix & operator +=(const CWTSMatrix &);
00187     CWTSMatrix & operator -=(const CWTSMatrix &);
00188     CWTSMatrix & operator *=(const T &);
00189     CWTSMatrix & operator /=(const T &value);
00190 
00191     bool operator ==(const CWTSMatrix &) const;
00192     bool operator !=(const CWTSMatrix &mat) const;
00193 
00194     void interchangeRows(unsigned, unsigned);
00195     void addRowToRow(unsigned, unsigned, const T & = CWTSUnity<T>());
00196     void multiplyRow(unsigned, const T &);
00197 
00198     // fills the whole array with a value.
00199     void fill(const T &);
00200     // stores matrix + matrix in this
00201     void storeSum(const CWTSMatrix &, const CWTSMatrix &);
00202     // stores CWMatrix at indicated position in this
00203     template <unsigned r2, unsigned c2>
00204     void storeAtPosition(unsigned, unsigned, const CWTSMatrix<r2, c2, T> &);
00205 
00206   private:
00207     // an array of rows
00208     T m_rgrow[r][c];
00209   };
00210 
00211   template <unsigned r, unsigned c, class T >
00212   inline CWTSMatrix<r, c, T>::CWTSMatrix(const CWTSMatrix<r, c, T> &mat)
00213   {
00214     // copy contents of input matrix
00215     (*this) = mat;
00216   }
00217 
00218   template <unsigned r, unsigned c, class T>
00219   CWTSMatrix<r, c, T> 
00220   CWTSMatrix<r, c, T>::operator +(const CWTSMatrix<r, c, T> &mat) const
00221   {
00222     // copy this and add argument
00223     return CWTSMatrix(*this) += mat;
00224   }
00225 
00226   template <unsigned r, unsigned c, class T>
00227   CWTSMatrix<r, c, T> 
00228   CWTSMatrix<r, c, T>::operator -(const CWTSMatrix<r, c, T> &mat) const
00229   {
00230     // copy this and subtract argument
00231     return CWTSMatrix(*this) -= mat;
00232   }
00233 
00234   template <unsigned r, unsigned c, class T>
00235   CWTSMatrix<r, c, T>
00236   CWTSMatrix<r, c, T>::operator -() const
00237   {
00238     return (*this)*(CWTSZero<T>() - CWTSUnity<T>());
00239   }
00240 
00241   template <unsigned r, unsigned c, class T>
00242   CWTSMatrix<r, c, T>
00243   CWTSMatrix<r, c, T>::operator *(const T &value) const
00244   {
00245     // copy this and multiply by argument
00246     return CWTSMatrix(*this) *= value;
00247   }
00248 
00249   template <unsigned r, unsigned c, class T>
00250   inline CWTSMatrix<r, c, T>
00251   CWTSMatrix<r, c, T>::operator /(const T &value) const
00252   {
00253     return (*this)*(CWTSUnity<T>()/value);
00254   }
00255 
00256   // assignment operator
00257   template <unsigned r, unsigned c, class T>
00258   CWTSMatrix<r, c, T> & 
00259   CWTSMatrix<r, c, T>::operator =(const CWTSMatrix<r, c, T> &mat)
00260   {
00261     for (unsigned irow = 0; irow < r; ++irow)
00262       {
00263         for (unsigned icol = 0; icol < c; ++icol)
00264           {
00265             m_rgrow[irow][icol] = mat.m_rgrow[irow][icol];
00266           }
00267       }
00268 
00269     return (*this);
00270   }
00271 
00272   template <unsigned r, unsigned c, class T>
00273   CWTSMatrix<r, c, T> & 
00274   CWTSMatrix<r, c, T>::operator +=(const CWTSMatrix<r, c, T> &mat)
00275   {
00276     for (unsigned irow = 0; irow < r; ++irow)
00277       {
00278         for (unsigned icol = 0; icol < c; ++icol)
00279           {
00280             m_rgrow[irow][icol] += mat.m_rgrow[irow][icol];
00281           }
00282       }
00283 
00284     return (*this);
00285   }
00286 
00287   template <unsigned r, unsigned c, class T>
00288   CWTSMatrix<r, c, T> & 
00289   CWTSMatrix<r, c, T>::operator -=(const CWTSMatrix<r, c, T> &mat)
00290   {
00291     for (unsigned irow = 0; irow < r; ++irow)
00292       {
00293         for (unsigned icol = 0; icol < c; ++icol)
00294           {
00295             m_rgrow[irow][icol] -= mat.m_rgrow[irow][icol];
00296           }
00297       }
00298 
00299     return (*this);
00300   }
00301 
00302   template <unsigned r, unsigned c, class T>
00303   CWTSMatrix<r, c, T> &
00304   CWTSMatrix<r, c, T>::operator *=(const T &value)
00305   {
00306     for (unsigned irow = 0; irow < r; ++irow)
00307       {
00308         for (unsigned icol = 0; icol < c; ++icol)
00309           {
00310             m_rgrow[irow][icol] *= value;
00311           }
00312       }
00313 
00314     return (*this);
00315   }
00316 
00317   template <unsigned r, unsigned c, class T>
00318   inline CWTSMatrix<r, c, T> &
00319   CWTSMatrix<r, c, T>::operator /=(const T &value)
00320   {
00321     return (*this) *= CWTSUnity<T>()/value;
00322   }
00323 
00324   template <unsigned r, unsigned c, class T>
00325   bool
00326   CWTSMatrix<r, c, T>::operator ==(const CWTSMatrix<r, c, T> &mat) const
00327   {
00328     for (unsigned irow = 0; irow < r; ++irow)
00329       {
00330         for (unsigned icol = 0; icol < c; ++icol)
00331           {
00332             if (m_rgrow[irow][icol] != mat.m_rgrow[irow][icol])
00333               {
00334                 return false;
00335               }
00336           }
00337       }
00338 
00339     return true;
00340   }
00341 
00342   template <unsigned r, unsigned c, class T>
00343   inline bool
00344   CWTSMatrix<r, c, T>::operator !=(const CWTSMatrix &mat) const
00345   {
00346     return !( (*this) == mat );
00347   }
00348 
00349   template <unsigned r, unsigned c, class T>
00350   void
00351   CWTSMatrix<r, c, T>::fill(const T &elemFill)
00352   {
00353     for (unsigned irow = 0; irow < r; ++irow)
00354       {
00355         for (unsigned icol = 0; icol < c; ++icol)
00356           {
00357             m_rgrow[irow][icol] = elemFill;
00358           }
00359       }
00360   }
00361 
00362   // stores mat1 + mat2 in this
00363   template <unsigned r, unsigned c, class T>
00364   void
00365   CWTSMatrix<r, c, T>::storeSum(const CWTSMatrix<r, c, T> &mat1,
00366                                 const CWTSMatrix<r, c, T> &mat2)
00367   {
00368     for (unsigned irow = 0; irow < r; ++irow)
00369       {
00370         for (unsigned icol = 0; icol < c; ++icol)
00371           {
00372             m_rgrow[irow][icol] = 
00373               mat1.m_rgrow[irow][icol] + mat2.m_rgrow[irow][icol];
00374           }
00375       }
00376   }
00377 
00378   template <unsigned r, unsigned c, class T>
00379   template <unsigned r2, unsigned c2>
00380   void
00381   CWTSMatrix<r, c, T>::storeAtPosition(unsigned irowStart,
00382                                        unsigned icolStart,
00383                                        const CWTSMatrix<r2, c2, T> &mat)
00384   {
00385     for (unsigned irow = 0; irow < r2; ++irow)
00386       {
00387         for (unsigned icol = 0; icol < c2; ++icol)
00388           {
00389             m_rgrow[irow + irowStart][icol + icolStart] = mat[irow][icol];
00390           }
00391       }
00392   }
00393 
00394   template <unsigned r, unsigned c, class T>
00395   void
00396   CWTSMatrix<r, c, T>::interchangeRows(unsigned irow1, unsigned irow2)
00397   {
00398     T elemTmp;
00399 
00400     for (unsigned icol = 0; icol < c; ++icol)
00401       {
00402         elemTmp = m_rgrow[irow1][icol];
00403         m_rgrow[irow1][icol] = m_rgrow[irow2][icol];
00404         m_rgrow[irow2][icol] = elemTmp;
00405       }
00406   }
00407 
00408   template <unsigned r, unsigned c, class T>
00409   void
00410   CWTSMatrix<r, c, T>::multiplyRow(unsigned irow, const T &value)
00411   {
00412     for (unsigned icol = 0; icol < c; ++icol)
00413       {
00414         m_rgrow[irow][icol] *= value;
00415       }
00416   }
00417 
00418   template <unsigned r, unsigned c, class T>
00419   void
00420   CWTSMatrix<r, c, T>::addRowToRow(unsigned irowSrc,
00421                                    unsigned irowDest,
00422                                    const T &value)
00423   {
00424     for (unsigned icol = 0; icol < c; ++icol)
00425       {
00426         m_rgrow[irowDest][icol] += m_rgrow[irowSrc][icol]*value;
00427       }
00428   }
00429 
00430   // template functions designed to work with the base matrix class
00431 
00432   template <unsigned r, unsigned c, class T>
00433   inline CWTSMatrix<r, c, T>
00434   operator *(const T &value, const CWTSMatrix<r, c, T> &mat)
00435   {
00436     return (mat*value);
00437   }
00438 
00439   template <unsigned r, unsigned c, unsigned c2, class T>
00440   CWTSMatrix<r, c2, T>
00441   operator *(CWTSMatrix<r, c, T> mat1, const CWTSMatrix<c, c2, T> &mat2)
00442   {
00443     CWTSMatrix<r, c2, T> matResult;
00444 
00445     for (unsigned irow = 0; irow < r; ++irow)
00446       {
00447         for (unsigned icol = 0; icol < c2; ++icol)
00448           {
00449             matResult[irow][icol] = CWTSZero<T>();
00450 
00451             for (unsigned icol2 = 0; icol2 < c; ++icol2)
00452               {
00453                 matResult[irow][icol] += mat1[irow][icol2]*mat2[icol2][icol];
00454               }
00455           }
00456       }
00457 
00458     return matResult;
00459   }
00460 
00461   template <unsigned r, unsigned c, class T>
00462   CWTSMatrix<r, c, T>
00463   transpose(const CWTSMatrix<c, r, T> &mat)
00464   {
00465     CWTSMatrix<r, c, T> matTranspose;
00466 
00467     for (unsigned irow = 0; irow < r; ++irow)
00468       {
00469         for (unsigned icol = 0; icol < c; ++icol)
00470           {
00471             matTranspose[irow][icol] = mat[icol][irow];
00472           }
00473       }
00474 
00475     return matTranspose;
00476   }
00477 
00478   template <unsigned r, unsigned c, class T>
00479   ostream &
00480   operator <<(ostream &os, const CWTSMatrix<r, c, T> &mtx)
00481   {
00482     os << "[" ;
00483 
00484     for (unsigned i = 0; i < r; i++)
00485       {
00486         if (i > 0)
00487           {
00488             os << "; ";
00489           }
00490 
00491         os << mtx[i][0];
00492 
00493         for (unsigned j = 1; j < c; j++)
00494           {
00495             os << ", " << mtx[i][j];
00496           }
00497       }
00498 
00499     os << "]";
00500 
00501     return os;
00502   }
00503 
00504 }
00505 
00506 #endif // IG_STAT_MATRIX_H
00507 

Generated on Sun Jul 3 12:18:46 2005 for Matrix and vector library by  doxygen 1.4.2