Gowdy solver
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
numMethods/matrix.h
Go to the documentation of this file.
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 /////////////////////////////////////////////////////////////////////////////////////////