1  #ifndef MATRIX4_H
  2  #define MATRIX4_H
  3  
  4  #include <iostream>
  5  #include <stdexcept>
  6  
  7  namespace BigCPlusPlus_Matrix {
  8  
  9  /**
 10     This class describes a matrix with arbitrary rows and columns
 11  */
 12  class Matrix
 13  {
 14  private:
 15     /**
 16        Forward reference for classes Row and ConstRow
 17     */
 18     class Row;
 19     class ConstRow;
 20  
 21  public:
 22  
 23     /**
 24        Constructs a matrix filled with zero elements.
 25     */
 26     Matrix(int r, int c);
 27  
 28     /**
 29        The big three
 30     */
 31     Matrix(const Matrix& other);
 32     Matrix& operator=(const Matrix& other);
 33     ~Matrix();
 34  
 35     /**
 36        Gets the number of rows of this matrix.
 37        @return the number of rows
 38     */
 39     int get_rows() const;
 40     
 41     /**
 42        Gets the number of columns of this matrix.
 43        @return the number of columns
 44     */
 45     int get_columns() const;
 46     
 47     /**
 48        Accesses a matrix element.
 49        @param i the row index
 50        @param j the column index
 51        @return a reference to the element with the given indexes
 52     */
 53     double& operator()(int i, int j);
 54  
 55     /**
 56        Accesses a matrix element.
 57        @param i the row index
 58        @param j the column index
 59        @return the element with the given indexes
 60     */
 61     double operator()(int i, int j) const;
 62  
 63     /**
 64        Accesses a matrix row.
 65        @param i the row index
 66        @return the row with the given index
 67     */
 68     Row operator[](int i);
 69  
 70     /**
 71        Accesses a matrix row.
 72        @param i the row index
 73        @return the row with the given index
 74     */
 75     ConstRow operator[](int i) const;
 76  
 77     /**
 78        Computes the matrix sum
 79        @param right another matrix
 80        @return the update matrix
 81     */
 82     Matrix& operator+=(const Matrix& right);
 83  
 84     /**
 85        Forward reference for classes MismatchException and IndexException
 86     */
 87     class MismatchException;
 88     class IndexException;
 89  
 90  private:
 91     /**
 92        Copies another matrix into this matrix.
 93        @param other the other matrix
 94     */
 95     void copy(const Matrix& other);
 96  
 97     /**
 98        Frees the memory for this matrix.
 99     */
100     void free();
101  
102     int rows;
103     int columns;
104     double* elements;
105  
106  };
107  
108  /**
109     This class describes a row in a matrix.
110  */
111  class Matrix::Row
112  {
113  public:
114     /**
115        Remembers a row for a given matrix
116        @param m a pointer to the matrix
117        @param s row index
118     */
119     Row(Matrix* m, int s);
120  
121     /**
122        Accesses a row element.
123        @param j the column index
124        @return a reference to the element with the given index
125     */
126     double& operator[](int j);
127  
128  private:
129     Matrix* mat;
130     int i;
131  };
132  
133  /**
134     This class describes a row in a constant matrix.
135  */
136  class Matrix::ConstRow
137  {
138  public:
139     /**
140        Constructs a row with a given start and size.
141        @param m a pointer to the matrix
142        @param s row index
143     */
144     ConstRow(const Matrix* m, int s);
145  
146     /**
147        Accesses a row element.
148        @param j the column index
149        @return a reference to the element with the given index
150     */
151     double operator[](int j) const;
152  
153  private:
154     const Matrix* mat;
155     int i;
156  };
157  
158  /**
159     Matrix exception class: Indexing error
160  */
161  class Matrix::IndexException : public std::out_of_range 
162  {
163  public:
164     IndexException(int i);
165  private:
166     std::string format_message(int i);
167  };
168  
169  /**
170     Matrix exception class: Mismatched Argument error
171  */
172  class Matrix::MismatchException : public std::invalid_argument 
173  {
174  public:   
175     MismatchException();
176  };
177
178  /**
179     Computes the matrix sum.
180     @param right another matrix
181     @return the product of this matrix and the other
182  */
183     Matrix operator+(const Matrix& left, const Matrix& right);
184  
185  /**
186     Computes the matrix product.
187     @param right another matrix
188     @return the product of this matrix and the other
189  */
190     Matrix operator*(const Matrix& left, const Matrix& right);
191  
192  /**
193     Computes the scalar product of a scalar value and a matrix.
194     @param left a scalar value
195     @param right a matrix
196     @return the sum of the given value and the given matrix
197  */
198  Matrix operator*(double left, const Matrix& right);
199  
200  /**
201     Computes the scalar product of a matrix and a scalar value.
202     @param right a scalar value
203     @return the sum of this matrix and the given value
204  */
205  Matrix operator*(const Matrix& left, double right);
206  
207  /**
208     Prints a matrix to an output stream.
209     @param left an output stream
210     @param right a matrix
211     @return the given output stream
212  */
213  std::ostream& operator<<(std::ostream& left, const Matrix& right);
214  
215  inline Matrix::IndexException::IndexException(int idx)
216     : out_of_range(format_message(idx)) {}
217  
218  inline Matrix::MismatchException::MismatchException() 
219     : invalid_argument("Matrix arguments have incompatible sizes")  {}
220
221  inline Matrix::Matrix(const Matrix& other) 
222  { 
223     copy(other); 
224  }
225  
226  inline Matrix::~Matrix() 
227  { 
228     free(); 
229  }
230  
231  inline int Matrix::get_rows() const 
232  { 
233     return rows; 
234  }
235  
236  inline int Matrix::get_columns() const 
237  { 
238     return columns; 
239  }
240  
241  inline void Matrix::free()
242  {
243     delete[] elements;
244  }
245  
246  inline Matrix::Row Matrix::operator[](int i)
247  {
248     return Matrix::Row(this, i);
249  }   
250  
251  inline Matrix::ConstRow Matrix::operator[](int i) const
252  {
253     return Matrix::ConstRow(this, i);
254  }   
255     
256  inline Matrix::Row::Row(Matrix* m, int s) : mat(m), i(s) { }
257  
258  inline double& Matrix::Row::operator[](int j)
259  {
260     return (*mat)(i,j);
261  }   
262  
263  inline Matrix::ConstRow::ConstRow(const Matrix* m, int s)
264     : mat(m), i(s) { }
265
266  inline double Matrix::ConstRow::operator[](int j) const
267  {
268     return (*mat)(i, j);
269  }   
270
271  inline Matrix operator*(double left, const Matrix& right)
272  {
273     return right * left;
274  }
275  }  // namespace BigCPlusPlus_Matrix
276  #endif