Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

Tools/Math/Matrix_nxn.h

Go to the documentation of this file.
00001 /**
00002 * @file Matrix_nxn.h
00003 * Contains class Matrix_nxn
00004 *
00005 * @author <a href="mailto:stefanuhrig@gmx.net">Stefan Uhrig</a>
00006 */
00007 //------------------------------------------------------------------------------
00008 #ifndef MATRIX_NXN_H_INCLUDED
00009 #define MATRIX_NXN_H_INCLUDED
00010 //------------------------------------------------------------------------------
00011 #define MATRIX_NXN_HEAP
00012 //------------------------------------------------------------------------------
00013 #include "MVTools.h"
00014 #include "Vector_n.h"
00015 //------------------------------------------------------------------------------
00016 // Ensure that memory version (use stack or heap) ist defined
00017 #if !defined(MATRIX_NXN_STACK) && !defined(MATRIX_NXN_HEAP)
00018 #error Define MATRIX_NXN_STACK if you'd like Matrix_nxn to use stack memory or \
00019 MATRIX_NXN_HEAP if you'd like Matrix_nxn to use heap memory!
00020 #endif
00021 //------------------------------------------------------------------------------
00022 // Forward-Deklarationen
00023 //------------------------------------------------------------------------------
00024 template <class T, size_t N>
00025 class Matrix_nxn;
00026 template<class T, size_t N>
00027 Matrix_nxn<T, N> operator*(const Matrix_nxn<T, N>& m1,
00028                            const Matrix_nxn<T, N>& m2);
00029 template<class T, size_t N>
00030 Matrix_nxn<T, N> invert(const Matrix_nxn<T, N>& m);
00031 //------------------------------------------------------------------------------
00032 /**
00033 * @class Matrix_nxn
00034 * Represents a nxn matrix of type T
00035 *
00036 * Matrix_nxn represents a nxn matrix of type T. The class supplies
00037 * standard arithmetic operations.
00038 */
00039 template <class T, size_t N>
00040 class Matrix_nxn
00041 {
00042 public:
00043   //----------------------------------------------------------------------------
00044   /**
00045   * Standard constructor
00046   *
00047   * Initializes the matrix with values supplied by the standard constructor
00048   * of T.
00049   *
00050   * Complexity: n^2
00051   */
00052   Matrix_nxn()
00053   {
00054     #ifdef MATRIX_NXN_HEAP
00055       content = new Vector_n<T, N>[N];
00056     #endif
00057 
00058     Vector_n<T, N>* init = content;
00059     Vector_n<T, N> zero = Vector_n<T, N>();
00060     for (size_t i = 0; i < N; ++i, ++init)
00061       *init = zero;
00062   }
00063   //----------------------------------------------------------------------------
00064   /**
00065   * Constructor that initializes the matrix with the values in the passed array
00066   * @param v Array with initialization values
00067   *
00068   * Complexity: n^2
00069   */
00070   Matrix_nxn(const T* v)
00071   {
00072     #ifdef MATRIX_NXN_HEAP
00073       content = new Vector_n<T, N>[N];
00074     #endif
00075 
00076     Vector_n<T, N>* init = content;
00077     for (size_t i = 0; i < N; ++i, ++init, v+=N)
00078       *init = Vector_n<T, N>(v);
00079   }
00080   //----------------------------------------------------------------------------
00081   /** 
00082   * Copy constructor
00083   * @param m Matrix to copy
00084   *
00085   * Complexity: n^2
00086   */
00087   Matrix_nxn(const Matrix_nxn<T, N>& m)
00088   {
00089     #ifdef MATRIX_NXN_HEAP
00090       content = new Vector_n<T, N>[N];
00091     #endif
00092 
00093     *this = m;
00094   }
00095   //----------------------------------------------------------------------------
00096   /**
00097   * Destructor
00098   *
00099   * Complexity: n^2
00100   */
00101   ~Matrix_nxn()
00102   {
00103     #ifdef MATRIX_NXN_HEAP
00104       delete [] content;
00105     #endif
00106   }
00107   //----------------------------------------------------------------------------
00108   /**
00109   * Copy operator
00110   * @param m Matrix to copy
00111   *
00112   * Complexity: n^2
00113   */
00114   Matrix_nxn<T, N>& operator=(const Matrix_nxn<T, N>& m)
00115   {
00116     for (size_t i = 0; i < N; ++i)
00117       content[i] = m.content[i];
00118     return *this;
00119   }
00120   //----------------------------------------------------------------------------
00121   /**
00122   * Copy operator
00123   * @param m Array with values to assign to this matrix
00124   *
00125   * Complexity: n^2
00126   */
00127   Matrix_nxn<T, N>& operator=(const T* m)
00128   {
00129     for (size_t i = 0; i < N; ++i)
00130       for (size_t j = 0; j <N; ++j, ++m)
00131         content[i][j] = *m;
00132     return *this;
00133   }
00134   //----------------------------------------------------------------------------
00135   /**
00136   * Copies contents of matrix to passed array
00137   * @param m Array the values are stored to
00138   *
00139   * Complexity: n^2
00140   */
00141   void copyTo(T* m) const
00142   {
00143     const Vector_n<T, N>* con = content;
00144     for (size_t i = 0; i < N; ++i, m+=N, ++con)
00145       con->copyTo(m);
00146   }
00147   //----------------------------------------------------------------------------
00148   /**
00149   * Constant row vector access operator
00150   * @param i Index of row vector to access (first row vector has index 0)
00151   * @return Constant reference to row vector
00152   *
00153   * Complexity: 1
00154   */
00155   const Vector_n<T, N>& operator[](size_t i) const
00156   {
00157     return content[i];
00158   }
00159   //----------------------------------------------------------------------------
00160   /**
00161   * Row vector access operator
00162   * @param i Index of row vector to access (first row vector has index 0)
00163   * @return Reference to row vector
00164   *
00165   * Complexity: 1
00166   */
00167   Vector_n<T, N>& operator[](size_t i)
00168   {
00169     return content[i];
00170   }
00171   //----------------------------------------------------------------------------
00172   /**
00173   * Operator +=
00174   * @param m Matrix to add
00175   *
00176   * Complexity: n^2
00177   */
00178   Matrix_nxn<T, N>& operator+=(const Matrix_nxn<T, N>& m)
00179   {
00180     for (size_t i = 0; i < N; ++i)
00181       content[i] += m.content[i];
00182     return *this;
00183   }
00184   //----------------------------------------------------------------------------
00185   /**
00186   * Operator -=
00187   * @param m Matrix to subtract
00188   *
00189   * Complexity: n^2
00190   */
00191   Matrix_nxn<T, N>& operator-=(const Matrix_nxn<T, N>& m)
00192   {
00193     for (size_t i = 0; i < N; ++i)
00194       content[i] -= m.content[i];
00195     return *this;
00196   }
00197   //----------------------------------------------------------------------------
00198   /**
00199   * Operator *=
00200   * @param m Matrix this matrix is to multiplied with
00201   *
00202   * Complexity: n^3
00203   */
00204   Matrix_nxn<T, N>& operator*=(const Matrix_nxn<T, N>& m)
00205   {
00206     *this = *this * m;
00207     return *this;
00208   }
00209   //----------------------------------------------------------------------------
00210   /**
00211   * Operator /=
00212   * @param m Matrix this matrix is to divided by
00213   *
00214   * Complexity: n^3
00215   */
00216   Matrix_nxn<T, N>& operator/=(const Matrix_nxn<T, N>& m)
00217   {
00218     *this = *this / m;
00219     return *this;
00220   }
00221   //----------------------------------------------------------------------------
00222   /**
00223   * Transposes this matrix
00224   *
00225   * Complexity: n^2
00226   */
00227   Matrix_nxn<T, N>& transpose()
00228   {
00229     *this = transpose(*this);
00230     return *this;
00231   }
00232   //----------------------------------------------------------------------------
00233   /**
00234   * Inverts this matrix
00235   *
00236   * Complexity: n^3
00237   */
00238   Matrix_nxn<T, N>& invert()
00239   {
00240     *this = invert(*this);
00241     return *this;
00242   }
00243   //----------------------------------------------------------------------------
00244   /**
00245   * Solves the system A*x=b where A is the actual matrix
00246   * @param b Vector b
00247   * @return Solution x
00248   *
00249   * Complexity: n^3
00250   *
00251   */
00252   Vector_n<T, N> solve(Vector_n<T, N> b) const
00253   {
00254     // create copy of actual matrix
00255     Matrix_nxn<T, N> m(*this);
00256     
00257     // initialize ranking vector
00258     Vector_n<int, N> ranking;
00259     size_t i;
00260     for (i = 0; i < N; ++i)
00261       ranking[i] = i;
00262 
00263     T z = T();
00264     int c;
00265     int r;
00266     for (c = 0; c < (int)N-1; ++c)
00267     {
00268       // find row containing highest value
00269       int maxRow = c;
00270       T maxValue = m[ranking[maxRow]][c];
00271       if (maxValue < z)
00272         maxValue = -maxValue;
00273       for (r = c+1; r < (int)N; ++r)
00274       {
00275         T value = m[ranking[r]][c];
00276         if (value < z)
00277           value = -value;
00278         if (value > maxValue)
00279         {
00280           maxRow = r;
00281           maxValue = value;
00282         }
00283       }
00284 
00285       // if maximum value zero --> matrix is singular
00286       if (MVTools::isNearZero(maxValue))
00287       {
00288         if (MVTools::isNearNegZero(maxValue))
00289           throw MVException(MVException::DivByNegZero);
00290         else
00291           throw MVException(MVException::DivByPosZero);
00292       }
00293       /*
00294       if (maxValue == z)
00295         return Vector_n<T, N>();
00296       */
00297 
00298       // swap rows in ranking
00299       int temp = ranking[c];
00300       ranking[c] = ranking[maxRow];
00301       ranking[maxRow] = temp;
00302 
00303       // process all following rows
00304       for (r = c+1; r < (int)N; ++r)
00305       {
00306         // calc factor for subtracting
00307         T factor = m[ranking[r]][c] / m[ranking[c]][c];
00308         if (MVTools::isNearInf(factor))
00309         {
00310           if (MVTools::isNearPosInf(factor))
00311             throw MVException(MVException::PosInfValue);
00312           else
00313             throw MVException(MVException::NegInfValue);
00314         }
00315 
00316         T sub;
00317         sub = factor*b[ranking[c]];
00318         if (MVTools::isNearInf(sub))
00319         {
00320           if (MVTools::isNearPosInf(sub))
00321             throw MVException(MVException::PosInfValue);
00322           else
00323             throw MVException(MVException::NegInfValue);
00324         }
00325 
00326         // change vector b
00327         b[ranking[r]] -= sub;
00328 
00329         // change matrix
00330         m[ranking[r]][c] = T();
00331         for (int c2 = c+1; c2 < (int)N; ++c2)
00332         {
00333           sub = factor*m[ranking[c]][c2];
00334           if (MVTools::isNearInf(sub))
00335           {
00336             if (MVTools::isNearPosInf(sub))
00337               throw MVException(MVException::PosInfValue);
00338             else
00339               throw MVException(MVException::NegInfValue);
00340           }
00341           m[ranking[r]][c2] -= sub;
00342         }
00343       }
00344     }
00345 
00346     // if last entry of matrix zero --> matrix is singular
00347     if (MVTools::isNearZero(m[ranking[N-1]][N-1]))
00348     {
00349       if (MVTools::isNearNegZero(m[ranking[N-1]][N-1]))
00350         throw MVException(MVException::DivByNegZero);
00351       else
00352         throw MVException(MVException::DivByPosZero);
00353     }
00354     /*
00355     if (m[ranking[N-1]][N-1] == z)
00356       return Vector_n<T, N>();
00357     */
00358 
00359     // matrix has triangle form
00360     // calculate solutions
00361     b[ranking[N-1]] /= m[ranking[N-1]][N-1];
00362     for (r = N-2; r >= 0; --r)
00363     {
00364       T sum = T();
00365       for (c = r+1; c < (int)N; ++c)
00366         sum += m[ranking[r]][c] * b[ranking[c]];
00367       if (MVTools::isNearInf(sum))
00368       {
00369         if (MVTools::isNearPosInf(sum))
00370           throw MVException(MVException::PosInfValue);
00371         else
00372           throw MVException(MVException::NegInfValue);
00373       }
00374       
00375       if (MVTools::isNearZero(m[ranking[r]][r]))
00376       {
00377         if (MVTools::isNearNegZero(m[ranking[r]][r]))
00378           throw MVException(MVException::DivByNegZero);
00379         else
00380           throw MVException(MVException::DivByPosZero);
00381       }
00382       b[ranking[r]] = (b[ranking[r]] - sum) / m[ranking[r]][r];
00383 
00384       if (MVTools::isNearInf(b[ranking[r]]))
00385       {
00386         if (MVTools::isNearPosInf(b[ranking[r]]))
00387           throw MVException(MVException::PosInfValue);
00388         else
00389           throw MVException(MVException::NegInfValue);
00390       }
00391     }
00392 
00393     // create vector with correct order
00394     Vector_n<T, N> x;
00395     for (r = 0; r < (int)N; ++r)
00396       x[r] = b[ranking[r]];
00397 
00398     return x;
00399   }
00400   //----------------------------------------------------------------------------
00401   /**
00402   * Returns determinant of this matrix
00403   * @return determinant
00404   *
00405   * Complexity: n^3
00406   */
00407   T det() const
00408   {
00409     // create copy of actual matrix
00410     Matrix_nxn<T, N> m(*this);
00411     
00412     // initialize ranking vector
00413     Vector_n<int, N> ranking;
00414     size_t i;
00415     for (i = 0; i < N; ++i)
00416       ranking[i] = i;
00417 
00418     T z = T();
00419     bool bPositive = true;
00420     int c;
00421     int r;
00422     for (c = 0; c < (int)(N-1); ++c)
00423     {
00424       // find row containing highest value
00425       int maxRow = c;
00426       T maxValue = m[ranking[maxRow]][c];
00427       if (maxValue < z)
00428         maxValue = -maxValue;
00429       for (r = c+1; r < (int)N; ++r)
00430       {
00431         T value = m[ranking[r]][c];
00432         if (value < z)
00433           value = -value;
00434         if (value > maxValue)
00435         {
00436           maxRow = r;
00437           maxValue = value;
00438         }
00439       }
00440 
00441       // if maximum value zero --> determinant is zero
00442       if (MVTools::isNearZero(maxValue))
00443         return z;
00444       /*if (maxValue == z)
00445         return z;*/
00446 
00447       // swap rows in ranking
00448       if (c != maxRow)
00449       {
00450         int temp = ranking[c];
00451         ranking[c] = ranking[maxRow];
00452         ranking[maxRow] = temp;
00453         bPositive = !bPositive;
00454       }
00455 
00456       // process all following rows
00457       for (r = c+1; r < (int)N; ++r)
00458       {
00459         // calc factor for subtracting
00460         T factor = m[ranking[r]][c] / m[ranking[c]][c];
00461         if (MVTools::isNearInf(factor))
00462         {
00463           if (MVTools::isNearPosInf(factor))
00464             throw MVException(MVException::PosInfValue);
00465           else
00466             throw MVException(MVException::NegInfValue);
00467         }
00468 
00469         // change matrix
00470         m[ranking[r]][c] = T();
00471         for (int c2 = c+1; c2 < (int)N; ++c2)
00472         {
00473           m[ranking[r]][c2] -= factor*m[ranking[c]][c2];
00474           T sub;
00475           sub = factor*m[ranking[c]][c2];
00476           if (MVTools::isNearInf(sub))
00477           {
00478             if (MVTools::isNearPosInf(sub))
00479               throw MVException(MVException::PosInfValue);
00480             else
00481               throw MVException(MVException::NegInfValue);
00482           }
00483         }
00484       }
00485     }
00486 
00487     // if last entry of matrix zero --> determinant is zero
00488     if (MVTools::isNearZero(m[ranking[N-1]][N-1]))
00489       return z;
00490     /*if (m[ranking[N-1]][N-1] == z)
00491       return z;*/
00492 
00493     // matrix has triangle form
00494     // calculate determinant
00495     T res = m[ranking[0]][0];
00496     for (r = 1; r < (int)N; ++r)
00497     {
00498       res *= m[ranking[r]][r];
00499       if (MVTools::isNearInf(res))
00500       {
00501         if (MVTools::isNearPosInf(res))
00502           throw MVException(MVException::PosInfValue);
00503         else
00504           throw MVException(MVException::NegInfValue);
00505       }
00506     }    
00507 
00508     if (!bPositive)
00509       res = -res;
00510     return res;
00511   }
00512   //----------------------------------------------------------------------------
00513   /**
00514   * Returns the identity matrix with same dimensions like this matrix
00515   * @return nxn identity matrix
00516   *
00517   * Complexity: n^2
00518   */
00519   static Matrix_nxn<T, N> eye()
00520   {
00521     Matrix_nxn<T, N> res;
00522     for (size_t i = 0; i < N; ++i)
00523       res[i][i] = (T)1;
00524     return res;
00525   }
00526   //----------------------------------------------------------------------------
00527 private:
00528   /** The vectors holding the contents of the matrix */
00529   #if defined(MATRIX_NXN_HEAP)
00530     Vector_n<T, N>* content;
00531   #elif defined(MATRIX_NXN_STACK)
00532     Vector_n<T, N> content[N];
00533   #endif
00534 };
00535 //------------------------------------------------------------------------------
00536 /**
00537 * Operator + for matrix additions
00538 * @param m1 First matrix
00539 * @param m2 Second matrix
00540 * @return m1+m2
00541 *
00542 * Complexity: n^2
00543 */
00544 template<class T, size_t N>
00545 Matrix_nxn<T, N> operator+(const Matrix_nxn<T, N>& m1,
00546                            const Matrix_nxn<T, N>& m2)
00547 {
00548   Matrix_nxn<T, N> res(m1);
00549   res += m2;
00550   return res;
00551 }
00552 //------------------------------------------------------------------------------
00553 /**
00554 * Operator - for matrix subtractions
00555 * @param m1 First matrix
00556 * @param m2 Second matrix
00557 * @return m1-m2
00558 *
00559 * Complexity: n^2
00560 */
00561 template<class T, size_t N>
00562 Matrix_nxn<T, N> operator-(const Matrix_nxn<T, N>& m1,
00563                            const Matrix_nxn<T, N>& m2)
00564 {
00565   Matrix_nxn<T, N> res(m1);
00566   res -= m2;
00567   return res;
00568 }
00569 //------------------------------------------------------------------------------
00570 /**
00571 * Operator * for matrix-matrix multiplication
00572 * @param m1 First matrix
00573 * @param m2 Second matrix
00574 * @return m1*m2
00575 *
00576 * Complexity: n^3
00577 */
00578 template<class T, size_t N>
00579 Matrix_nxn<T, N> operator*(const Matrix_nxn<T, N>& m1,
00580                            const Matrix_nxn<T, N>& m2)
00581 {
00582   Matrix_nxn<T, N> res;
00583   size_t i, j, k;
00584   for (i = 0; i < N; ++i)
00585   {
00586     for (j = 0; j < N; ++j)
00587     {
00588       for (k = 0; k < N; ++k)
00589       {
00590         res[i][j] += m1[i][k] * m2[k][j];
00591       }
00592       if (MVTools::isNearInf(res[i][j]))
00593       {
00594         if (MVTools::isNearPosInf(res[i][j]))
00595           throw MVException(MVException::PosInfValue);
00596         else
00597           throw MVException(MVException::NegInfValue);
00598       }
00599     }
00600   }
00601   return res;
00602 }
00603 //------------------------------------------------------------------------------
00604 /**
00605 * Operator * for matrix-vector multiplication
00606 * @param m Matrix
00607 * @param v Vector
00608 * @return m*v
00609 *
00610 * Complexity: n^2
00611 */
00612 template<class T, size_t N>
00613 Vector_n<T, N> operator*(const Matrix_nxn<T, N>& m,
00614                          const Vector_n<T, N>& v)
00615 {
00616   Vector_n<T, N> res;
00617   for (size_t i = 0; i < N; ++i)
00618   {
00619     for (size_t j = 0; j < N; ++j)
00620     {
00621       res[i] += m[i][j]*v[j];
00622     }
00623     if (MVTools::isNearInf(res[i]))
00624     {
00625       if (MVTools::isNearPosInf(res[i]))
00626         throw MVException(MVException::PosInfValue);
00627       else
00628         throw MVException(MVException::NegInfValue);
00629     }
00630   }
00631   return res;
00632 }
00633 //------------------------------------------------------------------------------
00634 /**
00635 * Transposes a matrix
00636 * @param m Matrix to be transposed
00637 * @return Transposed matrix
00638 *
00639 * Complexity: n^2
00640 */
00641 template<class T, size_t N>
00642 Matrix_nxn<T, N> transpose(const Matrix_nxn<T, N>& m)
00643 {
00644   Matrix_nxn<T, N> res;
00645   for (size_t i = 0; i < N; ++i)
00646     for (size_t j = 0; j < N; ++j)
00647       res[i][j] = m[j][i];
00648   return res;
00649 }
00650 //------------------------------------------------------------------------------
00651 /**
00652 * Creates an identity matrix
00653 * @return nxn identity matrix
00654 *
00655 * Complexity: n^2
00656 */
00657 template<class T, size_t N>
00658 Matrix_nxn<T, N> eye_nxn()
00659 {
00660   Matrix_nxn<T, N> res;
00661   for (size_t i = 0; i < N; ++i)
00662     res[i][i] = (T)1;
00663   return res;
00664 }
00665 //------------------------------------------------------------------------------
00666 /**
00667 * Inverts the passed matrix. Matrix must not be singular
00668 * @param m Matrix to be inverted
00669 * @return Inverted matrix
00670 *
00671 * Complexity: n^3
00672 */
00673 template<class T, size_t N>
00674 Matrix_nxn<T, N> invert(const Matrix_nxn<T, N>& m)
00675 {
00676   Matrix_nxn<T, N> left(m);
00677   Matrix_nxn<T, N> right(eye_nxn<T, N>());
00678   Vector_n<int, N> ranking;
00679   int i;
00680   for (i = 0; i < (int)N; ++i)
00681     ranking[i] = i;
00682 
00683   T zero = T();
00684   int r, r2, maxrow;
00685   for (r = 0; r < (int)(N-1); ++r)
00686   {
00687     // find highest value
00688     T maxval = left[ranking[r]][r];
00689     maxrow = r;
00690     if (maxval < zero)
00691       maxval = -maxval;
00692     for (r2 = r+1; r2 < (int)N; ++r2)
00693     {
00694       T val = left[ranking[r2]][r];
00695       if (val < zero)
00696         val = -val;
00697       if (val > maxval)
00698       {
00699         maxval = val;
00700         maxrow = r2;
00701       }
00702     }
00703 
00704     // swap rows
00705     int temp = ranking[r];
00706     ranking[r] = ranking[maxrow];
00707     ranking[maxrow] = temp;
00708 
00709     if (MVTools::isNearZero(left[ranking[r]][r]))
00710     {
00711       if (MVTools::isNearNegZero(left[ranking[r]][r]))
00712         throw MVException(MVException::DivByNegZero);
00713       else
00714         throw MVException(MVException::DivByPosZero);
00715     }
00716 
00717     for (r2 = r+1; r2 < (int)N; ++r2)
00718     {
00719       // calc factor for subtracting
00720       T factor = left[ranking[r2]][r] / left[ranking[r]][r];
00721       if (MVTools::isNearInf(factor))
00722       {
00723         if (MVTools::isNearPosInf(factor))
00724           throw MVException(MVException::PosInfValue);
00725         else
00726           throw MVException(MVException::NegInfValue);
00727       }
00728 
00729       // change left matrix
00730       left[ranking[r2]] -= factor*left[ranking[r]];
00731       
00732       // change right matrix
00733       right[ranking[r2]] -= factor*right[ranking[r]];
00734     }
00735   }
00736 
00737   // matrix has triangle form
00738   // bring to diagonal form
00739   for (r = (int)(N-1); r > 0; --r)
00740   {
00741     if (MVTools::isNearZero(left[ranking[r]][r]))
00742     {
00743       if (MVTools::isNearNegZero(left[ranking[r]][r]))
00744         throw MVException(MVException::DivByNegZero);
00745       else
00746         throw MVException(MVException::DivByPosZero);
00747     }
00748     for (r2 = r-1; r2 >= 0; --r2)
00749     {
00750       T factor = left[ranking[r2]][r] / left[ranking[r]][r];
00751       if (MVTools::isNearInf(factor))
00752       {
00753         if (MVTools::isNearPosInf(factor))
00754           throw MVException(MVException::PosInfValue);
00755         else
00756           throw MVException(MVException::NegInfValue);
00757       }
00758 
00759       // change left matrix
00760       left[ranking[r2]] -= factor*left[ranking[r]];
00761       
00762       // change right matrix
00763       right[ranking[r2]] -= factor*right[ranking[r]];
00764     }
00765   }
00766 
00767   // matrix has diagonal form
00768   // set entries of left matrix to 1 and apply multiplication to right
00769   Matrix_nxn<T, N> res;
00770   for (r = 0; r < (int)N; ++r)
00771   {
00772     res[r] = right[ranking[r]];
00773 
00774     if (MVTools::isNearZero(left[ranking[r]][r]))
00775     {
00776       if (MVTools::isNearNegZero(left[ranking[r]][r]))
00777         throw MVException(MVException::DivByNegZero);
00778       else
00779         throw MVException(MVException::DivByPosZero);
00780     }
00781     res[r] /= left[ranking[r]][r];
00782   }
00783 
00784   return res;
00785 }
00786 //------------------------------------------------------------------------------
00787 /**
00788 * Inverts the passed matrix. Matrix must not be singular
00789 * @param m Matrix to be inverted
00790 * @return Inverted matrix
00791 *
00792 * Complexity: n^3
00793 */
00794 template<class T, size_t N>
00795 Matrix_nxn<T, N> invert2(const Matrix_nxn<T, N>& m)
00796 {
00797   Matrix_nxn<T, N> res;
00798   for (size_t i = 0; i < N; ++i)
00799   {
00800     Vector_n<T, N> e;
00801     e[i] = (T)1;
00802     res[i] = m.solve(e);
00803   }
00804   return transpose(res);
00805 }
00806 //------------------------------------------------------------------------------
00807 /**
00808 * Divides first matrix by second matrix (multiplicates with inverse of
00809 * second matrix).
00810 * @param m1 First matrix
00811 * @param m2 Second matrix
00812 * @return m1 & m2
00813 *
00814 * Complexity: n^3
00815 */
00816 template<class T, size_t N>
00817 Matrix_nxn<T, N> operator/(const Matrix_nxn<T, N>& m1,
00818                            const Matrix_nxn<T, N>& m2)
00819 {
00820   return m1*invert(m2);
00821 }
00822 //------------------------------------------------------------------------------
00823 /**
00824 * Returns determinant of the passed matrix
00825 * @param m Matrix the determinant is to be calculated of
00826 * @return det(m)
00827 *
00828 * Complexity: n^3
00829 */
00830 template<class T, size_t N>
00831 T det(const Matrix_nxn<T, N>& m)
00832 {
00833   return m.det();
00834 }
00835 //------------------------------------------------------------------------------
00836 #endif
00837 //------------------------------------------------------------------------------
00838 
00839 /*
00840  * Change log :
00841  * $Log: Matrix_nxn.h,v $
00842  * Revision 1.1.1.1  2004/05/22 17:37:12  cvsadm
00843  * created new repository GT2004_WM
00844  *
00845  * Revision 1.4  2004/03/27 12:27:25  risler
00846  * changed to heap implementation since stack seems to produce compile problems on some few machines
00847  *
00848  * Revision 1.3  2004/03/18 14:50:50  uhrig
00849  * Corrected function solve for gnu compiler
00850  *
00851  * Revision 1.2  2004/03/15 12:28:52  risler
00852  * change log added
00853  *
00854  *
00855  */

Generated on Thu Sep 23 19:57:39 2004 for GT2004 by doxygen 1.3.6