From a135df2e96c47d5612c3e44e8e9a3c27165945de Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Tue, 14 May 2024 13:00:59 +0200 Subject: [PATCH] trop de trucs --- include/BigInt.h | 49 --------------------- include/IO.h | 4 -- include/Matrix.h | 12 +++--- include/NR.h | 17 ++++---- src/BigInt.cpp | 86 ------------------------------------- src/IO.cpp | 12 ------ src/Matrix.cpp | 2 + src/NR.cpp | 43 +++++++++++-------- src/Solver.cpp | 7 ++- src/Vect.cpp | 2 +- src/gui/PivotGui.cpp | 34 ++++++++++----- test/test_random_kernel.cpp | 20 ++++++--- test/test_solver.cpp | 22 ++++++---- xmake.lua | 2 - 14 files changed, 98 insertions(+), 214 deletions(-) delete mode 100644 include/BigInt.h delete mode 100644 src/BigInt.cpp diff --git a/include/BigInt.h b/include/BigInt.h deleted file mode 100644 index 41d7ecd..0000000 --- a/include/BigInt.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include -#include - -/** - * \class BigInt - * \brief Représente un entier d'une taille quelconque - * \warning Prend énormément de place en mémoire. À utiliser avec précaution ! -*/ -class BigInt { - private: - mpz_t m_Data; - - public: - BigInt(std::string&& a_Number); - - BigInt(long a_Number = 0); - - BigInt(const BigInt& a_Copy); - - BigInt(BigInt&& a_Move); - - ~BigInt(); - - BigInt operator+(const BigInt& a_Other); - - BigInt operator-(const BigInt& a_Other); - - BigInt operator*(const BigInt& a_Other); - - BigInt operator/(const BigInt& a_Other); - - BigInt operator+=(const BigInt& a_Other); - - BigInt operator-=(const BigInt& a_Other); - - BigInt operator*=(const BigInt& a_Other); - - BigInt operator/=(const BigInt& a_Other); - - bool operator==(const BigInt& a_Other); - - void operator=(const BigInt& a_Other); - - const std::string ToString() const; - - bool IsEqualZero() const; -}; \ No newline at end of file diff --git a/include/IO.h b/include/IO.h index 8f62402..01d6d45 100644 --- a/include/IO.h +++ b/include/IO.h @@ -10,14 +10,10 @@ class Matrix; class Vect; class VectAffine; -class BigInt; std::ostream& operator<<(std::ostream& stream, const Matrix& mat); std::istream& operator>>(std::istream& stream, Matrix& mat); -std::ostream& operator<<(std::ostream& stream, const BigInt& nbre); -std::istream& operator>>(std::istream& stream, BigInt& nbre); - /** * \brief Charge une matrice à partir d'un fichier * \param fileName Le chemin du fichier à charger diff --git a/include/Matrix.h b/include/Matrix.h index a0a8a70..c0b6df5 100644 --- a/include/Matrix.h +++ b/include/Matrix.h @@ -10,7 +10,7 @@ #include #include -#include "BigInt.h" +#include "NR.h" /** * \class Matrix @@ -18,7 +18,7 @@ */ class Matrix { public: - typedef long double Element; + typedef NR Element; typedef std::vector::iterator iterator; private: @@ -151,7 +151,7 @@ class Matrix { iterator begin(); iterator end(); - + iterator GetLineIterator(std::size_t a_Raw); }; @@ -171,6 +171,6 @@ inline bool IsEqualZero(const long& var) { } template <> -inline bool IsEqualZero(const BigInt& var) { - return var.IsEqualZero(); -} \ No newline at end of file +inline bool IsEqualZero(const NR& var) { + return var == 0; +} diff --git a/include/NR.h b/include/NR.h index 5799569..27f5872 100644 --- a/include/NR.h +++ b/include/NR.h @@ -3,17 +3,20 @@ #include class NR { + public: + using Int = long long; + private: - int m_Numerator; - int m_Denominator; // has to be > 0, sign is carried by the numerator + Int m_Numerator; + Int m_Denominator; // has to be > 0, sign is carried by the numerator public: NR(); - NR(int entier); - NR(int numerator, int denominator); // check if denominator != 0 + NR(Int entier); + NR(Int numerator, Int denominator); // check if denominator != 0 - int GetNumerator() const; - int GetDenominator() const; + Int GetNumerator() const; + Int GetDenominator() const; bool operator==(const NR& opNR) const; bool operator<(const NR& opNR) const; @@ -43,5 +46,3 @@ class NR { private: void Reduce(); }; - -int PGCD(int x, int y); diff --git a/src/BigInt.cpp b/src/BigInt.cpp deleted file mode 100644 index abd4b05..0000000 --- a/src/BigInt.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "BigInt.h" - -#include - -BigInt::~BigInt() { - mpz_clear(m_Data); -} - -BigInt::BigInt(BigInt&& a_Move) { - std::swap(m_Data, a_Move.m_Data); -} - -BigInt::BigInt(std::string&& a_Number) { - mpz_init_set_str(m_Data, a_Number.c_str(), 10); -} - -BigInt::BigInt(long a_Number) { - mpz_init_set_si(m_Data, a_Number); -} - -BigInt::BigInt(const BigInt& a_Copy) { - mpz_init_set(m_Data, a_Copy.m_Data); -} - -void BigInt::operator=(const BigInt& a_Other) { - mpz_init_set(m_Data, a_Other.m_Data); -} - -BigInt BigInt::operator+(const BigInt& a_Other) { - BigInt result = *this; - result += a_Other; - return result; -} - -BigInt BigInt::operator-(const BigInt& a_Other) { - BigInt result = *this; - result -= a_Other; - return result; -} - -BigInt BigInt::operator*(const BigInt& a_Other) { - BigInt result = *this; - result *= a_Other; - return result; -} - -BigInt BigInt::operator/(const BigInt& a_Other) { - BigInt result = *this; - result /= a_Other; - return result; -} - -BigInt BigInt::operator+=(const BigInt& a_Other) { - mpz_add(m_Data, m_Data, a_Other.m_Data); - return *this; -} - -BigInt BigInt::operator-=(const BigInt& a_Other) { - mpz_sub(m_Data, m_Data, a_Other.m_Data); - return *this; -} - -BigInt BigInt::operator*=(const BigInt& a_Other) { - mpz_mul(m_Data, m_Data, a_Other.m_Data); - return *this; -} - -BigInt BigInt::operator/=(const BigInt& a_Other) { - mpz_divexact(m_Data, m_Data, a_Other.m_Data); - return *this; -} - -bool BigInt::operator==(const BigInt& a_Other) { - return mpz_cmp(m_Data, a_Other.m_Data) == 0; -} - -const std::string BigInt::ToString() const { - std::string result; - result.reserve(mpz_sizeinbase(m_Data, 10) + 2); - mpz_get_str(result.data(), 10, m_Data); - return result.c_str(); -} - -bool BigInt::IsEqualZero() const { - return mpz_cmp_si(m_Data, 0) == 0; -} \ No newline at end of file diff --git a/src/IO.cpp b/src/IO.cpp index 495056a..800a3cd 100644 --- a/src/IO.cpp +++ b/src/IO.cpp @@ -31,18 +31,6 @@ std::istream& operator>>(std::istream& stream, Matrix& mat) { return stream; } -std::ostream& operator<<(std::ostream& stream, const BigInt& nbre) { - stream << nbre.ToString(); - return stream; -} - -std::istream& operator>>(std::istream& stream, BigInt& nbre) { - long value; - stream >> value; - nbre = BigInt(value); - return stream; -} - Matrix LoadMatrix(const std::string& fileName) { std::ifstream in {fileName}; if (!in) { diff --git a/src/Matrix.cpp b/src/Matrix.cpp index 9b18995..35a50a9 100644 --- a/src/Matrix.cpp +++ b/src/Matrix.cpp @@ -154,10 +154,12 @@ bool Matrix::operator==(const Matrix& a_Other) const { } Matrix::Element& Matrix::at(std::size_t a_Raw, std::size_t a_Column) { + assert(a_Raw < m_Raws && a_Column < m_Columns); return m_Data[a_Raw * m_Columns + a_Column]; } Matrix::Element Matrix::at(std::size_t a_Raw, std::size_t a_Column) const { + assert(a_Raw < m_Raws && a_Column < m_Columns); return m_Data[a_Raw * m_Columns + a_Column]; } diff --git a/src/NR.cpp b/src/NR.cpp index 19526b2..7ebdc0e 100644 --- a/src/NR.cpp +++ b/src/NR.cpp @@ -3,7 +3,7 @@ #include #include -int PGCD(int x, int y) { +NR::Int PGCD(NR::Int x, NR::Int y) { if (x == 0 || y == 0) return 1; else if (x % y == 0) @@ -14,18 +14,18 @@ int PGCD(int x, int y) { NR::NR() : m_Numerator(0), m_Denominator(1) {} -NR::NR(int entier) : m_Numerator(entier), m_Denominator(1) {} +NR::NR(NR::Int entier) : m_Numerator(entier), m_Denominator(1) {} -NR::NR(int numerator, int denominator) : +NR::NR(NR::Int numerator, NR::Int denominator) : m_Numerator((denominator > 0) ? numerator : -numerator), m_Denominator(std::abs(denominator)) { - assert(denominator != 0); Reduce(); } void NR::Reduce() { - int divisor = PGCD(m_Denominator, m_Numerator); + NR::Int divisor = PGCD(m_Denominator, m_Numerator); m_Denominator /= divisor; m_Numerator /= divisor; + assert(m_Denominator != 0); } NR NR::Inverse() const { @@ -33,11 +33,11 @@ NR NR::Inverse() const { return {m_Denominator, m_Numerator}; } -int NR::GetNumerator() const { +NR::Int NR::GetNumerator() const { return m_Numerator; } -int NR::GetDenominator() const { +NR::Int NR::GetDenominator() const { return m_Denominator; } @@ -66,48 +66,57 @@ bool NR::operator>=(const NR& opNR) const { } std::ostream& operator<<(std::ostream& os, const NR& opNR) { - os << opNR.GetNumerator() << "/" << opNR.GetDenominator(); + os << opNR.GetNumerator(); + if (opNR.GetDenominator() != 1) + os << "/" << opNR.GetDenominator(); return os; } std::istream& operator>>(std::istream& is, NR& opNR) { char slash; - is >> opNR.m_Numerator >> slash >> opNR.m_Denominator; + is >> opNR.m_Numerator >> slash; + if (slash != '/') { + // on revient un charactère en arrière + is.seekg(is.tellg() - static_cast(1)); + opNR.m_Denominator = 1; + } else { + is >> opNR.m_Denominator; + } opNR.Reduce(); return is; } NR NR::operator+(const NR& opNR) const { - int num, den; + Int num, den; num = m_Numerator * opNR.GetDenominator(); den = m_Denominator * opNR.GetDenominator(); num += (opNR.GetNumerator() * m_Denominator); - NR result(num, den); + NR result(num, num == 0 ? 1 : den); return result; } NR NR::operator-(const NR& opNR) const { - int num, den; + Int num, den; num = m_Numerator * opNR.GetDenominator(); den = m_Denominator * opNR.GetDenominator(); num -= (opNR.GetNumerator() * m_Denominator); - NR result(num, den); + NR result(num, num == 0 ? 1 : den); return result; } NR NR::operator*(const NR& opNR) const { - int num, den; + Int num, den; num = m_Numerator * opNR.GetNumerator(); den = m_Denominator * opNR.GetDenominator(); - NR result(num, den); + NR result(num, num == 0 ? 1 : den); return result; } NR NR::operator/(const NR& opNR) const { - int num, den; + Int num, den; num = m_Numerator * opNR.GetDenominator(); den = m_Denominator * opNR.GetNumerator(); - NR result(num, den); + NR result(num, num == 0 ? 1 : den); return result; } diff --git a/src/Solver.cpp b/src/Solver.cpp index 8091857..fc61df9 100644 --- a/src/Solver.cpp +++ b/src/Solver.cpp @@ -25,7 +25,7 @@ Vect Solver::Kernel(Matrix&& a_Matrix) const { a_Matrix.Transpose(); a_Matrix.Augment(Matrix::Identity(a_Matrix.GetRawCount())); - Gauss::GaussJordan(a_Matrix, false, false); + Gauss::GaussJordan(a_Matrix, false, true); a_Matrix.Transpose(); // nombre de colonnes non nulles @@ -45,9 +45,8 @@ VectAffine Solver::RectangularSystem(Matrix&& a_MatrixA, const Matrix& a_VectorB Vect noyau = solver.Kernel(std::move(a_MatrixA)); Matrix origin = mat.SubMatrix(0, mat.GetColumnCount() - 1, mat.GetRawCount(), 1); - // on rajoute des 0 si il faut - - Matrix fullOrigin {mat.GetColumnCount(), 1}; + // on calcule le vecteur qui dirige l'espace affine + Matrix fullOrigin {mat.GetColumnCount() - 1, 1}; for (std::size_t i = 0; i < mat.GetRawCount(); i++) { int pivot_index = FirstNotNullElementIndexOnLine(mat, i); diff --git a/src/Vect.cpp b/src/Vect.cpp index 4747ae3..da02e59 100644 --- a/src/Vect.cpp +++ b/src/Vect.cpp @@ -14,7 +14,7 @@ static bool IsColumnNull(Matrix& mat, std::size_t column) { Vect::Vect(Matrix&& a_Matrix) : m_Data(std::move(a_Matrix)) { m_Data.Transpose(); - Gauss::GaussJordan(m_Data, false, false); + Gauss::GaussJordan(m_Data, false, true); m_Data.Transpose(); Simplify(); } diff --git a/src/gui/PivotGui.cpp b/src/gui/PivotGui.cpp index 3885f16..f4636fa 100644 --- a/src/gui/PivotGui.cpp +++ b/src/gui/PivotGui.cpp @@ -3,6 +3,7 @@ #include "Matrix.h" #include "Solver.h" #include +#include static std::string equationsResultImage; @@ -16,6 +17,12 @@ static Matrix LoadMatrixFromStdVect(const std::vector>& data) { return result; } +static std::string ElementToString(Matrix::Element e) { + std::stringstream ss; + ss << e; + return ss.str(); +} + static std::string PrintVect(const Vect& vect) { if (vect.GetCardinal() == 0) return "{0}"; @@ -25,11 +32,13 @@ static std::string PrintVect(const Vect& vect) { Matrix vector = vect.GetVector(i); result += " ("; for (std::size_t j = 0; j < vect.GetDimension(); j++) { - result += std::to_string(static_cast(vector.at(j, 0))) + ", "; + result += ElementToString(vector.at(j, 0)) + ", "; } + result = result.substr(0, result.size() - 2); result += " ), "; } - result += " )"; + result = result.substr(0, result.size() - 2); + result += " )"; return result; } @@ -43,6 +52,8 @@ void PivotGui::Render() { static int matrixSizeY = 4; static Solver solver; + static bool refresh = true; + // divisions des fenetres ImVec2 topLeftWindowSize(io.DisplaySize.x * 0.5f, io.DisplaySize.y * 0.8f); ImVec2 topRightWindowSize(io.DisplaySize.x * 0.5f, io.DisplaySize.y * 0.8f); @@ -59,13 +70,15 @@ void PivotGui::Render() { ImGui::Text("Matrice initiale:"); - ImGui::InputInt("##RowsMatriceInitiale", &matrixSizeY); + if (ImGui::InputInt("##RowsMatriceInitiale", &matrixSizeY)) + refresh = true; matrixSizeY = std::max(1, matrixSizeY); ImGui::SameLine(); ImGui::Text("Lignes"); - ImGui::InputInt("##ColumnsMatriceInitiale", &matrixSizeX); + if (ImGui::InputInt("##ColumnsMatriceInitiale", &matrixSizeX)) + refresh = true; matrixSizeX = std::max(1, matrixSizeX); ImGui::SameLine(); ImGui::Text("Colonnes"); @@ -76,13 +89,13 @@ void PivotGui::Render() { // Resize matrixValues and initialize new elements to 0 - matrixValues.resize(matrixSizeY); - for (auto& row : matrixValues) { - row.resize(matrixSizeX, 0); + if (refresh) { + matrixValues.resize(matrixSizeY); + for (auto& row : matrixValues) { + row.resize(matrixSizeX, 0); + } } - bool refresh = false; - for (int y = 0; y < matrixSizeY; y++) { for (int x = 0; x < matrixSizeX; x++) { if (x > 0) @@ -136,7 +149,7 @@ void PivotGui::Render() { for (size_t i = 0; i < linearSystem.GetRawCount(); ++i) { for (size_t j = 0; j < linearSystem.GetColumnCount(); ++j) { equationsResultImage += - std::to_string(static_cast(linearSystem.at(i, j))) + "*" + std::string {static_cast('a' + j)} + " + "; + ElementToString(linearSystem.at(i, j)) + "*" + std::string {static_cast('a' + j)} + " + "; } equationsResultImage = equationsResultImage.substr(0, equationsResultImage.size() - 3) + " = 0\n"; } @@ -146,6 +159,7 @@ void PivotGui::Render() { PrintVect(image); } + refresh = false; ImGui::End(); // End fenetre bas } diff --git a/test/test_random_kernel.cpp b/test/test_random_kernel.cpp index 31e326e..009b80d 100644 --- a/test/test_random_kernel.cpp +++ b/test/test_random_kernel.cpp @@ -6,14 +6,14 @@ #include #include -static constexpr int EXECUTION_COUNT = 10; +static constexpr int EXECUTION_COUNT = 1000; static constexpr int KERNEL_CHECKS = 100; -static constexpr int MATRIX_MAX_SIZE = 10; +static constexpr int MATRIX_MAX_SIZE = 9; static const Solver solver; -static unsigned int GetRandomInt() { - return rand() % MATRIX_MAX_SIZE + 1; +static int GetRandomInt() { + return rand() % 11 - 5; } static Matrix GetRandomMatrix(std::size_t a_Raw, std::size_t a_Column) { @@ -28,8 +28,8 @@ static Matrix GetRandomMatrix(std::size_t a_Raw, std::size_t a_Column) { return matrix; } -static void Test() { - Matrix matrix = GetRandomMatrix(GetRandomInt(), GetRandomInt()); +static bool Test() { + Matrix matrix = GetRandomMatrix(rand() % MATRIX_MAX_SIZE + 1, rand() % MATRIX_MAX_SIZE + 1); for (std::size_t i = 0; i < matrix.GetRawCount(); i++) { for (std::size_t j = 0; j < matrix.GetColumnCount(); j++) { @@ -57,12 +57,13 @@ static void Test() { Vect kernel2 = solver.Kernel(kernel.GetLinearSystem()); test_assert(kernel == kernel2); + return true; } int main() { srand(time(0)); - std::vector> results; + std::vector> results; // appelle la fonction Test() en parallèle for (int i = 0; i < EXECUTION_COUNT; i++) { @@ -70,5 +71,10 @@ int main() { results.push_back(std::move(handle)); } + for (auto& result : results) { + if (!result.get()) + return EXIT_FAILURE; + } + return EXIT_SUCCESS; } diff --git a/test/test_solver.cpp b/test/test_solver.cpp index 6458f3b..0b126d1 100644 --- a/test/test_solver.cpp +++ b/test/test_solver.cpp @@ -1,7 +1,7 @@ +#include #include #include #include -#include #include "IO.h" #include "Solver.h" @@ -9,18 +9,22 @@ namespace fs = std::filesystem; -const static int EXECUTION_COUNT = 100; -static constexpr int MATRIX_MAX_SIZE = 20; +const static int EXECUTION_COUNT = 10000; +static constexpr int MATRIX_MAX_SIZE = 7; -static unsigned int GetRandomInt() { +static int GetRandomSize() { return rand() % MATRIX_MAX_SIZE + 1; } +static int GetRandomInt() { + return GetRandomSize(); +} + static Matrix GetRandomMatrix(std::size_t a_Raw, std::size_t a_Column) { Matrix matrix {a_Raw, a_Column}; - std::generate(matrix.GetLineIterator(0), matrix.GetLineIterator(a_Raw), [](){ - return GetRandomInt(); + std::generate(matrix.GetLineIterator(0), matrix.GetLineIterator(a_Raw), []() { + return GetRandomInt(); }); return matrix; @@ -33,14 +37,15 @@ void TestRectangular(const Matrix& system, const Matrix& origin) { for (std::size_t i = 0; i < solution.GetBase().GetCardinal(); i++) { Matrix vector = solution.GetBase().GetVector(i) + solution.GetOrigin(); - test_assert(system * vector == origin); + Matrix product = system * vector; + test_assert(product == origin); } } void RandomRectangular() { for (int i = 0; i < EXECUTION_COUNT; i++) { - Matrix system = GetRandomMatrix(GetRandomInt(), GetRandomInt()); + Matrix system = GetRandomMatrix(GetRandomSize(), GetRandomSize()); Matrix origin = GetRandomMatrix(system.GetRawCount(), 1); @@ -76,6 +81,7 @@ void TestKernelImage() { } int main() { + srand(time(0)); TestKernelImage(); RandomRectangular(); return 0; diff --git a/xmake.lua b/xmake.lua index f1a58cf..b1f574c 100644 --- a/xmake.lua +++ b/xmake.lua @@ -2,12 +2,10 @@ add_rules("mode.debug", "mode.release") add_requires("libsdl 2.28.3", {configs = {sdlmain = false}}) add_requires("imgui", {configs = {sdl2_no_renderer = true, opengl3 = true}}) -add_requires("gmp"); set_languages("c++20") set_warnings("all") add_includedirs("include") -add_packages("gmp") -- Solver Library target("Pivot")