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

stat_smatrix.h

Go to the documentation of this file.
00001 // -*-c++-*-
00002 #ifndef IG_STAT_SMATRIX_H
00003 #define IG_STAT_SMATRIX_H
00004 
00005 // $Id: stat_smatrix.h,v 1.1.2.7 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 #ifndef IG_STAT_MATRIX_H
00027 #include "stat_matrix.h"
00028 #endif
00029 
00030 namespace CwMtx
00031 {
00032   // prefix smat
00033   template <unsigned r, class T = double>
00034   class CWTSSquareMatrix : public CWTSMatrix<r, r, T>
00035   {
00036   public:
00037     CWTSSquareMatrix(): CWTSMatrix<r, r, T>() {}
00038     CWTSSquareMatrix(const CWTSMatrix<r, r, T> &mat):
00039       CWTSMatrix<r, r, T>(mat) {}
00040     CWTSSquareMatrix(const CWTSSquareMatrix &smat):
00041       CWTSMatrix<r, r, T>(smat) {}
00042 
00043     ~CWTSSquareMatrix() {}
00044 
00045     CWTSSquareMatrix operator +(const CWTSSquareMatrix &) const;
00046     CWTSSquareMatrix operator -(const CWTSSquareMatrix &) const;
00047     CWTSSquareMatrix operator -() const;
00048     CWTSSquareMatrix operator *(const T &) const;
00049     CWTSSquareMatrix operator *(const CWTSSquareMatrix &) const;
00050     CWTSSquareMatrix operator /(const T &value) const;
00051     CWTSSquareMatrix operator /(const CWTSSquareMatrix &) const;
00052 
00053     // not inherited
00054     CWTSSquareMatrix & operator =(const CWTSSquareMatrix &smat);
00055     CWTSSquareMatrix & operator +=(const CWTSSquareMatrix &smat);
00056     CWTSSquareMatrix & operator -=(const CWTSSquareMatrix &smat);
00057     CWTSSquareMatrix & operator *=(const T &value);
00058     CWTSSquareMatrix & operator *=(const CWTSSquareMatrix &);
00059     CWTSSquareMatrix & operator /=(const T &value);
00060     CWTSSquareMatrix & operator /=(const CWTSSquareMatrix &);
00061 
00062     // stores the adjoint of argument in this
00063     void storeAdjoint(const CWTSSquareMatrix &);
00064     // stores the inverse of argument in this
00065     void storeInverse(const CWTSSquareMatrix &);
00066     // makes this its own adjoint
00067     void makeAdjoint();
00068     // makes this its own inverse
00069     void makeInverse();
00070     // makes this a unity matrix
00071     void makeUnity();
00072   };
00073 
00074   // not inherited
00075   template <unsigned r, class T>
00076   inline CWTSSquareMatrix<r, T> &
00077   CWTSSquareMatrix<r, T>::operator =(const CWTSSquareMatrix<r, T> &smat)
00078   {
00079     return
00080       static_cast<CWTSSquareMatrix<r, T> &>(CWTSMatrix<r, r, T>::
00081 					    operator=(smat));
00082   }
00083 
00084   template <unsigned r, class T>
00085   inline CWTSSquareMatrix<r, T> &
00086   CWTSSquareMatrix<r, T>::operator +=(const CWTSSquareMatrix<r, T> &smat)
00087   {
00088     return
00089       static_cast<CWTSSquareMatrix<r, T> &>(CWTSMatrix<r, r, T>::
00090 					    operator+=(smat));
00091   }
00092 
00093   template <unsigned r, class T>
00094   inline CWTSSquareMatrix<r, T> &
00095   CWTSSquareMatrix<r, T>::operator -=(const CWTSSquareMatrix &smat)
00096   {
00097     return
00098       static_cast<CWTSSquareMatrix<r, T> &>(CWTSMatrix<r, r, T>::
00099 					    operator-=(smat));
00100   }
00101 
00102   template <unsigned r, class T>
00103   inline CWTSSquareMatrix<r, T> &
00104   CWTSSquareMatrix<r, T>::operator *=(const T &value)
00105   {
00106     return
00107       static_cast<CWTSSquareMatrix<r, T> &>(CWTSMatrix<r, r, T>::
00108 					    operator*=(value));
00109   }
00110 
00111   template <unsigned r, class T>
00112   inline CWTSSquareMatrix<r, T> &
00113   CWTSSquareMatrix<r, T>::operator *=(const CWTSSquareMatrix<r, T> &smat)
00114   {
00115     return (*this) = (*this)*smat;
00116   }
00117 
00118   template <unsigned r, class T>
00119   inline CWTSSquareMatrix<r, T> &
00120   CWTSSquareMatrix<r, T>::operator /=(const T &value)
00121   {
00122     return (*this) *= CWTSUnity<T>()/value;
00123   }
00124 
00125   template <unsigned r, class T>
00126   inline CWTSSquareMatrix<r, T> &
00127   CWTSSquareMatrix<r, T>::operator /=(const CWTSSquareMatrix<r, T> &smat)
00128   {
00129     return (*this) = (*this)/smat;
00130   }
00131 
00132   template <unsigned r, class T>
00133   CWTSSquareMatrix<r, T>
00134   CWTSSquareMatrix<r, T>::operator +(const CWTSSquareMatrix<r, T> &smat) const
00135   {
00136     return CWTSSquareMatrix(*this) += smat;
00137   }
00138 
00139   template <unsigned r, class T>
00140   CWTSSquareMatrix<r, T>
00141   CWTSSquareMatrix<r, T>::operator -(const CWTSSquareMatrix<r, T> &smat) const
00142   {
00143     return CWTSSquareMatrix(*this) -= smat;
00144   }
00145 
00146   template <unsigned r, class T>
00147   CWTSSquareMatrix<r, T> CWTSSquareMatrix<r, T>::operator -() const
00148   {
00149     return (*this)*(CWTSZero<T>() - CWTSUnity<T>());
00150   }
00151 
00152   template <unsigned r, class T>
00153   CWTSSquareMatrix<r, T>
00154   CWTSSquareMatrix<r, T>::operator *(const T &value) const
00155   {
00156     return CWTSSquareMatrix(*this) *= value;
00157   }
00158 
00159   template <unsigned r, class T>
00160   inline CWTSSquareMatrix<r, T>
00161   CWTSSquareMatrix<r, T>::operator /(const T &value) const
00162   {
00163     return (*this)*(CWTSUnity<T>()/value);
00164   }
00165 
00166   template <unsigned r, class T>
00167   CWTSSquareMatrix<r, T>
00168   CWTSSquareMatrix<r, T>::operator *(const CWTSSquareMatrix<r, T> &smat) const
00169   {
00170     CWTSSquareMatrix<r, T> smatResult;
00171 
00172     for (unsigned irow = 0; irow < r; ++irow)
00173       {
00174         for (unsigned icol = 0; icol < r; ++icol)
00175           {
00176             smatResult[irow][icol] = CWTSZero<T>();
00177 
00178             for (unsigned icol2 = 0; icol2 < r; ++icol2)
00179               {
00180                 smatResult[irow][icol] +=
00181                   (*this)[irow][icol2]*smat[icol2][icol];
00182               }
00183           }
00184       }
00185 
00186     return smatResult;
00187   }
00188 
00189   template <unsigned r, class T>
00190   CWTSSquareMatrix<r, T>
00191   CWTSSquareMatrix<r, T>::operator /(const CWTSSquareMatrix<r, T> &smat) const
00192   {
00193     return (*this)*inv(smat);
00194   }
00195 
00196   // stores inverse of argument in this
00197   template <unsigned r, class T>
00198   void
00199   CWTSSquareMatrix<r, T>::storeInverse(const CWTSSquareMatrix<r, T> &smat)
00200   {
00201     // copy input matrix in this
00202     (*this) = smat;
00203     makeInverse();
00204   }
00205 
00206   // makes this a unity matrix
00207   template <unsigned r, class T>
00208   void
00209   CWTSSquareMatrix<r, T>::makeUnity()
00210   {
00211     for (unsigned irow = 0; irow < r; ++irow)
00212       {
00213         for (unsigned icol = 0; icol < r; ++icol)
00214           {
00215             if (irow == icol)
00216               {
00217                 (*this)[irow][icol] = CWTSUnity<T>();
00218               }
00219             else
00220               {
00221                 (*this)[irow][icol] = CWTSZero<T>();
00222               }
00223           }
00224       }
00225   }
00226 
00227   // makes this its own adjoint
00228   template <unsigned r, class T>
00229   void
00230   CWTSSquareMatrix<r, T>::makeAdjoint()
00231   {
00232     // we need a copy of this
00233     CWTSSquareMatrix<r, T> smatCopy(*this);
00234     T elemTmp;
00235     // will eventually contain det(smatCopy)
00236     T elemDet = CWTSUnity<T>();
00237 
00238     // make this a unity matrix
00239     makeUnity();
00240 
00241     // start row reduction
00242     for (unsigned irow = 0; irow < r; ++irow)
00243       {
00244         // if element [irow][irow] is zero, add a row with non-zero
00245         // element at column irow
00246         if (smatCopy[irow][irow] == CWTSZero<T>())
00247           {
00248             for (unsigned irowTmp = irow; irowTmp < r; ++irowTmp)
00249               {
00250                 if (smatCopy[irowTmp][irow] != CWTSZero<T>())
00251                   {
00252                     // has no effect on adj(smat)
00253                     smatCopy.addRowToRow(irowTmp, irow);
00254                     // repeat action on this
00255                     this->addRowToRow(irowTmp, irow);
00256                     break;
00257                   }
00258               }
00259           }
00260 
00261         elemTmp = smatCopy[irow][irow];
00262         T tTmp = CWTSUnity<T>();
00263         tTmp /= elemTmp;
00264         smatCopy.multiplyRow(irow, tTmp);
00265         // repeat action on this
00266         multiplyRow(irow, tTmp);
00267         elemDet *= elemTmp;
00268 
00269         for (unsigned irowToAddTo = 0; irowToAddTo < r; ++irowToAddTo)
00270           {
00271             if (irowToAddTo != irow)
00272               {
00273                 elemTmp = -smatCopy[irowToAddTo][irow];
00274                 smatCopy.addRowToRow(irow, irowToAddTo, elemTmp);
00275                 // repeat action on this
00276                 addRowToRow(irow, irowToAddTo, elemTmp);
00277               }
00278           }
00279       }
00280 
00281     // this now contains its adjoint
00282     (*this) *= elemDet;
00283   }
00284 
00285   // stores adjoint of input matrix in this
00286   template <unsigned r, class T>
00287   void
00288   CWTSSquareMatrix<r, T>::storeAdjoint(const CWTSSquareMatrix<r, T> &smat)
00289   {
00290     // copy input matrix in this
00291     (*this) = smat;
00292     makeAdjoint();
00293   }
00294 
00295   // makes this its own inverse
00296   template <unsigned r, class T>
00297   void
00298   CWTSSquareMatrix<r, T>::makeInverse()
00299   {
00300     // we need a copy of this
00301     CWTSSquareMatrix<r, T> smatCopy(*this);
00302     T elemTmp;
00303 
00304     // make this a unity matrix
00305     makeUnity();
00306 
00307     // start row reduction
00308     for (unsigned irow = 0; irow < r; ++irow)
00309       {
00310         // if element [irow][irow] is zero, add a row with non-zero
00311         // element at column irow
00312         if (smatCopy[irow][irow] == CWTSZero<T>())
00313           {
00314             for (unsigned irowTmp = irow; irowTmp < r; ++irowTmp)
00315               {
00316                 // has no effect on inv(smat)
00317                 if (smatCopy[irowTmp][irow] != CWTSZero<T>())
00318                   {
00319                     smatCopy.addRowToRow(irowTmp, irow);
00320                     // repeat action on this
00321                     this->addRowToRow(irowTmp, irow);
00322                     break;
00323                   }
00324               }
00325           }
00326 
00327         elemTmp = smatCopy[irow][irow];
00328         T tTmp = CWTSUnity<T>();
00329         tTmp /= elemTmp;
00330         smatCopy.multiplyRow(irow, tTmp);
00331         multiplyRow(irow, tTmp);
00332 
00333         for (unsigned irowToAddTo = 0; irowToAddTo < r; ++irowToAddTo)
00334           {
00335             if (irowToAddTo != irow)
00336               {
00337                 elemTmp = -smatCopy[irowToAddTo][irow];
00338                 smatCopy.addRowToRow(irow, irowToAddTo, elemTmp);
00339                 // repeat action on this
00340                 addRowToRow(irow, irowToAddTo, elemTmp);
00341               }
00342           }
00343       }
00344 
00345     // this now contains its inverse
00346   }
00347 
00348   // template functions designed work with the Square Matrix class.
00349 
00350   template <unsigned r, class T>
00351   inline CWTSSquareMatrix<r, T>
00352   operator *(const T &value, const CWTSSquareMatrix<r, T> &smat)
00353   {
00354     return smat*value;
00355   }
00356 
00357   template <unsigned r, class T>
00358   CWTSSquareMatrix<r, T>
00359   transpose(const CWTSSquareMatrix<r, T> &smat)
00360   {
00361     CWTSSquareMatrix<r, T> smatTranspose;
00362 
00363     for (unsigned irow = 0; irow < r; ++irow)
00364       {
00365         for (unsigned icol = 0; icol < r; ++icol)
00366           {
00367             smatTranspose[irow][icol] = smat[icol][irow];
00368           }
00369       }
00370 
00371     return smatTranspose;
00372   }
00373 
00374   // returns the adjoint of a square matrix
00375   template <unsigned r, class T>
00376   CWTSSquareMatrix<r, T>
00377   adj(const CWTSSquareMatrix<r, T> &smat)
00378   {
00379     CWTSSquareMatrix<r, T> smatResult(smat);   // copy input matrix
00380     smatResult.makeAdjoint();
00381     return smatResult;
00382   }
00383 
00384   // calculates the inverse of a square matrix
00385   template <unsigned r, class T>
00386   CWTSSquareMatrix<r, T>
00387   inv(const CWTSSquareMatrix<r, T> &smat)
00388   {
00389     // copy input matrix
00390     CWTSSquareMatrix<r, T> smatResult(smat);
00391     smatResult.makeInverse();
00392     return smatResult;
00393   }
00394 
00395   // calculates the determinant of a square matrix
00396   template <unsigned r, class T>
00397   T
00398   det(const CWTSSquareMatrix<r, T> &smat)
00399   {
00400     // a copy of the input matrix
00401     CWTSSquareMatrix<r, T> smatCopy(smat);
00402 
00403     // start row reduction
00404     T elemTmp;
00405     // will eventually contain det(smatCopy)
00406     T elemDet = CWTSUnity<T>();
00407 
00408     for (unsigned irow = 0; irow < r; ++irow)
00409       {
00410         // if element [irow][irow] is zero, add a row with non-zero
00411         // element at column irow
00412         if (smatCopy[irow][irow] == CWTSZero<T>())
00413           {
00414             for (unsigned irowTmp = irow; irowTmp < r; ++irowTmp)
00415               {
00416                 // has no effect on inv(smat)
00417                 if (smatCopy[irowTmp][irow] != CWTSZero<T>())
00418                   {
00419                     smatCopy.addRowToRow(irowTmp, irow);
00420                     break;
00421                   }
00422               }
00423           }
00424 
00425         elemTmp = smatCopy[irow][irow];
00426         elemDet *= elemTmp;
00427 
00428         if (elemDet == CWTSZero<T>())
00429           {
00430             // once elemDet is zero it will stay zero
00431             return elemDet;
00432           }
00433 
00434         smatCopy.multiplyRow(irow, CWTSUnity<T>()/elemTmp);
00435 
00436         for (unsigned irowToAddTo = 0; irowToAddTo < r; ++irowToAddTo)
00437           {
00438             if (irowToAddTo != irow)
00439               {
00440                 smatCopy.addRowToRow(irow,
00441                                      irowToAddTo,
00442                                      -smatCopy[irowToAddTo][irow]);
00443               }
00444           }
00445       }
00446 
00447     return elemDet;
00448   }
00449 
00450   // trace
00451   template <unsigned r, class T>
00452   T
00453   tr(const CWTSSquareMatrix<r, T> &smat)
00454   {
00455     T elemTmp = CWTSZero<T>();
00456 
00457     for (unsigned c = 0; c < r; c++)
00458       {
00459         elemTmp += smat[c][c];
00460       }
00461 
00462     return elemTmp;
00463   }
00464 
00465 }
00466 
00467 #endif // IG_STAT_SMATRIX_H

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