Files Classes Functions Hierarchy
00001 #ifndef GAUSSELIM_H 00002 #define GAUSSELIM_H 00003 00004 #include <sstream> 00005 using namespace std; 00006 00007 #include <typedefs.h> 00008 #include <zero.h> 00009 00033 template< typename T > 00034 class gausselim 00035 { 00036 gausselim() { assert(false); } 00037 public: 00038 00040 T * mat; 00042 T * row; 00044 uintc dim; 00045 00047 gausselim( T * mat_, uintc dim_ ) 00048 : mat(mat_), dim(dim_) 00049 { row = new T[dim+1]; } 00051 ~gausselim() 00052 { delete[] row; } 00053 00056 boolc eval(); 00057 00060 void columnC( T * C ) const; 00061 00062 00063 // Possible Individual Operations on the state. 00064 00066 void rowget( uintc i ); 00068 void rowput( uintc i ); 00070 void mult(T const alpha); 00071 00073 void swap( uintc i, uintc k ); 00075 void norm( uintc row, uintc col ); 00076 00079 boolc pivot(uintc k); 00080 00082 void substitute( uintc i ); 00083 00085 operator stringc () const; 00086 }; 00087 00088 00089 //---------------------------------------------------------- 00090 // Implementation 00091 00092 00093 template< typename T > 00094 void gausselim<T>::columnC(T * C) const 00095 { 00096 for (uint i=0; i<dim; ++i) 00097 C[i] = mat[3+i*4]; 00098 } 00099 00100 template< typename T > 00101 boolc gausselim<T>::eval() 00102 { 00103 for (uint i=0; i<dim; ++i) 00104 { 00105 if (pivot(i)==false) 00106 return false; 00107 00108 substitute(i); 00109 } 00110 00111 return true; 00112 } 00113 00114 template< typename T > 00115 void gausselim<T>::substitute( uintc k ) 00116 { 00117 norm(k,k); 00118 00119 rowget(k); 00120 for (uint i=0; i<dim+1; ++i) 00121 row[i] *= -1; 00122 00123 uint b=0; 00124 T r; 00125 00126 for (uint i=0; i<dim; ++i) 00127 { 00128 if (i==k) 00129 { 00130 b += (dim+1); 00131 continue; 00132 } 00133 00134 r = mat[b+k]; 00135 00136 for (uint m=0; m<dim+1; ++m) 00137 mat[b++] += row[m]*r; 00138 } 00139 00140 } 00141 00142 template< typename T > 00143 boolc gausselim<T>::pivot( uintc k ) 00144 { 00145 assert(k<dim); 00146 00147 T lgnum = mat[ k*(dim+1) + k ]; 00148 T lgnum2 = lgnum*lgnum; 00149 uint lgi = k; 00150 T x; 00151 T x2; 00152 for (uint i=k+1; i<dim; ++i) 00153 { 00154 x = mat[ i*(dim+1) + k ]; 00155 x2 = x*x; 00156 if (x2>lgnum2) 00157 { 00158 lgnum2 = x2; 00159 lgnum = x; 00160 lgi = i; 00161 } 00162 } 00163 00164 if (k!=lgi) 00165 swap(k,lgi); 00166 00167 if (lgnum2 < zero<T>::val ) 00168 return false; 00169 00170 return true; 00171 } 00172 00173 template< typename T > 00174 void gausselim<T>::rowget( uintc i ) 00175 { 00176 assert(i<dim); 00177 00178 uint b = i*(dim+1); 00179 for (uint k=0; k<dim+1; ++k) 00180 row[k] = mat[b+k]; 00181 } 00182 00183 template< typename T > 00184 void gausselim<T>::rowput( uintc i ) 00185 { 00186 assert(i<dim); 00187 00188 uint b = i*(dim+1); 00189 for (uint k=0; k<dim+1; ++k) 00190 mat[b+k] = row[k]; 00191 } 00192 00193 template< typename T > 00194 void gausselim<T>::mult(T const alpha) 00195 { 00196 for (uint i=0; i<dim+1; ++i) 00197 row[i] *= alpha; 00198 } 00199 00200 template< typename T > 00201 void gausselim<T>::norm( uintc row, uintc col ) 00202 { 00203 assert(row<dim); 00204 assert(col<dim); 00205 00206 uint b = row*(dim+1); 00207 00208 T alpha = mat[b+col]; 00209 if (alpha==0) 00210 return; 00211 00212 alpha = 1.0/alpha; 00213 00214 for (uint i=0; i<dim+1; ++i) 00215 mat[b++] *= alpha; 00216 } 00217 00218 template< typename T > 00219 void gausselim<T>::swap( uintc i, uintc k ) 00220 { 00221 assert(i<dim); 00222 assert(k<dim); 00223 00224 T t; 00225 uint bi = i*(dim+1); 00226 uint bk = k*(dim+1); 00227 for (uint j=0; j<dim+1; ++j) 00228 { 00229 t = mat[bi]; 00230 mat[bi] = mat[bk]; 00231 mat[bk] = t; 00232 ++bi; 00233 ++bk; 00234 } 00235 } 00236 00237 template< typename T > 00238 gausselim<T>::operator stringc () const 00239 { 00240 stringstream ss; 00241 00242 for (uint i=0; i<dim; ++i) 00243 { 00244 for (uint k=0; k<dim+1; ++k) 00245 { 00246 ss << mat[i*(dim+1)+k] << " "; 00247 } 00248 if (i!=dim-1) 00249 ss << "\n"; 00250 } 00251 00252 return ss.str(); 00253 } 00254 00255 00256 00257 #endif 00258 00259
1.5.8