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 #ifndef WM4LINEARSYSTEM_H 00018 #define WM4LINEARSYSTEM_H 00019 00020 #include "Wm4FoundationLIB.h" 00021 #include "Wm4BandedMatrix.h" 00022 #include "Wm4GMatrix.h" 00023 00024 namespace Wm4 00025 { 00026 00027 template <class Real> 00028 class WM4_FOUNDATION_ITEM LinearSystem 00029 { 00030 public: 00031 // construction 00032 LinearSystem (); 00033 00034 // 2x2 and 3x3 systems (avoids overhead of Gaussian elimination) 00035 bool Solve2 (const Real aafA[2][2], const Real afB[2], Real afX[2]); 00036 bool Solve3 (const Real aafA[3][3], const Real afB[3], Real afX[3]); 00037 00038 // Input: 00039 // A[iSize][iSize], entries are A[row][col] 00040 // Output: 00041 // return value is TRUE if successful, FALSE if pivoting failed 00042 // InvA[iSize][iSize], inverse matrix 00043 bool Inverse (const GMatrix<Real>& rkA, GMatrix<Real>& rkInvA); 00044 00045 // Input: 00046 // A[iSize][iSize] coefficient matrix, entries are A[row][col] 00047 // B[iSize] vector, entries are B[row] 00048 // Output: 00049 // return value is TRUE if successful, FALSE if pivoting failed 00050 // X[iSize] is solution X to AX = B 00051 bool Solve (const GMatrix<Real>& rkA, const Real* afB, Real* afX); 00052 00053 // Input: 00054 // Matrix is tridiagonal. 00055 // Lower diagonal A[iSize-1] 00056 // Main diagonal B[iSize] 00057 // Upper diagonal C[iSize-1] 00058 // Right-hand side R[iSize] 00059 // Output: 00060 // return value is TRUE if successful, FALSE if pivoting failed 00061 // U[iSize] is solution 00062 bool SolveTri (int iSize, Real* afA, Real* afB, Real* afC, Real* afR, 00063 Real* afU); 00064 00065 // Input: 00066 // Matrix is tridiagonal. 00067 // Lower diagonal is constant, A 00068 // Main diagonal is constant, B 00069 // Upper diagonal is constant, C 00070 // Right-hand side Rr[iSize] 00071 // Output: 00072 // return value is TRUE if successful, FALSE if pivoting failed 00073 // U[iSize] is solution 00074 bool SolveConstTri (int iSize, Real fA, Real fB, Real fC, Real* afR, 00075 Real* afU); 00076 00077 // Solution using the conjugate gradient method. 00078 // Input: 00079 // A[iSize][iSize] symmetrix matrix, entries are A[row][col] 00080 // B[iSize] vector, entries are B[row] 00081 // Output: 00082 // X[iSize] is the solution x to Ax = B 00083 bool SolveSymmetricCG (const GMatrix<Real>& rkA, const Real* afB, 00084 Real* afX); 00085 00086 // Conjugate gradient method for sparse, symmetric matrices. 00087 // Input: 00088 // The nonzero entries of the symmetrix matrix A are stored in a map 00089 // whose keys are pairs (i,j) and whose values are real numbers. The 00090 // pair (i,j) is the location of the value in the array. Only one of 00091 // (i,j) and (j,i) should be stored since A is symmetric. The code 00092 // assumes this is how you set up A. The column vector B is stored as 00093 // an array of contiguous values. 00094 // Output: 00095 // X[iSize] is the solution x to Ax = B 00096 typedef std::map<std::pair<int,int>,Real> SparseMatrix; 00097 bool SolveSymmetricCG (int iSize, const SparseMatrix& rkA, 00098 const Real* afB, Real* afX); 00099 00100 // solve banded matrix systems 00101 // Input: 00102 // A, a banded matrix 00103 // B[iSize] vector, entries are B[row] 00104 // Output: 00105 // return value is TRUE if successful, FALSE if pivoting failed 00106 // X[iSize] is solution X to AX = B 00107 bool SolveBanded (const BandedMatrix<Real>& rkA, const Real* afB, 00108 Real* afX); 00109 00110 // invert a banded matrix 00111 // Input: 00112 // A, a banded matrix 00113 // Output: 00114 // return value is TRUE if the inverse exists, FALSE otherwise 00115 // InvA, the inverse of A 00116 bool Invert (const BandedMatrix<Real>& rkA, GMatrix<Real>& rkInvA); 00117 00118 // tolerance for linear system solving 00119 Real ZeroTolerance; // default = Math<Real>::ZERO_TOLERANCE 00120 00121 private: 00122 // support for the conjugate gradient method for standard arrays 00123 Real Dot (int iSize, const Real* afU, const Real* afV); 00124 void Multiply (const GMatrix<Real>& rkA, const Real* afX, Real* afProd); 00125 void UpdateX (int iSize, Real* afX, Real fAlpha, const Real* afP); 00126 void UpdateR (int iSize, Real* afR, Real fAlpha, const Real* afW); 00127 void UpdateP (int iSize, Real* afP, Real fBeta, const Real* afR); 00128 00129 // support for the conjugate gradient method for sparse arrays 00130 void Multiply (int iSize, const SparseMatrix& rkA, const Real* afX, 00131 Real* afProd); 00132 00133 // support for banded matrices 00134 bool ForwardEliminate (int iReduceRow, BandedMatrix<Real>& rkA, 00135 Real* afB); 00136 bool ForwardEliminate (int iReduceRow, BandedMatrix<Real>& rkA, 00137 GMatrix<Real>& rkB); 00138 void BackwardEliminate (int iReduceRow, BandedMatrix<Real>& rkA, 00139 GMatrix<Real>& rkB); 00140 }; 00141 00142 typedef LinearSystem<float> LinearSystemf; 00143 typedef LinearSystem<double> LinearSystemd; 00144 00145 } 00146 00147 #endif