solver move matricies

This commit is contained in:
2024-05-04 14:56:50 +02:00
parent 36ef301cb9
commit e71bc588e5
6 changed files with 37 additions and 32 deletions

View File

@@ -18,14 +18,14 @@ class Solver {
* \param a_Matrix La matrice à traiter * \param a_Matrix La matrice à traiter
* \return L'espace vectoriel correspondant * \return L'espace vectoriel correspondant
*/ */
Vect Image(const Matrix& a_Matrix) const; Vect Image(Matrix&& a_Matrix) const;
/** /**
* \brief Calcule le noyau d'une matrice * \brief Calcule le noyau d'une matrice
* \param a_Matrix La matrice à traiter * \param a_Matrix La matrice à traiter
* \return L'espace vectoriel correspondant * \return L'espace vectoriel correspondant
*/ */
Vect Kernel(const Matrix& a_Matrix) const; Vect Kernel(Matrix&& a_Matrix) const;
/** /**
* \brief Résout le système rectangulaire de la forme AX=B, avec X et B, des vecteurs colonne. * \brief Résout le système rectangulaire de la forme AX=B, avec X et B, des vecteurs colonne.
@@ -33,12 +33,12 @@ class Solver {
* \param a_VectorB La matrice colonne jouant le rôle de B * \param a_VectorB La matrice colonne jouant le rôle de B
* \return L'espace affine associé * \return L'espace affine associé
*/ */
VectAffine RectangularSystem(const Matrix& a_MatrixA, const Matrix& a_VectorB) const; VectAffine RectangularSystem(Matrix&& a_MatrixA, const Matrix& a_VectorB) const;
/** /**
* \brief Calcule le rang d'une matrice * \brief Calcule le rang d'une matrice
* \param a_Matrix La matrice à traiter * \param a_Matrix La matrice à traiter
* \note Ceci équivaut à \code Image(a_Matrix).GetCardinal() \endcode * \note Ceci équivaut à \code Image(a_Matrix).GetCardinal() \endcode
*/ */
std::size_t Rank(const Matrix& a_Matrix) const; std::size_t Rank(Matrix&& a_Matrix) const;
}; };

View File

