38 Commits

Author SHA1 Message Date
6b9987d561 fix action apt
Some checks failed
Linux arm64 / Build (push) Failing after 4m27s
2024-05-27 22:51:59 +02:00
5584df6486 Update .gitea/workflows/ubuntu.yaml
Some checks failed
Linux arm64 / Build (push) Failing after 28s
2024-05-27 22:50:56 +02:00
413ff4fce4 add project license
Some checks failed
Linux arm64 / Build (push) Failing after 40m2s
2024-05-23 17:32:01 +02:00
49e4d4b1e2 working linear system gui
Some checks failed
Linux arm64 / Build (push) Has been cancelled
2024-05-23 17:18:22 +02:00
9b84b9bf59 maybe fix test
Some checks failed
Linux arm64 / Build (push) Failing after 33m25s
2024-05-23 15:17:21 +02:00
bb650e4f2d gui refactor 2024-05-23 15:16:29 +02:00
e784a7b471 reduce solver random matrix size
Some checks failed
Linux arm64 / Build (push) Failing after 38m45s
2024-05-23 14:34:22 +02:00
9a5b99a79d init random
Some checks failed
Linux arm64 / Build (push) Failing after 2m43s
2024-05-14 23:09:51 +02:00
ffa0ebf4cb add missing include
Some checks failed
Linux arm64 / Build (push) Has been cancelled
2024-05-14 22:51:53 +02:00
4b3e878bc5 removed weird function
Some checks failed
Linux arm64 / Build (push) Failing after 2m26s
2024-05-14 22:41:01 +02:00
47f250170e remove useless xmake require
Some checks failed
Linux arm64 / Build (push) Has been cancelled
2024-05-14 22:39:57 +02:00
a4036ae36d add linear system test
Some checks failed
Linux arm64 / Build (push) Has been cancelled
2024-05-14 22:39:15 +02:00
e6d0785009 show jordaned matrix
Some checks failed
Linux arm64 / Build (push) Has been cancelled
2024-05-14 22:36:57 +02:00
a135df2e96 trop de trucs
All checks were successful
Linux arm64 / Build (push) Successful in 2m33s
2024-05-14 13:00:59 +02:00
d9e49d1319 forgot this 2024-05-13 21:30:52 +02:00
e127ff8c29 easier to debug assert 2024-05-13 21:11:40 +02:00
9b423f9c83 fix react system 2024-05-13 21:11:20 +02:00
fa7e70a437 better fill 2024-05-13 21:10:23 +02:00
76fa9fb329 fix gui build
Some checks failed
Linux arm64 / Build (push) Failing after 2m54s
2024-05-12 10:49:21 +02:00
7f1ef38286 fix solver
Some checks failed
Linux arm64 / Build (push) Failing after 2m0s
2024-05-12 09:23:37 +02:00
2af915057a fix intellisense
All checks were successful
Linux arm64 / Build (push) Successful in 2m29s
2024-05-11 19:44:43 +02:00
2975006972 big int 2024-05-11 19:44:32 +02:00
0d071b1cf9 remove unused include 2024-05-11 19:02:53 +02:00
a02f71e29e equations cartesiennes.
All checks were successful
Linux arm64 / Build (push) Successful in 3m10s
2024-05-11 18:44:20 +02:00
6833811b97 display kernel
All checks were successful
Linux arm64 / Build (push) Successful in 3m1s
2024-05-11 15:56:18 +02:00
b41bcae337 do computations
All checks were successful
Linux arm64 / Build (push) Successful in 2m56s
2024-05-10 18:53:29 +02:00
427eeb0b51 Merge branch 'master' into imgui
All checks were successful
Linux arm64 / Build (push) Successful in 3m16s
2024-05-10 18:39:37 +02:00
5fac74cefc fixing auto-insert of garbage values when adding columns
All checks were successful
Linux arm64 / Build (push) Successful in 37m37s
2024-05-10 15:35:41 +02:00
b239c0aaff adding dynamic number input and reading in matrix
Some checks failed
Linux arm64 / Build (push) Has been cancelled
2024-05-10 15:19:22 +02:00
6b763b8481 change c++ version
All checks were successful
Linux arm64 / Build (push) Successful in 1m45s
2024-05-09 15:57:52 +02:00
5391b7b76a more optimizations
Some checks failed
Linux arm64 / Build (push) Failing after 25s
2024-05-09 15:56:59 +02:00
99c0e2010b PivotGUI visuals + .lua update
All checks were successful
Linux arm64 / Build (push) Successful in 41m17s
2024-04-11 00:20:51 +02:00
Morph01
f595582948 added window for Pivot interface with a grid
All checks were successful
Linux arm64 / Build (push) Successful in 45m6s
2024-03-06 18:35:07 +01:00
b9a3fb4ca4 action: fix tests
All checks were successful
Linux arm64 / Build (push) Successful in 33m30s
2024-02-25 08:50:08 +01:00
ceda1b00df action: update for gui
Some checks failed
Linux arm64 / Build (push) Failing after 41m36s
2024-02-24 19:53:41 +01:00
23484289a4 ignore imgui.ini
Some checks failed
Linux arm64 / Build (push) Has been cancelled
2024-02-24 19:24:56 +01:00
766aa6ada4 add imgui support 2024-02-24 19:24:49 +01:00
208c79800e add vscode intellisense 2024-02-24 19:22:57 +01:00
21 changed files with 808 additions and 161 deletions

