From 3d01393f02eecfc2ba1a6b40b879f4a2d2421e36 Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Sun, 3 Mar 2024 12:16:26 +0100 Subject: [PATCH] add IsElementOf + ColumnVector --- include/Matrix.h | 13 +++++++++++++ include/Vect.h | 20 ++++++++++++++++++-- src/Matrix.cpp | 36 ++++++++++++++++++++++++++++++++++++ src/Vect.cpp | 16 ++++++++++++---- test/test_vect.cpp | 18 +++++++++++++++++- 5 files changed, 96 insertions(+), 7 deletions(-) diff --git a/include/Matrix.h b/include/Matrix.h index 142661e..440e1d6 100644 --- a/include/Matrix.h +++ b/include/Matrix.h @@ -79,6 +79,9 @@ class Matrix { */ Matrix SubMatrix(std::size_t raw_origin, std::size_t column_origin, std::size_t raw, std::size_t column) const; + Matrix operator+(const Matrix& other) const; + Matrix operator-(const Matrix& other) const; + bool operator==(const Matrix& other) const; /** @@ -105,6 +108,16 @@ class Matrix { * \param size La taille de la matrice carrée */ static Matrix Identity(std::size_t size); + + /** + * \brief Construit une matrice colonne à partir de données existantes.\n + * Exemple : + * \code + * Matrix::ColumnVector({1, 2, 3, 4}); + * \endcode + * construit une matrice de 4 lignes et 1 colonne de coordonnées (1, 2, 3, 4) + */ + static Matrix ColumnVector(std::initializer_list&&); }; template diff --git a/include/Vect.h b/include/Vect.h index 07f23f5..6756c5f 100644 --- a/include/Vect.h +++ b/include/Vect.h @@ -48,9 +48,15 @@ class Vect { /** * \brief Concatène la base actuelle avec un nouveau vecteur - * \param mat Une matrice colonne de taille GetDimension() + * \param vec Une matrice colonne de taille GetDimension() */ - void AddVector(const Matrix& mat); + void AddVector(const Matrix& vec); + + /** + * \brief Vérifie si le vecteur spécifié appartient au sous-espace vectoriel + * \param vec Une matrice colonne représentant le vecteur à tester + */ + bool IsElementOf(const Matrix& vec) const; bool operator==(const Vect& other) const; bool operator!=(const Vect& other) const; @@ -90,4 +96,14 @@ class VectAffine { const Matrix& GetOrigin() const { return m_Origin; } + + /** + * \brief Vérifie si le vecteur spécifié appartient à l'espace affine + * \param vec Une matrice colonne représentant le vecteur à tester + */ + bool IsElementOf(const Matrix& vec) const; + + bool operator==(const VectAffine& vect) const { + return m_Origin == vect.GetOrigin() && m_Base == vect.GetBase(); + }; }; \ No newline at end of file diff --git a/src/Matrix.cpp b/src/Matrix.cpp index 92eff63..fa8ee1f 100644 --- a/src/Matrix.cpp +++ b/src/Matrix.cpp @@ -57,6 +57,14 @@ Matrix Matrix::Identity(std::size_t taille) { return id; } +Matrix Matrix::ColumnVector(std::initializer_list&& initList) { + Matrix result {initList.size(), 1}; + + result.m_Data = initList; + + return result; +} + void Matrix::Augment(const Matrix& droite) { assert(droite.m_Raws == m_Raws); Matrix temp {m_Raws, m_Columns + droite.m_Columns}; @@ -76,6 +84,34 @@ void Matrix::Augment(const Matrix& droite) { *this = temp; } +Matrix Matrix::operator+(const Matrix& other) const { + assert(GetColumnCount() == other.GetColumnCount() && GetRawCount() == other.GetRawCount()); + + Matrix result = *this; + + for (std::size_t i = 0; i < GetRawCount(); i++) { + for (std::size_t j = 0; j < GetColumnCount(); j++) { + result.at(i, j) += other.at(i, j); + } + } + + return result; +} + +Matrix Matrix::operator-(const Matrix& other) const { + assert(GetColumnCount() == other.GetColumnCount() && GetRawCount() == other.GetRawCount()); + + Matrix result = *this; + + for (std::size_t i = 0; i < GetRawCount(); i++) { + for (std::size_t j = 0; j < GetColumnCount(); j++) { + result.at(i, j) -= other.at(i, j); + } + } + + return result; +} + bool Matrix::operator==(const Matrix& other) const { if (m_Raws != other.m_Raws || m_Columns != other.m_Columns) return false; diff --git a/src/Vect.cpp b/src/Vect.cpp index 58990cc..78c42f6 100644 --- a/src/Vect.cpp +++ b/src/Vect.cpp @@ -37,15 +37,19 @@ std::size_t Vect::GetCardinal() const { return m_Data.GetColumnCount(); } +bool Vect::IsElementOf(const Matrix& vec) const { + Vect base = *this; + base.AddVector(vec); + return base.GetCardinal() == GetCardinal(); +} + bool Vect::operator==(const Vect& other) const { if (GetDimension() != other.GetDimension() || GetCardinal() != other.GetCardinal()) return false; // on vérifie si chaque vecteur de la deuxième base appartient à l'espace vectoriel engendré par la première base for (std::size_t i = 0; i < GetCardinal(); i++) { - Vect base = *this; - base.AddVector(other.m_Data.SubMatrix(0, i, GetDimension(), 1)); - if (base.GetCardinal() != GetCardinal()) + if (!IsElementOf(other.GetVector(i))) return false; } return true; @@ -78,4 +82,8 @@ std::size_t Vect::GetDimension() const { } VectAffine::VectAffine(const Vect& base, const Matrix& origine) : - m_Base(base), m_Origin(origine.SubMatrix(0, 0, m_Base.GetDimension(), 1)) {} \ No newline at end of file + m_Base(base), m_Origin(origine.SubMatrix(0, 0, m_Base.GetDimension(), 1)) {} + +bool VectAffine::IsElementOf(const Matrix& vec) const { + return m_Base.IsElementOf(vec - m_Origin); +} diff --git a/test/test_vect.cpp b/test/test_vect.cpp index 66a261b..b5eb887 100644 --- a/test/test_vect.cpp +++ b/test/test_vect.cpp @@ -1,7 +1,7 @@ #include "Vect.h" #include -int main() { +void TestVect() { Vect vect1 {{3, 2, { 1, 2, 3, 4, @@ -27,5 +27,21 @@ int main() { assert(vect1 != vect2); assert(vect2 != vect3); assert(vect3 != vect4); + + assert(vect1.IsElementOf(Matrix::ColumnVector({3, 7, 11}))); + assert(!vect1.IsElementOf(Matrix::ColumnVector({3, 7, 12}))); +} + +void TestVectAffine() { + VectAffine aff {Matrix {3, 1, {-2, 3, 7}}, Matrix::ColumnVector({5, 2, -8})}; + + assert(aff.IsElementOf(Matrix::ColumnVector({5, 2, -8}))); + assert(aff.IsElementOf(Matrix::ColumnVector({3, 5, -1}))); + assert(!aff.IsElementOf(Matrix::ColumnVector({1, 2, 3}))); +} + +int main() { + TestVect(); + TestVectAffine(); return 0; } \ No newline at end of file