116 Commits

Author SHA1 Message Date
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
dc31f1f091 less use of transpose
All checks were successful
Linux arm64 / Build (push) Successful in 1m26s
2024-05-04 15:21:49 +02:00
11cc0fadad gauss column 2024-05-04 15:10:13 +02:00
e71bc588e5 solver move matricies 2024-05-04 14:56:50 +02:00
36ef301cb9 doc test_assert 2024-05-04 13:08:11 +02:00
f5a282c455 allow tests in release mode
All checks were successful
Linux arm64 / Build (push) Successful in 6m40s
2024-05-04 12:42:26 +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
851080c7a4 fix minor typos
All checks were successful
Linux arm64 / Build (push) Successful in 1m16s
2024-04-05 15:04:23 +02:00
2724ca173d improve random_kernel test
All checks were successful
Linux arm64 / Build (push) Successful in 1m25s
2024-03-14 21:54:13 +01:00
13c9bc40db added random kernel tests
All checks were successful
Linux arm64 / Build (push) Successful in 1m1s
2024-03-06 22:53:07 +01:00
1b994daf3c reduce Vect on construct 2024-03-06 22:31:18 +01:00
99624d1b00 solver rework + refactor 2024-03-06 21:24:15 +01: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
259750a794 fix warnings
All checks were successful
Linux arm64 / Build (push) Successful in 36s
2024-03-05 23:00:32 +01:00
5a44ff311a simplify rank
All checks were successful
Linux arm64 / Build (push) Successful in 38s
2024-03-05 22:23:41 +01:00
432fa99f71 fix triangular system 2024-03-05 22:23:29 +01:00
911f016bb7 add RawVector 2024-03-05 21:14:08 +01:00
0f72f6603e remove useless numbers in test 2024-03-05 20:43:14 +01:00
2b520f6648 better matrix doc
All checks were successful
Linux arm64 / Build (push) Successful in 9m48s
2024-03-03 12:30:43 +01:00
57d51a1406 better Intellisense on vscode 2024-03-03 12:20:11 +01:00
3d01393f02 add IsElementOf + ColumnVector 2024-03-03 12:16:26 +01:00
9d3d78fe16 better NR test
All checks were successful
Linux arm64 / Build (push) Successful in 37s
2024-03-02 13:11:43 +01:00
750781aa5c minor NR changes 2024-03-02 13:11:23 +01:00
222d723675 improve matrix doc
All checks were successful
Linux arm64 / Build (push) Successful in 36s
2024-02-29 22:38:36 +01:00
e072d30995 better doc 2024-02-29 22:36:07 +01:00
bbcf3aa88d add project desc 2024-02-29 22:29:09 +01:00
6ac75b12af fix doc 2024-02-29 22:27:04 +01:00
034326a21e fix include path 2024-02-29 22:25:39 +01:00
8c1c3d4f9e add more doc 2024-02-29 22:24:42 +01:00
9028b553c3 add doxygen config 2024-02-29 22:23:30 +01:00
46adc200d1 add doxygen-awesome-css 2024-02-29 22:23:17 +01:00
7c75728180 better assert 2024-02-29 21:48:27 +01:00
54346dc77f add some doc
All checks were successful
Linux arm64 / Build (push) Successful in 40s
2024-02-29 15:10:12 +01:00
d038ac5884 big internal rework 2024-02-29 14:48:36 +01:00
b9a5100cb0 fix typo 2024-02-29 14:05:12 +01:00
890575bc7d remove useless variables 2024-02-29 14:01:20 +01:00
10d2bb1da0 add another test 2024-02-29 12:13:14 +01:00
8d940cadf6 add matrix test 2024-02-29 12:07:58 +01:00
Julien Chataigner
edb79f725c ajout de tests
All checks were successful
Linux arm64 / Build (push) Successful in 37s
2024-02-27 16:12:56 +01:00
81e82b27a4 update Readme
All checks were successful
Linux arm64 / Build (push) Successful in 33s
2024-02-25 21:27:09 +01:00
b7bf653431 remove makefile
All checks were successful
Linux arm64 / Build (push) Successful in 33s
2024-02-25 21:18:30 +01:00
ff79704293 fix main
All checks were successful
Linux arm64 / Build (push) Successful in 33s
2024-02-25 21:16:07 +01:00
b8ee47e267 add very basic NR test
Some checks failed
Linux arm64 / Build (push) Failing after 8m57s
2024-02-25 20:29:10 +01:00
abd5c7ac56 refactor NR 2024-02-25 20:28:01 +01:00
Julien Chataigner
ad288b3661 test
All checks were successful
Linux arm64 / Build (push) Successful in 38s
2024-02-25 13:25:04 +01:00
Pierre CHATAIGNER
21e78a8820 nr take 2
All checks were successful
Linux arm64 / Build (push) Successful in 40s
2024-02-25 13:16:48 +01:00
Pierre CHATAIGNER
c7268fe536 nombres rationnels 2024-02-25 13:06:11 +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
6b03fab302 action: use xmake latest
All checks were successful
Linux arm64 / Build (push) Successful in 37s
2024-02-24 13:05:29 +01:00
a35f45015b Use fixed xmake version for action
All checks were successful
Linux arm64 / Build (push) Successful in 5m28s
2024-02-23 11:16:58 +01:00
5a5c247019 english name for symbols
Some checks failed
Linux arm64 / Build (push) Failing after 1m56s
2024-02-23 11:03:38 +01:00
99eca82b3a fix Vect display 2024-02-23 11:02:49 +01:00
3b07ae783f refactor project 2024-02-23 10:48:43 +01:00
82ad2e0696 format project 2024-02-23 10:14:23 +01:00
efd0a88868 format test_solver
All checks were successful
Linux arm64 / Build (push) Successful in 5m19s
2024-02-21 22:06:08 +01:00
54798d0ff2 resolve rectangular systems 2024-02-21 22:01:31 +01:00
99467048e2 change Vect display 2024-02-21 21:59:46 +01:00
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
a1d74ec126 vectorial space to linear equation
All checks were successful
Linux arm64 / Build (push) Successful in 30s
2024-02-14 22:22:59 +01:00
4ffeea8900 image et noyau
All checks were successful
Linux arm64 / Build (push) Successful in 36s
2024-02-14 21:35:26 +01:00
e1f501237d vect dimension 2024-02-14 21:31:23 +01:00
8ef738db55 matrice augmenter 2024-02-14 21:31:05 +01:00
cf64e4d33c improve identity 2024-02-14 21:30:41 +01:00
a016163b86 more example
All checks were successful
Linux arm64 / Build (push) Successful in 8m58s
2024-02-14 20:30:16 +01:00
d91d35a3af implement Vect 2024-02-14 20:29:25 +01:00
b90195cac1 change transpose signature 2024-02-14 20:29:02 +01:00
715bc843b2 O_o 2024-02-14 20:22:14 +01:00
23de24e9a1 add stuff
Some checks failed
Linux arm64 / Build (push) Failing after 14m40s
2024-02-13 11:38:52 +01:00
820308b6c7 fix action
All checks were successful
Linux arm64 / Build (push) Successful in 27s
2024-02-10 17:37:00 +01:00
a7a2986336 ignore .vscode folder
Some checks failed
Linux arm64 / Build (push) Failing after 12m27s
2024-02-10 16:59:33 +01:00
4c217a4b20 add basic test 2024-02-10 16:58:44 +01:00
150e67e30b update readme
All checks were successful
Linux arm64 / Build (push) Successful in 2m5s
2024-02-10 14:54:32 +01:00
21a7268cbc add actions
Some checks are pending
Linux arm64 / Build (push) Waiting to run
2024-02-10 14:31:54 +01:00
8c96ca4340 remove useless dimension 2024-02-10 12:18:34 +01:00
a5a14a9763 force c++ version 2024-02-08 21:57:34 +01:00
0ed89e2827 fix gauss 2024-02-08 11:30:54 +01:00
7a02a9d1cf rien 2024-02-08 10:42:11 +01:00
Morph01
014b102e4a reformat 2024-02-08 10:36:19 +01:00
Morph01
3644a0aae2 image read me 2024-02-07 15:09:36 +01:00
Morph01
92b8f8bd17 read me 2024-02-07 15:06:26 +01:00
07ebb29621 add readme 2024-02-07 01:31:36 +01:00
42 changed files with 5051 additions and 291 deletions

