Compare commits

...

4 Commits

Author SHA1 Message Date
88cc529009 add solver test
All checks were successful
Linux arm64 / Build (push) Successful in 30m33s
2024-02-16 11:09:27 +01:00
d156602da7 improve tests 2024-02-16 10:40:26 +01:00
46dcad1457 equality of vectorial spaces 2024-02-16 10:39:42 +01:00
c2fd2805fa matrix stream operators 2024-02-16 10:02:27 +01:00
10 changed files with 172 additions and 29 deletions

View File

@@ -0,0 +1,12 @@
2 3
1 2 3
4 5 6
2 2
0 1
1 0
3 1
1
-2
1

View File

@@ -74,13 +74,7 @@ void Matrix::Save(const std::string& fileName) {
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";
}
out << *this;
}
void Matrix::Load(const std::string& filename) {
@@ -89,13 +83,7 @@ void Matrix::Load(const std::string& filename) {
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);
}
}
in >> *this;
}
void Matrix::Transpose() {
@@ -266,4 +254,26 @@ Matrix Matrix::SubMatrix(std::size_t origine_ligne, std::size_t origine_colonne,
}
return result;
}
}
std::ostream& operator<<(std::ostream& stream, const Matrix& mat) {
stream << mat.m_Lignes << " " << mat.m_Colonnes << "\n";
for (std::size_t i = 0; i < mat.m_Lignes; i++) {
for (std::size_t j = 0; j < mat.m_Colonnes; j++) {
stream << mat.at(i, j) << " ";
}
stream << "\n";
}
return stream;
}
std::istream& operator>>(std::istream& stream, Matrix& mat) {
stream >> mat.m_Lignes >> mat.m_Colonnes;
mat.m_Data.resize(mat.m_Lignes * mat.m_Colonnes);
for (std::size_t i = 0; i < mat.m_Lignes; i++) {
for (std::size_t j = 0; j < mat.m_Colonnes; j++) {
stream >> mat.at(i, j);
}
}
return stream;
}

View File

@@ -55,6 +55,9 @@ class Matrix {
long double& at(std::size_t ligne, std::size_t colonne);
long double at(std::size_t ligne, std::size_t colonne) const;
friend std::ostream& operator<<(std::ostream& stream, const Matrix& mat);
friend std::istream& operator>>(std::istream& stream, Matrix& mat);
};
template <typename T>

View File

