00001 #include "smatrix.h" 00002 00003 template <class t> class TLUDecomp : public smatrix<t> 00004 { 00005 protected: 00006 smatrix<t> pivots; 00007 bool bDecomposed; 00008 00009 public: 00010 TLUDecomp(const smatrix<t> &m, bool bWithPartialPivot) : 00011 smatrix<t>(m) 00012 { 00013 bDecomposed = false; 00014 if(Decompose(bWithPartialPivot) == false) 00015 { 00016 pivots = smatrix<t>(); 00017 *this = TLUDecomp<t>(); 00018 } 00019 } 00020 TLUDecomp(const t* d, size_t iDim, size_t jDim, 00021 bool bWithPartialPivot) : smatrix<t> (d, iDim, jDim) 00022 { 00023 bDecomposed = false; 00024 if(Decompose(bWithPartialPivot) == false) 00025 { 00026 pivots = smatrix<t>(); 00027 *this = TLUDecomp<t>(); 00028 } 00029 } 00030 TLUDecomp() { bDecomposed = false; } 00031 bool Decompose(const smatrix<t> &m, bool bWithPartialPivot) 00032 { 00033 *this = m; 00034 bDecomposed = false; 00035 if(Decompose(bWithPartialPivot) == false) 00036 { 00037 pivots = smatrix<t>(); 00038 *this = TLUDecomp<t>(); 00039 return(false); 00040 } 00041 return(true); 00042 } 00043 void FwdElim(smatrix<t> &c) const 00044 { 00045 for(size_t k = 1; k < iDim; k++) 00046 { 00047 const_iterator i = IterForCol(k, k + 1); 00048 while(i != EndOfCol(k)) 00049 { 00050 t Scaler = Coef(i); 00051 size_t r = Index(i++); 00052 c.row(r) += c.row(k) * Scaler; 00053 } 00054 } 00055 } 00056 void BackElim(smatrix<t> &c) const 00057 { 00058 for(size_t k = iDim; k >= 1; k--) 00059 { 00060 t Diag = t(-1.0) / Coef(k, k); 00061 const_iterator i = IterForCol(k); 00062 while(Index(i) < k) 00063 { 00064 t Scaler = Coef(i) * Diag; 00065 size_t r = Index(i++); 00066 c.row(r) += c.row(k) * Scaler; 00067 } 00068 c.row(k) *= -Diag; 00069 } 00070 } 00071 bool Decompose(bool bWithPartialPivot) 00072 { 00073 if(bDecomposed) return(true); 00074 if(iDim != jDim) return(false); 00075 pivots = smIdentity<t>(iDim); 00076 for(size_t k = 1; k < iDim; k++) 00077 { 00078 t Diag; 00079 if(!GetDiag(k, Diag, bWithPartialPivot, &pivots)) 00080 return(false); 00081 Diag = t(-1.0) / Diag; 00082 iterator i = IterForCol(k, k + 1); 00083 while(i != EndOfCol(k)) 00084 { 00085 t Scaler = Coef(i) * Diag; 00086 size_t r = Index(i++); 00087 row(r) += row(k, rng(k + 1, jDim)) * Scaler; 00088 Coef(r, k) = Scaler; 00089 } 00090 } 00091 t Diag = Coef(k, k); 00092 if(abs(Diag) < epsilon) 00093 return(false); 00094 bDecomposed = true; 00095 return(true); 00096 } 00097 smatrix<t> Solve(const smatrix<t> &m) const 00098 { 00099 smatrix<t> c(m.iDim, m.jDim, m.NZ); 00100 if(bDecomposed) 00101 { 00102 for(size_t r = 1; r <= iDim; r++) 00103 { 00104 const_svector_ref &v = m.row(r); 00105 const_iterator i = pivots.IterForCol(r); 00106 size_t x = Index(i); 00107 c.row(x) = v; 00108 } 00109 FwdElim(c); 00110 BackElim(c); 00111 } 00112 return(c); 00113 } 00114 smatrix<t> Inverse() const 00115 { 00116 smatrix<t> c(pivots); 00117 if(bDecomposed) 00118 { 00119 FwdElim(c); 00120 BackElim(c); 00121 } 00122 return(c); 00123 } 00124 smatrix<t> L() const 00125 { 00126 smatrix<t> c(iDim, jDim, NZ); 00127 for(size_t r = 1; r <= iDim; r++) 00128 { 00129 c.row(r) = row(r, rng(1, r - 1)) * t(-1); 00130 c.Coef(r, r) = t(1); 00131 } 00132 return(c); 00133 } 00134 smatrix<t> U() const 00135 { 00136 smatrix<t> c(iDim, jDim, NZ); 00137 for(size_t r = 1; r <= iDim; r++) 00138 c.row(r) = row(r, rng(r, jDim)); 00139 return(c); 00140 } 00141 smatrix<t> P() const 00142 { 00143 return(pivots); 00144 } 00145 }; 00146 00147