From 7f1ef38286f4a8ea65a27860dadb5d7b6268ea69 Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Sun, 12 May 2024 09:23:37 +0200 Subject: [PATCH] fix solver --- include/Matrix.h | 2 +- src/Solver.cpp | 18 ++++++++++----- test/test_solver.cpp | 53 ++++++++++++++++++++++++++++++++++++-------- 3 files changed, 58 insertions(+), 15 deletions(-) diff --git a/include/Matrix.h b/include/Matrix.h index 25c23a4..a0a8a70 100644 --- a/include/Matrix.h +++ b/include/Matrix.h @@ -18,7 +18,7 @@ */ class Matrix { public: - typedef BigInt Element; + typedef long double Element; typedef std::vector::iterator iterator; private: diff --git a/src/Solver.cpp b/src/Solver.cpp index a1a19d2..e7a01a1 100644 --- a/src/Solver.cpp +++ b/src/Solver.cpp @@ -2,6 +2,15 @@ #include "Gauss.h" +static int FirstNotNullElementIndexOnLine(const Matrix& mat, std::size_t line) { + for (std::size_t i = 0; i < mat.GetColumnCount(); i++) { + if (!IsEqualZero(mat.at(line, i))) { + return i; + } + } + return -1; +} + Vect Solver::Image(Matrix&& a_Matrix) const { a_Matrix.Transpose(); Gauss::GaussJordan(a_Matrix, false, false); @@ -40,11 +49,10 @@ VectAffine Solver::RectangularSystem(Matrix&& a_MatrixA, const Matrix& a_VectorB Matrix fullOrigin {mat.GetColumnCount() - 1, 1}; for (std::size_t i = 0; i < mat.GetRawCount(); i++) { - fullOrigin.at(i, 0) = origin.at(i, 0); - } - - for (std::size_t i = mat.GetRawCount(); i < mat.GetColumnCount() - 1; i++) { - fullOrigin.at(i, 0) = 0; + int pivot_index = FirstNotNullElementIndexOnLine(mat, i); + if(pivot_index >= 0){ + fullOrigin.at(pivot_index, 0) = origin.at(i, 0); + } } return {noyau, fullOrigin}; diff --git a/test/test_solver.cpp b/test/test_solver.cpp index bebb537..7be444d 100644 --- a/test/test_solver.cpp +++ b/test/test_solver.cpp @@ -8,18 +8,53 @@ namespace fs = std::filesystem; -void TestRectangular() { - Matrix mat2 = {2, 4, { - 1, 1, 1, 1, - 1, -1, -1, 2 - }}; +const static int EXECUTION_COUNT = 100; +static constexpr int MATRIX_MAX_SIZE = 5; - VectAffine aff {Matrix::ColumnVector({0, -1, 1}), Matrix::ColumnVector({3, 0, -1})}; +static unsigned int GetRandomInt() { + return rand() % MATRIX_MAX_SIZE + 1; +} +static Matrix GetRandomMatrix(std::size_t a_Raw, std::size_t a_Column) { + Matrix matrix {a_Raw, a_Column}; + + for (std::size_t i = 0; i < matrix.GetRawCount(); i++) { + for (std::size_t j = 0; j < matrix.GetColumnCount(); j++) { + matrix.at(i, j) = GetRandomInt(); + } + } + + return matrix; +} + +void TestRectangular(const Matrix& system, const Matrix& origin) { Solver solver; - std::cout << solver.RectangularSystem(std::move(mat2), Matrix::ColumnVector({1, 2})).GetLinearSystem() << std::endl; - std::cout << aff.GetLinearSystem() << std::endl; + VectAffine solution = solver.RectangularSystem(std::move(Matrix(system)), origin); + + for (std::size_t i = 0; i < solution.GetBase().GetCardinal(); i++) { + Matrix vector = solution.GetBase().GetVector(i) + solution.GetOrigin(); + for (std::size_t j = 0; j < system.GetRawCount(); j++) { + Matrix line = system.SubMatrix(j, 0, 1, system.GetColumnCount()); + test_assert(line * vector == origin.SubMatrix(j, 0, 1, 1)); + } + } +} + +void RandomRectangular() { + for (int i = 0; i < EXECUTION_COUNT; i++) { + + Matrix system = GetRandomMatrix(GetRandomInt(), GetRandomInt()); + + if (system.GetColumnCount() == system.GetRawCount()) + continue; + + Matrix origin = GetRandomMatrix(system.GetRawCount(), 1); + + std::cout << "PIPI\n"; + + TestRectangular(system, origin); + } } void TestKernelImage() { @@ -51,6 +86,6 @@ void TestKernelImage() { int main() { TestKernelImage(); - TestRectangular(); + RandomRectangular(); return 0; } \ No newline at end of file