View File

@@ -7,15 +7,26 @@ jobs:
Build:
runs-on: ubuntu-latest
steps:
- name: Install opengl
run: |
apt update
apt install -y libsdl2-dev
- name: Check out repository code
uses: actions/checkout@v3
- name: Prepare XMake
- name: Prepare Xmake
uses: xmake-io/github-action-setup-xmake@v1
with:
xmake-version: latest
actions-cache-folder: '.xmake-cache'
actions-cache-key: 'ubuntu'
actions-cache-key: 'xmake-ubuntu'
- name: Cache
uses: actions/cache@v4
with:
path: ~/.xmake
key: 'ubuntu'
- name: XMake config
run: xmake f -p linux -y --root

3
.gitignore vendored
View File

@@ -7,3 +7,6 @@ build/
# VsCode
.vscode
#ImGui
imgui.ini

View File

@@ -2,8 +2,9 @@
"configurations": [
{
"name": "Pivot",
"cppStandard": "c++17",
"includePath": ["include"]
"cppStandard": "c++20",
"includePath": ["include"],
"compileCommands": "${workspaceFolder}/.vscode/compile_commands.json"
}
],
"version": 4

21
LICENSE.txt Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Simon Pribylski, Thibaut Alessi, Houssem Zammali, Julien Chataigner
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -17,12 +17,4 @@ namespace Gauss {
*/
void GaussJordan(Matrix& a_Matrix, bool a_Reduite, bool a_Normalise);
/**
* \brief Echelonne une matrice en colonne en utilisant l'algorithme de Gauss-Jordan
* \param a_Matrix La matrice à échelonner
* \param a_Reduite Mets des 0 au dessus des pivots
* \param a_Normalise Mets les pivots à 1
*/
void GaussJordanColumn(Matrix& a_Matrix, bool a_Reduite, bool a_Normalise);
} // namespace Gauss

View File

