From 86643012e255f1aa2284efc816ed746f9b7ea11b Mon Sep 17 00:00:00 2001 From: Robert Altner Date: Thu, 24 Jan 2019 04:11:32 +0100 Subject: [PATCH] Function "Invert()" now inverts a matrix --- Matrix/Matrix.hpp | 71 ++++++++++++++++++++++++++++++++++++++++++++++- Matrix/main.cpp | 33 ++++++++++++---------- 2 files changed, 88 insertions(+), 16 deletions(-) diff --git a/Matrix/Matrix.hpp b/Matrix/Matrix.hpp index 367e2c2..02fbd59 100644 --- a/Matrix/Matrix.hpp +++ b/Matrix/Matrix.hpp @@ -30,6 +30,8 @@ public: // Constructional functions friend void Zero(Matrix& mat); friend void Identity(Matrix& mat); + + friend Matrix Identity(uint dimension); // Setters / Getters @@ -47,6 +49,7 @@ public: // Transformation / arithmetic functions void Transpose(); + void Invert(); void MultiplyRow(uint row, double factor); void SwapRows(uint left, uint right); void AddMultiplesToRow(uint base, uint target, double factor); @@ -54,6 +57,9 @@ public: void TransformToEchelonForm(); void TransformToReducedEchelonForm(); + void ConcatVertically(const Matrix& other); + void ConcatHorizontally(const Matrix& other); + friend double det(const Matrix& mat); friend Matrix mul(const Matrix& left, const Matrix& right); @@ -139,6 +145,18 @@ inline void Identity(Matrix& mat) mat.m_matrix[k][k] = 1; } +//////////////////////////////////////////////////// +/// \brief Creates an identity matrix and returns it +/// +//////////////////////////////////////////////////// +inline Matrix Identity(uint dimension) +{ + Matrix id(dimension, dimension); + Identity(id); + + return id; +} + //////////////////////////////////////////////////// /// \brief Sets the number at a given position to a given value @@ -251,6 +269,29 @@ inline void Matrix::Transpose() } +//////////////////////////////////////////////////// +/// \brief Inverts the matrix +/// +//////////////////////////////////////////////////// +inline void Matrix::Invert() +{ + if (!IsInvertable()) + return; + + Matrix holder = *this; + holder.ConcatVertically(Identity(m_rows)); + + holder.TransformToReducedEchelonForm(); + + Matrix inverse(m_rows, m_cols); + for (int row = 0; row < m_rows; row++) + for (int col = 0; col < m_cols; col++) + inverse.SetNumber(row, col, holder.GetNumber(row, col + m_cols)); + *this = inverse; +} + + + //////////////////////////////////////////////////// /// \brief Multiplies each value of a given row by a given factor /// @@ -338,7 +379,7 @@ inline Matrix mul(const Matrix& right, const Matrix& left) for (uint row = 0; row < returnMatrix.m_rows; row++) for (uint col = 0; col < returnMatrix.m_cols; col++) - for (uint k = 0; k < right.m_cols; k++) + for (uint k = 0; k < right.m_cols; k++) returnMatrix.m_matrix[row][col] += right.m_matrix[row][k] * left.m_matrix[k][col]; return returnMatrix; @@ -491,6 +532,31 @@ inline void Matrix::TransformToReducedEchelonForm() if (m_matrix[row][col] == -0) m_matrix[row][col] = 0; } +inline void Matrix::ConcatVertically(const Matrix& other) +{ + if (m_rows != other.GetRows()) + return; + + Resize(m_rows, m_cols + other.GetColumns(), m_matrix); + + for (int row = 0; row < m_rows; row++) + for (int col = other.GetColumns(); col < m_cols; col++) + m_matrix[row][col] = other.GetNumber(row, col - other.GetColumns()); +} + + +inline void Matrix::ConcatHorizontally(const Matrix& other) +{ + if (m_cols != other.GetColumns()) + return; + + Resize(m_rows + other.GetRows(), m_cols, m_matrix); + + for (int col = 0; col < m_cols; col++) + for (int row = other.GetRows(); row < m_rows; row++) + m_matrix[row][col] = other.GetNumber(row, col - other.GetColumns()); +} + inline bool Matrix::InBounds(uint row, uint col) const { @@ -510,6 +576,9 @@ inline void Matrix::Resize(uint rows, uint cols, doubleMatrix& matrix) matrix.resize(rows); for (int row = 0; row < rows; row++) matrix[row].resize(cols); + + m_rows = rows; + m_cols = cols; } diff --git a/Matrix/main.cpp b/Matrix/main.cpp index 57c3e99..02d3560 100644 --- a/Matrix/main.cpp +++ b/Matrix/main.cpp @@ -8,24 +8,27 @@ int main(int argc, char** argv) std::default_random_engine engine(time(NULL)); std::uniform_int_distribution range(0, 4); - Matrix myMatrix(4, 4); - for (int row = 0; row < 3; row++) - for (int col = 0; col < 4; col++) - myMatrix.SetNumber(row, col, range(engine)); + // Hardcode a matrix + Matrix myMatrix(3, 3); + myMatrix.SetNumber(0, 0, 1); + myMatrix.SetNumber(0, 1, 1); + myMatrix.SetNumber(0, 2, 1); + myMatrix.SetNumber(1, 0, 0); + myMatrix.SetNumber(1, 1, 1); + myMatrix.SetNumber(1, 2, 1); + myMatrix.SetNumber(2, 0, 0); + myMatrix.SetNumber(2, 1, 0); + myMatrix.SetNumber(2, 2, 1); - Matrix otherMatrix(4, 4); - Identity(otherMatrix); + Matrix inverse = myMatrix; + inverse.Invert(); + - Matrix addMatrix = myMatrix * otherMatrix; + std::cout << myMatrix << std::endl; - std::cout << myMatrix; - std::cout << std::endl << "-" << std::endl << std::endl; - std::cout << otherMatrix; - std::cout << std::endl << "=" << std::endl << std::endl; - std::cout << addMatrix << std::endl; - std::cout << det(addMatrix) << std::endl; - std::cout << addMatrix.IsInvertable() << std::endl; - std::cout << std::endl; + std::cout << inverse << std::endl; + + std::cout << mul(myMatrix, inverse) << std::endl; getchar();