1 /** 2 * @file Array.h Header file for class Cantera::Array2D 3 */ 4 5 // This file is part of Cantera. See License.txt in the top-level directory or 6 // at https://cantera.org/license.txt for license and copyright information. 7 8 #ifndef CT_ARRAY_H 9 #define CT_ARRAY_H 10 11 #include "ct_defs.h" 12 #include <iostream> 13 14 namespace Cantera 15 { 16 17 //! A class for 2D arrays stored in column-major (Fortran-compatible) form. 18 /*! 19 * In this form, the data entry for an n row, m col matrix is 20 * 21 * index = i + (n-1) * j 22 * 23 * where 24 * 25 * J(i,j) = data_start + index 26 * i = row 27 * j = column 28 */ 29 class Array2D 30 { 31 public: 32 //! Type definition for the iterator class that is can be used by Array2D 33 //! types. 34 /*! 35 * This is just equal to vector_fp::iterator. 36 */ 37 typedef vector_fp::iterator iterator; 38 39 //! Type definition for the const_iterator class that is can be used by 40 //! Array2D types. 41 /*! 42 * This is just equal to vector_fp::const_iterator. 43 */ 44 typedef vector_fp::const_iterator const_iterator; 45 46 /** 47 * Default constructor. Create an empty array. 48 */ 49 Array2D(); 50 51 //! Constructor. 52 /*! 53 * Create an \c m by \c n array, and initialize all elements to \c v. 54 * 55 * @param m Number of rows 56 * @param n Number of columns 57 * @param v Default fill value. The default is 0.0 58 */ 59 Array2D(const size_t m, const size_t n, const double v=0.0); 60 61 //! Constructor. 62 /*! 63 * Create an \c m by \c n array, initialized with the contents of the array 64 * \c values. 65 * 66 * @param m Number of rows 67 * @param n Number of columns 68 * @param values Initial values of the array. Must be of length m*n, and 69 * stored in column-major order. 70 */ 71 Array2D(const size_t m, const size_t n, const double* values); 72 73 Array2D(const Array2D& y); 74 ~Array2D()75 virtual ~Array2D() {} 76 77 Array2D& operator=(const Array2D& y); 78 79 //! Resize the array, and fill the new entries with 'v' 80 /*! 81 * @param n This is the number of rows 82 * @param m This is the number of columns in the new matrix 83 * @param v Default fill value -> defaults to zero. 84 */ 85 void resize(size_t n, size_t m, double v=0.0); 86 87 //! Append a column to the existing matrix using a std vector 88 /*! 89 * This operation will add a column onto the existing matrix. 90 * 91 * @param c This vector is the entries in the column to be added. It must 92 * have a length equal to m_nrows or greater. 93 */ 94 void appendColumn(const vector_fp& c); 95 96 //! Append a column to the existing matrix 97 /*! 98 * This operation will add a column onto the existing matrix. 99 * 100 * @param c This vector of doubles is the entries in the column to be 101 * added. It must have a length equal to m_nrows or greater. 102 */ 103 void appendColumn(const double* const c); 104 105 //! Set the nth row to array rw 106 /*! 107 * @param n Index of the row to be changed 108 * @param rw Vector for the row. Must have a length of m_ncols. 109 */ 110 void setRow(size_t n, const double* const rw); 111 112 //! Get the nth row and return it in a vector 113 /*! 114 * @param n Index of the row to be returned. 115 * @param rw Return Vector for the operation. Must have a length of 116 * m_ncols. 117 */ 118 void getRow(size_t n, double* const rw); 119 120 //! Set the values in column m to those in array col 121 /*! 122 * A(i,m) = col(i) 123 * 124 * @param m Column to set 125 * @param col pointer to a col vector. Vector must have a length of m_nrows. 126 */ 127 void setColumn(size_t m, double* const col); 128 129 //! Get the values in column m 130 /*! 131 * col(i) = A(i,m) 132 * 133 * @param m Column to set 134 * @param col pointer to a col vector that will be returned 135 */ 136 void getColumn(size_t m, double* const col); 137 138 //! Set all of the entries to zero zero()139 void zero() { 140 m_data.assign(m_data.size(), 0.0); 141 } 142 143 //! Allows setting elements using the syntax A(i,j) = x. 144 /*! 145 * @param i row index 146 * @param j column index. 147 * @returns a reference to A(i,j) which may be assigned. 148 */ operator()149 doublereal& operator()(size_t i, size_t j) { 150 return value(i,j); 151 } 152 153 //! Allows retrieving elements using the syntax x = A(i,j). 154 /*! 155 * @param i Index for the row to be retrieved 156 * @param j Index for the column to be retrieved. 157 * @returns the value of the matrix entry 158 */ operator()159 doublereal operator()(size_t i, size_t j) const { 160 return value(i,j); 161 } 162 163 //! Returns a changeable reference to position in the matrix 164 /*! 165 * Returns a reference to the matrix's (i,j) element. This may be used as an 166 * L value. 167 * 168 * @param i The row index 169 * @param j The column index 170 * @returns a changeable reference to the matrix entry 171 */ value(size_t i,size_t j)172 doublereal& value(size_t i, size_t j) { 173 return m_data[m_nrows*j + i]; 174 } 175 176 //! Returns the value of a single matrix entry 177 /*! 178 * Returns the value of the matrix position (i,j) element. 179 * 180 * @param i The row index 181 * @param j The column index 182 */ value(size_t i,size_t j)183 doublereal value(size_t i, size_t j) const { 184 return m_data[m_nrows*j + i]; 185 } 186 187 /// Number of rows nRows()188 size_t nRows() const { 189 return m_nrows; 190 } 191 192 /// Number of columns nColumns()193 size_t nColumns() const { 194 return m_ncols; 195 } 196 197 /// Return an iterator pointing to the first element begin()198 iterator begin() { 199 return m_data.begin(); 200 } 201 202 /// Return an iterator pointing past the last element end()203 iterator end() { 204 return m_data.end(); 205 } 206 207 /// Return a const iterator pointing to the first element begin()208 const_iterator begin() const { 209 return m_data.begin(); 210 } 211 212 /// Return a const iterator pointing to past the last element end()213 const_iterator end() const { 214 return m_data.end(); 215 } 216 217 /// Return a reference to the data vector data()218 vector_fp& data() { 219 return m_data; 220 } 221 222 /// Return a const reference to the data vector data()223 const vector_fp& data() const { 224 return m_data; 225 } 226 227 //! Return a pointer to the top of column j, columns are contiguous 228 //! in memory 229 /*! 230 * @param j Value of the column 231 * @returns a pointer to the top of the column 232 */ ptrColumn(size_t j)233 doublereal* ptrColumn(size_t j) { 234 return &m_data[m_nrows*j]; 235 } 236 237 //! Return a const pointer to the top of column j, columns are contiguous 238 //! in memory 239 /*! 240 * @param j Value of the column 241 * @returns a const pointer to the top of the column 242 */ ptrColumn(size_t j)243 const doublereal* ptrColumn(size_t j) const { 244 return &m_data[m_nrows*j]; 245 } 246 247 protected: 248 //! Data stored in a single array 249 vector_fp m_data; 250 251 //! Number of rows 252 size_t m_nrows; 253 254 //! Number of columns 255 size_t m_ncols; 256 }; 257 258 //! Output the current contents of the Array2D object 259 /*! 260 * Example of usage: 261 * s << m << endl; 262 * 263 * @param s Reference to the ostream to write to 264 * @param m Object of type Array2D that you are querying 265 * @returns a reference to the ostream. 266 */ 267 std::ostream& operator<<(std::ostream& s, const Array2D& m); 268 269 //! Overload the times equals operator for multiplication of a matrix and a 270 //! scalar. 271 /*! 272 * Scaled every element of the matrix by the scalar input 273 * 274 * @param m Matrix 275 * @param a scalar 276 */ 277 void operator*=(Array2D& m, double a); 278 279 } 280 281 #endif 282