#include #include #include #include #define assertm(exp, msg) assert((void(msg), exp)) class Matrix{ private: std::vector> values; public: inline void Randomize(); inline void Randomize(float, float); inline void Set(float); inline Matrix Swap(const Matrix*); inline Matrix Multiply(float); inline Matrix Multiply(const Matrix*); inline void Hadamard(const Matrix*); inline Matrix Add(float); inline Matrix Add(const Matrix*); inline Matrix Substract(float); inline Matrix Substract(const Matrix*); inline Matrix Function(float (*f)(float)); inline void Print(std::string_view); inline Matrix Transpose(); // Operators inline Matrix operator=(const Matrix*); inline Matrix operator+(const Matrix*); inline Matrix operator-(const Matrix*); inline Matrix operator*(const Matrix*); inline Matrix operator+(float); inline Matrix operator-(float); inline Matrix operator*(float); // Constructors inline Matrix(int, int); inline Matrix(const Matrix*); }; Matrix Matrix::operator=(const Matrix* other){ return this->Swap(other); } Matrix Matrix::operator+(const Matrix* other){ return this->Add(other); } Matrix Matrix::operator-(const Matrix* other){ return this->Substract(other); } Matrix Matrix::operator*(const Matrix* other){ return this->Multiply(other); } Matrix Matrix::operator+(float value){ return this->Add(value); } Matrix Matrix::operator-(float value){ return this->Substract(value); } Matrix Matrix::operator*(float value){ return this->Multiply(value); } Matrix Matrix::Function(float (*f)(float)){ Matrix result = this; for(int m = 0; m < result.values.size(); m++){ for(int n = 0; n < result.values[m].size(); n++){ // Execute function on every value result.values[m][n] = f(result.values[m][n]); } } return result; } // Constructs a zero matrix Matrix::Matrix(int rows, int cols){ for(int m = 0; m < rows; m++){ std::vector buffer = {}; for(int n = 0; n < cols; n++){ buffer.push_back(0.0F); } this->values.push_back(buffer); } } Matrix::Matrix(const Matrix* other){ this->values = other->values; } Matrix Matrix::Swap(const Matrix* other){ this->values = other->values; return *this; } void Matrix::Hadamard(const Matrix* other){ // Matrices need to be the same size assertm(this->values.size() == other->values.size() && this->values[0].size() == other->values[0].size(), "Matrices need to be the same size"); for(int m = 0; m < this->values.size(); m++){ for(int n = 0; n < this->values[m].size(); n++){ this->values[m][n] *= other->values[m][n]; } } } // Multiply 2 matrices (AxB = this x other) Matrix Matrix::Multiply(const Matrix* other){ // Matrices need to be of right size assertm(this->values[0].size() == other->values.size(),"Wrong matrix size"); // Resulting size is this->M x other->N Matrix result(this->values.size(), other->values[0].size()); for(int m = 0; m < result.values.size(); m++){ for(int n = 0; n < result.values[m].size(); n++){ // Sum multiplications float buffer = 0.0F; for(int i = 0; i < this->values[0].size(); i++){ buffer += this->values[m][i] * other->values[i][n]; } result.values[m][n] = buffer; } } return result; } // Add 2 matrices Matrix Matrix::Add(const Matrix* other){ // Matrices need to be the same size assertm(this->values.size() == other->values.size() && this->values[0].size() == other->values[0].size(), "Wrong matrix size"); Matrix result = this; for(int m = 0; m < result.values.size(); m++){ for(int n = 0; n < result.values[m].size(); n++){ result.values[m][n] += other->values[m][n]; } } return result; } // Substract 2 matrices Matrix Matrix::Substract(const Matrix* other){ // Matrices need to be the same size assertm(this->values.size() == other->values.size() && this->values[0].size() == other->values[0].size(), "Wrong matrix size"); Matrix result = this; for(int m = 0; m < result.values.size(); m++){ for(int n = 0; n < result.values[m].size(); n++){ result.values[m][n] -= other->values[m][n]; } } return result; } // Print a matrix in terminal, with a title void Matrix::Print(std::string_view title){ std::cout << title << std::endl; for(int m = 0; m < values.size(); m++){ std::cout << '|'; for(int n = 0; n < values[m].size(); n++){ std::cout << values[m][n] << "|"; } std::cout << std::endl; } } // Add a constant value to every matrix case Matrix Matrix::Add(float value){ Matrix result = this; for(int m = 0; m < result.values.size(); m++){ for(int n = 0; n < result.values[m].size(); n++){ result.values[m][n] += value; } } return result; } // Substract a constant value to every matrix case Matrix Matrix::Substract(float value){ Matrix result = this; for(int m = 0; m < result.values.size(); m++){ for(int n = 0; n < result.values[m].size(); n++){ result.values[m][n] -= value; } } return result; } // Multiply every matrix case by a given factor Matrix Matrix::Multiply(float value){ Matrix result = this; for(int m = 0; m < result.values.size(); m++){ for(int n = 0; n < result.values[m].size(); n++){ result.values[m][n] *= value; } } return result; } // Set a matrix to a given value void Matrix::Set(float value){ for(int m = 0; m < this->values.size(); m++){ for(int n = 0; n < this->values[m].size(); n++){ this->values[m][n] = value; } } } // Transpose a matrix Matrix Matrix::Transpose(){ // Transposed matrix size is inverted Matrix result(this->values[0].size(), this->values.size()); for(int m = 0; m < result.values.size(); m++){ for(int n = 0; n < result.values[m].size(); n++){ result.values[m][n] = this->values[n][m]; } } return result; } // Randomize a matrix from 0.0F to 10.0F void Matrix::Randomize(){ this->Randomize(0.0F, 10.0F); } // Randomize a matrix from min to max void Matrix::Randomize(float min, float max){ for(int m = 0; m < this->values.size(); m++){ for(int n = 0; n < this->values[m].size(); n++){ this->values[m][n] = min + ((float)rand()/(float)(RAND_MAX)) * (max - min); } } }