refactor project

This commit is contained in:
2024-02-23 10:48:43 +01:00
parent 82ad2e0696
commit 3b07ae783f
8 changed files with 103 additions and 119 deletions

75
src/Gauss.cpp Normal file
View File

@@ -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

9
src/Gauss.h Normal file
View File

@@ -0,0 +1,9 @@
#pragma once
class Matrix;
namespace Gauss {
void GaussJordan(Matrix& mat, bool reduite, bool normalise);
} // namespace Gauss

View File

@@ -25,6 +25,7 @@ Matrix::~Matrix() {}
Matrix Matrix::operator*(const Matrix& other) const { Matrix Matrix::operator*(const Matrix& other) const {
if (m_Colonnes != other.m_Lignes) { if (m_Colonnes != other.m_Lignes) {
std::cerr << "Mutiplication impossible car la dimensions des matrices est incompatible" << std::endl; std::cerr << "Mutiplication impossible car la dimensions des matrices est incompatible" << std::endl;
return {1, 1, {0}};
} }
Matrix result(m_Lignes, other.m_Colonnes); 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() { void Matrix::Insert() {
for (size_t i = 0; i < m_Lignes; ++i) { for (size_t i = 0; i < m_Lignes; ++i) {
for (size_t j = 0; j < m_Colonnes; ++j) { for (size_t j = 0; j < m_Colonnes; ++j) {
@@ -97,32 +91,14 @@ void Matrix::Transpose() {
*this = result; *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 Matrix::Identity(std::size_t taille) {
Matrix id {taille, taille}; Matrix id {taille, taille};
id.Identity(); for (std::size_t i = 0; i < taille; i++) {
return id; for (std::size_t j = i; j < taille; j++) {
} id.at(i, j) = (i == j);
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;
} }
} }
return true; return id;
} }
void Matrix::Augmenter(const Matrix& droite) { void Matrix::Augmenter(const Matrix& droite) {
@@ -158,72 +134,6 @@ bool Matrix::operator==(const Matrix& other) const {
return true; 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) { long double& Matrix::operator[](std::size_t indice) {
return m_Data[indice]; return m_Data[indice];
} }

View File

@@ -20,40 +20,25 @@ class Matrix {
std::size_t GetRawCount() const; std::size_t GetRawCount() const;
std::size_t GetColumnCount() const; std::size_t GetColumnCount() const;
Matrix operator*(const Matrix& other) const; void Insert();
void GaussNonJordan(bool reduite);
void GaussJordan(bool reduite);
void Print() const; void Print() const;
void PrintDebug();
void Insert();
void Save(const std::string& fileName); void Save(const std::string& fileName);
void Load(const std::string& filename); void Load(const std::string& filename);
void Transpose(); void Transpose();
void Identity();
static Matrix Identity(std::size_t taille); static Matrix Identity(std::size_t taille);
bool IsInversed() const;
void Augmenter(const Matrix& droite); 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; 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; bool operator==(const Matrix& other) const;
Matrix operator*(const Matrix& other) const;
long double& operator[](std::size_t indice); 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);
long double at(std::size_t ligne, std::size_t colonne) const; long double at(std::size_t ligne, std::size_t colonne) const;
friend std::ostream& operator<<(std::ostream& stream, const Matrix& mat); friend std::ostream& operator<<(std::ostream& stream, const Matrix& mat);

View File

@@ -1,11 +1,13 @@
#include "Solver.h" #include "Solver.h"
#include "Gauss.h"
Solver::Solver(const Matrix& mat) : m_Matrix(mat) {} Solver::Solver(const Matrix& mat) : m_Matrix(mat) {}
Vect Solver::Image() const { Vect Solver::Image() const {
Matrix result = m_Matrix; Matrix result = m_Matrix;
result.Transpose(); result.Transpose();
result.GaussJordan(true); Gauss::GaussJordan(result, true, true);
result.Transpose(); result.Transpose();
return {result}; return {result};
} }
@@ -15,7 +17,7 @@ Vect Solver::Noyau() const {
Matrix result = m_Matrix; Matrix result = m_Matrix;
result.Transpose(); result.Transpose();
result.Augmenter(Matrix::Identity(result.GetRawCount())); result.Augmenter(Matrix::Identity(result.GetRawCount()));
result.GaussJordan(true); Gauss::GaussJordan(result, true, true);
result.Transpose(); result.Transpose();
// nombre de colonnes non nulles // nombre de colonnes non nulles
@@ -27,7 +29,7 @@ Vect Solver::Noyau() const {
VectAffine Solver::SystemeTriangulaire() const { VectAffine Solver::SystemeTriangulaire() const {
Matrix mat = m_Matrix; Matrix mat = m_Matrix;
mat.GaussJordan(true); Gauss::GaussJordan(mat, true, true);
Solver solver {mat.SubMatrix(0, 0, mat.GetRawCount(), mat.GetColumnCount() - 1)}; Solver solver {mat.SubMatrix(0, 0, mat.GetRawCount(), mat.GetColumnCount() - 1)};

View File

@@ -1,5 +1,6 @@
#include "Vect.h" #include "Vect.h"
#include "Gauss.h"
#include "Solver.h" #include "Solver.h"
#include <cassert> #include <cassert>
#include <iostream> #include <iostream>
@@ -45,7 +46,7 @@ bool Vect::operator==(const Vect& other) const {
void Vect::AddVector(const Matrix& mat) { void Vect::AddVector(const Matrix& mat) {
m_Data.Augmenter(mat); m_Data.Augmenter(mat);
m_Data.Transpose(); m_Data.Transpose();
m_Data.GaussNonJordan(false); Gauss::GaussJordan(m_Data, false, false);
m_Data.Transpose(); m_Data.Transpose();
Simplify(); Simplify();
} }
@@ -68,7 +69,7 @@ void Vect::Print() const {
std::cout << "Espace vectoriel de dimension " << GetCardinal() << " de base :\n\n"; 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 i = 0; i < m_Data.GetRawCount(); i++) {
for (std::size_t j = 0; j < m_Data.GetColumnCount(); j++) { for (std::size_t j = 0; j < m_Data.GetColumnCount(); j++) {
printf("[ %u ]\t", static_cast<float>(m_Data.at(i, j))); printf("[ %d ]\t", static_cast<float>(m_Data.at(i, j)));
} }
std::cout << "\n"; std::cout << "\n";
} }

View File

@@ -1,3 +1,4 @@
#include "Gauss.h"
#include "Solver.h" #include "Solver.h"
#include <iostream> #include <iostream>
@@ -52,7 +53,7 @@ void prompt() {
mat.Print(); mat.Print();
mat.GaussJordan(true); Gauss::GaussJordan(mat, true, true);
mat.Print(); mat.Print();
} }

View File

@@ -1,3 +1,4 @@
#include "Gauss.h"
#include "Matrix.h" #include "Matrix.h"
#include <cassert> #include <cassert>
@@ -35,7 +36,7 @@ static const std::vector<Test> TEST_MATRICES = {
void test() { void test() {
for (Test test : TEST_MATRICES) { for (Test test : TEST_MATRICES) {
test.mat.GaussJordan(true); Gauss::GaussJordan(test.mat, true, true);
assert(test.mat == test.res); assert(test.mat == test.res);
} }
} }