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