// *** output commands inserted in the definition of * #ifndef Matrix_ #define Matrix_ #include "xcept.h" template class Matrix { friend ostream& operator<<(ostream&, const Matrix&); // friend istream& operator>>(istream&, const Matrix&); friend istream& operator>>(istream&, Matrix&); // *** hw 4; another way at end public: Matrix(int r = 0, int c = 0); Matrix(const Matrix& m); // copy constructor ~Matrix() {delete [] element;} int Rows() const {return rows;} int Columns() const {return cols;} T& operator()(int i, int j) const; Matrix& operator=(const Matrix& m); Matrix operator+() const; // unary + Matrix operator+(const Matrix& m) const; Matrix operator-() const; // unary minus Matrix operator-(const Matrix& m) const; Matrix operator*(const Matrix& m) const; Matrix& operator+=(const T& x); private: int rows, cols; // matrix dimensions T *element; // element array }; template Matrix::Matrix(int r, int c) {// Matrix constructor. // validate r and c if (r < 0 || c < 0) throw BadInitializers(); if ((!r || !c) && (r || c)) throw BadInitializers(); // create the matrix rows = r; cols = c; element = new T [r * c]; } template Matrix::Matrix(const Matrix& m) {// Copy constructor for matrices. // create matrix rows = m.rows; cols = m.cols; element = new T [rows * cols]; // copy each element of m for (int i = 0; i < rows * cols; i++) element[i] = m.element[i]; } template Matrix& Matrix::operator=(const Matrix& m) {// Assignment. (*this) = m. if (this != &m) {// do not copy to self delete [] element; rows = m.rows; cols = m.cols; element = new T [rows * cols]; // copy each element for (int i = 0; i < rows * cols; i++) element[i] = m.element[i]; } return *this; } template T& Matrix::operator()(int i, int j) const {// Return a reference to element (i,j). if (i < 1 || i > rows || j < 1 || j > cols) throw OutOfBounds(); return element[(i - 1) * cols + j - 1]; } template Matrix Matrix:: operator+(const Matrix& m) const {// Return w = (*this) + m. if (rows != m.rows || cols != m.cols) throw SizeMismatch(); // create result matrix w Matrix w(rows, cols); for (int i = 0; i < rows * cols; i++) w.element[i] = element[i] + m.element[i]; return w; } template Matrix Matrix:: operator-(const Matrix& m) const {// Return (*this) - m. if (rows != m.rows || cols != m.cols) throw SizeMismatch(); // create result matrix w Matrix w(rows, cols); for (int i = 0; i < rows * cols; i++) w.element[i] = element[i] - m.element[i]; return w; } template Matrix Matrix::operator-() const {// Return w = -(*this). // create result matrix w Matrix w(rows, cols); for (int i = 0; i < rows * cols; i++) w.element[i] = -element[i]; return w; } template Matrix Matrix:: operator*(const Matrix& m) const {// Matrix multiply. Return w = (*this) * m. if (cols != m.rows) throw SizeMismatch(); Matrix w(rows, m.cols); // result matrix // define cursors for *this, m, and w // and initialize to location of (1,1) int ct = 0, cm = 0, cw = 0; // ************** output into a file // File output just like standard i/o: ofstream out("hw4.out"); // write assert(out); out << "A = " << endl; out << *this << endl; out << "B = " << endl; out << m << endl; // compute w(i,j) for all i and j for (int i = 1; i <= rows; i++) { // compute row i of result for (int j = 1; j <= m.cols; j++) { out << "ct = " << ct << " cm = " << cm << endl; // compute first term of w(i,j) T sum = element[ct] * m.element[cm]; // add in remaining terms for (int k = 2; k <= cols; k++) { ct++; // next term in row i of *this cm += m.cols; // next in column j of m sum += element[ct] * m.element[cm]; } out << "ct = " << ct << " cm = " << cm << " sum = " << sum << endl; out << endl; w.element[cw++] = sum; // save w(i,j) // reset to start of row and next column ct -= cols - 1; cm = j; } // reset to start of next row and first column ct += cols; cm = 0; } out << "W = A * B = " << endl; out << w << endl; return w; } template Matrix& Matrix::operator+=(const T& x) {// Increment all elements of *this by x. for (int i = 0; i < rows * cols; i++) element[i] += x; return *this; } template ostream& operator<<(ostream& out, const Matrix& x) {// Put matrix x into the stream out. // One row per line. int k = 0; // index into element array for (int i = 0; i < x.rows; i++) { // do row i for (int j = 0; j < x.cols; j++) out << x.element[k++] << " "; // row i finished out << endl;} return out; } template istream& operator>>(istream& in, Matrix& x) // memory for x allocated {// put matrix into stream in // through main() cout << "enter the next matrix rowwise" << endl; cout << "size of matrix is " << x.rows << " x " << x.cols << endl; for (int k=0; k > x.element[k]; return in; } #endif /******************************* another way to overload/implement operator >> void Input(istream& in); // declared within the class LowerMatrix template void Matrix::Input(istream& in) { cout<<"Enter the number of rows: "; in >> rows; cout<<"Enter the number of columns: "; in >> cols; if (rows <= 0 || cols <= 0) throw BadInitializers(); element = new T [rows * cols]; cout<<"Enter the elements one row at a time."<> element[i]; } template istream& operator>>(istream& in, Matrix& x) { x.Input(in); return in; } *****************************************/