diff --git a/src/Matrix.cpp b/src/Matrix.cpp new file mode 100644 index 0000000..badb1fa --- /dev/null +++ b/src/Matrix.cpp @@ -0,0 +1,211 @@ +#include +#include +#include +#include + +#include "Matrix.h" + +Matrix::Matrix(const std::string& fileNameInput) { + Load(fileNameInput); +} + +Matrix::Matrix(std::size_t lignes, std::size_t colonnes) : m_Lignes(lignes), m_Colonnes(colonnes), m_Dimension(lignes * colonnes) { + m_Data.resize(m_Dimension); +} +Matrix::Matrix(std::size_t lignes, std::size_t colonnes, std::initializer_list&& initList) : + m_Lignes(lignes), m_Colonnes(colonnes), m_Dimension(lignes * colonnes) { + m_Data = initList; + m_Data.resize(m_Dimension); +} +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; + } + + Matrix result(m_Lignes, other.m_Colonnes); + + for (std::size_t i = 0; i < m_Lignes; ++i) { + for (std::size_t j = 0; j < other.m_Colonnes; ++j) { + long double sum = 0; + for (std::size_t k = 0; k < m_Colonnes; k++) { + sum += at(i, k) * other.at(k, j); + } + result.at(i, j) = sum; + } + } + return result; +} + +static bool IsEqualZero(long double var) { + return std::abs(var) < std::pow(10, -5); +} + +void Matrix::Print() const { + for (size_t i = 0; i < m_Lignes; ++i) { + std::cout << "[ "; + for (size_t j = 0; j < m_Colonnes; ++j) { + std::size_t indice = i * m_Lignes + j; + std::cout << at(i, j) << " "; + } + std::cout << "]"; + std::cout << std::endl; + } +} + +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) { + std::cin >> at(i, j); + } + std::cout << std::endl; + } +} + +void Matrix::Save(const std::string& fileName) { + std::ofstream out{fileName}; + if (!out) { + std::cerr << "Impossible de sauvegarder la matrice !\n"; + return; + } + out << m_Lignes << " " << m_Colonnes << "\n"; + for (std::size_t i = 0; i < m_Lignes; i++) { + for (std::size_t j = 0; j < m_Colonnes; j++) { + out << at(i, j) << " "; + } + out << "\n"; + } +} + +void Matrix::Load(const std::string& filename) { + std::ifstream in{filename}; + if (!in) { + std::cerr << "Impossible de charger la matrice !\n"; + return; + } + in >> m_Lignes >> m_Colonnes; + m_Data.resize(m_Lignes * m_Colonnes); + for (std::size_t i = 0; i < m_Lignes; i++) { + for (std::size_t j = 0; j < m_Colonnes; j++) { + in >> at(i, j); + } + } +} + +void Matrix::Transpose() { + for (std::size_t i = 0; i < m_Lignes; i++) { + for (std::size_t j = i; j < m_Colonnes; j++) { + std::swap(at(i, j), at(j, i)); + } + } +} + +void Matrix::Identity() { + for (std::size_t i = 0; i < m_Lignes; i++) { + for (std::size_t j = i; j < m_Colonnes; j++) { + if (i != j) { + at(i, j) = 0; + } else { + at(i, j) = 1; + } + } + } +} + +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; +} + +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 (at(indice_ligne_maximum, j) != 0) { + 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) { + for (std::size_t i = 0; i < m_Lignes; i++) { + int k = -1; + for (std::size_t j = 0; j < m_Colonnes; j++) { + if (at(i, j) != 0) { + 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]; +} + +long double& Matrix::at(std::size_t ligne, std::size_t colonne) { + return m_Data[ligne * m_Lignes + colonne]; +} + +long double Matrix::at(std::size_t ligne, std::size_t colonne) const { + return m_Data[ligne * m_Lignes + colonne]; +} \ No newline at end of file diff --git a/src/Matrix.h b/src/Matrix.h index f1cf252..ad80018 100644 --- a/src/Matrix.h +++ b/src/Matrix.h @@ -1,256 +1,48 @@ #pragma once -#include -#include -#include -#include +#include #include -template -static bool EqualZero(T var) { - return std::abs(var) < std::pow(10, -5); -} - -template class Matrix { private: std::size_t m_Lignes; std::size_t m_Colonnes; std::size_t m_Dimension; - std::vector m_Data; + std::vector m_Data; public: - Matrix(const std::string& fileNameInput) { - Load(fileNameInput); - } - Matrix(std::size_t lignes, std::size_t colonnes) : m_Lignes(lignes), m_Colonnes(colonnes), m_Dimension(lignes * colonnes) { - m_Data.resize(m_Dimension); - } - Matrix(std::size_t lignes, std::size_t colonnes, std::initializer_list&& initList) : - m_Lignes(lignes), m_Colonnes(colonnes), m_Dimension(lignes * colonnes) { - m_Data = initList; - m_Data.resize(m_Dimension); - } - ~Matrix() {} + Matrix(const std::string& fileNameInput); + Matrix(std::size_t lignes, std::size_t colonnes); + Matrix(std::size_t lignes, std::size_t colonnes, std::initializer_list&& initList); + ~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; - } + Matrix operator*(const Matrix& other) const; - Matrix result(m_Lignes, other.m_Colonnes); + void GaussNonJordan(bool reduite); - for (std::size_t i = 0; i < m_Lignes; ++i) { - for (std::size_t j = 0; j < other.m_Colonnes; ++j) { - T sum = 0; - for (std::size_t k = 0; k < m_Colonnes; k++) { - sum += at(i, k) * other.at(k, j); - } - result.at(i, j) = sum; - } - } - return result; - } + void GaussJordan(bool reduite); - void Print() const { - for (size_t i = 0; i < m_Lignes; ++i) { - std::cout << "[ "; - for (size_t j = 0; j < m_Colonnes; ++j) { - std::size_t indice = i * m_Lignes + j; - std::cout << at(i, j) << " "; - } - std::cout << "]"; - std::cout << std::endl; - } - } + void Print() const; - void PrintDebug() { -#ifndef NDEBUG - Print(); - std::cout << "\n"; -#endif - } + void PrintDebug(); - void Insert() { - for (size_t i = 0; i < m_Lignes; ++i) { - for (size_t j = 0; j < m_Colonnes; ++j) { - std::cin >> at(i, j); - } - std::cout << std::endl; - } - } + void Insert(); - void Save(const std::string& fileName) { - std::ofstream out{fileName}; - if (!out) { - std::cerr << "Impossible de sauvegarder la matrice !\n"; - return; - } - out << m_Lignes << " " << m_Colonnes << "\n"; - for (std::size_t i = 0; i < m_Lignes; i++) { - for (std::size_t j = 0; j < m_Colonnes; j++) { - out << at(i, j) << " "; - } - out << "\n"; - } - } + void Save(const std::string& fileName); - void Load(const std::string& filename) { - std::ifstream in{filename}; - if (!in) { - std::cerr << "Impossible de charger la matrice !\n"; - return; - } - in >> m_Lignes >> m_Colonnes; - m_Data.resize(m_Lignes * m_Colonnes); - for (std::size_t i = 0; i < m_Lignes; i++) { - for (std::size_t j = 0; j < m_Colonnes; j++) { - in >> at(i, j); - } - } - } + void Load(const std::string& filename); - void Transpose() { - for (std::size_t i = 0; i < m_Lignes; i++) { - for (std::size_t j = i; j < m_Colonnes; j++) { - std::swap(at(i, j), at(j, i)); - } - } - } + void Transpose(); - void Identity() { - for (std::size_t i = 0; i < m_Lignes; i++) { - for (std::size_t j = i; j < m_Colonnes; j++) { - if (i != j) { - at(i, j) = 0; - } else { - at(i, j) = 1; - } - } - } - } + void Identity(); - bool IsInverse(const Matrix& mat, const Matrix& aug) const { - Matrix result = mat * aug; + bool IsInversed() const; - for (std::size_t i = 0; i < m_Lignes; ++i) { - for (std::size_t j = 0; j < m_Colonnes; ++j) { - if ((i == j && !EqualZero(result.at(i, j) - 1.0)) || (i != j && EqualZero(result.at(i, j)))) { - return false; - } - } - } - return true; - } + long double& operator[](std::size_t indice); - Matrix GaussNonJordan(bool reduite, bool augmentee) { - Matrix aug = Matrix(m_Lignes, m_Colonnes); - if (augmentee) { - std::size_t choix; - std::cout - << "Entrez 1 pour rentrer la matrice augmentee que je vous voulez ou 2 pour la matrice augmentee Id pour trouver " - "l'inverse si elle existe." - << std::endl; - std::cin >> choix; - while (choix != 1 && choix != 2) { - std::cout - << "Entrez 1 pour rentrer la matrice augmentee que je vous voulez ou 2 pour la matrice augmentee Id pour trouver " - "l'inverse si elle existe." - << std::endl; - std::cin >> choix; - } - if (choix == 1) { - std::cout << "Rentrez les coefficients de la matrice" << std::endl; - aug.Insert(); - } else { - aug.Identity(); - } - } - aug.Print(); - int r = -1; - for (std::size_t j = 0; j < m_Colonnes; j++) { - std::size_t indice_ligne_maximum = r + 1; + long double& at(std::size_t ligne, std::size_t colonne); - // 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 (at(indice_ligne_maximum, j) != 0) { - 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)); - // matrice augmentee - std::swap(aug.at(indice_ligne_maximum, k), aug.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]) - T anulid = at(i, j); - for (int k = m_Colonnes - 1; k >= 0; k--) { - T pivot = at(r, j); - T anul = at(i, j); - at(i, k) = at(i, k) * pivot - at(r, k) * anul; - // matrice augmentee - aug.at(i, k) = aug.at(i, k) * pivot - aug.at(r, k) * anulid; - } - } - } - } - } - return (aug); - } - - Matrix GaussJordan(bool reduite, bool augmentee) { - Matrix aug = GaussNonJordan(reduite, augmentee); - for (std::size_t i = 0; i < m_Lignes; i++) { - int k = -1; - int kaugmentee = -1; - for (std::size_t j = 0; j < m_Colonnes; j++) { - if (at(i, j) != 0) { - k = j; - break; - } - } - // ligne de 0 - if (k == -1) - break; - // on divise la ligne par (i, k) - T annul = at(i, k); - for (int j = 0; j < m_Colonnes; j++) { - at(i, j) /= annul; - // augmentee - aug.at(i, j) /= annul; - } - } - return aug; - } - - T& operator[](std::size_t indice) { - return at(indice); - } - - T& at(std::size_t ligne, std::size_t colonne) { - return m_Data[ligne * m_Lignes + colonne]; - } - - T at(std::size_t ligne, std::size_t colonne) const { - return m_Data[ligne * m_Lignes + colonne]; - } + long double at(std::size_t ligne, std::size_t colonne) const; }; + +static bool IsEqualZero(long double var); \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 71b40a7..8b47e66 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,13 +1,14 @@ #include "Matrix.h" +#include void test() { - Matrix mat{"matrice5x5.mat"}; + Matrix mat{"matrice5x5.mat"}; mat.Print(); // mat.Save("matrice3x3.mat"); std::cout << "sdfdjiofoseifheoiefhoig\n"; mat.Print(); mat = {"matrice5x5.mat"}; - mat.GaussJordan(false, true); + mat.GaussJordan(false); std::cout << "\nResultat :\n"; mat.Print(); mat.Transpose(); @@ -24,17 +25,11 @@ void prompt() { std::cin >> colonnes; std::size_t dimension = lignes * colonnes; std::cout << "Rentrez les coefficients de la matrice" << std::endl; - Matrix mat(lignes, colonnes); + Matrix mat(lignes, colonnes); mat.Insert(); mat.Print(); - Matrix aug = mat.GaussJordan(true, true); - std::cout << std::endl; - std::cout << "Matrice echelonnee reduite" << std::endl; - mat.Print(); - std::cout << "Matrice augmentee" << std::endl; - aug.Print(); } int main(int argc, char** argv) {