Partie 1 Finie

This commit is contained in:
FyloZ 2024-01-26 19:15:18 -05:00
parent cc8068b8fe
commit b529ec4e35
Signed by: william
GPG Key ID: 835378AE9AF4AE97
6 changed files with 188 additions and 67 deletions

8
.idea/.gitignore vendored
View File

@ -1,8 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View File

@ -5,6 +5,7 @@ project(labo01)
# Setup language requirements
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
# Add .cpp and .h files
set(HEADERS DenseStorage.h MatrixBase.h Matrix.h Math3D.h Vector.h Operators.h)

View File

@ -129,8 +129,7 @@ namespace gti320 {
/**
* Constructeur avec taille spécifiée
*/
explicit DenseStorage(int _size) : m_data(nullptr), m_size(_size) {
m_data = new _Scalar[_size];
explicit DenseStorage(int _size) : m_data(new _Scalar[_size]), m_size(_size) {
setZero();
}
@ -138,17 +137,20 @@ namespace gti320 {
* Constructeur de copie
*/
DenseStorage(const DenseStorage &other)
: m_data(nullptr), m_size(other.m_size) {
m_data = new _Scalar[m_size];
memcpy(m_data, other.m_data, m_size);
: m_data(new _Scalar[m_size]), m_size(other.m_size) {
memcpy(m_data, other.m_data, m_size * sizeof(_Scalar));
}
/**
* Opérateur de copie
*/
DenseStorage &operator=(const DenseStorage &other) {
m_data = other.m_data;
if (m_size != other.size()) {
resize(other.size());
}
m_size = other.m_size;
memcpy(m_data, other.m_data, m_size * sizeof(_Scalar));
return *this;
}
@ -173,18 +175,19 @@ namespace gti320 {
*/
void resize(int _size) {
auto *data = new _Scalar[_size];
// memcpy(data, m_data, m_size); // ???
delete[] m_data;
m_data = data;
m_size = _size;
setZero();
}
/**
* Met tous les éléments à zéro.
*/
void setZero() {
memset(m_data, 0, m_size);
memset(m_data, 0, m_size * sizeof(_Scalar));
}
/**

View File

@ -11,6 +11,7 @@
*
*/
#include <complex>
#include "MatrixBase.h"
namespace gti320 {
@ -59,13 +60,15 @@ namespace gti320 {
*/
template<typename _OtherScalar, int _OtherRows, int _OtherCols, int _OtherStorage>
Matrix &operator=(const SubMatrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage> &submatrix) {
if (_RowsAtCompile != _OtherRows || _ColsAtCompile != _OtherCols) {
this->resize(_OtherRows, _OtherCols);
if (this->rows() != submatrix->rows() || this->cols() != submatrix->cols()) {
this->resize(submatrix->rows(), submatrix->cols());
}
// TODO copier les données de la sous-matrice.
// Note : si les dimensions ne correspondent pas, la matrice doit être redimensionnée.
// Vous pouvez présumer qu'il s'agit d'un stockage par colonnes.
for (int i = 0; i < this->rows(); i++) {
for (int j = 0; j < this->cols(); j++) {
this(i, j) = submatrix(i, j);
}
}
return *this;
}
@ -73,18 +76,16 @@ namespace gti320 {
* Accesseur à une entrée de la matrice (lecture seule)
*/
_Scalar operator()(int i, int j) const {
// TODO implementer
return (double) (i + j);
int index = i * this->cols() + j;
return this->m_storage.data()[index];
}
/**
* Accesseur à une entrée de la matrice (lecture ou écriture)
*/
_Scalar &operator()(int i, int j) {
// TODO implementer
// Indice : l'implémentation est identique à celle de la fonction précédente.
_Scalar x = (double) (i + j);
return x;
int index = i * this->cols() + j;
return this->m_storage.data()[index];
}
/**
@ -107,17 +108,25 @@ namespace gti320 {
*/
template<typename _OtherScalar, int _OtherRows, int _OtherCols, int _OtherStorage>
Matrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage> transpose() const {
// TODO calcule et retourne la transposée de la matrice.
return Matrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage>(); // pas bon, à changer
auto transposed = Matrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage>(this->cols(), this->rows());
for (int i = 0; i < this->rows(); i++) {
for (int j = 0; j < this->cols(); j++) {
transposed(j, i) = (*this)(i, j);
}
}
return transposed;
}
/**
* Affecte l'identité à la matrice
*/
inline void setIdentity() {
// TODO affecter la valeur 0.0 partour, sauf sur la diagonale principale où c'est 1.0..
// Votre implémentation devrait aussi fonctionner pour des matrices qui ne sont pas carrées.
this->m_storage.setZero();
int smallest = std::min(this->rows(), this->cols());
for (int i = 0; i < smallest; i++) {
(*this)(i, i) = 1;
}
}
};
@ -157,11 +166,15 @@ namespace gti320 {
*/
template<typename _OtherScalar, int OtherRows, int _OtherCols, int _OtherStorage>
Matrix &operator=(const SubMatrix<_OtherScalar, OtherRows, _OtherCols, _OtherStorage> &submatrix) {
if (this->rows() != submatrix->rows() || this->cols() != submatrix->cols()) {
this->resize(submatrix->rows(), submatrix->cols());
}
// TODO copier les données de la sous-matrice.
// Note : si les dimensions ne correspondent pas, la matrice doit être redimensionnée.
// Vous pouvez présumer qu'il s'agit d'un stockage par lignes.
for (int j = 0; j < this->cols(); j++) {
for (int i = 0; i < this->rows(); i++) {
this(i, j) = submatrix(i, j);
}
}
return *this;
}
@ -169,17 +182,16 @@ namespace gti320 {
* Accesseur à une entrée de la matrice (lecture seule)
*/
_Scalar operator()(int i, int j) const {
// TODO implementer
return 0.0;
int index = j * this->rows() + i;
return this->m_storage.data()[index];
}
/**
* Accesseur à une entrée de la matrice (lecture ou écriture)
*/
_Scalar &operator()(int i, int j) {
// TODO implementer
_Scalar x = 0.0;
return x;
int index = j * this->rows() + i;
return this->m_storage.data()[index];
}
/**
@ -200,19 +212,28 @@ namespace gti320 {
/**
* Retourne la transposée de la matrice
*/
Matrix<_Scalar, _ColsAtCompile, _RowsAtCompile, ColumnStorage> transpose() const {
// TODO calcule et retourne la transposée de la matrice.
// Optimisez cette fonction en tenant compte du type de stockage utilisé.
Matrix<_Scalar, _RowsAtCompile, _ColsAtCompile, ColumnStorage> transpose() const {
auto t = Matrix<_Scalar, _RowsAtCompile, _ColsAtCompile, ColumnStorage>(this->cols(), this->rows());
return Matrix<_Scalar, _ColsAtCompile, _RowsAtCompile, ColumnStorage>();
for (int i = 0; i < this->rows(); i++) {
for (int j = 0; j < this->cols(); j++) {
t(j, i) = (*this)(i, j);
}
}
return t;
}
/**
* Affecte l'identité à la matrice
*/
inline void setIdentity() {
// TODO affecter la valeur 0.0 partour, sauf sur la diagonale principale où c'est 1.0..
// Votre implémentation devrait aussi fonctionner pour des matrices qui ne sont pas carrées.
this->m_storage.setZero();
int small_size = std::min(this->rows(), this->cols());
for (int i = 0; i < small_size; i++) {
(*this)(i, i) = 1;
}
}
};
@ -284,9 +305,15 @@ namespace gti320 {
*/
template<typename _OtherScalar, int _OtherRows, int _OtherCols, int _OtherStorage>
SubMatrix &operator=(const Matrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage> &matrix) {
// TODO Cpopie les valeurs de la matrice dans la sous-matrice.
// Note les dimensions de la matrice doivent correspondre à celle de
// la sous-matrice.
assert(this->rows() == matrix.rows());
assert(this->cols() == matrix.cols());
for (int i = 0; i < this->rows(); i++) {
for (int j = 0; j < this->cols(); j++) {
(*this)(i, j) = matrix(i, j);
}
}
return *this;
}
@ -297,16 +324,15 @@ namespace gti320 {
* sous-matrice
*/
_Scalar operator()(int i, int j) const {
assert(i > 0);
assert(i <= m_rows);
assert(j > 0);
assert(j <= m_cols);
assert(i >= 0);
assert(i <= this->rows());
assert(j >= 0);
assert(j <= this->cols());
int full_i = this->m_i + i;
int full_j = this->m_j + j;
int storage_index = full_i * this->m_matrix.rows() + full_j;
return this->m_matrix.data()[storage_index];
return this->m_matrix(full_i, full_j);
}
/**
@ -316,9 +342,14 @@ namespace gti320 {
* sous-matrice
*/
_Scalar &operator()(int i, int j) {
// TODO implémenter
_Scalar x = 0.0;
return x;
assert(i >= 0);
assert(i <= this->rows());
assert(j >= 0);
assert(j <= this->cols());
int full_i = this->m_i + i;
int full_j = this->m_j + j;
return this->m_matrix(full_i, full_j);
}
/**
@ -326,8 +357,15 @@ namespace gti320 {
*/
template<typename _OtherScalar, int _OtherRows, int _OtherCols, int _OtherStorage>
Matrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage> transpose() const {
// TODO implémenter
return Matrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage>();
auto t = Matrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage>(this->rows(), this->cols());
for (int i = 0; i < this->rows(); i++) {
for (int j = 0; j < this->cols(); j++) {
t(j, i) = (*this)(i, j);
}
}
return t;
}
inline int rows() const { return m_rows; }

View File

@ -50,7 +50,6 @@ namespace gti320 {
* Opérateur de copie
*/
Vector &operator=(const Vector &other) {
// TODO implémenter
this->m_storage = other.m_storage;
return *this;
}
@ -59,7 +58,7 @@ namespace gti320 {
* Accesseur à une entrée du vecteur (lecture seule)
*/
_Scalar operator()(int i) const {
return this->data()[i];
return this->m_storage.data()[i];
}
/**
@ -84,7 +83,7 @@ namespace gti320 {
_Scalar product = 0;
for (int i = 0; i < this->size(); i++) {
product += this->data()[i] * other.data()[i];
product += (*this)(i) * other(i);
}
return product;
@ -97,7 +96,7 @@ namespace gti320 {
_Scalar norm = 0;
for (int i = 0; i < this->size(); i++) {
norm += std::pow(this->data()[i], 2);
norm += std::pow((*this)(i), 2);
}
return std::sqrt(norm);

View File

@ -507,8 +507,96 @@ TEST(TestLabo1, PerformanceLargeMatrixMatrix)
TEST(TestLabo1, Supplementaires)
{
// TODO remplacez le code avec vos propres tests ici
EXPECT_TRUE(false);
// === Stockage ===
// Test 1: Set zero
DenseStorage<int, Dynamic> S1(10);
S1.setZero();
for (int i = 0; i < S1.size(); i++) {
EXPECT_EQ(S1.data()[i], 0);
}
// Test 2: Resize dynamique
int size = 16;
S1.resize(size);
EXPECT_EQ(S1.size(), size);
// Test 3: Resize statique
DenseStorage<int, 10> S2;
S2.resize(size);
EXPECT_EQ(S2.size(), 10);
// Test 4: Copie
DenseStorage<int, Dynamic> S3(20);
S3.data()[5] = 123;
S3.data()[7] = 321;
S1 = S3;
EXPECT_EQ(S1.size(), S3.size());
EXPECT_EQ(S1.data()[5], S3.data()[5]);
EXPECT_EQ(S1.data()[7], S3.data()[7]);
// === Matrices ===
// Test 5: Identité
Matrix<int, -1, -1, ColumnStorage> MC(4, 6);
MC.setIdentity();
for (int i = 0; i < MC.rows(); i++) {
for (int j = 0; j < MC.cols(); j++) {
int expected = 0;
if (i == j) {
expected = 1;
}
EXPECT_EQ(MC(i, j), expected);
}
}
// Test 6: Création d'une sous-matrice
MC(1, 1) = 1;
MC(1, 2) = 2;
MC(1, 3) = 3;
MC(2, 1) = 4;
MC(2, 2) = 5;
MC(2, 3) = 6;
MC(3, 1) = 7;
MC(3, 2) = 8;
MC(3, 3) = 9;
SubMatrix<int, -1, -1, ColumnStorage> s = MC.block(1, 1, 3, 3);
for (int i = 0; i < s.rows(); i++) {
for (int j = 0; j < s.cols(); j++) {
EXPECT_EQ(s(i, j), MC(i + 1, j + 1));
}
}
// Test 7: Transposée d'une sous-matrice
const Matrix<int, -1, -1, ColumnStorage> t = s.transpose<int, -1, -1, ColumnStorage>();
for (int i = 0; i < t.rows(); i++) {
for (int j = 0; j < t.cols(); j++) {
EXPECT_EQ(t(j, i), s(i, j));
}
}
// Test 8: Stockage par colonne
MC(0, 0) = 4;
MC(1, 0) = 5;
MC(0, 1) = 6;
EXPECT_EQ(MC.data()[0], MC(0, 0));
EXPECT_EQ(MC.data()[1], MC(0, 1));
// Test 9: Stockage par rangée
Matrix<int, -1, -1, RowStorage> MS(4, 6);
MS(0, 0) = 4;
MS(1, 0) = 5;
MS(0, 1) = 6;
EXPECT_EQ(MS.data()[0], MS(0, 0));
EXPECT_EQ(MS.data()[1], MS(1, 0));
// === Vecteurs ===
// Test 10: Copie
Vector<int> V1(10);
Vector<int> V2(16);
V2(12) = 543;
V1 = V2;
EXPECT_EQ(V1.size(), V2.size());
EXPECT_EQ(V1(12), V2(12));
}
int main(int argc, char** argv)