From 3b07ae783f34a170135027861f928b709c98b313 Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Fri, 23 Feb 2024 10:48:43 +0100 Subject: [PATCH] refactor project --- src/Gauss.cpp | 75 ++++++++++++++++++++++++++++++++ src/Gauss.h | 9 ++++ src/Matrix.cpp | 100 +++---------------------------------------- src/Matrix.h | 19 +------- src/Solver.cpp | 8 ++-- src/Vect.cpp | 5 ++- src/main.cpp | 3 +- test/test_jordan.cpp | 3 +- 8 files changed, 103 insertions(+), 119 deletions(-) create mode 100644 src/Gauss.cpp create mode 100644 src/Gauss.h diff --git a/src/Gauss.cpp b/src/Gauss.cpp new file mode 100644 index 0000000..60513ee --- /dev/null +++ b/src/Gauss.cpp @@ -0,0 +1,75 @@ +#include "Gauss.h" + +#include "Matrix.h" + +namespace Gauss { + +static void GaussNonJordan(Matrix& mat, bool reduite) { + int r = -1; + for (std::size_t j = 0; j < mat.GetColumnCount(); j++) { + std::size_t indice_ligne_maximum = r + 1; + + // Recherche maximum + for (std::size_t i = r + 1; i < mat.GetRawCount(); i++) { + if (std::abs(mat.at(i, j)) > std::abs(mat.at(indice_ligne_maximum, j))) + indice_ligne_maximum = i; + } + + // Si A[k,j]≠0 alors (A[k,j] désigne la valeur de la ligne k et de la colonne j) + if (!IsEqualZero(mat.at(indice_ligne_maximum, j))) { + r++; + + // Si k≠r alors + if (indice_ligne_maximum != r) { + // Échanger les lignes k et r (On place la ligne du pivot en position r) + for (std::size_t k = 0; k < mat.GetColumnCount(); k++) { + std::swap(mat.at(indice_ligne_maximum, k), mat.at(r, k)); + } + } + + // Pour i de 1 jusqu'à n (On simplifie les autres lignes) + for (std::size_t i = (reduite ? 0 : j); i < mat.GetRawCount(); i++) { + // Si i≠r alors + if (i != r) { + // Soustraire à la ligne i la ligne r multipliée par A[i,j] (de façon à + // annuler A[i,j]) + for (int k = mat.GetColumnCount() - 1; k >= 0; k--) { + long double pivot = mat.at(r, j); + long double anul = mat.at(i, j); + mat.at(i, k) = mat.at(i, k) * pivot - mat.at(r, k) * anul; + } + } + } + } + } +} + +static void GaussJordan(Matrix& mat, bool reduite) { + GaussNonJordan(mat, reduite); + for (std::size_t i = 0; i < mat.GetRawCount(); i++) { + int k = -1; + for (std::size_t j = 0; j < mat.GetColumnCount(); j++) { + if (!IsEqualZero(mat.at(i, j))) { + k = j; + break; + } + } + // ligne de 0 + if (k == -1) + break; + // on divise la ligne par (i, k) + long double annul = mat.at(i, k); + for (int j = 0; j < mat.GetColumnCount(); j++) { + mat.at(i, j) /= annul; + } + } +} + +void GaussJordan(Matrix& mat, bool reduite, bool normalise) { + if (normalise) + GaussJordan(mat, reduite); + else + GaussNonJordan(mat, reduite); +} + +} // namespace Gauss \ No newline at end of file diff --git a/src/Gauss.h b/src/Gauss.h new file mode 100644 index 0000000..168919a --- /dev/null +++ b/src/Gauss.h @@ -0,0 +1,9 @@ +#pragma once + +class Matrix; + +namespace Gauss { + +void GaussJordan(Matrix& mat, bool reduite, bool normalise); + +} // namespace Gauss \ No newline at end of file diff --git a/src/Matrix.cpp b/src/Matrix.cpp index 422a22a..b289cd3 100644 --- a/src/Matrix.cpp +++ b/src/Matrix.cpp @@ -25,6 +25,7 @@ Matrix::~Matrix() {} Matrix Matrix::operator*(const Matrix& other) const { if (m_Colonnes != other.m_Lignes) { std::cerr << "Mutiplication impossible car la dimensions des matrices est incompatible" << std::endl; + return {1, 1, {0}}; } Matrix result(m_Lignes, other.m_Colonnes); @@ -53,13 +54,6 @@ void Matrix::Print() const { } } -void Matrix::PrintDebug() { -#ifndef NDEBUG - Print(); - std::cout << "\n"; -#endif -} - void Matrix::Insert() { for (size_t i = 0; i < m_Lignes; ++i) { for (size_t j = 0; j < m_Colonnes; ++j) { @@ -97,32 +91,14 @@ void Matrix::Transpose() { *this = result; } -void Matrix::Identity() { - assert(m_Lignes == m_Colonnes); - for (std::size_t i = 0; i < m_Lignes; i++) { - for (std::size_t j = i; j < m_Colonnes; j++) { - at(i, j) = i == j; - } - } -} - Matrix Matrix::Identity(std::size_t taille) { Matrix id {taille, taille}; - id.Identity(); - return id; -} - -bool Matrix::IsInversed() const { - for (std::size_t i = 0; i < m_Lignes; ++i) { - std::size_t j; - for (j = 0; j < m_Colonnes; ++j) { - if (!IsEqualZero(at(i, j))) { - break; - } - return false; + for (std::size_t i = 0; i < taille; i++) { + for (std::size_t j = i; j < taille; j++) { + id.at(i, j) = (i == j); } } - return true; + return id; } void Matrix::Augmenter(const Matrix& droite) { @@ -158,72 +134,6 @@ bool Matrix::operator==(const Matrix& other) const { return true; } -void Matrix::GaussNonJordan(bool reduite) { - int r = -1; - for (std::size_t j = 0; j < m_Colonnes; j++) { - std::size_t indice_ligne_maximum = r + 1; - - // Recherche maximum - for (std::size_t i = r + 1; i < m_Lignes; i++) { - if (std::abs(at(i, j)) > std::abs(at(indice_ligne_maximum, j))) - indice_ligne_maximum = i; - } - - // std::cout << "l'indice du maximum est : " << indice_ligne_maximum << "\n\n"; - - // Si A[k,j]≠0 alors (A[k,j] désigne la valeur de la ligne k et de la colonne j) - if (!IsEqualZero(at(indice_ligne_maximum, j))) { - r++; - - // PrintDebug(); - - // Si k≠r alors - if (indice_ligne_maximum != r) { - // Échanger les lignes k et r (On place la ligne du pivot en position r) - // std::cout << "On échange les lignes " << indice_ligne_maximum << " et " << r << '\n'; - for (std::size_t k = 0; k < m_Colonnes; k++) { - std::swap(at(indice_ligne_maximum, k), at(r, k)); - } - } - - // Pour i de 1 jusqu'à n (On simplifie les autres lignes) - for (std::size_t i = (reduite ? 0 : j); i < m_Lignes; i++) { - // Si i≠r alors - if (i != r) { - // Soustraire à la ligne i la ligne r multipliée par A[i,j] (de façon à - // annuler A[i,j]) - for (int k = m_Colonnes - 1; k >= 0; k--) { - long double pivot = at(r, j); - long double anul = at(i, j); - at(i, k) = at(i, k) * pivot - at(r, k) * anul; - } - } - } - } - } -} - -void Matrix::GaussJordan(bool reduite) { - GaussNonJordan(reduite); - for (std::size_t i = 0; i < m_Lignes; i++) { - int k = -1; - for (std::size_t j = 0; j < m_Colonnes; j++) { - if (!IsEqualZero(at(i, j))) { - k = j; - break; - } - } - // ligne de 0 - if (k == -1) - break; - // on divise la ligne par (i, k) - long double annul = at(i, k); - for (int j = 0; j < m_Colonnes; j++) { - at(i, j) /= annul; - } - } -} - long double& Matrix::operator[](std::size_t indice) { return m_Data[indice]; } diff --git a/src/Matrix.h b/src/Matrix.h index 4e61977..c6fbb56 100644 --- a/src/Matrix.h +++ b/src/Matrix.h @@ -20,40 +20,25 @@ class Matrix { std::size_t GetRawCount() const; std::size_t GetColumnCount() const; - Matrix operator*(const Matrix& other) const; - - void GaussNonJordan(bool reduite); - - void GaussJordan(bool reduite); - + void Insert(); void Print() const; - void PrintDebug(); - - void Insert(); - void Save(const std::string& fileName); - void Load(const std::string& filename); void Transpose(); - void Identity(); - static Matrix Identity(std::size_t taille); - bool IsInversed() const; - void Augmenter(const Matrix& droite); Matrix SubMatrix(std::size_t origine_ligne, std::size_t origine_colonne, std::size_t ligne, std::size_t colonne) const; bool operator==(const Matrix& other) const; - + Matrix operator*(const Matrix& other) const; long double& operator[](std::size_t indice); long double& at(std::size_t ligne, std::size_t colonne); - long double at(std::size_t ligne, std::size_t colonne) const; friend std::ostream& operator<<(std::ostream& stream, const Matrix& mat); diff --git a/src/Solver.cpp b/src/Solver.cpp index db4adf3..69fed58 100644 --- a/src/Solver.cpp +++ b/src/Solver.cpp @@ -1,11 +1,13 @@ #include "Solver.h" +#include "Gauss.h" + Solver::Solver(const Matrix& mat) : m_Matrix(mat) {} Vect Solver::Image() const { Matrix result = m_Matrix; result.Transpose(); - result.GaussJordan(true); + Gauss::GaussJordan(result, true, true); result.Transpose(); return {result}; } @@ -15,7 +17,7 @@ Vect Solver::Noyau() const { Matrix result = m_Matrix; result.Transpose(); result.Augmenter(Matrix::Identity(result.GetRawCount())); - result.GaussJordan(true); + Gauss::GaussJordan(result, true, true); result.Transpose(); // nombre de colonnes non nulles @@ -27,7 +29,7 @@ Vect Solver::Noyau() const { VectAffine Solver::SystemeTriangulaire() const { Matrix mat = m_Matrix; - mat.GaussJordan(true); + Gauss::GaussJordan(mat, true, true); Solver solver {mat.SubMatrix(0, 0, mat.GetRawCount(), mat.GetColumnCount() - 1)}; diff --git a/src/Vect.cpp b/src/Vect.cpp index 936a6fd..f56bb08 100644 --- a/src/Vect.cpp +++ b/src/Vect.cpp @@ -1,5 +1,6 @@ #include "Vect.h" +#include "Gauss.h" #include "Solver.h" #include #include @@ -45,7 +46,7 @@ bool Vect::operator==(const Vect& other) const { void Vect::AddVector(const Matrix& mat) { m_Data.Augmenter(mat); m_Data.Transpose(); - m_Data.GaussNonJordan(false); + Gauss::GaussJordan(m_Data, false, false); m_Data.Transpose(); Simplify(); } @@ -68,7 +69,7 @@ void Vect::Print() const { std::cout << "Espace vectoriel de dimension " << GetCardinal() << " de base :\n\n"; for (std::size_t i = 0; i < m_Data.GetRawCount(); i++) { for (std::size_t j = 0; j < m_Data.GetColumnCount(); j++) { - printf("[ %u ]\t", static_cast(m_Data.at(i, j))); + printf("[ %d ]\t", static_cast(m_Data.at(i, j))); } std::cout << "\n"; } diff --git a/src/main.cpp b/src/main.cpp index cf4696a..a662fbc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,3 +1,4 @@ +#include "Gauss.h" #include "Solver.h" #include @@ -52,7 +53,7 @@ void prompt() { mat.Print(); - mat.GaussJordan(true); + Gauss::GaussJordan(mat, true, true); mat.Print(); } diff --git a/test/test_jordan.cpp b/test/test_jordan.cpp index 6272486..d61e51a 100644 --- a/test/test_jordan.cpp +++ b/test/test_jordan.cpp @@ -1,3 +1,4 @@ +#include "Gauss.h" #include "Matrix.h" #include @@ -35,7 +36,7 @@ static const std::vector TEST_MATRICES = { void test() { for (Test test : TEST_MATRICES) { - test.mat.GaussJordan(true); + Gauss::GaussJordan(test.mat, true, true); assert(test.mat == test.res); } }