![]() |
Gowdy solver
|
00001 /** 00002 * @file matrix.h 00003 * @brief Vector and Matrix classes. 00004 * @author Mikica Kocic 00005 * @copyright GNU General Public License (GPLv3). 00006 */ 00007 00008 ///////////////////////////////////////////////////////////////////////////////////////// 00009 /** @defgroup g11 Numerical Methods */ 00010 ///////////////////////////////////////////////////////////////////////////////////////// 00011 /*@{*/ 00012 #ifdef _DEBUG 00013 #define assertBounds(v,e) do if(!(v)) { std::cerr << e << endl; throw(e); } while(0) 00014 // #define assertBounds(v,e) 00015 #else 00016 #define assertBounds(v,e) 00017 #endif 00018 00019 ///////////////////////////////////////////////////////////////////////////////////////// 00020 /** A vector (or an array) of elements. 00021 */ 00022 template <class T> 00023 class Vector 00024 { 00025 Int nn; //!< The size of the array. The upper index is `nn-1`. 00026 T* v; //!< The elements of the array. 00027 00028 public: 00029 typedef T value_type; //!< Makes `T` available externally 00030 00031 /** Constructs the empty vector. 00032 */ 00033 Vector () 00034 : nn( 0 ) 00035 , v( NULL ) 00036 {} 00037 00038 /** Destructs the vector, freeing allocated resources. 00039 */ 00040 ~Vector () 00041 { 00042 if( v != NULL ) { 00043 delete[] v; 00044 } 00045 } 00046 00047 /** Constructs the zero-based vector. 00048 */ 00049 explicit Vector( Int n ) 00050 : nn( n ) 00051 , v( n > 0 ? new T[n] : NULL ) 00052 {} 00053 00054 /** Constructs the vector initialized to a constant value. 00055 */ 00056 Vector( Int n, const T& c ) 00057 : nn( n ) 00058 , v( n>0 ? new T[n] : NULL ) 00059 { 00060 for( Int i = 0; i < n; ++i ) { 00061 v[i] = c; 00062 } 00063 } 00064 00065 /** Constructs the vector from an array. 00066 */ 00067 Vector( Int n, const T* ap ) 00068 : nn( n ) 00069 , v( n > 0 ? new T[n] : NULL ) 00070 { 00071 for( Int i = 0; i < n; ++i ) { 00072 v[i] = *ap++; 00073 } 00074 } 00075 00076 Vector( const Vector<T>& rhs ) 00077 : nn( rhs.nn ) 00078 , v( nn > 0 ? new T[nn] : NULL ) 00079 { 00080 for( Int i = 0; i < nn; ++i ) { 00081 v[i] = rhs[i]; 00082 } 00083 } 00084 00085 /** Assigns an existing vector. Postcondition: normal assignment via copying has 00086 * been performed; if vector and rhs were different sizes, vector has been resized 00087 * to match the size of rhs. 00088 */ 00089 Vector<T>& operator=( const Vector<T>& rhs ) 00090 { 00091 if( this != &rhs ) 00092 { 00093 if( nn != rhs.nn ) { 00094 if( v != NULL ) { 00095 delete[] v; 00096 } 00097 nn = rhs.nn; 00098 v= nn > 0 ? new T[nn] : NULL; 00099 } 00100 for( Int i = 0; i < nn; ++i ) { 00101 v[i] = rhs[i]; 00102 } 00103 } 00104 return *this; 00105 } 00106 00107 T& operator[]( const Int i ) 00108 { 00109 assertBounds( i >= 0 && i < nn, "Vector subscript out of bounds" ); 00110 return v[i]; 00111 } 00112 00113 const T& operator[](const Int i) const 00114 { 00115 assertBounds( i >= 0 && i < nn, "Vector subscript out of bounds" ); 00116 return v[i]; 00117 } 00118 00119 /** Returns the size. 00120 */ 00121 Int size () const { 00122 return nn; 00123 } 00124 00125 /** Resize the array. 00126 */ 00127 void resize( Int newn ) 00128 { 00129 if( newn != nn ) 00130 { 00131 if( v != NULL ) { 00132 delete[] v; 00133 } 00134 nn = newn; 00135 v = nn > 0 ? new T[nn] : NULL; 00136 } 00137 } 00138 00139 /** Resize and assign a constant value. 00140 */ 00141 void assign( Int newn, const T& c ) 00142 { 00143 if( newn != nn ) { 00144 if( v != NULL ) { 00145 delete[] v; 00146 } 00147 nn = newn; 00148 v = nn > 0 ? new T[nn] : NULL; 00149 } 00150 for( Int i = 0; i < nn; ++i ) { 00151 v[i] = c; 00152 } 00153 } 00154 }; 00155 00156 ///////////////////////////////////////////////////////////////////////////////////////// 00157 /** A matrix (a two-dimensional array) of elements. 00158 */ 00159 template <class T> 00160 class Matrix 00161 { 00162 Int nn; //!< The number of rows. 00163 Int mm; //!< The number of columns. 00164 T** v; //!< The elements of the two-dimensional array. 00165 00166 public: 00167 typedef T value_type; //!< Makes `T` available externally. 00168 00169 Matrix () 00170 : nn(0), mm(0) 00171 , v(NULL) 00172 {} 00173 00174 ~Matrix () 00175 { 00176 if( v != NULL ) { 00177 delete[] v[0]; 00178 delete[] v; 00179 } 00180 } 00181 00182 Matrix( Int n, Int m ) 00183 : nn(n), mm(m) 00184 , v( n > 0 ? new T*[n] : NULL ) 00185 { 00186 Int nel = m * n; 00187 if( v ) { 00188 v[0] = nel > 0 ? new T[nel] : NULL; 00189 } 00190 for( Int i = 1; i < n; ++i ) { 00191 v[i] = v[i-1] + m; 00192 } 00193 } 00194 00195 Matrix(Int n, Int m, const T& c ) 00196 : nn(n), mm(m) 00197 , v( n > 0 ? new T*[n] : NULL ) 00198 { 00199 Int nel = m*n; 00200 if( v ) { 00201 v[0] = nel > 0 ? new T[nel] : NULL; 00202 } 00203 for( Int i = 1; i < n; ++i ) { 00204 v[i] = v[i-1] + m; 00205 } 00206 for( Int i = 0; i < n; ++i ) { 00207 for( Int j = 0; j < m; ++j ) { 00208 v[i][j] = c; 00209 } 00210 } 00211 } 00212 00213 Matrix(Int n, Int m, const T* ap ) 00214 : nn(n), mm(m) 00215 , v( n > 0 ? new T*[n] : NULL ) 00216 { 00217 Int nel = m * n; 00218 if( v ) { 00219 v[0] = nel > 0 ? new T[nel] : NULL; 00220 } 00221 for( Int i = 1; i < n; ++i ) { 00222 v[i] = v[i-1] + m; 00223 } 00224 for( Int i = 0; i < n; ++i ) { 00225 for( Int j = 0; j < m; ++j ) { 00226 v[i][j] = *ap++; 00227 } 00228 } 00229 } 00230 00231 Matrix( const Matrix& rhs ) 00232 : nn(rhs.nn), mm(rhs.mm) 00233 , v( nn > 0 ? new T*[nn] : NULL ) 00234 { 00235 Int nel = mm * nn; 00236 if( v ) { 00237 v[0] = nel > 0 ? new T[nel] : NULL; 00238 } 00239 for( Int i = 1; i< nn; ++i ) { 00240 v[i] = v[i-1] + mm; 00241 } 00242 for( Int i = 0; i< nn; ++i ) { 00243 for( Int j = 0; j<mm; ++j ) { 00244 v[i][j] = rhs[i][j]; 00245 } 00246 } 00247 } 00248 00249 /** The matrix assignment. Postcondition: normal assignment via copying has been 00250 * performed; If matrix and rhs were different sizes, matrix has been resized 00251 * to match the size of rhs 00252 */ 00253 Matrix<T>& operator=( const Matrix<T>& rhs ) 00254 { 00255 if( this != &rhs ) { 00256 Int i,j,nel; 00257 if (nn != rhs.nn || mm != rhs.mm) { 00258 if (v != NULL) { 00259 delete[] v[0]; 00260 delete[] v; 00261 } 00262 nn=rhs.nn; 00263 mm=rhs.mm; 00264 v = nn>0 ? new T*[nn] : NULL; 00265 nel = mm*nn; 00266 if( v ) { 00267 v[0] = nel > 0 ? new T[nel] : NULL; 00268 } 00269 for( i = 1; i< nn; ++i ) 00270 v[i] = v[i-1] + mm; 00271 } 00272 for( i = 0; i< nn; ++i ) 00273 for( j = 0; j<mm; ++j ) 00274 v[i][j] = rhs[i][j]; 00275 } 00276 return *this; 00277 } 00278 00279 /** Returns the pointer to a row. 00280 */ 00281 T* operator[]( const Int i ) 00282 { 00283 assertBounds( i >= 0 && i < nn, "Matrix subscript out of bounds" ); 00284 return v[i]; 00285 } 00286 00287 const T* operator[]( const Int i ) const 00288 { 00289 assertBounds( i >= 0 && i < nn, "Matrix subscript out of bounds" ); 00290 return v[i]; 00291 } 00292 00293 Int nrows () const { 00294 return nn; 00295 } 00296 00297 Int ncols () const { 00298 return mm; 00299 } 00300 00301 void resize( Int newn, Int newm ) 00302 { 00303 Int i,nel; 00304 if( newn != nn || newm != mm ) { 00305 if( v != NULL ) { 00306 delete[] v[0]; 00307 delete[] v; 00308 } 00309 nn = newn; 00310 mm = newm; 00311 v = nn>0 ? new T*[nn] : NULL; 00312 nel = mm*nn; 00313 if( v ) { 00314 v[0] = nel>0 ? new T[nel] : NULL; 00315 } 00316 for( i = 1; i < nn; ++i ) { 00317 v[i] = v[i-1] + mm; 00318 } 00319 } 00320 } 00321 00322 00323 void assign( Int newn, Int newm, const T& c ) 00324 { 00325 Int i,j,nel; 00326 if( newn != nn || newm != mm ) { 00327 if( v != NULL ) { 00328 delete[] v[0]; 00329 delete[] v; 00330 } 00331 nn = newn; 00332 mm = newm; 00333 v = nn>0 ? new T*[nn] : NULL; 00334 nel = mm*nn; 00335 if( v ) v[0] = nel>0 ? new T[nel] : NULL; 00336 for( i = 1; i < nn; ++i ) 00337 v[i] = v[i-1] + mm; 00338 } 00339 for( i = 0; i < nn; ++i ) 00340 for( j = 0; j<mm; ++j ) 00341 v[i][j] = c; 00342 } 00343 }; 00344 00345 ///////////////////////////////////////////////////////////////////////////////////////// 00346 // Datatypes needed by banmul and Bandec (compatible with NR3). 00347 00348 typedef const Vector<Real> VecReal_I; 00349 typedef Vector<Real> VecReal, VecReal_O, VecReal_IO; 00350 00351 typedef Vector<Int> VecInt; 00352 00353 typedef const Matrix<Real> MatReal_I; 00354 typedef Matrix<Real> MatReal, MatReal_O, MatReal_IO; 00355 /*@}*/ 00356 /////////////////////////////////////////////////////////////////////////////////////////