Complete the implementations of the member functions of the Matrix
class and write client code that thoroughly tests the class.
[ fromfile: useroperators.xml id: None ]
Example 19.20. solution/matrix/matrix.h
[ . . . . ] class Matrix { public: Matrix(int rows, int cols); // allocates and zeros all cells Matrix(const Matrix& mat); // copy constructor - clones mat ~Matrix(); double& operator()(int i, int j); double operator()(int i, int j) const; Matrix& operator=(const Matrix& mat); // deletes host content and clones mat Matrix operator+(const Matrix& mat) const; // matrix addition Matrix operator*(const Matrix& mat) const; // matrix multiplication bool operator==(const Matrix& mat) const; int getRows() const; int getCols() const; QString toString() const; private: int m_Rows, m_Cols; double **m_NumArray; void sweepClean(); // Refactoring utility void clone(const Matrix& mat); // Refactoring utility double rcprod(int row, const Matrix& mat, int col) const; // host-row dot mat-col }; [ . . . . ]
<include src="solution/matrix/matrix.h" href="solution/matrix/matrix.h" role="solution" mode="cpp"/>
Example 19.21. solution/matrix/matrix.cpp
[ . . . . ] // Allocates memory for a rows x cols array of double and // initializes each cell to zero. Matrix:: Matrix(int rows, int cols):m_Rows(rows), m_Cols(cols) { m_NumArray = new double*[rows]; for (int r = 0; r < rows; ++r) { m_NumArray[r] = new double[cols]; for(int c = 0; c < cols; ++c) m_NumArray[r][c] = 0; } } // Refactoring utility function void Matrix::sweepClean() { for (int r = 0; r < m_Rows; ++r) delete[] m_NumArray[r] ; delete[] m_NumArray; } Matrix::~Matrix() { sweepClean(); } // Refactoring utility function void Matrix::clone(const Matrix& mat) { m_NumArray = new double*[mat.m_Rows]; for (int r = 0; r < mat.m_Rows; ++r) { m_NumArray[r] = new double[mat.m_Cols]; for(int c = 0; c < mat.m_Cols; ++c) m_NumArray[r][c] = mat(r,c); } } // Clones mat Matrix::Matrix(const Matrix& mat) { clone(mat); } double& Matrix::operator()(int r, int c) { assert (r >= 0 && r < m_Rows && c >= 0 && c < m_Cols); return m_NumArray[r][c]; } double Matrix::operator()(int r, int c) const { assert (r >= 0 && r < m_Rows && c >= 0 && c < m_Cols); return m_NumArray[r][c]; } // Deletes host content and then clones mat Matrix& Matrix::operator=(const Matrix& mat) { sweepClean(); clone(mat); return *this; } // matrix addition - assumes size compatibility Matrix Matrix::operator+(const Matrix& mat) const { assert(m_Rows == mat.m_Rows && m_Cols == mat.m_Cols); Matrix mat2(*this); for (int r = 0; r < m_Rows; ++r) for(int c = 0; c < m_Cols; ++c) mat2(r,c) += mat(r,c); return mat2; } // Dot product of host row times other Matrix col. // Assumes both have same size. double Matrix::rcprod(int row, const Matrix& mat, int col) const { double res(0); for (int i = 0; i < m_Cols; ++i) res += m_NumArray[row][i] * mat(i, col); return res; } // matrix multiplication - assumes size compatibility Matrix Matrix::operator*(const Matrix& mat) const { assert(m_Cols == mat.m_Rows); Matrix mat2(m_Rows, mat.m_Cols); for (int r = 0; r < m_Rows; ++r) for(int c = 0; c < mat.m_Cols; ++c) mat2(r,c) = rcprod(r, mat, c); return mat2; } bool Matrix::operator==(const Matrix& mat) const { if(m_Rows != mat.m_Rows || m_Cols != mat.m_Cols) return false; for (int r = 0; r < m_Rows; ++r) for(int c = 0; c < m_Cols; ++c) if(m_NumArray[r][c] != mat(r,c)) return false; return true; } int Matrix::getRows() const { return m_Rows; } int Matrix::getCols() const { return m_Cols; } QString Matrix::toString() const { QString res; int pos; for (int r = 0; r < m_Rows; ++r) { for(int c = 0; c < m_Cols; ++c) res += QString("%1\t").arg(m_NumArray[r][c]); pos = res.lastIndexOf('\t'); res.replace(pos, 1, '\n'); } return res; }
<include src="solution/matrix/matrix.cpp" href="solution/matrix/matrix.cpp" role="solution" mode="cpp"/>
Example 19.22. solution/matrix/matrix-test.cpp
#include <QTextStream> #include "matrix.h" QTextStream cout(stdout); void fill(Matrix& m, double d) { for(int r = 0; r < m.getRows(); ++r) for(int c = 0; c < m.getCols(); ++c) m(r,c) = d; } /* This client code does not test the Matrix class thoroughly. It gives some hints for making a more thorough test. */ int main() { Matrix m1(3,4), m2(4,3); fill(m1, 2); fill(m2, 3); Matrix m3(m1 * m2); cout << m3.toString() << endl; }
<include src="solution/matrix/matrix-test.cpp" href="solution/matrix/matrix-test.cpp" role="solution" mode="cpp"/>
Generated: 2012-03-02 | © 2012 Alan Ezust and Paul Ezust. |