הערה (קובץ קוד)
קובץ זה הוא קובץ קוד מסוג CPP.
#include <cmath>
#include "Matrix.h"
#include "Utilities.h"
#define GET_INDEX_AT(row, col, width) ((row*width) + col)
Matrix::Matrix(int rows, int columns, int value) : mat(new int[rows * columns]()) {
this->rows = rows;
this->cols = columns;
for (int i = 0; i < rows * columns; i++) {
this->mat[i] = value;
}
}
Matrix::Matrix(const Matrix& matrix) : mat(new int[matrix.rows * matrix.cols]) {
this->rows = matrix.rows;
this->cols = matrix.cols;
for (int i = 0; i < rows * cols; i++) {
this->mat[i] = matrix.mat[i];
}
}
Matrix::~Matrix() {
delete[] mat;
}
std::ostream& operator<<(std::ostream& ostream, const Matrix& matrix) {
for (int i = 0; i < matrix.rows; i++) {
for (int j = 0; j < matrix.cols; j++) {
ostream << "|" << matrix(i, j);
}
ostream << "|" << std::endl;
}
return ostream;
}
Matrix& Matrix::operator=(const Matrix& matrix) {
if (this == &matrix) {
return *this;
}
cols = matrix.cols;
rows = matrix.rows;
delete[] mat;
mat = new int[rows * cols];
for (int i = 0; i < rows * cols; i++) {
mat[i] = matrix.mat[i];
}
return *this;
}
int& Matrix::operator()(int row, int column) {
if (row < 0 || row >= rows || column < 0 || column >= cols) {
exitWithError(MatamErrorType::OutOfBounds);
}
return mat[GET_INDEX_AT(row, column, cols)];
}
int Matrix::operator()(int row, int column) const {
if (row < 0 || row >= rows || column < 0 || column >= cols) {
exitWithError(MatamErrorType::OutOfBounds);
}
return mat[GET_INDEX_AT(row, column, cols)];
}
Matrix& Matrix::operator+=(const Matrix& matrix) {
if (rows != matrix.rows || cols != matrix.cols) {
exitWithError(MatamErrorType::UnmatchedSizes);
}
for (int i = 0; i < (rows * cols); i++) {
mat[i] += matrix.mat[i];
}
return *this;
}
Matrix& Matrix::operator-=(const Matrix& matrix) {
if (rows != matrix.rows || cols != matrix.cols) {
exitWithError(MatamErrorType::UnmatchedSizes);
}
for (int i = 0; i < (rows * cols); i++) {
mat[i] -= matrix.mat[i];
}
return *this;
}
Matrix& Matrix::operator*=(const Matrix& matrix) {
if (this->cols != matrix.rows) {
exitWithError(MatamErrorType::UnmatchedSizes);
return *this;
}
int* result = new int[rows * matrix.cols];
// calculating the new matrix
for (int i = 0; i < this->rows; i++) {
for (int j = 0; j < matrix.cols; j++) {
int sum = 0;
for (int k = 0; k < this->cols; k++) {
sum += (*this)(i, k) * matrix(k, j);
}
result[GET_INDEX_AT(i, j, matrix.cols)] = sum;
}
}
// reassigning the attributes
delete[] mat;
mat = result;
cols = matrix.cols;
return *this;
}
Matrix operator+(const Matrix& mat1, const Matrix& mat2) {
Matrix result(mat1);
return (result += mat2);
}
Matrix operator-(const Matrix& mat1, const Matrix& mat2) {
Matrix result(mat1);
return (result -= mat2);
}
Matrix operator*(const Matrix& mat1, const Matrix& mat2) {
Matrix result(mat1);
return (result *= mat2);
}
Matrix Matrix::operator-() const {
Matrix result(this->rows, this->cols);
return (result -= *this);
}
Matrix& Matrix::operator*=(int value) {
for (int i = 0; i < (rows * cols); i++) {
mat[i] *= value;
}
return *this;
}
Matrix operator*(const Matrix& mat, int value) {
Matrix result(mat);
return (result *= value);
}
Matrix operator*(int value, const Matrix& mat) {
Matrix result(mat);
return (result *= value);
}
bool Matrix::operator==(const Matrix& matrix) const {
if (cols != matrix.cols || rows != matrix.rows) {
return false;
}
for (int i = 0; i < rows * cols; i++) {
if (this->mat[i] != matrix.mat[i]) {
return false;
}
}
return true;
}
bool Matrix::operator!=(const Matrix& matrix) const {
return !(*this == matrix);
}
Matrix Matrix::rotateClockwise() const {
Matrix result(cols, rows);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
result(j, rows - 1 - i) = (*this)(i, j);
}
}
return result;
}
Matrix Matrix::rotateCounterClockwise() const {
Matrix result(cols, rows);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
result(cols - 1 - j, i) = (*this)(i, j);
}
}
return result;
}
Matrix Matrix::transpose() const {
Matrix result(cols, rows);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
result(j, i) = (*this)(i, j);
}
}
return result;
}
double Matrix::CalcFrobeniusNorm(const Matrix& mat) {
double sum = 0;
for (int i = 0; i < mat.cols * mat.rows; i++) {
sum += (mat.mat[i] * mat.mat[i]);
}
return sqrt(sum);
}
int Matrix::CalcDeterminant(const Matrix& mat) {
if (mat.rows != mat.cols) {
exitWithError(MatamErrorType::NotSquareMatrix);
}
switch (mat.rows) {
case 0:
return 0;
case 1:
return mat(0, 0);
case 2:
return mat(0, 0) * mat(1, 1) - mat(0, 1) * mat(1, 0);
default: {
int sum = 0, minus = 1;
for (int i = 0; i < mat.rows; i++) {
Matrix minor = getMinor(mat, i);
sum += minus * mat(0, i) * CalcDeterminant(minor);
minus *= -1;
}
return sum;
}
}
}
Matrix Matrix::getMinor(const Matrix& mat, int index) {
int size = mat.rows - 1;
Matrix minor(size, size);
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
minor(i, j) = mat(i + 1, j >= index ? j + 1 : j);
}
}
return minor;
}