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