      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