@@ -10,13 +10,16 @@
#include <string>
#include <vector>
#include "NR.h"
/**
* \class Matrix
* \brief Représente une matrice d'éléments
*/
class Matrix {
public:
typedef long double Element;
typedef NR Element;
typedef std::vector<Element>::iterator iterator;
private:
std::size_t m_Raws;
@@ -145,9 +148,29 @@ class Matrix {
* construit une matrice de 1 ligne et 4 colonnes de coordonnées (1, 2, 3, 4)
*/
static Matrix RawVector(std::initializer_list<Element>&& a_Elements);
iterator begin();
iterator end();
iterator GetLineIterator(std::size_t a_Raw);
};
template <typename T>
bool IsEqualZero(T var) {
bool IsEqualZero(const T& var) {
return std::abs(var) < std::pow(10, -5);
}
template <>
inline bool IsEqualZero(const int& var) {
return var == 0;
}
template <>
inline bool IsEqualZero(const long& var) {
return var == 0;
}
template <>
inline bool IsEqualZero(const NR& var) {
return var == 0;
}

View File

@@ -3,17 +3,20 @@
#include <iostream>
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);

View File

@@ -21,7 +21,7 @@ class Vect {
* Les colonnes de 0 sont ignorées
* \param a_Matrix Une matrice échelonnée.
*/
Vect(const Matrix& a_Matrix);
Vect(Matrix&& a_Matrix);
/**
* \brief Permet d'obtenir le ieme vecteur de la base
@@ -105,12 +105,6 @@ class VectAffine {
*/
bool IsElementOf(const Matrix& a_Vector) const;
/**
* \brief Exprime l'espace vectoriel comme les solutions d'un système linéaire des coordonnées des vecteurs
* \return Une matrice représentant le système linéaire
*/
Matrix GetLinearSystem() const;
bool operator==(const VectAffine& a_VectAffine) const {
return m_Origin == a_VectAffine.GetOrigin() && m_Base == a_VectAffine.GetBase();
};

View File

@@ -2,30 +2,20 @@
#include "Matrix.h"
#include <algorithm>
#include <execution>
#include <ranges>
namespace Gauss {
static void SwapLines(Matrix& mat, std::size_t line1, std::size_t line2) {
for (std::size_t k = 0; k < mat.GetColumnCount(); k++) {
std::swap(mat.at(line1, k), mat.at(line2, k));
}
}
static void SwapColumns(Matrix& mat, std::size_t column1, std::size_t column2) {
for (std::size_t k = 0; k < mat.GetRawCount(); k++) {
std::swap(mat.at(k, column1), mat.at(k, column2));
}
std::swap_ranges(
std::execution::par_unseq, mat.GetLineIterator(line1), mat.GetLineIterator(line1 + 1), mat.GetLineIterator(line2));
}
static void DivideLine(Matrix& mat, std::size_t line, Matrix::Element number) {
for (std::size_t j = 0; j < mat.GetColumnCount(); j++) {
mat.at(line, j) /= number;
}
}
static void DivideColumn(Matrix& mat, std::size_t column, Matrix::Element number) {
for (std::size_t j = 0; j < mat.GetRawCount(); j++) {
mat.at(j, column) /= number;
}
std::transform(std::execution::par_unseq, mat.GetLineIterator(line), mat.GetLineIterator(line + 1), mat.GetLineIterator(line),
[number](Matrix::Element e) { return e /= number; });
}
static int FirstNotNullElementIndexOnColumn(Matrix& mat, std::size_t column, std::size_t startLine = 0) {
@@ -37,34 +27,18 @@ static int FirstNotNullElementIndexOnColumn(Matrix& mat, std::size_t column, std
return -1;
}
static int FirstNotNullElementIndexOnLine(Matrix& mat, std::size_t line, std::size_t startColumn = 0) {
for (std::size_t i = startColumn; i < mat.GetColumnCount(); i++) {
if (!IsEqualZero(mat.at(line, i))) {
return i;
}
}
return -1;
}
static void SimplifyLine(Matrix& mat, std::size_t line, std::size_t pivot_line, std::size_t pivot_column) {
const Matrix::Element pivot = mat.at(pivot_line, pivot_column);
const Matrix::Element anul = mat.at(line, pivot_column);
for (std::size_t j = 0; j < mat.GetColumnCount(); j++) {
auto range = std::views::iota(static_cast<std::size_t>(0), mat.GetColumnCount());
std::for_each(std::execution::par_unseq, range.begin(), range.end(), [&mat, pivot, anul, line, pivot_line](std::size_t j) {
mat.at(line, j) = mat.at(line, j) * pivot - mat.at(pivot_line, j) * anul;
}
});
}
static void SimplifyColumn(Matrix& mat, std::size_t column, std::size_t pivot_line, std::size_t pivot_column) {
const Matrix::Element pivot = mat.at(pivot_line, pivot_column);
const Matrix::Element anul = mat.at(pivot_line, column);
for (std::size_t j = 0; j < mat.GetRawCount(); j++) {
mat.at(j, column) = mat.at(j, column) * pivot - mat.at(j, pivot_column) * anul;
}
}
void GaussJordan(Matrix& a_Matrix, bool a_Reduite, bool a_Normalise) {
static void GaussJordanReduced(Matrix& a_Matrix, bool a_Normalise) {
int indice_ligne_pivot = -1;
for (std::size_t j = 0; j < a_Matrix.GetColumnCount(); j++) {
@@ -86,46 +60,54 @@ void GaussJordan(Matrix& a_Matrix, bool a_Reduite, bool a_Normalise) {
DivideLine(a_Matrix, indice_ligne_pivot, pivot);
}
auto range = std::views::iota(static_cast<std::size_t>(0), a_Matrix.GetRawCount());
// On simplifie les autres lignes
for (std::size_t i = (a_Reduite ? 0 : j); i < a_Matrix.GetRawCount(); i++) {
// Pour les lignes autre que la ligne pivot
std::for_each(std::execution::par_unseq, range.begin(), range.end(), [&a_Matrix, j, indice_ligne_pivot](std::size_t i) {
if (i != static_cast<std::size_t>(indice_ligne_pivot)) {
SimplifyLine(a_Matrix, i, indice_ligne_pivot, j);
}
}
});
}
}
void GaussJordanColumn(Matrix& a_Matrix, bool a_Reduite, bool a_Normalise) {
int indice_colonne_pivot = -1;
static void GaussJordanTriangular(Matrix& a_Matrix, bool a_Normalise) {
int indice_ligne_pivot = -1;
for (std::size_t j = 0; j < a_Matrix.GetRawCount(); j++) {
for (std::size_t j = 0; j < a_Matrix.GetColumnCount(); j++) {
int indice_colonne_pivot_trouve = FirstNotNullElementIndexOnLine(a_Matrix, j, indice_colonne_pivot + 1);
int indice_ligne_pivot_trouve = FirstNotNullElementIndexOnColumn(a_Matrix, j, indice_ligne_pivot + 1);
if (indice_colonne_pivot_trouve < 0) // ligne de 0
continue; // on regarde la prochaine ligne
if (indice_ligne_pivot_trouve < 0) // colonne de 0
continue; // on regarde la prochaine colonne
indice_colonne_pivot++;
indice_ligne_pivot++;
if (indice_colonne_pivot_trouve != indice_colonne_pivot) {
SwapColumns(a_Matrix, indice_colonne_pivot_trouve, indice_colonne_pivot);
if (indice_ligne_pivot_trouve != indice_ligne_pivot) {
SwapLines(a_Matrix, indice_ligne_pivot_trouve, indice_ligne_pivot);
}
Matrix::Element pivot = a_Matrix.at(j, indice_colonne_pivot);
Matrix::Element pivot = a_Matrix.at(indice_ligne_pivot, j);
if (a_Normalise) {
DivideColumn(a_Matrix, indice_colonne_pivot, pivot);
DivideLine(a_Matrix, indice_ligne_pivot, pivot);
}
// On simplifie les autres lignes
for (std::size_t i = (a_Reduite ? 0 : j); i < a_Matrix.GetColumnCount(); i++) {
// Pour les lignes autre que la ligne pivot
if (i != static_cast<std::size_t>(indice_colonne_pivot)) {
SimplifyColumn(a_Matrix, i, j, indice_colonne_pivot);
}
}
auto range = std::views::iota(static_cast<std::size_t>(indice_ligne_pivot + 1), a_Matrix.GetRawCount());
// On simplifie les autres lignes après la ligne du pivot
std::for_each(std::execution::par_unseq, range.begin(), range.end(),
[&a_Matrix, indice_ligne_pivot, j](std::size_t i) {
SimplifyLine(a_Matrix, i, indice_ligne_pivot, j);
});
}
}
void GaussJordan(Matrix& a_Matrix, bool a_Reduite, bool a_Normalise) {
if (a_Reduite)
GaussJordanReduced(a_Matrix, a_Normalise);
else
GaussJordanTriangular(a_Matrix, a_Normalise);
}
} // namespace Gauss

View File

@@ -71,11 +71,7 @@ Matrix Matrix::RawVector(std::initializer_list<Element>&& a_Elements) {
}
void Matrix::Fill(Element a_Element) {
for (std::size_t i = 0; i < m_Raws; i++) {
for (std::size_t j = 0; j < m_Columns; j++) {
at(i, j) = a_Element;
}
}
std::fill(GetLineIterator(0), GetLineIterator(m_Raws), a_Element);
}
void Matrix::Augment(const Matrix& a_Right) {
@@ -158,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];
}
@@ -187,3 +185,15 @@ Matrix Matrix::SubMatrix(
return result;
}
Matrix::iterator Matrix::begin() {
return m_Data.begin();
}
Matrix::iterator Matrix::end() {
return m_Data.end();
}
Matrix::iterator Matrix::GetLineIterator(std::size_t a_Raw) {
return m_Data.begin() + a_Raw * GetColumnCount();
}

View File

@@ -3,7 +3,7 @@
#include <cassert>
#include <iostream>
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<std::streampos>(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;
}

View File

@@ -2,9 +2,20 @@
#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 {
Gauss::GaussJordanColumn(a_Matrix, true, true);
return {a_Matrix};
a_Matrix.Transpose();
Gauss::GaussJordan(a_Matrix, false, false);
a_Matrix.Transpose();
return {std::move(a_Matrix)};
}
// https://en.wikipedia.org/wiki/Kernel_(linear_algebra)#Computation_by_Gaussian_elimination
@@ -12,8 +23,10 @@ Vect Solver::Kernel(Matrix&& a_Matrix) const {
std::size_t matrixRawCount = a_Matrix.GetRawCount();
std::size_t matrixColumnCount = a_Matrix.GetColumnCount();
a_Matrix.AugmentBottom(Matrix::Identity(a_Matrix.GetColumnCount()));
Gauss::GaussJordanColumn(a_Matrix, true, true);
a_Matrix.Transpose();
a_Matrix.Augment(Matrix::Identity(a_Matrix.GetRawCount()));
Gauss::GaussJordan(a_Matrix, false, true);
a_Matrix.Transpose();
// nombre de colonnes non nulles
std::size_t origine_colonne = Vect(a_Matrix.SubMatrix(0, 0, matrixRawCount, matrixColumnCount)).GetCardinal();
@@ -32,15 +45,21 @@ 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
// 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++) {
fullOrigin.at(i, 0) = origin.at(i, 0);
}
int pivot_index = FirstNotNullElementIndexOnLine(mat, i);
for (std::size_t i = mat.GetRawCount(); i < mat.GetColumnCount() - 1; i++) {
fullOrigin.at(i, 0) = 0;
if (static_cast<std::size_t>(pivot_index) == mat.GetColumnCount() - 1) {
// on a une ligne du type 0 = n. Aucune solution !
return {Matrix {}, Matrix::ColumnVector({0})};
}
// ligne entière de 0
if (pivot_index < 0)
continue;
fullOrigin.at(pivot_index, 0) = origin.at(i, 0);
}
return {noyau, fullOrigin};

View File

@@ -2,8 +2,6 @@
#include "Gauss.h"
#include "Solver.h"
#include <cassert>
#include <iostream>
static bool IsColumnNull(Matrix& mat, std::size_t column) {
for (std::size_t i = 0; i < mat.GetRawCount(); i++) {
@@ -14,9 +12,9 @@ static bool IsColumnNull(Matrix& mat, std::size_t column) {
return true;
}
Vect::Vect(const Matrix& a_Matrix) : m_Data(a_Matrix) {
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();
}
@@ -90,11 +88,3 @@ VectAffine::VectAffine(const Vect& a_Base, const Matrix& a_Origin) :
bool VectAffine::IsElementOf(const Matrix& a_Vector) const {
return m_Base.IsElementOf(a_Vector - m_Origin);
}
Matrix VectAffine::GetLinearSystem() const {
Matrix result = m_Base.GetLinearSystem();
result.Augment(m_Origin.SubMatrix(0, 0, result.GetRawCount(), 1));
return result;
}

311
src/gui/PivotGui.cpp Normal file
View File

@@ -0,0 +1,311 @@
#include "PivotGui.h"
#include "Gauss.h"
#include "Matrix.h"
#include "Solver.h"
#include <imgui.h>
#include <sstream>
static std::string equationsResultImage;
struct GuiMatrix {
std::vector<std::vector<int>> matrixValues;
int matrixSizeX = 4;
int matrixSizeY = 4;
};
static void ResizeGuiMatrix(bool refresh, GuiMatrix& guiMatrix) {
if (refresh) {
guiMatrix.matrixValues.resize(guiMatrix.matrixSizeY);
for (auto& row : guiMatrix.matrixValues) {
row.resize(guiMatrix.matrixSizeX, 0);
}
}
}
static void RenderMatrix(bool& refresh, GuiMatrix& guiMatrix) {
ResizeGuiMatrix(refresh, guiMatrix);
for (int y = 0; y < guiMatrix.matrixSizeY; y++) {
for (int x = 0; x < guiMatrix.matrixSizeX; x++) {
if (x > 0)
ImGui::SameLine();
ImGui::PushID((guiMatrix.matrixSizeX * 20 + guiMatrix.matrixSizeY * 50) + y * guiMatrix.matrixSizeX + x);
ImGui::PushItemWidth(60); // Adjust this value to change the cell size
if (ImGui::InputInt("", &guiMatrix.matrixValues[y][x], 0, 0, ImGuiInputTextFlags_CharsDecimal))
refresh = true;
ImGui::PopItemWidth();
ImGui::PopID();
}
}
}
static Matrix LoadMatrixFromStdVect(const std::vector<std::vector<int>>& data) {
Matrix result {data.size(), data.empty() ? 0 : data[0].size()};
for (std::size_t i = 0; i < result.GetRawCount(); i++) {
for (std::size_t j = 0; j < result.GetColumnCount(); j++) {
result.at(i, j) = static_cast<Matrix::Element>(data[i][j]);
}
}
return result;
}
static std::string ElementToString(Matrix::Element e) {
std::stringstream ss;
ss << e;
return ss.str();
}
static std::string PrintRawMatrix(const Matrix& mat) {
if (mat.GetRawCount() == 0)
return "";
std::string result = " ( ";
for (std::size_t j = 0; j < mat.GetRawCount(); j++) {
result += ElementToString(mat.at(j, 0)) + ", ";
}
result = result.substr(0, result.size() - 2);
result += " )";
return result;
}
static std::string PrintVect(const Vect& vect) {
if (vect.GetCardinal() == 0)
return "{0}";
std::string result = "Vect( ";
for (std::size_t i = 0; i < vect.GetCardinal(); i++) {
Matrix vector = vect.GetVector(i);
result += PrintRawMatrix(vector);
result += ", ";
}
result = result.substr(0, result.size() - 2);
result += " )";
return result;
}
void PivotGui::Init() {}
static void RenderLeftSystemChild(bool& refresh, GuiMatrix& system, GuiMatrix& origin) {
ImVec2 topLeftWindowSize(ImGui::GetContentRegionAvail().x * 0.5f, 0);
ImGui::BeginChild("Left Child", topLeftWindowSize, ImGuiChildFlags_Border);
ImGui::Text("Système de la forme AX=B");
ImGui::Separator();
ImGui::Text("Taille matrice A :");
if (ImGui::InputInt("##RowsMatriceInitiale", &system.matrixSizeY))
refresh = true;
system.matrixSizeY = std::max(1, system.matrixSizeY);
ImGui::SameLine();
ImGui::Text("Lignes");
if (ImGui::InputInt("##ColumnsMatriceInitiale", &system.matrixSizeX))
refresh = true;
system.matrixSizeX = std::max(1, system.matrixSizeX);
ImGui::SameLine();
ImGui::Text("Colonnes");
ImGui::NewLine();
RenderMatrix(refresh, system);
if (refresh) {
origin.matrixSizeX = 1;
origin.matrixSizeY = system.matrixSizeY;
}
ImGui::NewLine();
ImGui::Separator();
ImGui::Text("Matrice B :");
ImGui::NewLine();
RenderMatrix(refresh, origin);
ImGui::EndChild();
}
static void RenderRightSystemChild(bool& refresh, GuiMatrix& system, GuiMatrix& origin) {
ImGui::BeginChild("Right Child", {0, 0}, ImGuiChildFlags_Border);
static std::string result = "";
static Solver solver;
if (refresh) {
VectAffine solutions =
solver.RectangularSystem(LoadMatrixFromStdVect(system.matrixValues), LoadMatrixFromStdVect(origin.matrixValues));
result = "Solutions :\n";
result += PrintVect(solutions.GetBase());
result += "\n\n+\n\n";
result += PrintRawMatrix(solutions.GetOrigin());
}
ImGui::TextWrapped("%s", result.c_str());
ImGui::EndChild();
}
static void RenderSystemTab() {
static GuiMatrix guiMatrix, originMatrix;
static bool refresh = true;
RenderLeftSystemChild(refresh, guiMatrix, originMatrix);
ImGui::SameLine();
RenderRightSystemChild(refresh, guiMatrix, originMatrix);
}
static void RenderLeftGaussChild(bool& refresh, GuiMatrix& guiMatrix) {
// divisions des fenetres
ImVec2 topLeftWindowSize(ImGui::GetContentRegionAvail().x * 0.5f, 0);
// Begin fenetre top left
// ImGui::SetNextWindowPos(ImVec2(0, 0)); // Position at the top-left corner
ImGui::BeginChild("Left Top Window", topLeftWindowSize, ImGuiChildFlags_Border);
/*ImGui::Begin(, nullptr,
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoScrollbar);
*/
// ImGui::BeginTabBar("MainMenu");
// Get window position
ImVec2 windowPos = ImGui::GetWindowPos();
ImGui::Text("Matrice initiale:");
if (ImGui::InputInt("##RowsMatriceInitiale", &guiMatrix.matrixSizeY))
refresh = true;
guiMatrix.matrixSizeY = std::max(1, guiMatrix.matrixSizeY);
ImGui::SameLine();
ImGui::Text("Lignes");
if (ImGui::InputInt("##ColumnsMatriceInitiale", &guiMatrix.matrixSizeX))
refresh = true;
guiMatrix.matrixSizeX = std::max(1, guiMatrix.matrixSizeX);
ImGui::SameLine();
ImGui::Text("Colonnes");
ImGui::NewLine();
// ImGui::BeginChild("MatriceInitiale", ImVec2(topLeftWindowSize.x, io.DisplaySize.y * 0.7f), false);
// Resize matrixValues and initialize new elements to 0
RenderMatrix(refresh, guiMatrix);
// ImGui::EndChild(); // End Matrice initiale
ImGui::NewLine();
ImGui::Text("Matrice échelonnée:");
// Convert the "result" string back to a matrix
Matrix resultMatrix = LoadMatrixFromStdVect(guiMatrix.matrixValues);
// Apply the Gauss-Jordan elimination to the matrix
Gauss::GaussJordan(resultMatrix, true, true); // Assuming you want to reduce and normalize the matrix
// Display the matrix
for (std::size_t i = 0; i < resultMatrix.GetRawCount(); i++) {
for (std::size_t j = 0; j < resultMatrix.GetColumnCount(); j++) {
ImGui::PushID(i * resultMatrix.GetColumnCount() + j);
if (ImGui::Button(ElementToString(resultMatrix.at(i, j)).c_str(), ImVec2(70, 70))) { // Adjust the size as needed
// Handle button click here if needed
}
ImGui::PopID();
if (j < resultMatrix.GetColumnCount() - 1)
ImGui::SameLine();
}
}
ImGui::EndChild();
}
static void RenderRightGaussChild(bool& refresh, GuiMatrix& guiMatrix) {
static Solver solver;
// Begin fenetre top right
// ImGui::SetNextWindowSize(topRightWindowSize);
// ImGui::SetNextWindowPos(ImVec2(windowPos.x + topLeftWindowSize.x, 0)); // Position at the top-right corner
ImGui::BeginChild("Right Top Window", {0, 0}, ImGuiChildFlags_Border);
// ImGui::Begin("Right Top Window", nullptr,
// ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoScrollbar);
// rajouter le code pour la partie top right
static std::string result = "";
if (refresh) {
// Calculate the kernel and image
Vect image = solver.Image(LoadMatrixFromStdVect(guiMatrix.matrixValues));
Matrix linearSystem = image.GetLinearSystem();
// Store the equationsResult strings in the global variable
equationsResultImage = "Equations cartesiennes de l'espace vectoriel (Image):\n";
for (size_t i = 0; i < linearSystem.GetRawCount(); ++i) {
for (size_t j = 0; j < linearSystem.GetColumnCount(); ++j) {
equationsResultImage +=
ElementToString(linearSystem.at(i, j)) + "*" + std::string {static_cast<char>('a' + j)} + " + ";
}
equationsResultImage = equationsResultImage.substr(0, equationsResultImage.size() - 3) + " = 0\n";
}
result = "\nNoyau: \n" + PrintVect(solver.Kernel(LoadMatrixFromStdVect(guiMatrix.matrixValues))) + "\n" +
"\n" + "Rang: " + "\n" + std::to_string(solver.Rank(LoadMatrixFromStdVect(guiMatrix.matrixValues))) + "\n" + "\n" +
"Image: " + "\n" + PrintVect(image);
}
refresh = false;
// Display the equationsResult strings in the GUI if they are not empty
if (!equationsResultImage.empty()) {
ImGui::TextWrapped("%s", equationsResultImage.c_str());
}
ImGui::TextWrapped("%s", result.c_str());
ImGui::EndChild(); // End fenetre top right
}
static void RenderGaussTab() {
static GuiMatrix guiMatrix;
static bool refresh = true;
RenderLeftGaussChild(refresh, guiMatrix);
ImGui::SameLine();
RenderRightGaussChild(refresh, guiMatrix);
}
static void RenderMainWindow() {
ImGuiIO& io = ImGui::GetIO();
ImGui::SetNextWindowSize(io.DisplaySize);
ImGui::SetNextWindowPos({0, 0});
ImGui::Begin("MainWindow", nullptr,
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoScrollbar);
ImGui::BeginTabBar("MainBar");
if (ImGui::BeginTabItem("Noyau et Image")) {
RenderGaussTab();
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Systèmes")) {
RenderSystemTab();
ImGui::EndTabItem();
}
ImGui::EndTabBar();
ImGui::End();
}
void PivotGui::Render() {
RenderMainWindow();
#ifndef NDEBUG
ImGui::ShowDemoWindow(nullptr);
#endif
}
void PivotGui::Destroy() {}

9
src/gui/PivotGui.h Normal file
View File

@@ -0,0 +1,9 @@
#pragma once
namespace PivotGui {
void Init();
void Render();
void Destroy();
} // namespace PivotGui

174
src/gui/mainGui.cpp Normal file
View File

@@ -0,0 +1,174 @@
// Dear ImGui: standalone example application for SDL2 + OpenGL
// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.)
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq
// - Getting Started https://dearimgui.com/getting-started
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
// - Introduction, links and more at the top of imgui.cpp
#include <SDL2/SDL.h>
#include <imgui.h>
#include <imgui_impl_opengl3.h>
#include <imgui_impl_opengl3_loader.h>
#include <imgui_impl_sdl2.h>
#include <stdio.h>
#include "PivotGui.h"
// This example can also compile and run with Emscripten! See 'Makefile.emscripten' for details.
#ifdef __EMSCRIPTEN__
#include "../libs/emscripten/emscripten_mainloop_stub.h"
#endif
// Main code
int main(int, char**) {
// Setup SDL
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0) {
printf("Error: %s\n", SDL_GetError());
return -1;
}
// Decide GL+GLSL versions
#if defined(IMGUI_IMPL_OPENGL_ES2)
// GL ES 2.0 + GLSL 100
const char* glsl_version = "#version 100";
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
#elif defined(__APPLE__)
// GL 3.2 Core + GLSL 150
const char* glsl_version = "#version 150";
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); // Always required on Mac
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
#else
// GL 3.0 + GLSL 130
const char* glsl_version = "#version 130";
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
#endif
// From 2.0.18: Enable native IME.
#ifdef SDL_HINT_IME_SHOW_UI
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
#endif
// Create window with graphics context
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
SDL_Window* window = SDL_CreateWindow("Solver Gui", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
if (window == nullptr) {
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return -1;
}
SDL_GLContext gl_context = SDL_GL_CreateContext(window);
SDL_GL_MakeCurrent(window, gl_context);
SDL_GL_SetSwapInterval(1); // Enable vsync
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
// Setup Dear ImGui style
ImGui::StyleColorsDark();
// ImGui::StyleColorsLight();
// Setup Platform/Renderer backends
ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
ImGui_ImplOpenGL3_Init(glsl_version);
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use
// ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an
// assertion, or display an error and quit).
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling
// ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
// - Read 'docs/FONTS.md' for more instructions and details.
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
// - Our Emscripten build process allows embedding fonts to be accessible at runtime from the "fonts/" folder. See
// Makefile.emscripten for details.
// io.Fonts->AddFontDefault();
// io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f);
// io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
// io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
// io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
// ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr,
// io.Fonts->GetGlyphRangesJapanese()); IM_ASSERT(font != nullptr);
ImFontConfig cfg;
cfg.SizePixels = 30.0f;
io.Fonts->AddFontDefault(&cfg);
PivotGui::Init();
// Main loop
bool done = false;
#ifdef __EMSCRIPTEN__
// For an Emscripten build we are disabling file-system access, so let's not attempt to do a fopen() of the imgui.ini file.
// You may manually call LoadIniSettingsFromMemory() to load settings from your own storage.
io.IniFilename = nullptr;
EMSCRIPTEN_MAINLOOP_BEGIN
#else
while (!done)
#endif
{
// Poll and handle events (inputs, window resize, etc.)
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy
// of the mouse data.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your
// copy of the keyboard data. Generally you may always pass all inputs to dear imgui, and hide them from your application based
// on those two flags.
SDL_Event event;
while (SDL_PollEvent(&event)) {
ImGui_ImplSDL2_ProcessEvent(&event);
if (event.type == SDL_QUIT)
done = true;
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE &&
event.window.windowID == SDL_GetWindowID(window))
done = true;
}
// Start the Dear ImGui frame
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplSDL2_NewFrame();
ImGui::NewFrame();
PivotGui::Render();
// Rendering
ImGui::Render();
glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
glClear(GL_COLOR_BUFFER_BIT);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
SDL_GL_SwapWindow(window);
}
#ifdef __EMSCRIPTEN__
EMSCRIPTEN_MAINLOOP_END;
#endif
// Cleanup
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplSDL2_Shutdown();
ImGui::DestroyContext();
SDL_GL_DeleteContext(gl_context);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}

View File

@@ -6,6 +6,7 @@
*/
#include <iostream>
#include <stdexcept>
/**
* \def TEST_SUCCESSFUL
@@ -37,6 +38,5 @@
if (!static_cast<bool>(__VA_ARGS__)) { \
std::cout << __FILE__ << ":" << __LINE__ << ": " << __FUNCTION_NAME__ << ": Assertion failed !\n"; \
std::cout << " " << __LINE__ << " |\t" << #__VA_ARGS__ << std::endl; \
std::exit(TEST_FAILED); \
throw std::runtime_error("Assertion failed !"); \
}

View File

@@ -6,14 +6,14 @@
#include <iostream>
#include <vector>
static constexpr int EXECUTION_COUNT = 100;
static constexpr int EXECUTION_COUNT = 1000;
static constexpr int KERNEL_CHECKS = 100;
static constexpr int MATRIX_MAX_SIZE = 100;
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<std::future<void>> results;
std::vector<std::future<bool>> 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;
}

View File

@@ -1,3 +1,4 @@
#include <algorithm>
#include <filesystem>
#include <fstream>
#include <iostream>
@@ -8,18 +9,48 @@
namespace fs = std::filesystem;
void TestRectangular() {
Matrix mat2 = {2, 4, {
1, 1, 1, 1,
1, -1, -1, 2
}};
const static int EXECUTION_COUNT = 10000;
static constexpr int MATRIX_MAX_SIZE = 5;
VectAffine aff {Matrix::ColumnVector({0, -1, 1}), Matrix::ColumnVector({3.0 / 2.0, 0, -1.0 / 2.0})};
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();
});
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();
Matrix product = system * vector;
test_assert(product == origin);
}
}
void RandomRectangular() {
for (int i = 0; i < EXECUTION_COUNT; i++) {
Matrix system = GetRandomMatrix(GetRandomSize(), GetRandomSize());
Matrix origin = GetRandomMatrix(system.GetRawCount(), 1);
TestRectangular(system, origin);
}
}
void TestKernelImage() {
@@ -34,20 +65,24 @@ void TestKernelImage() {
Matrix mat, imageMat, noyauMat;
in >> mat >> imageMat >> noyauMat;
Vect image {imageMat};
Vect noyau {noyauMat};
Vect image {std::move(imageMat)};
Vect noyau {std::move(noyauMat)};
Solver solver;
Matrix copy = mat;
test_assert(solver.Image(std::move(copy)) == image);
test_assert(solver.Kernel(std::move(mat)) == noyau);
Vect imageCalc = solver.Image(std::move(copy));
Vect kernelCalc = solver.Kernel(std::move(mat));
test_assert(imageCalc == image);
test_assert(kernelCalc == noyau);
}
}
int main() {
srand(time(0));
TestKernelImage();
TestRectangular();
RandomRectangular();
return 0;
}

View File

@@ -1,6 +1,27 @@
#include "Vect.h"
#include "test_assert.h"
#include <algorithm>
const static int EXECUTION_COUNT = 100000;
static constexpr int MATRIX_MAX_SIZE = 5;
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(); });
return matrix;
}
void TestVect() {
Vect vect1 {{3, 2, {
1, 2,
@@ -41,8 +62,23 @@ void TestVectAffine() {
test_assert(!aff.IsElementOf(Matrix::ColumnVector({1, 2, 3})));
}
void TestLinearSystem() {
for (std::size_t i = 0; i < EXECUTION_COUNT; i++) {
Vect vect = GetRandomMatrix(GetRandomSize(), GetRandomSize());
Matrix systeme = vect.GetLinearSystem();
for (std::size_t j = 0; j < vect.GetCardinal(); j++) {
Matrix nullMatrix {systeme.GetColumnCount(), 1};
test_assert(systeme * vect.GetVector(j) == nullMatrix);
}
}
}
int main() {
srand(time(0));
TestVect();
TestVectAffine();
TestLinearSystem();
return 0;
}

View File

@@ -1,9 +1,19 @@
set_project("Pivot")
set_description("Solutionneur de matrice par le pivot de Gauss")
set_license("MIT")
set_xmakever("2.8.5")
add_rules("mode.debug", "mode.release")
set_languages("c++17")
add_requires("imgui", {configs = {sdl2_no_renderer = true, opengl3 = true}})
set_languages("c++20")
set_warnings("all")
add_includedirs("include")
-- Solver Library
target("Pivot")
set_kind("static")
@@ -19,9 +29,19 @@ target("PivotMain")
set_rundir("$(projectdir)/matricies")
add_files("src/main.cpp")
add_deps("Pivot")
set_default(false)
-- Gui interface
target("PivotGui")
set_rundir("$(projectdir)")
add_files("src/gui/*.cpp")
add_deps("Pivot")
set_default(true)
add_packages("libsdl", "imgui")