matrix.cpp
#include <iostream> //#include <iomanip> #include "matrix.h" namespace SW { /* // Example #include "matrix.h" #include <iostream> int main(int argc, char **argv) { Matrix<double> mat1(10, 10, 1.0); Matrix<double> mat2(10, 10, 2.0); Matrix<double> mat3 = mat1 + mat2; for (int i = 0; i<mat3.get_rows(); i++) { for (int j = 0; j<mat3.get_cols(); j++) { std::cout << mat3(i, j) << ", "; } std::cout << std::endl; } return 0; } */ // Basic Constructor. template<typename T> Matrix<T>::Matrix() { rows = 0; cols = 0; } /**/ // Parameter Constructor. template<typename T> Matrix<T>::Matrix(unsigned _rows, unsigned _cols) { mat.resize(_rows); for (unsigned i = 0; i<mat.size(); i++) { mat[i].resize(_cols, 0); } rows = _rows; cols = _cols; } // Parameter Constructor. template<typename T> Matrix<T>::Matrix(unsigned _rows, unsigned _cols, const T& _initial) { mat.resize(_rows); for (unsigned i = 0; i<mat.size(); i++) { mat[i].resize(_cols, _initial); } rows = _rows; cols = _cols; } /**/ // Copy Constructor. template<typename T> Matrix<T>::Matrix(const Matrix<T>& rhs) { mat = rhs.mat; rows = rhs.get_rows(); cols = rhs.get_cols(); } // (Virtual) Destructor. template<typename T> Matrix<T>::~Matrix() { } /**/ // Comparison Operator ==. template<typename T> bool Matrix<T>::operator==(const Matrix<T>& rhs) const { unsigned rows = rhs.get_rows(); unsigned cols = rhs.get_cols(); if (get_rows() != rows) return false; if (get_cols() != cols) return false; for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { if (this->mat[i][j] != rhs(i, j)) return false; } } return true; } // Comparison Operator !=. template<typename T> bool Matrix<T>::operator!=(const Matrix<T>& rhs) const { unsigned rows = rhs.get_rows(); unsigned cols = rhs.get_cols(); if (get_rows() != rows) return true; if (get_cols() != cols) return true; for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { if (this->mat[i][j] == rhs(i, j)) return false; } } return false; } // Comparison Operator <. template<typename T> bool Matrix<T>::operator<(const Matrix<T>& rhs) const { unsigned rows = rhs.get_rows(); unsigned cols = rhs.get_cols(); if (get_rows() != rows) return false; if (get_cols() != cols) return false; for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { if (this->mat[i][j] >= rhs(i, j)) return false; } } return true; } // Comparison Operator <=. template<typename T> bool Matrix<T>::operator<=(const Matrix<T>& rhs) const { unsigned rows = rhs.get_rows(); unsigned cols = rhs.get_cols(); if (get_rows() != rows) return false; if (get_cols() != cols) return false; for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { if (this->mat[i][j] > rhs(i, j)) return false; } } return true; } // Comparison Operator <. template<typename T> bool Matrix<T>::operator>(const Matrix<T>& rhs) const { unsigned rows = rhs.get_rows(); unsigned cols = rhs.get_cols(); if (get_rows() != rows) return false; if (get_cols() != cols) return false; for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { if (this->mat[i][j] <= rhs(i, j)) return false; } } return true; } // Comparison Operator >=. template<typename T> bool Matrix<T>::operator>=(const Matrix<T>& rhs) const { unsigned rows = rhs.get_rows(); unsigned cols = rhs.get_cols(); if (get_rows() != rows) return false; if (get_cols() != cols) return false; for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { if (this->mat[i][j] < rhs(i, j)) return false; } } return true; } // Assignment Operator. template<typename T> Matrix<T>& Matrix<T>::operator=(const Matrix<T>& rhs) { if (&rhs == this) return *this; unsigned new_rows = rhs.get_rows(); unsigned new_cols = rhs.get_cols(); mat.resize(new_rows); for (unsigned i = 0; i<mat.size(); i++) { mat[i].resize(new_cols); } for (unsigned i = 0; i<new_rows; i++) { for (unsigned j = 0; j<new_cols; j++) { mat[i][j] = rhs(i, j); } } rows = new_rows; cols = new_cols; return *this; } // Unary - operator template<typename T> Matrix<T> Matrix<T>::operator -() const { Matrix result(rows, cols, 0.0); for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { result(i, j) = -this->mat[i][j]; } } return result; } // Prefix increment operator template<typename T> Matrix<T> Matrix<T>::operator ++ () { Matrix result(rows, cols, 0.0); for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { result(i, j) = this->mat[i][j] + 1; } } return *this = result; } // Postfix increment operator template<typename T> Matrix<T> Matrix<T>::operator ++ (int) { Matrix result(rows, cols, 0.0); for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { result(i, j) = this->mat[i][j] + 1; } } return result; } // Prefix decrement operator template<typename T> Matrix<T> Matrix<T>::operator -- () { Matrix result(rows, cols, 0.0); for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { result(i, j) = this->mat[i][j] - 1; } } return *this = result; } // Postfix decrement operator template<typename T> Matrix<T> Matrix<T>::operator -- (int) { Matrix result(rows, cols, 0.0); for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { result(i, j) = this->mat[i][j] - 1; } } return result; } // Addition of two matrices. template<typename T> Matrix<T> Matrix<T>::operator+(const Matrix<T>& rhs) { Matrix result(rows, cols, 0.0); for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { result(i, j) = this->mat[i][j] + rhs(i, j); } } return result; } // Cumulative addition of this matrix and another. template<typename T> Matrix<T>& Matrix<T>::operator+=(const Matrix<T>& rhs) { unsigned rows = rhs.get_rows(); unsigned cols = rhs.get_cols(); for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { this->mat[i][j] += rhs(i, j); } } return *this; } // Subtraction of this matrix and another. template<typename T> Matrix<T> Matrix<T>::operator-(const Matrix<T>& rhs) { unsigned rows = rhs.get_rows(); unsigned cols = rhs.get_cols(); Matrix result(rows, cols, 0.0); for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { result(i, j) = this->mat[i][j] - rhs(i, j); } } return result; } // Cumulative subtraction of this matrix and another. template<typename T> Matrix<T>& Matrix<T>::operator-=(const Matrix<T>& rhs) { unsigned rows = rhs.get_rows(); unsigned cols = rhs.get_cols(); for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { this->mat[i][j] -= rhs(i, j); } } return *this; } // Left multiplication of this matrix and another. template<typename T> Matrix<T> Matrix<T>::operator*(const Matrix<T>& rhs) { unsigned rows = rhs.get_rows(); unsigned cols = rhs.get_cols(); Matrix result(rows, cols, 0.0); for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { for (unsigned k = 0; k<rows; k++) { result(i, j) += this->mat[i][k] * rhs(k, j); } } } return result; } // Cumulative left multiplication of this matrix and another. template<typename T> Matrix<T>& Matrix<T>::operator*=(const Matrix<T>& rhs) { Matrix result = (*this) * rhs; (*this) = result; return *this; } // Left mod of this matrix and another. template<typename T> Matrix<T> Matrix<T>::operator%(const Matrix<T>& rhs) { unsigned rows = rhs.get_rows(); unsigned cols = rhs.get_cols(); Matrix result(rows, cols, 0.0); for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { for (unsigned k = 0; k<rows; k++) { result(i, j) += this->mat[i][k] % rhs(k, j); } } } return result; } // Cumulative left mod of this matrix and another. template<typename T> Matrix<T>& Matrix<T>::operator%=(const Matrix<T>& rhs) { Matrix result = (*this) % rhs; (*this) = result; return *this; } // Left raise of this matrix and another. template<typename T> Matrix<T> Matrix<T>::operator^(const Matrix<T>& rhs) { // unsigned rows = rhs.get_rows(); // unsigned cols = rhs.get_cols(); Matrix result(rows, cols, 0.0); for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { for (unsigned k = 0; k<rows; k++) { result(i, j) += this->mat[i][k] ^ rhs(k, j); } } } return result; } // Cumulative left raise of this matrix and another. template<typename T> Matrix<T>& Matrix<T>::operator^=(const Matrix<T>& rhs) { Matrix result = (*this) % rhs; (*this) = result; return *this; } /* template<typename T> //Matrix<T> Matrix<T>::operator^(const Matrix<T>& rhs, const int power) Matrix<T> Matrix<T>::operator^(const int power) { std::cout << "Z" << std::endl; //unsigned rows = rhs.get_rows(); //unsigned cols = rhs.get_cols(); Matrix result(rows, cols, 0.0); //result = rhs; for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { T temp = this->mat[i][j]; std::cout << "T=" << std::endl; //T temp = 2; //T temp = rhs[i][j]; // not <= below \/ because first time counts as 2 for (int k = 2; k<=power; k++) //result(i, j) += this->mat[i][j] * this->mat[i][j]; result(i, j) = result(i, j) * temp; } } return result; } */ // Left raise of this matrix and another. template<typename T> Matrix<T>& Matrix<T>::operator^=(const int power) { Matrix result = (*this); unsigned rows = result.get_rows(); unsigned cols = result.get_cols(); for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { T temp = this->mat[i][j]; // not <= below \/ because first time counts as 2 for (int k = 2; k <= power; k++) result(i, j) = result(i, j) * temp; } } //(*this) = result; *this = result; return *this; } // Concerts all values to their absolute value within the matrix. template<typename T> Matrix<T> Matrix<T>::abs() { Matrix result(rows, cols, 0.0); for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { result(i, j) = std::math::abs(this->mat[j][i]); } } return result; } // Concerts all values to their square roots within the matrix. template<typename T> Matrix<T> Matrix<T>::sqrt() { Matrix result(rows, cols, 0.0); for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { result(i, j) = std::math::sqrt(this->mat[j][i]); } } return result; } // Calculate a transpose of this matrix. template<typename T> Matrix<T> Matrix<T>::transpose() { Matrix result(rows, cols, 0.0); for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { result(i, j) = this->mat[j][i]; } } return result; } // Matrix/scalar addition. template<typename T> Matrix<T> Matrix<T>::operator+(const T& rhs) { Matrix result(rows, cols, 0.0); for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { result(i, j) = this->mat[i][j] + rhs; } } return result; } // Matrix/scalar subtraction. template<typename T> Matrix<T> Matrix<T>::operator-(const T& rhs) { Matrix result(rows, cols, 0.0); for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { result(i, j) = this->mat[i][j] - rhs; } } return result; } // Matrix/scalar multiplication. template<typename T> Matrix<T> Matrix<T>::operator*(const T& rhs) { Matrix result(rows, cols, 0.0); for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { result(i, j) = this->mat[i][j] * rhs; } } return result; } // Matrix/scalar division. template<typename T> Matrix<T> Matrix<T>::operator/(const T& rhs) { Matrix result(rows, cols, 0.0); for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { result(i, j) = this->mat[i][j] / rhs; } } return result; } // Multiply a matrix with a vector. template<typename T> std::vector<T> Matrix<T>::operator*(const std::vector<T>& rhs) { std::vector<T> result(rhs.size(), 0.0); for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { result[i] = this->mat[i][j] * rhs[j]; } } return result; } // Obtain a vector of the diagonal elements. template<typename T> std::vector<T> Matrix<T>::diag_vec() { std::vector<T> result(rows, 0.0); for (unsigned i = 0; i<rows; i++) { result[i] = this->mat[i][i]; } return result; } // Access the individual elements. template<typename T> T& Matrix<T>::operator()(const unsigned& row, const unsigned& col) { return this->mat[row][col]; } // Access the individual elements (const). template<typename T> const T& Matrix<T>::operator()(const unsigned& row, const unsigned& col) const { return this->mat[row][col]; } // Get the number of rows of the matrix. template<typename T> unsigned Matrix<T>::get_rows() const { return this->rows; } // Get the number of columns of the matrix. template<typename T> unsigned Matrix<T>::get_cols() const { return this->cols; } template<typename T> std::ostream & operator << (std::ostream &s, const Matrix<T>& m) { unsigned rows = m.get_rows(); unsigned cols = m.get_cols(); for (unsigned i = 0; i<rows; i++) { for (unsigned j = 0; j<cols; j++) { s << m(i, j); if ((i*j) < (((rows - 1)*(cols - 1)) - 1)) s << ", "; } s << std::endl; } return s; } template<typename T> std::istream & operator >> (std::istream &s, Matrix<T>& m) { /* std::string temp(10000, ' '); s >> temp; v = Verylong(temp); */ return s; } } // end namespace SW