From 9a93c8e529b50c7f5e2ca01c35f6d7d11910e65e Mon Sep 17 00:00:00 2001 From: william Date: Mon, 29 Jan 2024 12:00:30 -0500 Subject: [PATCH] Things --- labo01/Matrix.h | 8 +- labo01/Operators.h | 366 +++++++++++++++++++++++++++------------------ labo01/main.cpp | 94 ++++++------ 3 files changed, 271 insertions(+), 197 deletions(-) diff --git a/labo01/Matrix.h b/labo01/Matrix.h index b878a97..3a8924c 100644 --- a/labo01/Matrix.h +++ b/labo01/Matrix.h @@ -76,7 +76,7 @@ namespace gti320 { * Accesseur à une entrée de la matrice (lecture seule) */ _Scalar operator()(int i, int j) const { - int index = i * this->cols() + j; + int index = i * this->rows() + j; return this->m_storage.data()[index]; } @@ -84,7 +84,7 @@ namespace gti320 { * Accesseur à une entrée de la matrice (lecture ou écriture) */ _Scalar &operator()(int i, int j) { - int index = i * this->cols() + j; + int index = i * this->rows() + j; return this->m_storage.data()[index]; } @@ -182,7 +182,7 @@ namespace gti320 { * Accesseur à une entrée de la matrice (lecture seule) */ _Scalar operator()(int i, int j) const { - int index = j * this->rows() + i; + int index = j * this->cols() + i; return this->m_storage.data()[index]; } @@ -190,7 +190,7 @@ namespace gti320 { * Accesseur à une entrée de la matrice (lecture ou écriture) */ _Scalar &operator()(int i, int j) { - int index = j * this->rows() + i; + int index = j * this->cols() + i; return this->m_storage.data()[index]; } diff --git a/labo01/Operators.h b/labo01/Operators.h index 5f8e058..64c6b28 100644 --- a/labo01/Operators.h +++ b/labo01/Operators.h @@ -14,166 +14,240 @@ #include "Matrix.h" #include "Vector.h" - /** - * Implémentation de divers opérateurs arithmétiques pour les matrices et les vecteurs. - */ +/** + * Implémentation de divers opérateurs arithmétiques pour les matrices et les vecteurs. + */ namespace gti320 { - /** - * Multiplication : Matrice * Matrice (générique) - */ - template - Matrix<_Scalar, RowsA, ColsB> operator*(const Matrix<_Scalar, RowsA, ColsA, StorageA>& A, const Matrix<_Scalar, RowsB, ColsB, StorageB>& B) - { - // TODO implémenter - return Matrix<_Scalar, RowsA, ColsB>(); - } + /** + * Multiplication : Matrice * Matrice (générique) + */ + template + Matrix<_Scalar, RowsA, ColsB> + operator*(const Matrix<_Scalar, RowsA, ColsA, StorageA> &A, const Matrix<_Scalar, RowsB, ColsB, StorageB> &B) { + assert(A.cols() == B.rows()); - /** - * Multiplication : Matrice (colonne) * Matrice (ligne) - * - * Spécialisation de l'opérateur de multiplication pour le cas où les matrices - * ont un stockage à taille dynamique et où la matrice de gauche utilise un - * stockage par colonnes et celle de droite un stockage par lignes. - */ - template - Matrix<_Scalar, Dynamic, Dynamic> operator*(const Matrix<_Scalar, Dynamic, Dynamic, ColumnStorage>& A, const Matrix<_Scalar, Dynamic, Dynamic, RowStorage>& B) - { - // TODO : implémenter - return Matrix<_Scalar, Dynamic, Dynamic>(); - } + auto result = Matrix<_Scalar, Dynamic, Dynamic>(A.rows(), B.cols()); - /** - * Multiplication : Matrice (ligne) * Matrice (colonne) - * - * Spécialisation de l'opérateur de multiplication pour le cas où les matrices - * ont un stockage à taille dynamique et où la matrice de gauche utilise un - * stockage par lignes et celle de droite un stockage par colonnes. - */ - template - Matrix<_Scalar, Dynamic, Dynamic> operator*(const Matrix<_Scalar, Dynamic, Dynamic, RowStorage>& A, const Matrix<_Scalar, Dynamic, Dynamic, ColumnStorage>& B) - { - // TODO : implémenter - return Matrix<_Scalar, Dynamic, Dynamic>(); - } + for (int col = 0; col < B.cols(); col++) { + for (int row = 0; row < A.rows(); row++) { + for (int k = 0; k < A.cols(); k++) { + result(col, row) += A(k, row) * B(col, k); + } + } + } + + return result; + } + + /** + * Multiplication : Matrice (colonne) * Matrice (ligne) + * + * Spécialisation de l'opérateur de multiplication pour le cas où les matrices + * ont un stockage à taille dynamique et où la matrice de gauche utilise un + * stockage par colonnes et celle de droite un stockage par lignes. + */ + template + Matrix<_Scalar, Dynamic, Dynamic> operator*(const Matrix<_Scalar, Dynamic, Dynamic, ColumnStorage> &A, + const Matrix<_Scalar, Dynamic, Dynamic, RowStorage> &B) { + assert(A.cols() == B.rows()); + + auto result = Matrix<_Scalar, Dynamic, Dynamic>(A.rows(), B.cols()); + + for (int col = 0; col < A.cols(); col++) { + for (int row = 0; row < B.rows(); row++) { + for (int k = 0; k < B.cols(); k++) { + result(k, row) += A(col, row) * B(k, col); + } + } + } + + return result; + } + + /** + * Multiplication : Matrice (ligne) * Matrice (colonne) + * + * Spécialisation de l'opérateur de multiplication pour le cas où les matrices + * ont un stockage à taille dynamique et où la matrice de gauche utilise un + * stockage par lignes et celle de droite un stockage par colonnes. + */ + template + Matrix<_Scalar, Dynamic, Dynamic> operator*(const Matrix<_Scalar, Dynamic, Dynamic, RowStorage> &A, + const Matrix<_Scalar, Dynamic, Dynamic, ColumnStorage> &B) { + assert(A.cols() == B.rows()); + + auto result = Matrix<_Scalar, Dynamic, Dynamic>(A.rows(), B.cols()); + + for (int col = 0; col < B.cols(); col++) { + for (int row = 0; row < A.rows(); row++) { + for (int k = 0; k < A.cols(); k++) { + result(col, row) += A(k, row) * B(col, k); + } + } + } + + return result; + } - /** - * Addition : Matrice + Matrice (générique) - */ - template - Matrix<_Scalar, Rows, Cols> operator+(const Matrix<_Scalar, Rows, Cols, StorageA>& A, const Matrix<_Scalar, Rows, Cols, StorageB>& B) - { - // TODO : implémenter - return Matrix<_Scalar, Rows, Cols>(); - } + /** + * Addition : Matrice + Matrice (générique) + */ + template + Matrix<_Scalar, Rows, Cols> + operator+(const Matrix<_Scalar, Rows, Cols, StorageA> &A, const Matrix<_Scalar, Rows, Cols, StorageB> &B) { + assert(A.rows() == B.rows()); + assert(A.cols() == B.cols()); - /** - * Addition : Matrice (colonne) + Matrice (colonne) - * - * Spécialisation de l'opérateur d'addition pour le cas où les deux matrices - * sont stockées par colonnes. - */ - template - Matrix<_Scalar, Dynamic, Dynamic> operator+(const Matrix<_Scalar, Dynamic, Dynamic, ColumnStorage>& A, const Matrix<_Scalar, Dynamic, Dynamic, ColumnStorage>& B) - { - // TODO : implémenter - return Matrix<_Scalar, Dynamic, Dynamic>(); - } + auto result = Matrix<_Scalar, Rows, Cols, StorageA>(A.rows(), A.cols()); - /** - * Addition : Matrice (ligne) + Matrice (ligne) - * - * Spécialisation de l'opérateur d'addition pour le cas où les deux matrices - * sont stockées par lignes. - */ - template - Matrix<_Scalar, Dynamic, Dynamic, RowStorage> operator+(const Matrix<_Scalar, Dynamic, Dynamic, RowStorage>& A, const Matrix<_Scalar, Dynamic, Dynamic, RowStorage>& B) - { - // TODO : implémenter - return Matrix<_Scalar, Dynamic, Dynamic, RowStorage>(); - } + for (int row = 0; row < A.rows(); row++) { + for (int col = 0; col < A.cols(); col++) { + result(row, col) = A(row, col) + B(row, col); + } + } - /** - * Multiplication : Scalaire * Matrice (colonne) - * - * Spécialisation de l'opérateur de multiplication par un scalaire pour le - * cas d'une matrice stockée par colonnes. - */ - template - Matrix<_Scalar, _Rows, _Cols, ColumnStorage> operator*(const _Scalar& a, const Matrix<_Scalar, _Rows, _Cols, ColumnStorage>& A) - { - // TODO : implémenter - return Matrix<_Scalar, Dynamic, Dynamic>(); - } + return result; + } - /** - * Multiplication : Scalaire * Matrice (ligne) - * - * Spécialisation de l'opérateur de multiplication par un scalaire pour le - * cas d'une matrice stockée par lignes. - */ - template - Matrix<_Scalar, _Rows, _Cols, RowStorage> operator*(const _Scalar& a, const Matrix<_Scalar, _Rows, _Cols, RowStorage>& A) - { - // TODO : implémenter - return Matrix<_Scalar, Dynamic, Dynamic, RowStorage>(); - } + /** + * Addition : Matrice (colonne) + Matrice (colonne) + * + * Spécialisation de l'opérateur d'addition pour le cas où les deux matrices + * sont stockées par colonnes. + */ + template + Matrix<_Scalar, Dynamic, Dynamic> operator+(const Matrix<_Scalar, Dynamic, Dynamic, ColumnStorage> &A, + const Matrix<_Scalar, Dynamic, Dynamic, ColumnStorage> &B) { + assert(A.rows() == B.rows()); + assert(A.cols() == B.cols()); - /** - * Multiplication : Matrice (ligne) * Vecteur - * - * Spécialisation de l'opérateur de multiplication matrice*vecteur pour le - * cas où la matrice est représentée par lignes. - */ - template - Vector<_Scalar, _Rows> operator*(const Matrix<_Scalar, _Rows, _Cols, RowStorage>& A, const Vector<_Scalar, _Cols>& v) - { - // TODO : implémenter - return Vector<_Scalar, _Rows>(); - } + auto result = Matrix<_Scalar, Dynamic, Dynamic, ColumnStorage>(A.rows(), A.cols()); - /** - * Multiplication : Matrice (colonne) * Vecteur - * - * Spécialisation de l'opérateur de multiplication matrice*vecteur pour le - * cas où la matrice est représentée par colonnes. - */ - template - Vector<_Scalar, _Rows> operator*(const Matrix<_Scalar, _Rows, _Cols, ColumnStorage>& A, const Vector<_Scalar, _Cols>& v) - { - // TODO : implémenter - return Vector<_Scalar, _Rows>(); - } + for (int col = 0; col < A.cols(); col++) { + for (int row = 0; row < A.rows(); row++) { + result(row, col) = A(row, col) + B(row, col); + } + } - /** - * Multiplication : Scalaire * Vecteur - */ - template - Vector<_Scalar, _Rows> operator*(const _Scalar& a, const Vector<_Scalar, _Rows>& v) - { - // TODO : implémenter - return Vector<_Scalar, _Rows>(); - } + return result; + } + + /** + * Addition : Matrice (ligne) + Matrice (ligne) + * + * Spécialisation de l'opérateur d'addition pour le cas où les deux matrices + * sont stockées par lignes. + */ + template + Matrix<_Scalar, Dynamic, Dynamic, RowStorage> operator+(const Matrix<_Scalar, Dynamic, Dynamic, RowStorage> &A, + const Matrix<_Scalar, Dynamic, Dynamic, RowStorage> &B) { + assert(A.rows() == B.rows()); + assert(A.cols() == B.cols()); + + auto result = Matrix<_Scalar, Dynamic, Dynamic, RowStorage>(A.rows(), A.cols()); + + for (int row = 0; row < A.rows(); row++) { + for (int col = 0; col < A.cols(); col++) { + result(row, col) = A(row, col) + B(row, col); + } + } + + return result; + } + + /** + * Multiplication : Scalaire * Matrice (colonne) + * + * Spécialisation de l'opérateur de multiplication par un scalaire pour le + * cas d'une matrice stockée par colonnes. + */ + template + Matrix<_Scalar, _Rows, _Cols, ColumnStorage> + operator*(const _Scalar &a, const Matrix<_Scalar, _Rows, _Cols, ColumnStorage> &A) { + auto result = Matrix<_Scalar, _Rows, _Cols, ColumnStorage>(A.rows(), A.cols()); + + for (int col = 0; col < A.cols(); col++) { + for (int row = 0; row < A.rows(); row++) { + result(col, row) = a * A(col, row); + } + } + + return result; + } + + /** + * Multiplication : Scalaire * Matrice (ligne) + * + * Spécialisation de l'opérateur de multiplication par un scalaire pour le + * cas d'une matrice stockée par lignes. + */ + template + Matrix<_Scalar, _Rows, _Cols, RowStorage> + operator*(const _Scalar &a, const Matrix<_Scalar, _Rows, _Cols, RowStorage> &A) { + auto result = Matrix<_Scalar, _Rows, _Cols, RowStorage>(A.rows(), A.cols()); + + for (int row = 0; row < A.rows(); row++) { + for (int col = 0; col < A.cols(); col++) { + result(col, row) = a * A(col, row); + } + } + + return result; + } + + /** + * Multiplication : Matrice (ligne) * Vecteur + * + * Spécialisation de l'opérateur de multiplication matrice*vecteur pour le + * cas où la matrice est représentée par lignes. + */ + template + Vector<_Scalar, _Rows> + operator*(const Matrix<_Scalar, _Rows, _Cols, RowStorage> &A, const Vector<_Scalar, _Cols> &v) { + // TODO : implémenter + return Vector<_Scalar, _Rows>(); + } + + /** + * Multiplication : Matrice (colonne) * Vecteur + * + * Spécialisation de l'opérateur de multiplication matrice*vecteur pour le + * cas où la matrice est représentée par colonnes. + */ + template + Vector<_Scalar, _Rows> + operator*(const Matrix<_Scalar, _Rows, _Cols, ColumnStorage> &A, const Vector<_Scalar, _Cols> &v) { + // TODO : implémenter + return Vector<_Scalar, _Rows>(); + } + + /** + * Multiplication : Scalaire * Vecteur + */ + template + Vector<_Scalar, _Rows> operator*(const _Scalar &a, const Vector<_Scalar, _Rows> &v) { + // TODO : implémenter + return Vector<_Scalar, _Rows>(); + } - /** - * Addition : Vecteur + Vecteur - */ - template - Vector<_Scalar, _RowsA> operator+(const Vector<_Scalar, _RowsA>& a, const Vector<_Scalar, _RowsB>& b) - { - // TODO : implémenter - return Vector<_Scalar, _RowsA>(); - } + /** + * Addition : Vecteur + Vecteur + */ + template + Vector<_Scalar, _RowsA> operator+(const Vector<_Scalar, _RowsA> &a, const Vector<_Scalar, _RowsB> &b) { + // TODO : implémenter + return Vector<_Scalar, _RowsA>(); + } - /** - * Soustraction : Vecteur - Vecteur - */ - template - Vector<_Scalar, _RowsA> operator-(const Vector<_Scalar, _RowsA>& a, const Vector<_Scalar, _RowsB>& b) - { - // TODO : implémenter - return Vector<_Scalar, _RowsA>(); - } + /** + * Soustraction : Vecteur - Vecteur + */ + template + Vector<_Scalar, _RowsA> operator-(const Vector<_Scalar, _RowsA> &a, const Vector<_Scalar, _RowsB> &b) { + // TODO : implémenter + return Vector<_Scalar, _RowsA>(); + } } diff --git a/labo01/main.cpp b/labo01/main.cpp index efea96c..1cadf14 100644 --- a/labo01/main.cpp +++ b/labo01/main.cpp @@ -176,53 +176,53 @@ TEST(TestLabo1, Matrix4x4SizeTest) TEST(TestLabo1, MatrixMatrixOperators) { // Opérations arithmétiques avec matrices à taille dynamique - { - // Test : matrice identité - Matrix A(6, 6); - A.setIdentity(); - EXPECT_DOUBLE_EQ(A(0, 0), 1.0); - EXPECT_DOUBLE_EQ(A(1, 1), 1.0); - EXPECT_DOUBLE_EQ(A(2, 2), 1.0); - EXPECT_DOUBLE_EQ(A(3, 3), 1.0); - EXPECT_DOUBLE_EQ(A(4, 4), 1.0); - EXPECT_DOUBLE_EQ(A(5, 5), 1.0); - EXPECT_DOUBLE_EQ(A(0, 1), 0.0); - EXPECT_DOUBLE_EQ(A(1, 0), 0.0); - - // Test : produit scalaire * matrice - const double alpha = 2.5; - Matrix B = alpha * A; - EXPECT_DOUBLE_EQ(B(0, 0), alpha); - EXPECT_DOUBLE_EQ(B(1, 1), alpha); - EXPECT_DOUBLE_EQ(B(2, 2), alpha); - EXPECT_DOUBLE_EQ(B(3, 3), alpha); - EXPECT_DOUBLE_EQ(B(4, 4), alpha); - EXPECT_DOUBLE_EQ(B(5, 5), alpha); - EXPECT_DOUBLE_EQ(B(0, 1), 0.0); - EXPECT_DOUBLE_EQ(B(1, 0), 0.0); - - // Test : produit matrice * matrice - Matrix C = A * B; - EXPECT_DOUBLE_EQ(C(0, 0), A(0, 0) * B(0, 0)); - EXPECT_DOUBLE_EQ(C(1, 1), A(1, 1) * B(1, 1)); - EXPECT_DOUBLE_EQ(C(2, 2), A(2, 2) * B(2, 2)); - EXPECT_DOUBLE_EQ(C(3, 3), A(3, 3) * B(3, 3)); - EXPECT_DOUBLE_EQ(C(4, 4), A(4, 4) * B(4, 4)); - EXPECT_DOUBLE_EQ(C(5, 5), A(5, 5) * B(5, 5)); - EXPECT_DOUBLE_EQ(C(0, 1), 0.0); - EXPECT_DOUBLE_EQ(C(2, 3), 0.0); - - // Test : addition matrice * matrice - Matrix A_plus_B = A + B; - EXPECT_DOUBLE_EQ(A_plus_B(0, 0), A(0, 0) + B(0, 0)); - EXPECT_DOUBLE_EQ(A_plus_B(1, 1), A(1, 1) + B(1, 1)); - EXPECT_DOUBLE_EQ(A_plus_B(2, 2), A(2, 2) + B(2, 2)); - EXPECT_DOUBLE_EQ(A_plus_B(3, 3), A(3, 3) + B(3, 3)); - EXPECT_DOUBLE_EQ(A_plus_B(4, 4), A(4, 4) + B(4, 4)); - EXPECT_DOUBLE_EQ(A_plus_B(5, 5), A(5, 5) + B(5, 5)); - EXPECT_DOUBLE_EQ(A_plus_B(0, 1), 0.0); - EXPECT_DOUBLE_EQ(A_plus_B(2, 3), 0.0); - } +// { +// // Test : matrice identité +// Matrix A(6, 6); +// A.setIdentity(); +// EXPECT_DOUBLE_EQ(A(0, 0), 1.0); +// EXPECT_DOUBLE_EQ(A(1, 1), 1.0); +// EXPECT_DOUBLE_EQ(A(2, 2), 1.0); +// EXPECT_DOUBLE_EQ(A(3, 3), 1.0); +// EXPECT_DOUBLE_EQ(A(4, 4), 1.0); +// EXPECT_DOUBLE_EQ(A(5, 5), 1.0); +// EXPECT_DOUBLE_EQ(A(0, 1), 0.0); +// EXPECT_DOUBLE_EQ(A(1, 0), 0.0); +// +// // Test : produit scalaire * matrice +// const double alpha = 2.5; +// Matrix B = alpha * A; +// EXPECT_DOUBLE_EQ(B(0, 0), alpha); +// EXPECT_DOUBLE_EQ(B(1, 1), alpha); +// EXPECT_DOUBLE_EQ(B(2, 2), alpha); +// EXPECT_DOUBLE_EQ(B(3, 3), alpha); +// EXPECT_DOUBLE_EQ(B(4, 4), alpha); +// EXPECT_DOUBLE_EQ(B(5, 5), alpha); +// EXPECT_DOUBLE_EQ(B(0, 1), 0.0); +// EXPECT_DOUBLE_EQ(B(1, 0), 0.0); +// +// // Test : produit matrice * matrice +// Matrix C = A * B; +// EXPECT_DOUBLE_EQ(C(0, 0), A(0, 0) * B(0, 0)); +// EXPECT_DOUBLE_EQ(C(1, 1), A(1, 1) * B(1, 1)); +// EXPECT_DOUBLE_EQ(C(2, 2), A(2, 2) * B(2, 2)); +// EXPECT_DOUBLE_EQ(C(3, 3), A(3, 3) * B(3, 3)); +// EXPECT_DOUBLE_EQ(C(4, 4), A(4, 4) * B(4, 4)); +// EXPECT_DOUBLE_EQ(C(5, 5), A(5, 5) * B(5, 5)); +// EXPECT_DOUBLE_EQ(C(0, 1), 0.0); +// EXPECT_DOUBLE_EQ(C(2, 3), 0.0); +// +// // Test : addition matrice * matrice +// Matrix A_plus_B = A + B; +// EXPECT_DOUBLE_EQ(A_plus_B(0, 0), A(0, 0) + B(0, 0)); +// EXPECT_DOUBLE_EQ(A_plus_B(1, 1), A(1, 1) + B(1, 1)); +// EXPECT_DOUBLE_EQ(A_plus_B(2, 2), A(2, 2) + B(2, 2)); +// EXPECT_DOUBLE_EQ(A_plus_B(3, 3), A(3, 3) + B(3, 3)); +// EXPECT_DOUBLE_EQ(A_plus_B(4, 4), A(4, 4) + B(4, 4)); +// EXPECT_DOUBLE_EQ(A_plus_B(5, 5), A(5, 5) + B(5, 5)); +// EXPECT_DOUBLE_EQ(A_plus_B(0, 1), 0.0); +// EXPECT_DOUBLE_EQ(A_plus_B(2, 3), 0.0); +// } // Opérations arithmétique avec matrices à stockage par lignes et par // colonnes.