#include // defines various exceptions we throw #include // need stringstream for operator<< #include "matrix.h" using namespace std; /***************************************************** * matrix class ****************************************************/ matrix::matrix(int numRows, int numColumns, double value) : _nr(numRows), _nc(numColumns), data(numRows*numColumns, value) {} matrix::matrix(const matrix_expression& m) { *this = m; // rely on operator= implementation } matrix& matrix::operator=(const matrix& other) { if (this != &other) { _nr = other._nr; _nc = other._nc; data = other.data; } return *this; } matrix& matrix::operator=(const matrix_expression& m) { if (this != &m) { _nr = m.numRows(); _nc = m.numColumns(); data.resize(_nr * _nc); for (int r=0; r < _nr; r++) for (int c=0; c < _nc; c++) (*this)(r,c) = m(r,c); } return *this; } // Returns the number of rows int matrix::numRows() const { return _nr; } // Returns the number of columns int matrix::numColumns() const { return _nc; } // Change the apparent size of this matrix. // Overall number of elements must be preserved. void matrix::reshape(int r, int c) { if (r * c != _nr * _nc) throw invalid_argument("To reshape, the number of elements must not change."); _nr = r; _nc = c; } // Provides read-only access via indexing operator double matrix::operator()(int r, int c) const { if (r < 0 || r >= _nr || c < 0 || c >= _nc) throw out_of_range("Invalid indices for matrix"); return data[r + c * _nr]; // column-major } // Provides write-access through indexing operator double& matrix::operator()(int r, int c) { if (r < 0 || r >= _nr || c < 0 || c >= _nc) throw out_of_range("Invalid indices for matrix"); return data[r + c * _nr]; // column-major } /***************************************************** * IO operations ****************************************************/ istream& operator>>(istream& in, matrix& m) { // presumes that there is a blank line to terminate the matrix vector< vector > data; unsigned int numColumns = 0; bool done = false; while (!done) { vector row; string temp; getline(in, temp); stringstream s(temp); double val; while (s >> val) { row.push_back(val); } if (row.size() == 0) done = true; else if (numColumns > 0 and numColumns != row.size()) done = true; else { numColumns = row.size(); data.push_back(row); } } m = matrix(data.size(), numColumns); for (int r=0; r < m.numRows(); r++) for (int c=0; c< m.numColumns(); c++) m(r,c) = data[r][c]; return in; }