@@ -19,7 +19,7 @@ Vect Solver::Noyau() const {
result.Transpose();
// nombre de colonnes non nulles
std::size_t origine_colonne = Vect(result.SubMatrix(0, 0, m_Matrix.GetRawCount(), m_Matrix.GetColumnCount())).GetDimension();
std::size_t origine_colonne = Vect(result.SubMatrix(0, 0, m_Matrix.GetRawCount(), m_Matrix.GetColumnCount())).GetCardinal();
return {result.SubMatrix(m_Matrix.GetRawCount(), origine_colonne, result.GetRawCount() - m_Matrix.GetRawCount(),
result.GetColumnCount() - origine_colonne)};
@@ -27,5 +27,5 @@ Vect Solver::Noyau() const {
std::size_t Solver::Rang() const {
Vect image = Image();
return image.GetDimension();
return image.GetCardinal();
}

View File

@@ -23,18 +23,48 @@ void Vect::Simplify() {
m_Data = mat;
}
std::size_t Vect::GetCardinal() const {
return m_Data.GetColumnCount();
}
bool Vect::operator==(const Vect& other) const {
if (GetDimension() != other.GetDimension() || GetCardinal() != other.GetCardinal())
return false;
// on vérifie si chaque vecteur de la deuxième base appartient à la première base
for (std::size_t i = 0; i < GetCardinal(); i++) {
Vect base = *this;
base.AddVector(other.m_Data.SubMatrix(0, i, GetDimension(), 1));
if (base.GetCardinal() != GetCardinal())
return false;
}
return true;
}
void Vect::AddVector(const Matrix& mat) {
m_Data.Augmenter(mat);
m_Data.Transpose();
m_Data.GaussNonJordan(false);
m_Data.Transpose();
Simplify();
}
bool Vect::operator!=(const Vect& other) const {
return !(*this == other);
}
Matrix Vect::GetLinearSystem() const {
Matrix vect = m_Data;
vect.Transpose();
Solver solver {vect};
Solver solver{vect};
vect = solver.Noyau().m_Data;
vect.Transpose();
return vect;
}
void Vect::Print() const {
std::cout << "Espace vectoriel de dimension " << GetDimension() << " 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 j = 0; j < m_Data.GetColumnCount(); j++) {
printf("[ %.3f ]\t", static_cast<float>(m_Data.at(i, j)));
@@ -44,5 +74,5 @@ void Vect::Print() const {
}
std::size_t Vect::GetDimension() const {
return m_Data.GetColumnCount();
return m_Data.GetRawCount();
}

View File

@@ -21,9 +21,19 @@ class Vect {
void Print() const;
std::size_t GetDimension() const;
std::size_t GetCardinal() const;
Matrix GetLinearSystem() const;
/**
* \brief Concatène la base actuelle avec un nouveau vecteur
* \param mat Une matrice colonne de taille GetDimension()
*/
void AddVector(const Matrix& mat);
bool operator==(const Vect& other) const;
bool operator!=(const Vect& other) const;
private:
void Simplify();
};

26
test/test_solver.cpp Normal file
View File

@@ -0,0 +1,26 @@
#include "Solver.h"
#include <cassert>
#include <filesystem>
#include <fstream>
#include <iostream>
namespace fs = std::filesystem;
int main() {
std::string path = "test";
for (const auto& entry : fs::directory_iterator(path)) {
std::string fileName = entry.path().string();
std::cout << "Opening " << fileName << " ...\n";
std::ifstream in{fileName};
Matrix mat{1, 1}, imageMat{1, 1}, noyauMat{1, 1};
in >> mat >> imageMat >> noyauMat;
Vect image{imageMat};
Vect noyau{noyauMat};
Solver solver{mat};
assert(solver.Image() == image);
assert(solver.Noyau() == noyau);
}
return 0;
}

31
test/test_vect.cpp Normal file
View File

@@ -0,0 +1,31 @@
#include "Vect.h"
#include <cassert>
int main() {
Vect vect1 {{3, 2, {
1, 2,
3, 4,
5, 6,
}}};
Vect vect2 {{3, 2, {
1, 0,
0, 0,
0, 1,
}}};
Vect vect3 {{3, 2, {
1, 3,
3, 7,
5, 11,
}}};
Vect vect4 {{3, 2, {
1, 0,
0, 0,
1, 11,
}}};
assert(vect1 == vect3);
assert(vect2 == vect4);
assert(vect1 != vect2);
assert(vect2 != vect3);
assert(vect3 != vect4);
return 0;
}

View File

@@ -1,22 +1,43 @@
add_rules("mode.debug", "mode.release")
set_languages("c++17")
-- Solver Library
target("Pivot")
set_kind("binary")
set_kind("static")
add_files("src/*.cpp")
remove_files("src/main.cpp")
-- Solver Main
target("PivotMain")
set_rundir("$(projectdir)/matricies")
set_languages("c++17")
add_files("src/main.cpp")
add_deps("Pivot")
set_default(true)
target("PivotTest")
set_kind("binary")
add_files("test/*.cpp", "src/Matrix.cpp")
add_includedirs("src")
set_default(false)
add_tests("compile_and_run")
set_rundir("$(projectdir)/matricies")
-- Solver tests
for _, file in ipairs(os.files("test/test_*.cpp")) do
local name = path.basename(file)
target(name)
set_kind("binary")
add_files("test/" .. name .. ".cpp")
set_rundir("$(projectdir)/matricies")
add_includedirs("src")
set_default(false)
add_deps("Pivot")
add_tests("compile_and_run")
end
--
-- If you want to known more usage about xmake, please see https://xmake.io