/* * Naam : R. Wacanno * UvAnetID : 11741163 * Studie : BSc Informatica * * Matrix.h * -Defines a Matrix-object containing unspecified types. */ #include #include #include #include #include #include #include template class Matrix { public: Matrix(); Matrix(std::string filename); Matrix(unsigned rows, unsigned cols); template Matrix(const Matrix& m); Matrix& operator+=(const Matrix& m); Matrix operator+(const Matrix& n); Matrix& operator-=(const Matrix& m); Matrix operator-(const Matrix& m); Matrix& operator*=(const Matrix& m); Matrix operator*(const Matrix& m); Matrix& operator=(const Matrix& m); template friend std::ostream& operator<<(std::ostream& os,const Matrix& m); template friend std::istream& operator>>(std::istream& is, Matrix& m); Matrix& transpose(); bool load(std::string filename); bool save(std::string filename); private: std::vector< std::vector > values; int last_prec; }; /* Constructs an empty 0X0 matrix */ template Matrix::Matrix(){} /* Constructs a mitrix who's contents and dimensions * are read from a given file */ template Matrix::Matrix(std::string filename) { this->load(filename); } /* Constructs an emtry rowsXcols matrix */ template Matrix::Matrix(unsigned rows, unsigned cols) { for (unsigned i = 0; i < rows; i++) { std::vector r(cols); values.push_back(r); } } /* Constructs a matrix of type T with the contents and dimensions * of a matrix with type U*/ template template Matrix::Matrix(const Matrix& m) { std::stringstream ss; ss << m; ss >> *this; } /* Adds matrix B to matrix A */ template Matrix& Matrix::operator+=(const Matrix& m) { if ((values.size() != values.size()) || (values[0].size() != m.values[0].size())) { throw std::logic_error("Matrices are incompatible"); } for (int i = 0; i < values.size(); i++) { for (int j = 0; j < values[0].size(); j++) { values[i][j] += m.values[i][j]; } } return *this; } /* Adds matrix A and B and returns the result as a new matrix */ template Matrix Matrix::operator+(const Matrix& m) { Matrix mCopy = *this; mCopy += m; return mCopy; } /* subtracts matrix B from matrix A */ template Matrix& Matrix::operator-=(const Matrix& m) { if ((values.size() != values.size()) || (values[0].size() != m.values[0].size())) { throw std::logic_error("Matrices are incompatible"); } for (int i = 0; i < values.size(); i++) { for (int j = 0; j < values[0].size(); j++) { values[i][j] -= m.values[i][j]; } } return *this; } /* Subtracts matrix A and B and returns the result as a new matrix */ template Matrix Matrix::operator-(const Matrix& m) { Matrix mCopy = *this; mCopy -= m; return mCopy; } /* Multiplies matrix B with matrix A */ template Matrix& Matrix::operator*=(const Matrix& m) { if (values[0].size() != m.values.size()) { throw std::logic_error("Matrices are incompatible"); } std::vector< std::vector > new_val(values.size()); for (int i = 0; i < new_val.size(); i++) { for (int j = 0; j < m.values[0].size(); j++) { T sum{}; for (int k = 0; k < values[0].size(); k++) { sum += (values[i][k] * m.values[k][j]); } new_val[i].push_back(sum); } } values = new_val; return *this; } /* Multiplies matrix A and B and returns the result as a new matrix */ template Matrix Matrix::operator*(const Matrix& m) { Matrix mCopy = *this; mCopy *= m; return mCopy; } /* Assigns the value of matrix B to matrix A */ template Matrix& Matrix::operator=(const Matrix& m) { std::stringstream ss; ss << m; ss >> *this; return *this; } /* Passes a matrix into a stream */ template std::ostream& operator<<(std::ostream& os,const Matrix& m) { for (int i = 0; i < m.values.size(); i++) { for (int j = 0; j < m.values[i].size(); j++) { os << m.values[i][j]; if (j < (m.values[0].size() - 1)) { os << " "; } } if (i < (m.values.size() - 1)) { os << std::endl; } } return os; } /* Reads a matrix from a stream */ template std::istream& operator>>(std::istream& is, Matrix& m) { std::string line; std::vector< std::vector > new_val; while (std::getline(is, line)) { std::stringstream ss(line); std::vector row; std::string val_str; T val; while (std::getline(ss, val_str, ' ')) { std::stringstream ss_val(val_str); ss_val >> val; row.push_back(val); } new_val.push_back(row); } m.values = new_val; return is; } /* Transposes a given matrix */ template Matrix& Matrix::transpose() { Matrix new_m(values[0].size(), values.size()); for (int i = 0; i < new_m.values.size(); i++) { for (int j = 0; j < new_m.values[0].size(); j++) { new_m.values[i][j] = values[j][i]; } } values = new_m.values; return *this; } /* Returns a transposed copy of a given matrix */ template Matrix transpose(Matrix& m) { Matrix new_m; new_m = m; new_m.transpose(); return new_m; } /* Loads a matrix from a given file */ template bool Matrix::load(std::string filename) { std::ifstream file(filename); if (file.is_open()) { file >> *this; file.close(); return true; } else { return false; } } /* Saves a matrix into a given file */ template bool Matrix::save(std::string filename) { std::ofstream file(filename); if (file.is_open()) { file << *this << std::endl; file.close(); return true; } else { return false; } }