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