View File

@@ -7,6 +7,8 @@ ConstructorInitializerAllOnOneLineOrOnePerLine: true
PointerAlignment: Left
SortIncludes: true
SpacesBeforeTrailingComments: 2
SeparateDefinitionBlocks: Always
SpaceBeforeCpp11BracedList: true
UseTab: Always
MaxEmptyLinesToKeep: 5

View File

@@ -0,0 +1,40 @@
name: Linux arm64
run-name: Build And Test
on: [push]
jobs:
Build:
runs-on: ubuntu-latest
steps:
- name: Install opengl
run: |
apt update
apt install libgl-dev -y
- name: Check out repository code
uses: actions/checkout@v3
- name: Prepare Xmake
uses: xmake-io/github-action-setup-xmake@v1
with:
xmake-version: latest
actions-cache-folder: '.xmake-cache'
actions-cache-key: 'ubuntu-xmake'
- name: Cache
uses: actions/cache@v4
with:
path: ~/.xmake
key: 'ubuntu'
- name: XMake config
run: xmake f -p linux -y --root
- name: Build
run: xmake --root
- name: Test
run: |
xmake f -m debug --root
xmake test --root

4
.gitignore vendored
View File

@@ -5,4 +5,8 @@ build/
# MacOS Cache
.DS_Store
# VsCode
.vscode
#ImGui
imgui.ini

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "doc/doxygen-awesome-css"]
path = doc/doxygen-awesome-css
url = https://github.com/jothepro/doxygen-awesome-css

11
.vscode/c_cpp_properties.json vendored Normal file
View File

