Wm4GMatrix.inl

Go to the documentation of this file.
00001 // Wild Magic Source Code
00002 // David Eberly
00003 // http://www.geometrictools.com
00004 // Copyright (c) 1998-2007
00005 //
00006 // This library is free software; you can redistribute it and/or modify it
00007 // under the terms of the GNU Lesser General Public License as published by
00008 // the Free Software Foundation; either version 2.1 of the License, or (at
00009 // your option) any later version.  The license is available for reading at
00010 // either of the locations:
00011 //     http://www.gnu.org/copyleft/lgpl.html
00012 //     http://www.geometrictools.com/License/WildMagicLicense.pdf
00013 // The license applies to versions 0 through 4 of Wild Magic.
00014 //
00015 // Version: 4.0.0 (2006/06/28)
00016 
00017 namespace Wm4
00018 {
00019 //----------------------------------------------------------------------------
00020 template <class Real>
00021 GMatrix<Real>::GMatrix (int iRows, int iCols)
00022 {
00023     m_afData = 0;
00024     m_aafEntry = 0;
00025     SetSize(iRows,iCols);
00026 }
00027 //----------------------------------------------------------------------------
00028 template <class Real>
00029 GMatrix<Real>::GMatrix (int iRows, int iCols, const Real* afEntry)
00030 {
00031     m_afData = 0;
00032     m_aafEntry = 0;
00033     SetMatrix(iRows,iCols,afEntry);
00034 }
00035 //----------------------------------------------------------------------------
00036 template <class Real>
00037 GMatrix<Real>::GMatrix (int iRows, int iCols, const Real** aafMatrix)
00038 {
00039     m_afData = 0;
00040     m_aafEntry = 0;
00041     SetMatrix(iRows,iCols,aafMatrix);
00042 }
00043 //----------------------------------------------------------------------------
00044 template <class Real>
00045 GMatrix<Real>::GMatrix (const GMatrix& rkM)
00046 {
00047     m_iRows = 0;
00048     m_iCols = 0;
00049     m_iQuantity = 0;
00050     m_afData = 0;
00051     m_aafEntry = 0;
00052     *this = rkM;
00053 }
00054 //----------------------------------------------------------------------------
00055 template <class Real>
00056 GMatrix<Real>::~GMatrix ()
00057 {
00058     Deallocate();
00059 }
00060 //----------------------------------------------------------------------------
00061 template <class Real>
00062 void GMatrix<Real>::Allocate (bool bSetToZero)
00063 {
00064     // assert:  m_iRows, m_iCols, and m_iQuantity already initialized
00065 
00066     m_afData = WM4_NEW Real[m_iQuantity];
00067     if (bSetToZero)
00068     {
00069         memset(m_afData,0,m_iQuantity*sizeof(Real));
00070     }
00071 
00072     m_aafEntry = WM4_NEW Real*[m_iRows];
00073     for (int iRow = 0; iRow < m_iRows; iRow++)
00074     {
00075         m_aafEntry[iRow] = &m_afData[iRow*m_iCols];
00076     }
00077 }
00078 //----------------------------------------------------------------------------
00079 template <class Real>
00080 void GMatrix<Real>::Deallocate ()
00081 {
00082     WM4_DELETE[] m_afData;
00083     WM4_DELETE[] m_aafEntry;
00084 }
00085 //----------------------------------------------------------------------------
00086 template <class Real>
00087 void GMatrix<Real>::SetSize (int iRows, int iCols)
00088 {
00089     Deallocate();
00090     if (iRows > 0 && iCols > 0)
00091     {
00092         m_iRows = iRows;
00093         m_iCols = iCols;
00094         m_iQuantity = m_iRows*m_iCols;
00095         Allocate(true);
00096     }
00097     else
00098     {
00099         m_iRows = 0;
00100         m_iCols = 0;
00101         m_iQuantity = 0;
00102         m_afData = 0;
00103         m_aafEntry = 0;
00104     }
00105 }
00106 //----------------------------------------------------------------------------
00107 template <class Real>
00108 void GMatrix<Real>::GetSize (int& riRows, int& riCols) const
00109 {
00110     riRows = m_iRows;
00111     riCols = m_iCols;
00112 }
00113 //----------------------------------------------------------------------------
00114 template <class Real>
00115 int GMatrix<Real>::GetRows () const
00116 {
00117     return m_iRows;
00118 }
00119 //----------------------------------------------------------------------------
00120 template <class Real>
00121 int GMatrix<Real>::GetColumns () const
00122 {
00123     return m_iCols;
00124 }
00125 //----------------------------------------------------------------------------
00126 template <class Real>
00127 int GMatrix<Real>::GetQuantity () const
00128 {
00129     return m_iQuantity;
00130 }
00131 //----------------------------------------------------------------------------
00132 template <class Real>
00133 GMatrix<Real>::operator const Real* () const
00134 {
00135     return m_afData;
00136 }
00137 //----------------------------------------------------------------------------
00138 template <class Real>
00139 GMatrix<Real>::operator Real* ()
00140 {
00141     return m_afData;
00142 }
00143 //----------------------------------------------------------------------------
00144 template <class Real>
00145 const Real* GMatrix<Real>::operator[] (int iRow) const
00146 {
00147     assert(0 <= iRow && iRow < m_iRows);
00148     return m_aafEntry[iRow];
00149 }
00150 //----------------------------------------------------------------------------
00151 template <class Real>
00152 Real* GMatrix<Real>::operator[] (int iRow)
00153 {
00154     assert(0 <= iRow && iRow < m_iRows);
00155     return m_aafEntry[iRow];
00156 }
00157 //----------------------------------------------------------------------------
00158 template <class Real>
00159 Real GMatrix<Real>::operator() (int iRow, int iCol) const
00160 {
00161     return m_aafEntry[iRow][iCol];
00162 }
00163 //----------------------------------------------------------------------------
00164 template <class Real>
00165 Real& GMatrix<Real>::operator() (int iRow, int iCol)
00166 {
00167     assert(0 <= iRow && iRow < m_iRows && 0 <= iCol && iCol <= m_iCols);
00168     return m_aafEntry[iRow][iCol];
00169 }
00170 //----------------------------------------------------------------------------
00171 template <class Real>
00172 void GMatrix<Real>::SwapRows (int iRow0, int iRow1)
00173 {
00174     assert(0 <= iRow0 && iRow0 < m_iRows && 0 <= iRow1 && iRow1 < m_iRows);
00175     Real* afSave = m_aafEntry[iRow0];
00176     m_aafEntry[iRow0] = m_aafEntry[iRow1];
00177     m_aafEntry[iRow1] = afSave;
00178 }
00179 //----------------------------------------------------------------------------
00180 template <class Real>
00181 void GMatrix<Real>::SetRow (int iRow, const GVector<Real>& rkV)
00182 {
00183     assert((0 <= iRow && iRow < m_iRows) && (rkV.GetSize() == m_iCols));
00184     for (int iCol = 0; iCol < m_iCols; iCol++)
00185     {
00186         m_aafEntry[iRow][iCol] = rkV[iCol];
00187     }
00188 }
00189 //----------------------------------------------------------------------------
00190 template <class Real>
00191 GVector<Real> GMatrix<Real>::GetRow (int iRow) const
00192 {
00193     assert(0 <= iRow && iRow < m_iRows);
00194     GVector<Real> kV(m_iCols);
00195     for (int iCol = 0; iCol < m_iCols; iCol++)
00196     {
00197         kV[iCol] = m_aafEntry[iRow][iCol];
00198     }
00199     return kV;
00200 }
00201 //----------------------------------------------------------------------------
00202 template <class Real>
00203 void GMatrix<Real>::SetColumn (int iCol, const GVector<Real>& rkV)
00204 {
00205     assert((0 <= iCol && iCol < m_iCols) && (rkV.GetSize() == m_iRows));
00206     for (int iRow = 0; iRow < m_iRows; iRow++)
00207     {
00208         m_aafEntry[iRow][iCol] = rkV[iRow];
00209     }
00210 }
00211 //----------------------------------------------------------------------------
00212 template <class Real>
00213 GVector<Real> GMatrix<Real>::GetColumn (int iCol) const
00214 {
00215     assert(0 <= iCol && iCol < m_iCols);
00216     GVector<Real> kV(m_iRows);
00217     for (int iRow = 0; iRow < m_iRows; iRow++)
00218     {
00219         kV[iRow] = m_aafEntry[iRow][iCol];
00220     }
00221     return kV;
00222 }
00223 //----------------------------------------------------------------------------
00224 template <class Real>
00225 void GMatrix<Real>::SetMatrix (int iRows, int iCols, const Real* afData)
00226 {
00227     Deallocate();
00228     if (iRows > 0 && iCols > 0)
00229     {
00230         m_iRows = iRows;
00231         m_iCols = iCols;
00232         m_iQuantity = m_iRows*m_iCols;
00233         Allocate(false);
00234         size_t uiSize = m_iQuantity*sizeof(Real);
00235         System::Memcpy(m_afData,uiSize,afData,uiSize);
00236     }
00237     else
00238     {
00239         m_iRows = 0;
00240         m_iCols = 0;
00241         m_iQuantity = 0;
00242         m_afData = 0;
00243         m_aafEntry = 0;
00244     }
00245 }
00246 //----------------------------------------------------------------------------
00247 template <class Real>
00248 void GMatrix<Real>::SetMatrix (int iRows, int iCols, const Real** aafEntry)
00249 {
00250     Deallocate();
00251     if (iRows > 0 && iCols > 0)
00252     {
00253         m_iRows = iRows;
00254         m_iCols = iCols;
00255         m_iQuantity = m_iRows*m_iCols;
00256         Allocate(false);
00257         for (int iRow = 0; iRow < m_iRows; iRow++)
00258         {
00259             for (int iCol = 0; iCol < m_iCols; iCol++)
00260             {
00261                 m_aafEntry[iRow][iCol] = aafEntry[iRow][iCol];
00262             }
00263         }
00264     }
00265     else
00266     {
00267         m_iRows = 0;
00268         m_iCols = 0;
00269         m_iQuantity = 0;
00270         m_afData = 0;
00271         m_aafEntry = 0;
00272     }
00273 }
00274 //----------------------------------------------------------------------------
00275 template <class Real>
00276 void GMatrix<Real>::GetColumnMajor (Real* afCMajor) const
00277 {
00278     for (int iRow = 0, i = 0; iRow < m_iRows; iRow++)
00279     {
00280         for (int iCol = 0; iCol < m_iCols; iCol++)
00281         {
00282             afCMajor[i++] = m_aafEntry[iCol][iRow];
00283         }
00284     }
00285 }
00286 //----------------------------------------------------------------------------
00287 template <class Real>
00288 GMatrix<Real>& GMatrix<Real>::operator= (const GMatrix& rkM)
00289 {
00290     if (rkM.m_iQuantity > 0)
00291     {
00292         if (m_iRows != rkM.m_iRows || m_iCols != rkM.m_iCols)
00293         {
00294             Deallocate();
00295             m_iRows = rkM.m_iRows;
00296             m_iCols = rkM.m_iCols;
00297             m_iQuantity = rkM.m_iQuantity;
00298             Allocate(false);
00299         }
00300         for (int iRow = 0; iRow < m_iRows; iRow++)
00301         {
00302             for (int iCol = 0; iCol < m_iCols; iCol++)
00303             {
00304                 m_aafEntry[iRow][iCol] = rkM.m_aafEntry[iRow][iCol];
00305             }
00306         }
00307     }
00308     else
00309     {
00310         Deallocate();
00311         m_iRows = 0;
00312         m_iCols = 0;
00313         m_iQuantity = 0;
00314         m_afData = 0;
00315         m_aafEntry = 0;
00316     }
00317     return *this;
00318 }
00319 //----------------------------------------------------------------------------
00320 template <class Real>
00321 int GMatrix<Real>::CompareArrays (const GMatrix& rkM) const
00322 {
00323     return memcmp(m_afData,rkM.m_afData,m_iQuantity*sizeof(Real));
00324 }
00325 //----------------------------------------------------------------------------
00326 template <class Real>
00327 bool GMatrix<Real>::operator== (const GMatrix& rkM) const
00328 {
00329     return CompareArrays(rkM) == 0;
00330 }
00331 //----------------------------------------------------------------------------
00332 template <class Real>
00333 bool GMatrix<Real>::operator!= (const GMatrix& rkM) const
00334 {
00335     return CompareArrays(rkM) != 0;
00336 }
00337 //----------------------------------------------------------------------------
00338 template <class Real>
00339 bool GMatrix<Real>::operator<  (const GMatrix& rkM) const
00340 {
00341     return CompareArrays(rkM) < 0;
00342 }
00343 //----------------------------------------------------------------------------
00344 template <class Real>
00345 bool GMatrix<Real>::operator<= (const GMatrix& rkM) const
00346 {
00347     return CompareArrays(rkM) <= 0;
00348 }
00349 //----------------------------------------------------------------------------
00350 template <class Real>
00351 bool GMatrix<Real>::operator>  (const GMatrix& rkM) const
00352 {
00353     return CompareArrays(rkM) > 0;
00354 }
00355 //----------------------------------------------------------------------------
00356 template <class Real>
00357 bool GMatrix<Real>::operator>= (const GMatrix& rkM) const
00358 {
00359     return CompareArrays(rkM) >= 0;
00360 }
00361 //----------------------------------------------------------------------------
00362 template <class Real>
00363 GMatrix<Real> GMatrix<Real>::operator+ (const GMatrix& rkM) const
00364 {
00365     GMatrix<Real> kSum(rkM.m_iRows,rkM.m_iCols);
00366     for (int i = 0; i < m_iQuantity; i++)
00367     {
00368         kSum.m_afData[i] = m_afData[i] + rkM.m_afData[i];
00369     }
00370     return kSum;
00371 }
00372 //----------------------------------------------------------------------------
00373 template <class Real>
00374 GMatrix<Real> GMatrix<Real>::operator- (const GMatrix& rkM) const
00375 {
00376     GMatrix<Real> kDiff(rkM.m_iRows,rkM.m_iCols);
00377     for (int i = 0; i < m_iQuantity; i++)
00378     {
00379         kDiff.m_afData[i] = m_afData[i] - rkM.m_afData[i];
00380     }
00381     return kDiff;
00382 }
00383 //----------------------------------------------------------------------------
00384 template <class Real>
00385 GMatrix<Real> GMatrix<Real>::operator* (const GMatrix& rkM) const
00386 {
00387     // 'this' is RxN, 'M' is NxC, 'product = this*M' is RxC
00388     assert(m_iCols == rkM.m_iRows);
00389     GMatrix<Real> kProd(m_iRows,rkM.m_iCols);
00390     for (int iRow = 0; iRow < kProd.m_iRows; iRow++)
00391     {
00392         for (int iCol = 0; iCol < kProd.m_iCols; iCol++)
00393         {
00394             for (int iMid = 0; iMid < m_iCols; iMid++)
00395             {
00396                 kProd.m_aafEntry[iRow][iCol] += m_aafEntry[iRow][iMid] *
00397                     rkM.m_aafEntry[iMid][iCol];
00398             }
00399         }
00400     }
00401     return kProd;
00402 }
00403 //----------------------------------------------------------------------------
00404 template <class Real>
00405 GMatrix<Real> GMatrix<Real>::operator* (Real fScalar) const
00406 {
00407     GMatrix<Real> kProd(m_iRows,m_iCols);
00408     for (int i = 0; i < m_iQuantity; i++)
00409     {
00410         kProd.m_afData[i] = fScalar*m_afData[i];
00411     }
00412     return kProd;
00413 }
00414 //----------------------------------------------------------------------------
00415 template <class Real>
00416 GMatrix<Real> GMatrix<Real>::operator/ (Real fScalar) const
00417 {
00418     GMatrix<Real> kQuot(m_iRows,m_iCols);
00419     int i;
00420 
00421     if (fScalar != (Real)0.0)
00422     {
00423         Real fInvScalar = ((Real)1.0)/fScalar;
00424         for (i = 0; i < m_iQuantity; i++)
00425         {
00426             kQuot.m_afData[i] = fInvScalar*m_afData[i];
00427         }
00428     }
00429     else
00430     {
00431         for (i = 0; i < m_iQuantity; i++)
00432         {
00433             kQuot.m_afData[i] = Math<Real>::MAX_REAL;
00434         }
00435     }
00436 
00437     return kQuot;
00438 }
00439 //----------------------------------------------------------------------------
00440 template <class Real>
00441 GMatrix<Real> GMatrix<Real>::operator- () const
00442 {
00443     GMatrix<Real> kNeg(m_iRows,m_iCols);
00444     for (int i = 0; i < m_iQuantity; i++)
00445     {
00446         kNeg.m_afData[i] = -m_afData[i];
00447     }
00448     return kNeg;
00449 }
00450 //----------------------------------------------------------------------------
00451 template <class Real>
00452 GMatrix<Real> operator* (Real fScalar, const GMatrix<Real>& rkM)
00453 {
00454     GMatrix<Real> kProd(rkM.GetRows(),rkM.GetColumns());
00455     const Real* afMEntry = rkM;
00456     Real* afPEntry = kProd;
00457     for (int i = 0; i < rkM.GetQuantity(); i++)
00458     {
00459         afPEntry[i] = fScalar*afMEntry[i];
00460     }
00461     return kProd;
00462 }
00463 //----------------------------------------------------------------------------
00464 template <class Real>
00465 GMatrix<Real>& GMatrix<Real>::operator+= (const GMatrix& rkM)
00466 {
00467     for (int i = 0; i < m_iQuantity; i++)
00468     {
00469         m_afData[i] += rkM.m_afData[i];
00470     }
00471     return *this;
00472 }
00473 //----------------------------------------------------------------------------
00474 template <class Real>
00475 GMatrix<Real>& GMatrix<Real>::operator-= (const GMatrix& rkM)
00476 {
00477     for (int i = 0; i < m_iQuantity; i++)
00478     {
00479         m_afData[i] -= rkM.m_afData[i];
00480     }
00481     return *this;
00482 }
00483 //----------------------------------------------------------------------------
00484 template <class Real>
00485 GMatrix<Real>& GMatrix<Real>::operator*= (Real fScalar)
00486 {
00487     for (int i = 0; i < m_iQuantity; i++)
00488     {
00489         m_afData[i] *= fScalar;
00490     }
00491     return *this;
00492 }
00493 //----------------------------------------------------------------------------
00494 template <class Real>
00495 GMatrix<Real>& GMatrix<Real>::operator/= (Real fScalar)
00496 {
00497     int i;
00498 
00499     if (fScalar != (Real)0.0)
00500     {
00501         Real fInvScalar = ((Real)1.0)/fScalar;
00502         for (i = 0; i < m_iQuantity; i++)
00503         {
00504             m_afData[i] *= fInvScalar;
00505         }
00506     }
00507     else
00508     {
00509         for (i = 0; i < m_iQuantity; i++)
00510         {
00511             m_afData[i] = Math<Real>::MAX_REAL;
00512         }
00513     }
00514 
00515     return *this;
00516 }
00517 //----------------------------------------------------------------------------
00518 template <class Real>
00519 GMatrix<Real> GMatrix<Real>::Transpose () const
00520 {
00521     GMatrix<Real> kTranspose(m_iCols,m_iRows);
00522     for (int iRow = 0; iRow < m_iRows; iRow++)
00523     {
00524         for (int iCol = 0; iCol < m_iCols; iCol++)
00525         {
00526             kTranspose.m_aafEntry[iCol][iRow] = m_aafEntry[iRow][iCol];
00527         }
00528     }
00529     return kTranspose;
00530 }
00531 //----------------------------------------------------------------------------
00532 template <class Real>
00533 GMatrix<Real> GMatrix<Real>::TransposeTimes (const GMatrix& rkM) const
00534 {
00535     // P = A^T*B, P[r][c] = sum_m A[m][r]*B[m][c]
00536     assert(m_iRows == rkM.m_iRows);
00537     GMatrix<Real> kProd(m_iCols,rkM.m_iCols);
00538     for (int iRow = 0; iRow < kProd.m_iRows; iRow++)
00539     {
00540         for (int iCol = 0; iCol < kProd.m_iCols; iCol++)
00541         {
00542             for (int iMid = 0; iMid < m_iRows; iMid++)
00543             {
00544                 kProd.m_aafEntry[iRow][iCol] += m_aafEntry[iMid][iRow] *
00545                     rkM.m_aafEntry[iMid][iCol];
00546             }
00547         }
00548     }
00549     return kProd;
00550 }
00551 //----------------------------------------------------------------------------
00552 template <class Real>
00553 GMatrix<Real> GMatrix<Real>::TimesTranspose (const GMatrix& rkM) const
00554 {
00555     // P = A*B^T, P[r][c] = sum_m A[r][m]*B[c][m]
00556     assert(m_iCols == rkM.m_iCols);
00557     GMatrix<Real> kProd(m_iRows,rkM.m_iRows);
00558     for (int iRow = 0; iRow < kProd.m_iRows; iRow++)
00559     {
00560         for (int iCol = 0; iCol < kProd.m_iCols; iCol++)
00561         {
00562             for (int iMid = 0; iMid < m_iCols; iMid++)
00563             {
00564                 kProd.m_aafEntry[iRow][iCol] +=  m_aafEntry[iRow][iMid] *
00565                     rkM.m_aafEntry[iCol][iMid];
00566             }
00567         }
00568     }
00569     return kProd;
00570 }
00571 //----------------------------------------------------------------------------
00572 template <class Real>
00573 GVector<Real> GMatrix<Real>::operator* (const GVector<Real>& rkV) const
00574 {
00575     assert(rkV.GetSize() == m_iCols);
00576     GVector<Real> kProd(m_iRows);
00577     for (int iRow = 0; iRow < m_iRows; iRow++)
00578     {
00579         for (int iCol = 0; iCol < m_iCols; iCol++)
00580         {
00581             kProd[iRow] += m_aafEntry[iRow][iCol]*rkV[iCol];
00582         }
00583             
00584     }
00585     return kProd;
00586 }
00587 //----------------------------------------------------------------------------
00588 template <class Real>
00589 GVector<Real> operator* (const GVector<Real>& rkV, const GMatrix<Real>& rkM)
00590 {
00591     assert(rkV.GetSize() == rkM.GetRows());
00592     GVector<Real> kProd(rkM.GetColumns());
00593     Real* afPEntry = kProd;
00594     for (int iCol = 0; iCol < rkM.GetColumns(); iCol++)
00595     {
00596         for (int iRow = 0; iRow < rkM.GetRows(); iRow++)
00597         {
00598             afPEntry[iCol] += rkV[iRow]*rkM[iRow][iCol];
00599         }
00600     }
00601     return kProd;
00602 }
00603 //----------------------------------------------------------------------------
00604 template <class Real>
00605 Real GMatrix<Real>::QForm (const GVector<Real>& rkU, const GVector<Real>& rkV)
00606     const
00607 {
00608     assert(rkU.GetSize() == m_iRows && rkV.GetSize() == m_iCols);
00609     return rkU.Dot((*this)*rkV);
00610 }
00611 //----------------------------------------------------------------------------
00612 template <class Real>
00613 bool GMatrix<Real>::GetInverse (GMatrix<Real>& rkInverse) const
00614 {
00615     // computations are performed in-place
00616     if (GetRows() > 0 && GetRows() != GetColumns())
00617     {
00618         return false;
00619     }
00620 
00621     int iSize = GetRows();
00622     rkInverse = *this;
00623 
00624     int* aiColIndex = WM4_NEW int[iSize];
00625     int* aiRowIndex = WM4_NEW int[iSize];
00626     bool* abPivoted = WM4_NEW bool[iSize];
00627     memset(abPivoted,0,iSize*sizeof(bool));
00628 
00629     int i1, i2, iRow = 0, iCol = 0;
00630     Real fSave;
00631 
00632     // elimination by full pivoting
00633     for (int i0 = 0; i0 < iSize; i0++)
00634     {
00635         // search matrix (excluding pivoted rows) for maximum absolute entry
00636         Real fMax = (Real)0.0;
00637         for (i1 = 0; i1 < iSize; i1++)
00638         {
00639             if (!abPivoted[i1])
00640             {
00641                 for (i2 = 0; i2 < iSize; i2++)
00642                 {
00643                     if (!abPivoted[i2])
00644                     {
00645                         Real fAbs = Math<Real>::FAbs(rkInverse[i1][i2]);
00646                         if (fAbs > fMax)
00647                         {
00648                             fMax = fAbs;
00649                             iRow = i1;
00650                             iCol = i2;
00651                         }
00652                     }
00653                 }
00654             }
00655         }
00656 
00657         if (fMax == (Real)0.0)
00658         {
00659             // matrix is not invertible
00660             WM4_DELETE[] aiColIndex;
00661             WM4_DELETE[] aiRowIndex;
00662             WM4_DELETE[] abPivoted;
00663             return false;
00664         }
00665 
00666         abPivoted[iCol] = true;
00667 
00668         // swap rows so that A[iCol][iCol] contains the pivot entry
00669         if (iRow != iCol)
00670         {
00671             rkInverse.SwapRows(iRow,iCol);
00672         }
00673 
00674         // keep track of the permutations of the rows
00675         aiRowIndex[i0] = iRow;
00676         aiColIndex[i0] = iCol;
00677 
00678         // scale the row so that the pivot entry is 1
00679         Real fInv = ((Real)1.0)/rkInverse[iCol][iCol];
00680         rkInverse[iCol][iCol] = (Real)1.0;
00681         for (i2 = 0; i2 < iSize; i2++)
00682         {
00683             rkInverse[iCol][i2] *= fInv;
00684         }
00685 
00686         // zero out the pivot column locations in the other rows
00687         for (i1 = 0; i1 < iSize; i1++)
00688         {
00689             if (i1 != iCol)
00690             {
00691                 fSave = rkInverse[i1][iCol];
00692                 rkInverse[i1][iCol] = (Real)0.0;
00693                 for (i2 = 0; i2 < iSize; i2++)
00694                 {
00695                     rkInverse[i1][i2] -= rkInverse[iCol][i2]*fSave;
00696                 }
00697             }
00698         }
00699     }
00700 
00701     // reorder rows so that A[][] stores the inverse of the original matrix
00702     for (i1 = iSize-1; i1 >= 0; i1--)
00703     {
00704         if (aiRowIndex[i1] != aiColIndex[i1])
00705         {
00706             for (i2 = 0; i2 < iSize; i2++)
00707             {
00708                 fSave = rkInverse[i2][aiRowIndex[i1]];
00709                 rkInverse[i2][aiRowIndex[i1]] =
00710                     rkInverse[i2][aiColIndex[i1]];
00711                 rkInverse[i2][aiColIndex[i1]] = fSave;
00712             }
00713         }
00714     }
00715 
00716     WM4_DELETE[] aiColIndex;
00717     WM4_DELETE[] aiRowIndex;
00718     WM4_DELETE[] abPivoted;
00719     return true;
00720 }
00721 //----------------------------------------------------------------------------
00722 } //namespace Wm4

Generated on Wed Nov 23 19:01:03 2011 for FreeCAD by  doxygen 1.6.1