00001
00012 #ifndef TBCI_SOLVER_GAUSS_JORDAN_H
00013 #define TBCI_SOLVER_GAUSS_JORDAN_H
00014
00015 #include "../basics.h"
00016 #include "../matrix.h"
00017
00018 #ifdef PRAGMA_I
00019 # pragma interface "gauss_jordan.h"
00020 #endif
00021
00022 #ifndef GJ_MINVAL
00023 # define GJ_MINVAL 1e-16
00024 #endif
00025
00026
00027 #ifndef HVAL
00028 # define HVAL 1e38
00029 #endif
00030
00031 NAMESPACE_TBCI
00032
00033 INST(template <typename T> class Matrix friend char gaussj (Matrix<T>&, Matrix<T>&);)
00034
00045 template <typename T>
00046 char gaussj(Matrix<T>& a, Matrix<T>& b)
00047 {
00048 const int n = a.row, m = b.col;
00049 char err = 0;
00050
00051 BVector<unsigned> indxc((unsigned)n);
00052 BVector<unsigned> indxr((unsigned)n);
00053 BVector<unsigned> ipiv ((unsigned)0, n);
00054
00055 BCHK(a.col != b.row, MatErr, Wrong sizes in gaussj, b.row, 1);
00056
00057 for (int i = 0; i < n; ++i) {
00058 double big = 0.0;
00059 int icol = 0, irow = 0;
00060 for (int j = 0; j < n; ++j)
00061 if (ipiv(j) != 1)
00062 for (register int k = 0; k < n; ++k) {
00063 if (ipiv(k) == 0) {
00064 if (MATH__ fabs(a(j, k)) >= MATH__ fabs(big)) {
00065 big = MATH__ fabs(a(j, k));
00066 irow = j; icol = k;
00067 }
00068 } else if (ipiv(k) > 1) {
00069 STD__ cerr << "\n\n error: gaussj: singular Matrix-1 \n\n";
00070 err |= 1;
00071 }
00072 }
00073 ++(ipiv(icol));
00074 if (irow != icol) {
00075 for (register int l = 0; l < n; ++l)
00076 SWAP(a(irow, l), a(icol, l));
00077 for (register int z = 0; z < m; ++z)
00078 SWAP(b(irow, z), b(icol, z));
00079 }
00080 indxr(i) = irow;
00081 indxc(i) = icol;
00082 T pivinv;
00083 if (MATH__ fabs(a(icol, icol)) < GJ_MINVAL) {
00084 STD__ cerr << "\n\n error: gaussj: singular Matrix-2 \n" << STD__ endl;
00085 err |= 2; pivinv = (T)HVAL;
00086 } else
00087 pivinv = 1.0 / a(icol, icol);
00088 a(icol, icol) = (T)1.0;
00089 for (register int l = 0; l < n; ++l)
00090 a(icol, l) *= pivinv;
00091 for (register int z = 0; z < m; ++z)
00092 b(icol, z) *= pivinv;
00093 for (int ll = 0; ll < n; ++ll)
00094 if (ll != icol) {
00095 register T dum = a(ll, icol);
00096 a(ll, icol) = (T)0.0;
00097 for (register int v = 0; v < n; ++v)
00098 a(ll, v) -= a(icol, v) * dum;
00099 for (register int w = 0; w < m; ++w)
00100 b(ll, w) -= b(icol, w) * dum;
00101 }
00102 }
00103 for (int l = n-1; l >= 0; --l) {
00104 if (indxr(l) != indxc(l))
00105 for(register int k = 0; k < n; ++k)
00106 SWAP(a(k, indxr(l)), a(k, indxc(l)));
00107 }
00108 return err;
00109 }
00110
00111 NAMESPACE_END
00112 #endif