diff --git a/include/Gauss.h b/include/Gauss.h index 0b448c1..0a50ec5 100644 --- a/include/Gauss.h +++ b/include/Gauss.h @@ -10,11 +10,19 @@ class Matrix; namespace Gauss { /** - * \brief Echelonne une matrice en utilisant l'algorithme de Gauss-Jordan - * \param mat La matrice à échelonner - * \param reduite Mets des 0 au dessus des pivots - * \param normalise Mets les pivots à 1 + * \brief Echelonne une matrice en ligne en utilisant l'algorithme de Gauss-Jordan + * \param a_Matrix La matrice à échelonner + * \param a_Reduite Mets des 0 au dessus des pivots + * \param a_Normalise Mets les pivots à 1 */ void GaussJordan(Matrix& a_Matrix, bool a_Reduite, bool a_Normalise); +/** + * \brief Echelonne une matrice en colonne en utilisant l'algorithme de Gauss-Jordan + * \param a_Matrix La matrice à échelonner + * \param a_Reduite Mets des 0 au dessus des pivots + * \param a_Normalise Mets les pivots à 1 + */ +void GaussJordanColumn(Matrix& a_Matrix, bool a_Reduite, bool a_Normalise); + } // namespace Gauss \ No newline at end of file diff --git a/src/Gauss.cpp b/src/Gauss.cpp index 08aefba..dff05c6 100644 --- a/src/Gauss.cpp +++ b/src/Gauss.cpp @@ -10,12 +10,24 @@ static void SwapLines(Matrix& mat, std::size_t line1, std::size_t line2) { } } +static void SwapColumns(Matrix& mat, std::size_t column1, std::size_t column2) { + for (std::size_t k = 0; k < mat.GetRawCount(); k++) { + std::swap(mat.at(k, column1), mat.at(k, column2)); + } +} + static void DivideLine(Matrix& mat, std::size_t line, Matrix::Element number) { for (std::size_t j = 0; j < mat.GetColumnCount(); j++) { mat.at(line, j) /= number; } } +static void DivideColumn(Matrix& mat, std::size_t column, Matrix::Element number) { + for (std::size_t j = 0; j < mat.GetRawCount(); j++) { + mat.at(j, column) /= number; + } +} + static int FirstNotNullElementIndexOnColumn(Matrix& mat, std::size_t column, std::size_t startLine = 0) { for (std::size_t i = startLine; i < mat.GetRawCount(); i++) { if (!IsEqualZero(mat.at(i, column))) { @@ -25,6 +37,15 @@ static int FirstNotNullElementIndexOnColumn(Matrix& mat, std::size_t column, std return -1; } +static int FirstNotNullElementIndexOnLine(Matrix& mat, std::size_t line, std::size_t startColumn = 0) { + for (std::size_t i = startColumn; i < mat.GetColumnCount(); i++) { + if (!IsEqualZero(mat.at(line, i))) { + return i; + } + } + return -1; +} + static void SimplifyLine(Matrix& mat, std::size_t line, std::size_t pivot_line, std::size_t pivot_column) { const Matrix::Element pivot = mat.at(pivot_line, pivot_column); const Matrix::Element anul = mat.at(line, pivot_column); @@ -34,6 +55,15 @@ static void SimplifyLine(Matrix& mat, std::size_t line, std::size_t pivot_line, } } +static void SimplifyColumn(Matrix& mat, std::size_t column, std::size_t pivot_line, std::size_t pivot_column) { + const Matrix::Element pivot = mat.at(pivot_line, pivot_column); + const Matrix::Element anul = mat.at(pivot_line, column); + + for (std::size_t j = 0; j < mat.GetRawCount(); j++) { + mat.at(j, column) = mat.at(j, column) * pivot - mat.at(j, pivot_column) * anul; + } +} + void GaussJordan(Matrix& a_Matrix, bool a_Reduite, bool a_Normalise) { int indice_ligne_pivot = -1; @@ -66,4 +96,36 @@ void GaussJordan(Matrix& a_Matrix, bool a_Reduite, bool a_Normalise) { } } +void GaussJordanColumn(Matrix& a_Matrix, bool a_Reduite, bool a_Normalise) { + int indice_colonne_pivot = -1; + + for (std::size_t j = 0; j < a_Matrix.GetRawCount(); j++) { + + int indice_colonne_pivot_trouve = FirstNotNullElementIndexOnLine(a_Matrix, j, indice_colonne_pivot + 1); + + if (indice_colonne_pivot_trouve < 0) // ligne de 0 + continue; // on regarde la prochaine ligne + + indice_colonne_pivot++; + + if (indice_colonne_pivot_trouve != indice_colonne_pivot) { + SwapColumns(a_Matrix, indice_colonne_pivot_trouve, indice_colonne_pivot); + } + + Matrix::Element pivot = a_Matrix.at(j, indice_colonne_pivot); + + if (a_Normalise) { + DivideColumn(a_Matrix, indice_colonne_pivot, pivot); + } + + // On simplifie les autres lignes + for (std::size_t i = (a_Reduite ? 0 : j); i < a_Matrix.GetColumnCount(); i++) { + // Pour les lignes autre que la ligne pivot + if (i != static_cast(indice_colonne_pivot)) { + SimplifyColumn(a_Matrix, i, j, indice_colonne_pivot); + } + } + } +} + } // namespace Gauss \ No newline at end of file