Array.h

Go to the documentation of this file.
00001 /**
00002  *  @file Array.h
00003  *  Header file for class Array2D
00004  */
00005 
00006 /*
00007  *  $Author: hkmoffa $
00008  *  $Revision: 368 $
00009  *  $Date: 2010-01-03 19:46:26 -0500 (Sun, 03 Jan 2010) $
00010  */
00011 
00012 // Copyright 2001  California Institute of Technology
00013 
00014 
00015 #ifndef CT_ARRAY_H
00016 #define CT_ARRAY_H
00017 
00018 #include "ct_defs.h"
00019 #include "ctexceptions.h"
00020 #include "utilities.h"
00021 
00022 namespace Cantera { 
00023 
00024 
00025  
00026   //!  A class for 2D arrays stored in column-major
00027   //!  (Fortran-compatible) form.
00028   /*!
00029    *  In this form, the data entry for an n row, m col 
00030    *  matrix is 
00031    *       index = i + (n-1) * j
00032    *  where
00033    *     J(i,j) = data_start + index 
00034    *         i = row
00035    *         j = column
00036    */
00037   class Array2D {
00038 
00039   public:
00040 
00041     //! Type definition for the iterator class that is
00042     //! can be used by Array2D types.
00043     /*!
00044      *  this is just equal to vector_fp iterator.
00045      */
00046     typedef vector_fp::iterator iterator;
00047 
00048 
00049     //! Type definition for the const_iterator class that is
00050     //! can be used by Array2D types.
00051     /*!
00052      *  this is just equal to vector_fp const_iterator.
00053      */
00054     typedef vector_fp::const_iterator const_iterator;
00055 
00056     /**
00057      * Default constructor. Create an empty array.
00058      */
00059     Array2D() : m_nrows(0), m_ncols(0) { 
00060       m_data.clear();
00061     }
00062 
00063     //!  Constructor.
00064     /*!
00065      *    Create an \c m by \c n array, and initialize
00066      *    all elements to \c v.
00067      *
00068      *  @param m   Number of rows
00069      *  @param n   Number of columns
00070      *  @param v   Default fill value. The default is 0.0
00071      */
00072     Array2D(const int m, const int n, const doublereal v = 0.0) 
00073       : m_nrows(m), m_ncols(n) {
00074       m_data.resize(n*m);
00075       std::fill(m_data.begin(), m_data.end(), v);
00076     }
00077 
00078     //!  Copy constructor
00079     /*!
00080      *   @param y  Array2D to make the copy from
00081      */
00082     Array2D(const Array2D& y) {
00083       m_nrows = y.m_nrows;
00084       m_ncols = y.m_ncols;
00085       m_data.resize(m_nrows*m_ncols);
00086       m_data = y.m_data;
00087     }
00088 
00089     //! assignment operator
00090     /*!
00091      *  @param y Array2D to get the values from
00092      */
00093     Array2D& operator=(const Array2D& y) {
00094       if (&y == this) return *this;
00095       m_nrows = y.m_nrows;
00096       m_ncols = y.m_ncols;
00097       m_data.resize(m_nrows*m_ncols);
00098       m_data = y.m_data;
00099       return *this;
00100     }
00101 
00102     //! Resize the array, and fill the new entries with 'v'
00103     /*!
00104      * @param n  This is the number of rows
00105      * @param m  This is the number of columns in the new matrix
00106      * @param v  Default fill value -> defaults to zero.
00107      */
00108     void resize(int n, int m, doublereal v = 0.0) {
00109       m_nrows = n;
00110       m_ncols = m;
00111       m_data.resize(n*m, v);
00112     }
00113 
00114     //! Append a column to the existing matrix using a std vector
00115     /*!
00116      *  This operation will add a column onto the existing matrix.
00117      *  
00118      *  @param c  This vector<doublereal> is the entries in the
00119      *            column to be added. It must have a length
00120      *            equal to m_nrows or greater.
00121      */
00122     void appendColumn(const vector_fp& c) {
00123       m_ncols++;
00124       m_data.resize(m_nrows*m_ncols);
00125       int m;
00126       for (m = 0;  m < m_nrows; m++) value(m_ncols, m) = c[m];
00127     }
00128 
00129     //! Append a column to the existing matrix
00130     /*!
00131      *  This operation will add a column onto the existing matrix.
00132      *  
00133      *  @param c  This vector of doubles is the entries in the
00134      *            column to be added. It must have a length
00135      *            equal to m_nrows or greater.
00136      */
00137     void appendColumn(const doublereal* const c) {
00138       m_ncols++;
00139       m_data.resize(m_nrows*m_ncols);
00140       int m;
00141       for (m = 0;  m < m_nrows; m++) value(m_ncols, m) = c[m];
00142     }
00143 
00144     //! Set the nth row to array rw
00145     /*!
00146      *  @param  n  Index of the row to be changed
00147      *  @param  rw  Vector for the row. Must have a length of m_ncols.
00148      */
00149     void setRow(int n, const doublereal* const rw) {
00150       for (int j = 0; j < m_ncols; j++) {
00151         m_data[m_nrows*j + n] = rw[j];
00152       }
00153     }
00154 
00155     //! Get the nth row and return it in a vector
00156     /*!
00157      *   @param n    Index of the row to be returned.
00158      *   @param rw   Return Vector  for the operation. 
00159      *               Must have a length of m_ncols.
00160      */
00161     void getRow(int n, doublereal* const rw) {
00162       for (int j = 0; j < m_ncols; j++) {
00163         rw[j] = m_data[m_nrows*j + n];
00164       }
00165     }
00166 
00167     //! Set the values in column m to those in array col
00168     /*!
00169      *  A(i,m) = col(i)
00170      *
00171      *  @param m    Column to set
00172      *  @param col  pointer to a col vector. Vector 
00173      *              must have a length of m_nrows.
00174      */
00175     void setColumn(int m, doublereal* const col) {
00176       for (int i = 0; i < m_nrows; i++) {
00177         m_data[m_nrows*m + i] = col[i];
00178       }
00179     }
00180 
00181     //! Get the values in column m 
00182     /*!
00183      * col(i) =  A(i,m) 
00184      *
00185      *  @param m    Column to set
00186      *  @param col  pointer to a col vector that will be returned
00187      */
00188     void getColumn(int m, doublereal* const col) {
00189       for (int i = 0; i < m_nrows; i++) {
00190         col[i] = m_data[m_nrows*m + i];
00191       }
00192     }
00193                 
00194     /**
00195      * Destructor. Does nothing, since no memory allocated on the
00196      * heap.
00197      */
00198     virtual ~Array2D(){}
00199     
00200     //! Evaluate z = a*x + y.
00201     /*!
00202      *  This function evaluates the AXPY operation, and stores
00203      *  the result in the object's Array2D object.
00204      *  It's assumed that all 3 objects have the same dimensions,
00205      *  but no error checking is done. 
00206      *
00207      *  @param a  scalar to multiply x with
00208      *  @param x  First Array2D object to be used
00209      *  @param y  Second Array2D object to be used 
00210      *
00211      */
00212     void axpy(doublereal a, const Array2D& x, const Array2D& y) {
00213       iterator b = begin();
00214       const_iterator xb = x.begin();
00215       const_iterator yb = y.begin();
00216       for (; b != end(); ++b, ++xb, ++yb)  *b = a*(*xb) + *yb;
00217     }
00218 
00219     
00220     //! Allows setting elements using the syntax A(i,j) = x.
00221     /*!
00222      *  @param  i            row index
00223      *  @param  j            column index.
00224      *
00225      *  @return Returns a reference to A(i,j) which may be assigned.
00226      */ 
00227     doublereal& operator()( int i, int j) { return value(i,j); }
00228 
00229     
00230     //! Allows retrieving elements using the syntax x = A(i,j).
00231     /*!
00232      *   @param i   Index for the row to be retrieved
00233      *   @param j   Index for the column to be retrieved.
00234      *
00235      *   @return    Returns the value of the matrix entry
00236      */ 
00237     doublereal operator() (int i, int j) const {
00238       return value(i,j);
00239     }
00240 
00241     //! Returns a changeable reference to position in the matrix
00242     /*!
00243      * This is a key entry. Returns a reference to the matrixes (i,j)
00244      * element. This may be used as an L value.
00245      *
00246      * @param i   The row index
00247      * @param j   The column index
00248      *
00249      * @return  Returns a changeable reference to the matrix entry
00250      */
00251     doublereal& value(int i, int j) {
00252       return m_data[m_nrows*j + i];
00253     }
00254 
00255     //! Returns the value of a single matrix entry
00256     /*!
00257      * This is a key entry. Returns the value of the  matrix position (i,j)
00258      * element. 
00259      *
00260      * @param i   The row index
00261      * @param j   The column index
00262      */
00263     doublereal value(int i, int j) const {
00264       return m_data[m_nrows*j + i];
00265     }
00266 
00267     /// Number of rows
00268     size_t nRows() const { return m_nrows; }
00269 
00270     /// Number of columns
00271     size_t nColumns() const { return m_ncols; }
00272 
00273     /// Return an iterator pointing to the first element
00274     iterator begin() { return m_data.begin(); }
00275 
00276     /// Return an iterator pointing past the last element
00277     iterator end() { return m_data.end(); }
00278 
00279     /// Return a const iterator pointing to the first element
00280     const_iterator begin() const { return m_data.begin(); }
00281 
00282     /// Return a const iterator pointing to past the last element
00283     const_iterator end() const { return m_data.end(); }
00284 
00285     /// Return a reference to the data vector
00286     vector_fp& data() { return m_data; }
00287 
00288     /// Return a const reference to the data vector
00289     const vector_fp& data() const { return m_data; }
00290 
00291     //! Return a pointer to the top of column j, columns are contiguous
00292     //! in memory
00293     /*!
00294      *  @param j   Value of the column
00295      *
00296      *  @return  Returns a pointer to the top of the column
00297      */
00298     doublereal * ptrColumn(int j) { return &(m_data[m_nrows*j]); }
00299 
00300     //! Return a const pointer to the top of column j, columns are contiguous
00301     //! in memory
00302     /*!
00303      *  @param j   Value of the column
00304      *
00305      *  @return  Returns a const pointer to the top of the column
00306      */
00307     const doublereal * ptrColumn(int j) const { 
00308       return &(m_data[m_nrows*j]); 
00309     }
00310 
00311   protected:
00312 
00313     //! Data storred in a single array
00314     vector_fp m_data;
00315 
00316     //! Number of rows
00317     int m_nrows;
00318 
00319     //! Number of columns
00320     int m_ncols;
00321   };
00322 
00323   //! Output the current contents of the Array2D object
00324   /*!
00325    *  Example of usage:
00326    *        s << m << endl;
00327    *
00328    *  @param s   Reference to the ostream to write to
00329    *  @param m   Object of type Array2D that you are querying
00330    *
00331    *  @return    Returns a reference to the ostream.
00332    */
00333   inline std::ostream& operator<<(std::ostream& s, const Array2D& m) {
00334     int nr = static_cast<int>(m.nRows());
00335     int nc = static_cast<int>(m.nColumns());
00336     int i,j;
00337     for (i = 0; i < nr; i++) {
00338       for (j = 0; j < nc; j++) {
00339         s << m(i,j) << ", ";
00340       }
00341       s << std::endl;
00342     }
00343     return s;
00344   }
00345 
00346   //! Overload the times equals operator for multiplication
00347   //! of a matrix and a scalar.
00348   /*!
00349    *  Scaled every element of the matrix by the scalar input
00350    *
00351    *   @param m   Matrix
00352    *   @param a   scalar
00353    */
00354   inline void operator*=(Array2D& m, doublereal a) {
00355     scale(m.begin(), m.end(), m.begin(), a);
00356   }
00357 
00358   //! Overload the plus equals operator for addition
00359   //! of one matrix with another
00360   /*!
00361    *   Adds each element of the second matrix into the first
00362    *   matrix
00363    *
00364    *   @param x   First matrix
00365    *   @param y   Second matrix, which is a const
00366    */
00367   inline void operator+=(Array2D& x, const Array2D& y) {
00368     sum_each(x.begin(), x.end(), y.begin());
00369   }
00370   
00371 }
00372 
00373 #endif
Generated by  doxygen 1.6.3