@@ -0,0 +1,11 @@
{
"configurations": [
{
"name": "Pivot",
"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.

23
README.md Normal file
View File

@@ -0,0 +1,23 @@
# Projet MAM Pivot
# Cahier des charges
![imagecdc](projet.jpg)
# Build ⚙️
```
xmake
```
# Run 🏃
```
xmake run
```
# Test 🛠
```
xmake test
```

2736
doxyfile Normal file

File diff suppressed because it is too large Load Diff

BIN
icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

20
include/Gauss.h Normal file
View File

@@ -0,0 +1,20 @@
#pragma once
/**
* \file Gauss.h
* \brief Contient la définition de l'algorithme de Gauss
*/
class Matrix;
namespace Gauss {
/**
* \brief Echelonne une matrice en ligne 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 GaussJordan(Matrix& a_Matrix, bool a_Reduite, bool a_Normalise);
} // namespace Gauss

52
include/IO.h Normal file
View File

@@ -0,0 +1,52 @@
#pragma once
/**
* \file IO.h
* \brief Contient des fonctions utiles pour travailler avec les systèmes d'entrée et de sortie
*/
#include <string>
class Matrix;
class Vect;
class VectAffine;
std::ostream& operator<<(std::ostream& stream, const Matrix& mat);
std::istream& operator>>(std::istream& stream, Matrix& mat);
/**
* \brief Charge une matrice à partir d'un fichier
* \param fileName Le chemin du fichier à charger
* \return Une matrice de taille nulle si une erreur intervient
*/
Matrix LoadMatrix(const std::string& fileName);
/**
* \brief Sauvegarde une matrice dans un fichier
* \param mat La matrice à sauver
* \param fileName Le chemin du fichier à écrire
*/
void SaveMatrix(const Matrix& mat, const std::string& fileName);
/**
* \brief Permet de saisir une matrice à partir de la console
*/
Matrix InsertMatrix();
/**
* \brief Affiche une matrice dans la console
* \param mat La matrice à afficher
*/
void Print(const Matrix& mat);
/**
* \brief Affiche un espace vectoriel dans la console
* \param vect L'espace vectoriel à afficher
*/
void Print(const Vect& vect);
/**
* \brief Affiche un espace affine dans la console
* \param vect L'espace affine à afficher
*/
void Print(const VectAffine& vect);

176
include/Matrix.h Normal file
View File

@@ -0,0 +1,176 @@
#pragma once
/**
* \file Matrix.h
* \brief Contient la définition d'une matrice
*/
#include <cmath>
#include <cstddef>
#include <string>
#include <vector>
#include "NR.h"
/**
* \class Matrix
* \brief Représente une matrice d'éléments
*/
class Matrix {
public:
typedef NR Element;
typedef std::vector<Element>::iterator iterator;
private:
std::size_t m_Raws;
std::size_t m_Columns;
std::vector<Element> m_Data;
public:
/**
* \brief Constructeur par défaut. Crée une matrice de taille nulle
*/
Matrix() : m_Raws(0), m_Columns(0) {}
/**
* \brief Construit une matrice de taille donnée remplie de données aléatoires (et peut-être invalides !)
* \param a_Raws Le nombre de lignes
* \param a_Columns Le nombre de colonne
*/
Matrix(std::size_t a_Raws, std::size_t a_Columns);
/**
* \brief Construit une matrice de taille donnée avec des éléments donnés.\n
* Exemple :
* \code Matrix(2, 2, {1, 2, 3, 4}) \endcode construit la matrice \n
* [1, 2]\n
* [3, 4]
* \param a_Raws Le nombre de lignes
* \param a_Columns Le nombre de colonne
* \param a_Elements Les élements à mettre
*/
Matrix(std::size_t a_Raws, std::size_t a_Columns, std::initializer_list<Element>&& a_Elements);
~Matrix() {}
/**
* \brief Retourne le nombre de lignes de la matrice
*/
std::size_t GetRawCount() const;
/**
* \brief Retourne le nombre de colonnes de la matrice
*/
std::size_t GetColumnCount() const;
/**
* \brief Transpose la matrice
*/
void Transpose();
/**
* \brief Augmente la matrice actuelle à droite avec une autre
* \param a_Right Une matrice avec le bon nombre de lignes
* \pre Les deux matrices doivent avoir le même nombre de lignes
*/
void Augment(const Matrix& a_Right);
/**
* \brief Augmente la matrice actuelle en dessous avec une autre
* \param a_Bottom Une matrice avec le bon nombre de colonnes
* \pre Les deux matrices doivent avoir le même nombre de colonnes
*/
void AugmentBottom(const Matrix& a_Bottom);
/**
* \brief Affecte tous les coefficients de la matrice à un élément
* \param a_Element L'élément à affecter
*/
void Fill(Element a_Element);
/**
* \brief Retourne la sous-matrice spécifiée
* \param a_RawOrigin L'indice de la première ligne de la matrice à récupérer
* \param a_ColumnOrigin L'indice de la première colonne de la matrice à récupérer
* \param a_RawCount Le nombre de lignes de la sous-matrice
* \param a_ColumnCount Le nombre de colonnes de la sous-matrice
* \pre a_RawOrigin + a_RawCount <= GetRawCount()
* \pre a_ColumnOrigin + a_ColumnCount <= GetColumnCount()
*/
Matrix SubMatrix(std::size_t a_RawOrigin, std::size_t a_ColumnOrigin, std::size_t a_RawCount, std::size_t a_ColumnCount) const;
Matrix operator+(const Matrix& a_Other) const;
Matrix operator-(const Matrix& a_Other) const;
bool operator==(const Matrix& a_Other) const;
/**
* \brief Effectue un produit matriciel
*/
Matrix operator*(const Matrix& a_Other) const;
/**
* \brief Retourne l'élément à l'indice recherché
* \param a_Raw L'indice de la ligne
* \param a_Column L'indice de la colonne
*/
Element& at(std::size_t a_Raw, std::size_t a_Column);
/**
* \brief Retourne l'élément à l'indice recherché (version constante)
* \param a_Raw L'indice de la ligne
* \param a_Column L'indice de la colonne
*/
Element at(std::size_t a_Raw, std::size_t a_Column) const;
/**
* \brief Construit une matrice identité de taille donnée
* \param a_Size La taille de la matrice carrée
*/
static Matrix Identity(std::size_t a_Size);
/**
* \brief Construit une matrice colonne à partir de données existantes.\n
* Exemple :
* \code
* Matrix::ColumnVector({1, 2, 3, 4});
* \endcode
* construit une matrice de 4 lignes et 1 colonne de coordonnées (1, 2, 3, 4)
*/
static Matrix ColumnVector(std::initializer_list<Element>&& a_Elements);
/**
* \brief Construit une matrice ligne à partir de données existantes.\n
* Exemple :
* \code
* Matrix::RawVector({1, 2, 3, 4});
* \endcode
* 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(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;
}

48
include/NR.h Normal file
View File

@@ -0,0 +1,48 @@
#pragma once
#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
public:
NR();
NR(Int entier);
NR(Int numerator, Int denominator); // check if denominator != 0
Int GetNumerator() const;
Int GetDenominator() const;
bool operator==(const NR& opNR) const;
bool operator<(const NR& opNR) const;
bool operator>(const NR& opNR) const;
bool operator!=(const NR& opNR) const;
bool operator<=(const NR& opNR) const;
bool operator>=(const NR& opNR) const;
NR operator+(const NR& opNR) const;
NR operator-(const NR& opNR) const;
NR operator*(const NR& opNR) const;
NR operator/(const NR& opNR) const;
NR& operator+=(const NR& opNR);
NR& operator-=(const NR& opNR);
NR& operator*=(const NR& opNR);
NR& operator/=(const NR& opNR);
NR operator-() const;
NR Inverse() const;
friend std::ostream& operator<<(std::ostream& os, const NR& opNR);
friend std::istream& operator>>(std::istream& os, NR& opNR);
private:
void Reduce();
};

44
include/Solver.h Normal file
View File

@@ -0,0 +1,44 @@
#pragma once
/**
* \file Solver.h
* \brief Contient la définition du solutionneur
*/
#include "Vect.h"
/**
* \class Solver
* \brief Permet d'obtenir différentes propriétés d'une matrice comme l'image ou le noyau
*/
class Solver {
public:
/**
* \brief Calcule l'image d'une matrice
* \param a_Matrix La matrice à traiter
* \return L'espace vectoriel correspondant
*/
Vect Image(Matrix&& a_Matrix) const;
/**
* \brief Calcule le noyau d'une matrice
* \param a_Matrix La matrice à traiter
* \return L'espace vectoriel correspondant
*/
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.
* \param a_MatrixA La matrice jouant le rôle de A
* \param a_VectorB La matrice colonne jouant le rôle de B
* \return L'espace affine associé
*/
VectAffine RectangularSystem(Matrix&& a_MatrixA, const Matrix& a_VectorB) const;
/**
* \brief Calcule le rang d'une matrice
* \param a_Matrix La matrice à traiter
* \note Ceci équivaut à \code Image(a_Matrix).GetCardinal() \endcode
*/
std::size_t Rank(Matrix&& a_Matrix) const;
};

111
include/Vect.h Normal file
View File

@@ -0,0 +1,111 @@
#pragma once
/**
* \file Vect.h
* \brief Contient la définition d'un espace affine et d'un espace vectoriel
*/
#include "Matrix.h"
/**
* \class Vect
* \brief Représente une base d'un espace vectoriel de dimension finie
*/
class Vect {
private:
Matrix m_Data;
public:
/**
* \brief Construit une base d'un espace vectoriel à partir des colonnes d'une matrice.
* Les colonnes de 0 sont ignorées
* \param a_Matrix Une matrice échelonnée.
*/
Vect(Matrix&& a_Matrix);
/**
* \brief Permet d'obtenir le ieme vecteur de la base
* \param a_Index l'index du vecteur souhaité
* \return Une matrice colonne
*/
Matrix GetVector(std::size_t a_Index) const;
/**
* \brief Retourne le nombre de coordonnées des vecteurs de la base (leur nombre de colonne)
*/
std::size_t GetDimension() const;
/**
* \brief Retourne le nombre de vecteur de la base
*/
std::size_t GetCardinal() 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;
/**
* \brief Concatène la base actuelle avec un nouveau vecteur
* \param a_Vector Une matrice colonne de taille GetDimension()
*/
void AddVector(const Matrix& a_Vector);
/**
* \brief Vérifie si le vecteur spécifié appartient au sous-espace vectoriel
* \param a_Vector Une matrice colonne représentant le vecteur à tester
*/
bool IsElementOf(const Matrix& a_Vector) const;
bool operator==(const Vect& a_Other) const;
bool operator!=(const Vect& a_Other) const;
private:
void Simplify();
friend class VectAffine;
};
/**
* \class VectAffine
* \brief Représente un espace affine
*/
class VectAffine {
private:
Vect m_Base;
Matrix m_Origin;
public:
/**
* \brief Construit un espace affine à partir d'un espace vectoriel et d'une origine
* \param a_Base La base de l'espace vectoriel
* \param a_Origin Le vecteur d'origine (matrice colonne)
*/
VectAffine(const Vect& a_Base, const Matrix& a_Origin);
/**
* \brief Retourne l'espace vectoriel correspondant
*/
const Vect& GetBase() const {
return m_Base;
}
/**
* \brief Retourne l'origine de l'espace affine
* \return Un vecteur colonne
*/
const Matrix& GetOrigin() const {
return m_Origin;
}
/**
* \brief Vérifie si le vecteur spécifié appartient à l'espace affine
* \param a_Vector Une matrice colonne représentant le vecteur à tester
*/
bool IsElementOf(const Matrix& a_Vector) const;
bool operator==(const VectAffine& a_VectAffine) const {
return m_Origin == a_VectAffine.GetOrigin() && m_Base == a_VectAffine.GetBase();
};
};

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

@@ -0,0 +1,11 @@
3 3
1 0 1
0 1 3
0 4 4
3 3
1 0 0
0 1 0
0 0 1
3 0

View File

@@ -0,0 +1,16 @@
4 3
1 -1 0
2 1 3
1 2 3
2 -2 0
4 2
1 0
1 1
0 1
2 0
3 1
1
1
-1

View File

@@ -0,0 +1,17 @@
4 4
5 2 3 0
9 0 -9 0
1 0 -1 0
0 0 3 -3
4 3
1 0 0
0 0 9
0 0 1
0 -3 0
4 1
1
-4
1
1

View File

@@ -0,0 +1,14 @@
5 4
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
5 0
4 4
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1

View File

@@ -0,0 +1,19 @@
5 4
0 0 0 0
0 0 0 1
0 0 0 0
0 0 0 0
0 0 0 0
5 1
0
1
0
0
0
4 3
1 0 0
0 1 0
0 0 1
0 0 0

BIN
projet.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 809 KiB

113
src/Gauss.cpp Normal file
View File

@@ -0,0 +1,113 @@
#include "Gauss.h"
#include "Matrix.h"
#include <algorithm>
#include <execution>
#include <ranges>
namespace Gauss {
static void SwapLines(Matrix& mat, std::size_t line1, std::size_t line2) {
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) {
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) {
for (std::size_t i = startLine; i < mat.GetRawCount(); i++) {
if (!IsEqualZero(mat.at(i, column))) {
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);
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 GaussJordanReduced(Matrix& a_Matrix, bool a_Normalise) {
int indice_ligne_pivot = -1;
for (std::size_t j = 0; j < a_Matrix.GetColumnCount(); j++) {
int indice_ligne_pivot_trouve = FirstNotNullElementIndexOnColumn(a_Matrix, j, indice_ligne_pivot + 1);
if (indice_ligne_pivot_trouve < 0) // colonne de 0
continue; // on regarde la prochaine colonne
indice_ligne_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(indice_ligne_pivot, j);
if (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
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);
}
});
}
}
static void GaussJordanTriangular(Matrix& a_Matrix, bool a_Normalise) {
int indice_ligne_pivot = -1;
for (std::size_t j = 0; j < a_Matrix.GetColumnCount(); j++) {
int indice_ligne_pivot_trouve = FirstNotNullElementIndexOnColumn(a_Matrix, j, indice_ligne_pivot + 1);
if (indice_ligne_pivot_trouve < 0) // colonne de 0
continue; // on regarde la prochaine colonne
indice_ligne_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(indice_ligne_pivot, j);
if (a_Normalise) {
DivideLine(a_Matrix, indice_ligne_pivot, 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

101
src/IO.cpp Normal file
View File

@@ -0,0 +1,101 @@
#include "IO.h"
#include "Vect.h"
#include <fstream>
#include <iostream>
std::ostream& operator<<(std::ostream& stream, const Matrix& mat) {
stream << mat.GetRawCount() << " " << mat.GetColumnCount() << "\n";
for (std::size_t i = 0; i < mat.GetRawCount(); i++) {
for (std::size_t j = 0; j < mat.GetColumnCount(); j++) {
stream << mat.at(i, j) << " ";
}
stream << "\n";
}
return stream;
}
std::istream& operator>>(std::istream& stream, Matrix& mat) {
std::size_t raw, column;
stream >> raw >> column;
Matrix result {raw, column};
mat = result;
for (std::size_t i = 0; i < mat.GetRawCount(); i++) {
for (std::size_t j = 0; j < mat.GetColumnCount(); j++) {
stream >> mat.at(i, j);
}
}
return stream;
}
Matrix LoadMatrix(const std::string& fileName) {
std::ifstream in {fileName};
if (!in) {
std::cerr << "Impossible de charger la matrice !\n";
return {};
}
Matrix result;
in >> result;
return result;
}
void SaveMatrix(const Matrix& mat, const std::string& fileName) {
std::ofstream out {fileName};
if (!out) {
std::cerr << "Impossible de sauvegarder la matrice !\n";
return;
}
out << mat;
}
Matrix InsertMatrix() {
std::cout << "Quelle est le nombre de lignes de votre matrice ?" << std::endl;
std::size_t lignes;
std::cin >> lignes;
std::cout << "Quelle est le nombre de colonnes de votre matrice ?" << std::endl;
std::size_t colonnes;
std::cin >> colonnes;
std::cout << "Rentrez les coefficients de la matrice" << std::endl;
Matrix result(lignes, colonnes);
for (size_t i = 0; i < result.GetRawCount(); ++i) {
for (size_t j = 0; j < result.GetColumnCount(); ++j) {
std::cin >> result.at(i, j);
}
std::cout << std::endl;
}
return result;
}
void Print(const Matrix& mat) {
for (size_t i = 0; i < mat.GetRawCount(); ++i) {
std::cout << "[ ";
for (size_t j = 0; j < mat.GetColumnCount(); ++j) {
std::cout << mat.at(i, j) << " ";
}
std::cout << "]";
std::cout << std::endl;
}
}
void Print(const Vect& vect) {
std::cout << "Espace vectoriel de dimension " << vect.GetCardinal() << " de base :\n\n";
for (std::size_t i = 0; i < vect.GetDimension(); i++) {
for (std::size_t j = 0; j < vect.GetCardinal(); j++) {
Matrix vector = vect.GetVector(j);
std::cout << "[ " << vector.at(i, 0) << " ]\t";
}
std::cout << "\n";
}
}
void Print(const VectAffine& vect) {
std::cout << "\tEspace Affine :\n\n";
Print(vect.GetBase());
std::cout << "\nOrigine :\n\n";
Print(vect.GetOrigin());
}

199
src/Matrix.cpp Normal file
View File

@@ -0,0 +1,199 @@
#include "Matrix.h"
#include "IO.h"
#include <algorithm>
#include <cassert>
#include <cmath>
#include <fstream>
#include <iostream>
Matrix::Matrix(std::size_t a_Raws, std::size_t a_Columns) : m_Raws(a_Raws), m_Columns(a_Columns) {
m_Data.resize(m_Raws * m_Columns);
}
Matrix::Matrix(std::size_t a_Raws, std::size_t a_Columns, std::initializer_list<Element>&& a_Elements) :
m_Raws(a_Raws), m_Columns(a_Columns) {
m_Data = a_Elements;
m_Data.resize(m_Raws * m_Columns);
}
Matrix Matrix::operator*(const Matrix& a_Other) const {
assert(m_Columns == a_Other.m_Raws);
Matrix result(m_Raws, a_Other.m_Columns);
for (std::size_t i = 0; i < m_Raws; ++i) {
for (std::size_t j = 0; j < a_Other.m_Columns; ++j) {
Element sum = 0;
for (std::size_t k = 0; k < m_Columns; k++) {
sum += at(i, k) * a_Other.at(k, j);
}
result.at(i, j) = sum;
}
}
return result;
}
void Matrix::Transpose() {
Matrix result {m_Columns, m_Raws};
for (std::size_t i = 0; i < m_Raws; i++) {
for (std::size_t j = 0; j < m_Columns; j++) {
result.at(j, i) = at(i, j);
}
}
*this = result;
}
Matrix Matrix::Identity(std::size_t a_Size) {
Matrix id {a_Size, a_Size};
for (std::size_t i = 0; i < a_Size; i++) {
for (std::size_t j = i; j < a_Size; j++) {
id.at(i, j) = (i == j);
}
}
return id;
}
Matrix Matrix::ColumnVector(std::initializer_list<Element>&& a_Elements) {
Matrix result {a_Elements.size(), 1};
result.m_Data = a_Elements;
return result;
}
Matrix Matrix::RawVector(std::initializer_list<Element>&& a_Elements) {
Matrix result {1, a_Elements.size()};
result.m_Data = a_Elements;
return result;
}
void Matrix::Fill(Element a_Element) {
std::fill(GetLineIterator(0), GetLineIterator(m_Raws), a_Element);
}
void Matrix::Augment(const Matrix& a_Right) {
assert(a_Right.m_Raws == m_Raws);
Matrix temp {m_Raws, m_Columns + a_Right.m_Columns};
for (std::size_t i = 0; i < m_Raws; i++) {
for (std::size_t j = 0; j < m_Columns; j++) {
temp.at(i, j) = at(i, j);
}
}
for (std::size_t i = 0; i < m_Raws; i++) {
for (std::size_t j = 0; j < a_Right.m_Columns; j++) {
temp.at(i, j + m_Columns) = a_Right.at(i, j);
}
}
*this = temp;
}
void Matrix::AugmentBottom(const Matrix& a_Bottom) {
assert(a_Bottom.m_Columns == m_Columns);
Matrix temp {m_Raws + a_Bottom.GetRawCount(), m_Columns};
for (std::size_t i = 0; i < m_Raws; i++) {
for (std::size_t j = 0; j < m_Columns; j++) {
temp.at(i, j) = at(i, j);
}
}
for (std::size_t i = 0; i < a_Bottom.GetRawCount(); i++) {
for (std::size_t j = 0; j < GetColumnCount(); j++) {
temp.at(i + GetRawCount(), j) = a_Bottom.at(i, j);
}
}
*this = temp;
}
Matrix Matrix::operator+(const Matrix& a_Other) const {
assert(GetColumnCount() == a_Other.GetColumnCount() && GetRawCount() == a_Other.GetRawCount());
Matrix result = *this;
for (std::size_t i = 0; i < GetRawCount(); i++) {
for (std::size_t j = 0; j < GetColumnCount(); j++) {
result.at(i, j) += a_Other.at(i, j);
}
}
return result;
}
Matrix Matrix::operator-(const Matrix& a_Other) const {
assert(GetColumnCount() == a_Other.GetColumnCount() && GetRawCount() == a_Other.GetRawCount());
Matrix result = *this;
for (std::size_t i = 0; i < GetRawCount(); i++) {
for (std::size_t j = 0; j < GetColumnCount(); j++) {
result.at(i, j) -= a_Other.at(i, j);
}
}
return result;
}
bool Matrix::operator==(const Matrix& a_Other) const {
assert(m_Raws == a_Other.m_Raws && m_Columns == a_Other.m_Columns);
for (std::size_t i = 0; i < m_Raws; i++) {
for (std::size_t j = 0; j < m_Columns; j++) {
if (!IsEqualZero(at(i, j) - a_Other.at(i, j)))
return false;
}
}
return true;
}
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];
}
std::size_t Matrix::GetRawCount() const {
return m_Raws;
}
std::size_t Matrix::GetColumnCount() const {
return m_Columns;
}
Matrix Matrix::SubMatrix(
std::size_t a_RawOrigin, std::size_t a_ColumnOrigin, std::size_t a_RawCount, std::size_t a_ColumnCount) const {
assert(m_Raws >= a_RawOrigin + a_RawCount && m_Columns >= a_ColumnOrigin + a_ColumnCount);
Matrix result {a_RawCount, a_ColumnCount};
for (std::size_t i = 0; i < result.GetRawCount(); i++) {
for (std::size_t j = 0; j < result.GetColumnCount(); j++) {
result.at(i, j) = at(i + a_RawOrigin, j + a_ColumnOrigin);
}
}
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

@@ -1,256 +0,0 @@
#pragma once
#include <algorithm>
#include <cmath>
#include <fstream>
#include <iostream>
#include <vector>
template <typename T>
static bool EqualZero(T var) {
return std::abs(var) < std::pow(10, -5);
}
template <typename T>
class Matrix {
private:
std::size_t m_Lignes;
std::size_t m_Colonnes;
std::size_t m_Dimension;
std::vector<T> m_Data;
public:
Matrix(const std::string& fileNameInput) {
Load(fileNameInput);
}
Matrix(std::size_t lignes, std::size_t colonnes) : m_Lignes(lignes), m_Colonnes(colonnes), m_Dimension(lignes * colonnes) {
m_Data.resize(m_Dimension);
}
Matrix(std::size_t lignes, std::size_t colonnes, std::initializer_list<T>&& initList) :
m_Lignes(lignes), m_Colonnes(colonnes), m_Dimension(lignes * colonnes) {
m_Data = initList;
m_Data.resize(m_Dimension);
}
~Matrix() {}
Matrix operator*(const Matrix& other) const {
if (m_Colonnes != other.m_Lignes) {
std::cerr << "Mutiplication impossible car la dimensions des matrices est incompatible" << std::endl;
}
Matrix result(m_Lignes, other.m_Colonnes);
for (std::size_t i = 0; i < m_Lignes; ++i) {
for (std::size_t j = 0; j < other.m_Colonnes; ++j) {
T sum = 0;
for (std::size_t k = 0; k < m_Colonnes; k++) {
sum += at(i, k) * other.at(k, j);
}
result.at(i, j) = sum;
}
}
return result;
}
void Print() const {
for (size_t i = 0; i < m_Lignes; ++i) {
std::cout << "[ ";
for (size_t j = 0; j < m_Colonnes; ++j) {
std::size_t indice = i * m_Lignes + j;
std::cout << at(i, j) << " ";
}
std::cout << "]";
std::cout << std::endl;
}
}
void PrintDebug() {
#ifndef NDEBUG
Print();
std::cout << "\n";
#endif
}
void Insert() {
for (size_t i = 0; i < m_Lignes; ++i) {
for (size_t j = 0; j < m_Colonnes; ++j) {
std::cin >> at(i, j);
}
std::cout << std::endl;
}
}
void Save(const std::string& fileName) {
std::ofstream out{fileName};
if (!out) {
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";
}
}
void Load(const std::string& filename) {
std::ifstream in{filename};
if (!in) {
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);
}
}
}
void Transpose() {
for (std::size_t i = 0; i < m_Lignes; i++) {
for (std::size_t j = i; j < m_Colonnes; j++) {
std::swap(at(i, j), at(j, i));
}
}
}
void Identity() {
for (std::size_t i = 0; i < m_Lignes; i++) {
for (std::size_t j = i; j < m_Colonnes; j++) {
if (i != j) {
at(i, j) = 0;
} else {
at(i, j) = 1;
}
}
}
}
bool IsInverse(const Matrix& mat, const Matrix& aug) const {
Matrix result = mat * aug;
for (std::size_t i = 0; i < m_Lignes; ++i) {
for (std::size_t j = 0; j < m_Colonnes; ++j) {
if ((i == j && !EqualZero(result.at(i, j) - 1.0)) || (i != j && EqualZero(result.at(i, j)))) {
return false;
}
}
}
return true;
}
Matrix GaussNonJordan(bool reduite, bool augmentee) {
Matrix<float> aug = Matrix(m_Lignes, m_Colonnes);
if (augmentee) {
std::size_t choix;
std::cout
<< "Entrez 1 pour rentrer la matrice augmentee que je vous voulez ou 2 pour la matrice augmentee Id pour trouver "
"l'inverse si elle existe."
<< std::endl;
std::cin >> choix;
while (choix != 1 && choix != 2) {
std::cout
<< "Entrez 1 pour rentrer la matrice augmentee que je vous voulez ou 2 pour la matrice augmentee Id pour trouver "
"l'inverse si elle existe."
<< std::endl;
std::cin >> choix;
}
if (choix == 1) {
std::cout << "Rentrez les coefficients de la matrice" << std::endl;
aug.Insert();
} else {
aug.Identity();
}
}
aug.Print();
int r = -1;
for (std::size_t j = 0; j < m_Colonnes; j++) {
std::size_t indice_ligne_maximum = r + 1;
// Recherche maximum
for (std::size_t i = r + 1; i < m_Lignes; i++) {
if (std::abs(at(i, j)) > std::abs(at(indice_ligne_maximum, j)))
indice_ligne_maximum = i;
}
// std::cout << "l'indice du maximum est : " << indice_ligne_maximum << "\n\n";
// Si A[k,j]≠0 alors (A[k,j] désigne la valeur de la ligne k et de la colonne j)
if (at(indice_ligne_maximum, j) != 0) {
r++;
// PrintDebug();
// Si k≠r alors
if (indice_ligne_maximum != r) {
// Échanger les lignes k et r (On place la ligne du pivot en position r)
// std::cout << "On échange les lignes " << indice_ligne_maximum << " et " << r << '\n';
for (std::size_t k = 0; k < m_Colonnes; k++) {
std::swap(at(indice_ligne_maximum, k), at(r, k));
// matrice augmentee
std::swap(aug.at(indice_ligne_maximum, k), aug.at(r, k));
}
}
// Pour i de 1 jusqu'à n (On simplifie les autres lignes)
for (std::size_t i = (reduite ? 0 : j); i < m_Lignes; i++) {
// Si i≠r alors
if (i != r) {
// Soustraire à la ligne i la ligne r multipliée par A[i,j] (de façon à
// annuler A[i,j])
T anulid = at(i, j);
for (int k = m_Colonnes - 1; k >= 0; k--) {
T pivot = at(r, j);
T anul = at(i, j);
at(i, k) = at(i, k) * pivot - at(r, k) * anul;
// matrice augmentee
aug.at(i, k) = aug.at(i, k) * pivot - aug.at(r, k) * anulid;
}
}
}
}
}
return (aug);
}
Matrix GaussJordan(bool reduite, bool augmentee) {
Matrix<float> aug = GaussNonJordan(reduite, augmentee);
for (std::size_t i = 0; i < m_Lignes; i++) {
int k = -1;
int kaugmentee = -1;
for (std::size_t j = 0; j < m_Colonnes; j++) {
if (at(i, j) != 0) {
k = j;
break;
}
}
// ligne de 0
if (k == -1)
break;
// on divise la ligne par (i, k)
T annul = at(i, k);
for (int j = 0; j < m_Colonnes; j++) {
at(i, j) /= annul;
// augmentee
aug.at(i, j) /= annul;
}
}
return aug;
}
T& operator[](std::size_t indice) {
return at(indice);
}
T& at(std::size_t ligne, std::size_t colonne) {
return m_Data[ligne * m_Lignes + colonne];
}
T at(std::size_t ligne, std::size_t colonne) const {
return m_Data[ligne * m_Lignes + colonne];
}
};

145
src/NR.cpp Normal file
View File

@@ -0,0 +1,145 @@
#include "NR.h"
#include <cassert>
#include <iostream>
NR::Int PGCD(NR::Int x, NR::Int y) {
if (x == 0 || y == 0)
return 1;
else if (x % y == 0)
return std::abs(y);
else
return PGCD(y, x % y);
}
NR::NR() : m_Numerator(0), m_Denominator(1) {}
NR::NR(NR::Int entier) : m_Numerator(entier), m_Denominator(1) {}
NR::NR(NR::Int numerator, NR::Int denominator) :
m_Numerator((denominator > 0) ? numerator : -numerator), m_Denominator(std::abs(denominator)) {
Reduce();
}
void NR::Reduce() {
NR::Int divisor = PGCD(m_Denominator, m_Numerator);
m_Denominator /= divisor;
m_Numerator /= divisor;
assert(m_Denominator != 0);
}
NR NR::Inverse() const {
assert(*this != 0);
return {m_Denominator, m_Numerator};
}
NR::Int NR::GetNumerator() const {
return m_Numerator;
}
NR::Int NR::GetDenominator() const {
return m_Denominator;
}
bool NR::operator==(const NR& opNR) const {
return (m_Numerator * opNR.GetDenominator() == m_Denominator * opNR.GetNumerator());
}
bool NR::operator<(const NR& opNR) const {
return (m_Numerator * opNR.GetDenominator() < m_Denominator * opNR.GetNumerator());
}
bool NR::operator>(const NR& opNR) const {
return (m_Numerator * opNR.GetDenominator() > m_Denominator * opNR.GetNumerator());
}
bool NR::operator!=(const NR& opNR) const {
return !(*this == opNR);
}
bool NR::operator<=(const NR& opNR) const {
return !(*this > opNR);
}
bool NR::operator>=(const NR& opNR) const {
return !(*this < opNR);
}
std::ostream& operator<<(std::ostream& os, const NR& opNR) {
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;
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;
num = m_Numerator * opNR.GetDenominator();
den = m_Denominator * opNR.GetDenominator();
num += (opNR.GetNumerator() * m_Denominator);
NR result(num, num == 0 ? 1 : den);
return result;
}
NR NR::operator-(const NR& opNR) const {
Int num, den;
num = m_Numerator * opNR.GetDenominator();
den = m_Denominator * opNR.GetDenominator();
num -= (opNR.GetNumerator() * m_Denominator);
NR result(num, num == 0 ? 1 : den);
return result;
}
NR NR::operator*(const NR& opNR) const {
Int num, den;
num = m_Numerator * opNR.GetNumerator();
den = m_Denominator * opNR.GetDenominator();
NR result(num, num == 0 ? 1 : den);
return result;
}
NR NR::operator/(const NR& opNR) const {
Int num, den;
num = m_Numerator * opNR.GetDenominator();
den = m_Denominator * opNR.GetNumerator();
NR result(num, num == 0 ? 1 : den);
return result;
}
NR& NR::operator+=(const NR& opNR) {
*this = *this + opNR;
return *this;
}
NR& NR::operator-=(const NR& opNR) {
*this = *this - opNR;
return *this;
}
NR& NR::operator*=(const NR& opNR) {
*this = *this * opNR;
return *this;
}
NR& NR::operator/=(const NR& opNR) {
*this = *this / opNR;
return *this;
}
NR NR::operator-() const {
return {-m_Numerator, m_Denominator};
}

View File

@@ -1,12 +0,0 @@
#pragma once
class NR {
private:
int m_Numerator;
int m_Denominator;
public:
NR() : m_Numerator(0), m_Denominator(1) {}
NR(int entier) : m_Numerator(entier), m_Denominator(1) {}
NR(int numerator, int denominator) : m_Numerator(numerator), m_Denominator(denominator) {}
};

70
src/Solver.cpp Normal file
View File

@@ -0,0 +1,70 @@
#include "Solver.h"
#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);
a_Matrix.Transpose();
return {std::move(a_Matrix)};
}
// https://en.wikipedia.org/wiki/Kernel_(linear_algebra)#Computation_by_Gaussian_elimination
Vect Solver::Kernel(Matrix&& a_Matrix) const {
std::size_t matrixRawCount = a_Matrix.GetRawCount();
std::size_t matrixColumnCount = a_Matrix.GetColumnCount();
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();
return {a_Matrix.SubMatrix(
matrixRawCount, origine_colonne, a_Matrix.GetRawCount() - matrixRawCount, a_Matrix.GetColumnCount() - origine_colonne)};
}
VectAffine Solver::RectangularSystem(Matrix&& a_MatrixA, const Matrix& a_VectorB) const {
Matrix mat = a_MatrixA;
mat.Augment(a_VectorB);
Gauss::GaussJordan(mat, true, true);
Solver solver;
Vect noyau = solver.Kernel(std::move(a_MatrixA));
Matrix origin = mat.SubMatrix(0, mat.GetColumnCount() - 1, mat.GetRawCount(), 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);
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};
}
std::size_t Solver::Rank(Matrix&& a_Matrix) const {
return Image(std::move(a_Matrix)).GetCardinal();
}

90
src/Vect.cpp Normal file
View File

@@ -0,0 +1,90 @@
#include "Vect.h"
#include "Gauss.h"
#include "Solver.h"
static bool IsColumnNull(Matrix& mat, std::size_t column) {
for (std::size_t i = 0; i < mat.GetRawCount(); i++) {
if (!IsEqualZero(mat.at(i, column))) {
return false;
}
}
return true;
}
Vect::Vect(Matrix&& a_Matrix) : m_Data(std::move(a_Matrix)) {
m_Data.Transpose();
Gauss::GaussJordan(m_Data, false, true);
m_Data.Transpose();
Simplify();
}
void Vect::Simplify() {
Matrix mat = m_Data;
for (std::size_t j = 0; j < mat.GetColumnCount(); j++) {
if (IsColumnNull(mat, j)) {
m_Data = mat.SubMatrix(0, 0, mat.GetRawCount(), j);
return;
}
}
m_Data = mat;
}
Matrix Vect::GetVector(std::size_t a_Index) const {
return m_Data.SubMatrix(0, a_Index, m_Data.GetRawCount(), 1);
}
std::size_t Vect::GetCardinal() const {
return m_Data.GetColumnCount();
}
bool Vect::IsElementOf(const Matrix& a_Vector) const {
Vect base = *this;
base.AddVector(a_Vector);
return base.GetCardinal() == GetCardinal();
}
bool Vect::operator==(const Vect& a_Other) const {
if (GetDimension() != a_Other.GetDimension() || GetCardinal() != a_Other.GetCardinal())
return false;
// on vérifie si chaque vecteur de la deuxième base appartient à l'espace vectoriel engendré par la première base
for (std::size_t i = 0; i < GetCardinal(); i++) {
if (!IsElementOf(a_Other.GetVector(i)))
return false;
}
return true;
}
void Vect::AddVector(const Matrix& a_Vector) {
m_Data.Augment(a_Vector);
m_Data.Transpose();
Gauss::GaussJordan(m_Data, false, false);
m_Data.Transpose();
Simplify();
}
bool Vect::operator!=(const Vect& a_Other) const {
return !(*this == a_Other);
}
Matrix Vect::GetLinearSystem() const {
Matrix vect = m_Data;
vect.Transpose();
Solver solver;
Matrix result = solver.Kernel(std::move(vect)).m_Data;
result.Transpose();
return result;
}
std::size_t Vect::GetDimension() const {
return m_Data.GetRawCount();
}
VectAffine::VectAffine(const Vect& a_Base, const Matrix& a_Origin) :
m_Base(a_Base), m_Origin(a_Origin.SubMatrix(0, 0, m_Base.GetDimension(), 1)) {}
bool VectAffine::IsElementOf(const Matrix& a_Vector) const {
return m_Base.IsElementOf(a_Vector - m_Origin);
}

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

@@ -1,44 +1,59 @@
#include "Gauss.h"
#include "IO.h"
#include "Matrix.h"
#include "NR.h"
#include "Solver.h"
#include <iostream>
void test() {
Matrix<float> mat{"matrice5x5.mat"};
/* Matrix mat{"matrice4x4.mat"};
mat.Print();
// mat.Save("matrice3x3.mat");
std::cout << "sdfdjiofoseifheoiefhoig\n";
mat.Print();
mat = {"matrice5x5.mat"};
mat.GaussJordan(false, true);
//mat = {"matrice4x4.mat"};
mat.GaussJordan(false);
std::cout << "\nResultat :\n";
mat.Print();
mat.Transpose();
std::cout << "<<\nTransposée:\n";
mat.Print();
// mat.Save("matrice4x4echelonne.mat");
// mat.Save("matrice4x4echelonne.mat"); */
Matrix mat2 = LoadMatrix("matrice4x4.mat");
Print(mat2);
Solver solver;
Vect image = solver.Image(Matrix{mat2});
Vect noyau = solver.Kernel(Matrix{mat2});
std::cout << "\tImage :\n";
Print(image);
std::cout << "Système :\n";
Print(image.GetLinearSystem());
std::cout << "\tNoyau :\n";
Print(noyau);
std::cout << "Système :\n";
Print(noyau.GetLinearSystem());
std::cout << "\n\n";
// Print(solver.TriangularSystem(mat2));
}
void prompt() {
std::cout << "Quelle est le nombre de lignes de votre matrice ?" << std::endl;
std::size_t lignes;
std::cin >> lignes;
std::cout << "Quelle est le nombre de colonnes de votre matrice ?" << std::endl;
std::size_t colonnes;
std::cin >> colonnes;
std::size_t dimension = lignes * colonnes;
std::cout << "Rentrez les coefficients de la matrice" << std::endl;
Matrix<float> mat(lignes, colonnes);
mat.Insert();
Matrix mat = InsertMatrix();
mat.Print();
Matrix<float> aug = mat.GaussJordan(true, true);
std::cout << std::endl;
std::cout << "Matrice echelonnee reduite" << std::endl;
mat.Print();
std::cout << "Matrice augmentee" << std::endl;
aug.Print();
Print(mat);
Gauss::GaussJordan(mat, true, true);
Print(mat);
}
int main(int argc, char** argv) {
// test();
test();
prompt();
return 0;
}

42
test/test_assert.h Normal file
View File

@@ -0,0 +1,42 @@
#pragma once
/**
* \file Test.h
* \brief Contient une assertion utilisable avec les optimisations
*/
#include <iostream>
#include <stdexcept>
/**
* \def TEST_SUCCESSFUL
* \brief Indique que le test a été passé
*/
#define TEST_SUCCESSFUL 0
/**
* \def TEST_FAILED
* \brief Indique que le test a échoué
*/
#define TEST_FAILED 1
#ifndef __FUNCTION_NAME__
#ifdef _WIN32
#define __FUNCTION_NAME__ __FUNCTION__
#else
#define __FUNCTION_NAME__ __PRETTY_FUNCTION__
#endif
#endif
/**
* \def test_assert
* \param ... L'expression à évaluer
* \brief Evalue une expression et arrête le programme si elle n'est pas valide
* \note Cette macro équivaut à assert() mais fonctionne également avec les optimisations activées
*/
#define test_assert(...) \
if (!static_cast<bool>(__VA_ARGS__)) { \
std::cout << __FILE__ << ":" << __LINE__ << ": " << __FUNCTION_NAME__ << ": Assertion failed !\n"; \
std::cout << " " << __LINE__ << " |\t" << #__VA_ARGS__ << std::endl; \
throw std::runtime_error("Assertion failed !"); \
}

43
test/test_jordan.cpp Normal file
View File

@@ -0,0 +1,43 @@
#include "Gauss.h"
#include "Matrix.h"
#include "test_assert.h"
struct Test {
Matrix mat;
Matrix res;
};
static const std::vector<Test> TEST_MATRICES = {
// test 1
{{3, 3, {
1, 2, 3,
4, 5, 6,
7, 8, 9,
}}, {3, 3, {
1, 0, -1,
0, 1, 2,
0, 0, 0,
}}},
// test 2
{{3, 3, {
4, 5, 6,
1, 2, 3,
7, 8, 9,
}}, {3, 3, {
1, 0, -1,
0, 1, 2,
0, 0, 0,
}}}
};
void test() {
for (Test test : TEST_MATRICES) {
Gauss::GaussJordan(test.mat, true, true);
test_assert(test.mat == test.res);
}
}
int main(int argc, char** argv) {
test();
return 0;
}

View File

@@ -0,0 +1,80 @@
#include "Solver.h"
#include "test_assert.h"
#include <cstdlib>
#include <future>
#include <iostream>
#include <vector>
static constexpr int EXECUTION_COUNT = 1000;
static constexpr int KERNEL_CHECKS = 100;
static constexpr int MATRIX_MAX_SIZE = 9;
static const Solver solver;
static int GetRandomInt() {
return rand() % 11 - 5;
}
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;
}
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++) {
matrix.at(i, j) = GetRandomInt();
}
}
Matrix copy = matrix;
Vect kernel = solver.Kernel(std::move(copy));
Matrix nullVector {matrix.GetRawCount(), 1};
nullVector.Fill(0.0);
for (std::size_t i = 0; i < kernel.GetCardinal(); i++) {
test_assert(matrix * kernel.GetVector(i) == nullVector);
}
for (std::size_t i = 0; i < KERNEL_CHECKS; i++) {
Matrix vector = GetRandomMatrix(kernel.GetDimension(), 1);
test_assert(kernel.IsElementOf(vector) == (matrix * vector == nullVector));
}
Vect kernel2 = solver.Kernel(kernel.GetLinearSystem());
test_assert(kernel == kernel2);
return true;
}
int main() {
srand(time(0));
std::vector<std::future<bool>> results;
// appelle la fonction Test() en parallèle
for (int i = 0; i < EXECUTION_COUNT; i++) {
auto handle = std::async(std::launch::async, &Test);
results.push_back(std::move(handle));
}
for (auto& result : results) {
if (!result.get())
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

28
test/test_rational.cpp Normal file
View File

@@ -0,0 +1,28 @@
#include "NR.h"
#include "test_assert.h"
static void test() {
test_assert((NR {1, 5} == NR {5, 25}));
test_assert((NR {1, 5} != NR {4, 25}));
test_assert(NR {2} == NR {1} + 1);
test_assert(NR {1} == (NR {1, 4} + NR {3, 4}));
test_assert((NR {-3, -4} == NR {1, 2} + NR {1, 4}));
test_assert((NR {-1, 4} == NR {1, 4} - NR {1, 2}));
test_assert((NR {1, -4} == NR {1, 4} - NR {1, 2}));
test_assert((-NR {1, 4} == NR {1, 4} - NR {1, 2}));
test_assert((NR {2} == NR {4, 3} * NR {3, 2}));
test_assert((NR {3, 5} == NR {4, 5} * NR {3, 4}));
test_assert((NR {21, 16} == NR {7, 8} / NR {6, 9}));
test_assert((NR {4, 3} == NR {3, 4}.Inverse()));
}
int main(int argc, char** argv) {
test();
return 0;
}

88
test/test_solver.cpp Normal file
View File

@@ -0,0 +1,88 @@
#include <algorithm>
#include <filesystem>
#include <fstream>
#include <iostream>
#include "IO.h"
#include "Solver.h"
#include "test_assert.h"
namespace fs = std::filesystem;
const static int EXECUTION_COUNT = 10000;
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 TestRectangular(const Matrix& system, const Matrix& origin) {
Solver solver;
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() {
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, imageMat, noyauMat;
in >> mat >> imageMat >> noyauMat;
Vect image {std::move(imageMat)};
Vect noyau {std::move(noyauMat)};
Solver solver;
Matrix copy = mat;
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();
RandomRectangular();
return 0;
}

84
test/test_vect.cpp Normal file
View File

@@ -0,0 +1,84 @@
#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,
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,
}}};
test_assert(vect1 == vect3);
test_assert(vect2 == vect4);
test_assert(vect1 != vect2);
test_assert(vect2 != vect3);
test_assert(vect3 != vect4);
test_assert(vect1.IsElementOf(Matrix::ColumnVector({3, 7, 11})));
test_assert(!vect1.IsElementOf(Matrix::ColumnVector({3, 7, 12})));
}
void TestVectAffine() {
VectAffine aff {Matrix::ColumnVector({-2, 3, 7}), Matrix::ColumnVector({5, 2, -8})};
test_assert(aff.IsElementOf(Matrix::ColumnVector({5, 2, -8})));
test_assert(aff.IsElementOf(Matrix::ColumnVector({3, 5, -1})));
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,64 @@
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")
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("binary")
set_kind("static")
add_files("src/*.cpp")
remove_files("src/main.cpp")
-- Solver Main
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")
-- 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")
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