@@ -2,37 +2,38 @@
#include "Gauss.h" #include "Gauss.h"
Vect Solver::Image(const Matrix& a_Matrix) const { Vect Solver::Image(Matrix&& a_Matrix) const {
Matrix result = a_Matrix; a_Matrix.Transpose();
result.Transpose(); Gauss::GaussJordan(a_Matrix, true, true);
Gauss::GaussJordan(result, true, true); a_Matrix.Transpose();
result.Transpose(); return {a_Matrix};
return {result};
} }
// https://en.wikipedia.org/wiki/Kernel_(linear_algebra)#Computation_by_Gaussian_elimination // https://en.wikipedia.org/wiki/Kernel_(linear_algebra)#Computation_by_Gaussian_elimination
Vect Solver::Kernel(const Matrix& a_Matrix) const { Vect Solver::Kernel(Matrix&& a_Matrix) const {
Matrix result = a_Matrix; std::size_t matrixRawCount = a_Matrix.GetRawCount();
result.Transpose(); std::size_t matrixColumnCount = a_Matrix.GetColumnCount();
result.Augment(Matrix::Identity(result.GetRawCount()));
Gauss::GaussJordan(result, true, true); a_Matrix.Transpose();
result.Transpose(); a_Matrix.Augment(Matrix::Identity(a_Matrix.GetRawCount()));
Gauss::GaussJordan(a_Matrix, true, true);
a_Matrix.Transpose();
// nombre de colonnes non nulles // nombre de colonnes non nulles
std::size_t origine_colonne = Vect(result.SubMatrix(0, 0, a_Matrix.GetRawCount(), a_Matrix.GetColumnCount())).GetCardinal(); std::size_t origine_colonne = Vect(a_Matrix.SubMatrix(0, 0, matrixRawCount, matrixColumnCount)).GetCardinal();
return {result.SubMatrix(a_Matrix.GetRawCount(), origine_colonne, result.GetRawCount() - a_Matrix.GetRawCount(), return {a_Matrix.SubMatrix(matrixRawCount, origine_colonne, a_Matrix.GetRawCount() - matrixRawCount,
result.GetColumnCount() - origine_colonne)}; a_Matrix.GetColumnCount() - origine_colonne)};
} }
VectAffine Solver::RectangularSystem(const Matrix& a_MatrixA, const Matrix& a_VectorB) const { VectAffine Solver::RectangularSystem(Matrix&& a_MatrixA, const Matrix& a_VectorB) const {
Matrix mat = a_MatrixA; Matrix mat = a_MatrixA;
mat.Augment(a_VectorB); mat.Augment(a_VectorB);
Gauss::GaussJordan(mat, true, true); Gauss::GaussJordan(mat, true, true);
Solver solver; Solver solver;
Vect noyau = solver.Kernel(a_MatrixA); Vect noyau = solver.Kernel(std::move(a_MatrixA));
Matrix origin = mat.SubMatrix(0, mat.GetColumnCount() - 1, mat.GetRawCount(), 1); Matrix origin = mat.SubMatrix(0, mat.GetColumnCount() - 1, mat.GetRawCount(), 1);
// on rajoute des 0 si il faut // on rajoute des 0 si il faut
@@ -49,6 +50,6 @@ VectAffine Solver::RectangularSystem(const Matrix& a_MatrixA, const Matrix& a_Ve
return {noyau, fullOrigin}; return {noyau, fullOrigin};
} }
std::size_t Solver::Rank(const Matrix& a_Matrix) const { std::size_t Solver::Rank(Matrix&& a_Matrix) const {
return Image(a_Matrix).GetCardinal(); return Image(std::move(a_Matrix)).GetCardinal();
} }

View File

@@ -75,9 +75,9 @@ Matrix Vect::GetLinearSystem() const {
vect.Transpose(); vect.Transpose();
Solver solver; Solver solver;
vect = solver.Kernel(vect).m_Data; Matrix result = solver.Kernel(std::move(vect)).m_Data;
vect.Transpose(); result.Transpose();
return vect; return result;
} }
std::size_t Vect::GetDimension() const { std::size_t Vect::GetDimension() const {

View File

@@ -25,8 +25,8 @@ void test() {
Solver solver; Solver solver;
Vect image = solver.Image(mat2); Vect image = solver.Image(Matrix{mat2});
Vect noyau = solver.Kernel(mat2); Vect noyau = solver.Kernel(Matrix{mat2});
std::cout << "\tImage :\n"; std::cout << "\tImage :\n";
Print(image); Print(image);

View File

@@ -37,7 +37,9 @@ static void Test() {
} }
} }
Vect kernel = solver.Kernel(matrix); Matrix copy = matrix;
Vect kernel = solver.Kernel(std::move(copy));
Matrix nullVector {matrix.GetRawCount(), 1}; Matrix nullVector {matrix.GetRawCount(), 1};
nullVector.Fill(0.0); nullVector.Fill(0.0);

View File

@@ -18,7 +18,7 @@ void TestRectangular() {
Solver solver; Solver solver;
std::cout << solver.RectangularSystem(mat2, Matrix::ColumnVector({1, 2})).GetLinearSystem() << std::endl; std::cout << solver.RectangularSystem(std::move(mat2), Matrix::ColumnVector({1, 2})).GetLinearSystem() << std::endl;
std::cout << aff.GetLinearSystem() << std::endl; std::cout << aff.GetLinearSystem() << std::endl;
} }
@@ -39,8 +39,10 @@ void TestKernelImage() {
Solver solver; Solver solver;
test_assert(solver.Image(mat) == image); Matrix copy = mat;
test_assert(solver.Kernel(mat) == noyau);
test_assert(solver.Image(std::move(copy)) == image);
test_assert(solver.Kernel(std::move(mat)) == noyau);
} }
} }