From 6346ab1354e34484e6726b9eff097c6198d4558e Mon Sep 17 00:00:00 2001 From: william Date: Mon, 1 Apr 2024 17:31:21 -0400 Subject: [PATCH] Lab 01, compilation errors --- .idea/.name | 1 + CMakeLists.txt | 2 +- labo01/CMakeLists.txt | 11 +- labo01/{src => }/DenseStorage.h | 120 ++-- labo01/Math3D.h | 139 +++++ labo01/Matrix.h | 401 +++++++++++++ labo01/{src => }/MatrixBase.h | 30 +- labo01/Operators.h | 364 +++++++++++ labo01/Vector.h | 123 ++++ labo01/main.cpp | 710 +++++++++++++++++++++- labo01/src/Math3D.h | 110 ---- labo01/src/Matrix.h | 350 ----------- labo01/src/Operators.h | 179 ------ labo01/src/Vector.h | 104 ---- labo01/tests/Tests1a.cpp | 398 ------------ labo01/tests/Tests1b.cpp | 801 ------------------------- labo01/tests/TestsSupplementaire1a.cpp | 54 -- labo01/tests/TestsSupplementaire1b.cpp | 56 -- labo_ik/IKApplication.cpp | 1 + labo_ik/IKApplication.h | 1 + 20 files changed, 1803 insertions(+), 2152 deletions(-) create mode 100644 .idea/.name rename labo01/{src => }/DenseStorage.h (60%) create mode 100644 labo01/Math3D.h create mode 100644 labo01/Matrix.h rename labo01/{src => }/MatrixBase.h (93%) create mode 100644 labo01/Operators.h create mode 100644 labo01/Vector.h delete mode 100644 labo01/src/Math3D.h delete mode 100644 labo01/src/Matrix.h delete mode 100644 labo01/src/Operators.h delete mode 100644 labo01/src/Vector.h delete mode 100644 labo01/tests/Tests1a.cpp delete mode 100644 labo01/tests/Tests1b.cpp delete mode 100644 labo01/tests/TestsSupplementaire1a.cpp delete mode 100644 labo01/tests/TestsSupplementaire1b.cpp diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..71e3aea --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +GTI320-labos \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index e0c6fc2..f98a902 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,7 +37,7 @@ set( NANOGUI_USE_OPENGL ON CACHE BOOL "" FORCE) FetchContent_MakeAvailable(nanogui) set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) -include_directories(${CMAKE_SOURCE_DIR}/labo01/src ${COMMON_INCLUDES}) +include_directories(${CMAKE_SOURCE_DIR}/labo01 ${COMMON_INCLUDES}) add_subdirectory(labo01) add_subdirectory(labo_ik) diff --git a/labo01/CMakeLists.txt b/labo01/CMakeLists.txt index 26b203f..5144fc1 100644 --- a/labo01/CMakeLists.txt +++ b/labo01/CMakeLists.txt @@ -3,18 +3,21 @@ cmake_minimum_required(VERSION 3.15) project(labo01) # Setup language requirements -set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # Add .cpp and .h files -file(GLOB_RECURSE TESTS_SOURCES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" CONFIGURE_DEPENDS "tests/*.cpp") -file(GLOB_RECURSE MAIN_SOURCES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" CONFIGURE_DEPENDS "src/*.h") +file(GLOB_RECURSE MAIN_SOURCES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" CONFIGURE_DEPENDS "*.h") add_executable(labo01 main.cpp ${MAIN_SOURCES} ${TESTS_SOURCES}) +# Add .cpp and .h files +#set(HEADERS DenseStorage.h MatrixBase.h Matrix.h Math3D.h Vector.h Operators.h) +#set(SOURCE main.cpp) +#add_executable(labo01 ${SOURCE} ${HEADERS}) + # Add linking information for Google Test target_link_libraries(labo01 gtest) - # Set labo01 as the startup project for Visual Studio if( MSVC ) set_property(TARGET labo01 PROPERTY VS_DEBUGGER_WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/labo01) diff --git a/labo01/src/DenseStorage.h b/labo01/DenseStorage.h similarity index 60% rename from labo01/src/DenseStorage.h rename to labo01/DenseStorage.h index cfa95e2..22f6e8f 100644 --- a/labo01/src/DenseStorage.h +++ b/labo01/DenseStorage.h @@ -5,18 +5,19 @@ * * @brief Stockage dense pour des données à taille fixe ou dynamique. * - * Nom: - * Code permanent : - * Email : + * Nom: William Nolin + * Code permanent : NOLW76060101 + * Email : william.nolin.1@ens.etsmtl.ca * */ #include #include -namespace gti320 -{ - enum SizeType { Dynamic = -1 }; +namespace gti320 { + enum SizeType { + Dynamic = -1 + }; /** * Stockage à taille fixe. @@ -27,43 +28,37 @@ namespace gti320 * Un tampon (tableau) de taille `_Size_` est alloué sur la pile d'exécution. */ template - class DenseStorage - { + class DenseStorage { private: - // TODO déclarer une variable m_data et allouer la mémoire pour y stocker _Size éléments - _Scalar* m_data; // <-- Ceci n'est pas bon, à modifier + _Scalar m_data[_Size]; public: /** * Constructeur par défaut */ - DenseStorage() { } + DenseStorage() {} /** * Constructeur de copie */ - DenseStorage(const DenseStorage& other) - { + DenseStorage(const DenseStorage &other) { memcpy(m_data, other.m_data, sizeof(m_data)); } /** - * Constructeur avec taille spécifiée. - * Doit être la même que la taille spécifiée dans le patron + * Constructeur avec taille spécifiée * + * (doit être la même que la taille spécifiée dans le patron) */ - explicit DenseStorage(int _size) - { - assert(_size > 0 && _size == _Size); + explicit DenseStorage(int _size) { } /** - * Constructeur avec taille (_size) et données initiales (_data). + * Constructor avec taille (_size) et données initiales (_data). */ - explicit DenseStorage(const _Scalar* _data, int _size) - { + explicit DenseStorage(const _Scalar *_data, int _size) { assert(_size >= 0 && _size == _Size); memcpy(m_data, _data, sizeof(_Scalar) * _size); } @@ -71,10 +66,8 @@ namespace gti320 /** * Opérateur de copie */ - DenseStorage& operator=(const DenseStorage& other) - { - if (this != &other) - { + DenseStorage &operator=(const DenseStorage &other) { + if (this != &other) { assert(other.size() == _Size); memcpy(m_data, other.m_data, sizeof(m_data)); } @@ -86,38 +79,33 @@ namespace gti320 /** * Redimensionne le stockage pour qu'il contienne `size` élément. */ - void resize(int size) - { + void resize(int size) { // Ne rien faire. Invalide pour les matrices à taille fixe. } /** * Mets tous les éléments à zéro. */ - void setZero() - { + void setZero() { memset(m_data, 0, sizeof(_Scalar) * _Size); } /** * Accès au tampon de données (en lecteur seulement) */ - const _Scalar* data() const - { - return m_data; + const _Scalar *data() const { + return &m_data[0]; } /** * Accès au tampon de données (pour lecture et écriture) */ - _Scalar* data() - { - return m_data; + _Scalar *data() { + return &m_data[0]; } }; - /** * Stockage à taille dynamique. * @@ -126,10 +114,9 @@ namespace gti320 * l'opérateur `new []` et la mémoire doit être libérée avec `delete[]` */ template - class DenseStorage<_Scalar, Dynamic> - { + class DenseStorage<_Scalar, Dynamic> { private: - _Scalar* m_data; + _Scalar *m_data; int m_size; public: @@ -142,42 +129,36 @@ namespace gti320 /** * Constructeur avec taille spécifiée */ - explicit DenseStorage(int _size) : m_data(nullptr), m_size(_size) - { - // TODO allouer un tampon pour stocker _size éléments de type _Scalar. - - // TODO initialiser ce tampon à zéro. + explicit DenseStorage(int _size) : m_data(new _Scalar[_size]), m_size(_size) { + setZero(); } /** * Constructeur de copie */ - DenseStorage(const DenseStorage& other) - : m_data(nullptr) - , m_size(other.m_size) - { - // TODO allouer un tampon pour stocker _size éléments de type _Scalar. - - // TODO copier other.m_data dans m_data. - + DenseStorage(const DenseStorage &other) + : m_data(new _Scalar[other.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) - { - // TODO implémenter ! + DenseStorage &operator=(const DenseStorage &other) { + 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; } /** * Destructeur */ - ~DenseStorage() - { - // TODO libérer la mémoire allouée - + ~DenseStorage() { + delete[] m_data; } /** @@ -188,33 +169,36 @@ namespace gti320 /** * Redimensionne le tampon alloué pour le stockage. * La mémoire qui n'est plus utilisée doit être libérée. - * + * * Note :​ Toutes opérations de redimensionnement entraînent une réallocation de mémoire. * Il n’est pas pertinent de copier les données car le résultat serait de toute façon incohérent. */ - void resize(int _size) - { - // TODO redimensionner la mémoire allouée + void resize(int _size) { + auto *data = new _Scalar[_size]; + delete[] m_data; + m_data = data; + m_size = _size; + + setZero(); } /** * Met tous les éléments à zéro. */ - void setZero() - { - // TODO implémenter ! + void setZero() { + memset(m_data, 0, m_size * sizeof(_Scalar)); } /** * Accès au tampon de données (en lecteur seulement) */ - const _Scalar* data() const { return m_data; } + const _Scalar *data() const { return m_data; } /** * Accès au tampon de données (pour lecture et écriture) */ - _Scalar* data() { return m_data; } + _Scalar *data() { return m_data; } }; } diff --git a/labo01/Math3D.h b/labo01/Math3D.h new file mode 100644 index 0000000..9657cea --- /dev/null +++ b/labo01/Math3D.h @@ -0,0 +1,139 @@ +#pragma once + +/** + * @file Math3D.h + * + * @brief Fonctions pour l'intinialisation et la manipulation de matrices de + * rotation, des matrices de transformations en coordonnées homogènes et les + * vecteurs 3D. + * + * Nom: William Nolin + * Code permanent : NOLW76060101 + * Email : william.nolin.1@ens.etsmtl.ca + * + */ + +#include "Matrix.h" +#include "Vector.h" +#include "Operators.h" + +#ifndef _USE_MATH_DEFINES +#define _USE_MATH_DEFINES +#endif + +#include + + +namespace gti320 { + + // Deux types de vecteurs 3D considérés ici + typedef Vector Vector3d; + typedef Vector Vector3f; + + // Dans le cadre de ce projet, nous considérons seulement deux + // cas : + // + // - les rotations + // - les translations + // + // Deux types de matrices en coordonnées homogèes : + typedef Matrix Matrix4d; + typedef Matrix Matrix4f; + // + // Deux types de matrices pour les rotations + typedef Matrix Matrix3d; + typedef Matrix Matrix3f; + + /** + * Initialise et retourne la matrice identité + */ + template<> + inline void Matrix4d::setIdentity() { + this->setZero(); + + for (int i = 0; i < 4; i++) { + (*this)(i, i) = 1; + } + } + + /** + * Calcul de la matrice inverse, SPÉCIALISÉ pour le cas d'une matrice de + * transformation en coordonnées homogènes. + */ + template<> + inline Matrix4d Matrix4d::inverse() const { + auto transposed_rotation = this->block(0, 0, 3, 3).transpose(); + auto translation = Vector(); + for (int i = 0; i < 3; i++) { + translation(i) = (*this)(i, 3); + } + + auto result = Matrix4d(); + result(3, 3) = 1; + + // Applique la matrice de rotation + result.block(0, 0, 3, 3) = transposed_rotation; + + // Applique le vecteur de translation + auto inverted_translation = (-1.0 * transposed_rotation) * translation; + auto trans_block = result.block(0, 3, 3, 1); + trans_block(0, 0) = inverted_translation(0); + trans_block(1, 0) = inverted_translation(1); + trans_block(2, 0) = inverted_translation(2); + + return result; + } + + /** + * Calcul de la matrice inverse, SPÉCIALISÉ pour le cas d'une matrice de rotation. + * + * (vous pouvez supposer qu'il s'agit d'une matrice de rotation) + */ + template<> + inline Matrix3d Matrix3d::inverse() const { + return this->transpose(); + } + + /** + * Multiplication d'une matrice 4x4 avec un vecteur 3D où la matrice + * représente une transformation en coordonnées homogène. + */ + template + Vector<_Scalar, 3> operator*(const Matrix<_Scalar, 4, 4, ColumnStorage> &A, const Vector<_Scalar, 3> &v) { + auto homogeneous = Vector<_Scalar, 4>(v); + homogeneous(3) = 1; + Vector<_Scalar, 4> transformed = A * homogeneous; + return Vector<_Scalar, 3>(transformed); + } + + + /** + * Initialise et retourne la matrice de rotation définie par les angles + * d'Euler XYZ exprimés en radians. + * + * La matrice doit correspondre au produit : Rz*Ry*Rx. + */ + template + static Matrix<_Scalar, 3, 3> makeRotation(_Scalar x, _Scalar y, _Scalar z) { + double sin_theta = std::sin(x); + double cos_theta = std::cos(x); + double sin_phi = std::sin(y); + double cos_phi = std::cos(y); + double sin_psi = std::sin(z); + double cos_psi = std::cos(z); + + auto m = Matrix<_Scalar, 3, 3>(); + m(0, 0) = cos_phi * cos_psi; + m(1, 0) = cos_phi * sin_psi; + m(2, 0) = -sin_phi; + m(0, 1) = sin_theta * sin_phi * cos_psi - cos_theta * sin_psi; + m(1, 1) = sin_theta * sin_phi * sin_psi + cos_theta * cos_psi; + m(2, 1) = sin_theta * cos_phi; + m(0, 2) = cos_theta * sin_phi * cos_psi + sin_theta * sin_psi; + m(1, 2) = cos_theta * sin_phi * sin_psi - sin_theta * cos_psi; + m(2, 2) = cos_theta * cos_phi; + + return m; + } + +} diff --git a/labo01/Matrix.h b/labo01/Matrix.h new file mode 100644 index 0000000..a725e3a --- /dev/null +++ b/labo01/Matrix.h @@ -0,0 +1,401 @@ +#pragma once + +/** + * @file Matrix.h + * + * @brief Implémentation de matrices simples. + * + * Nom: William Nolin + * Code permanent : NOLW76060101 + * Email : william.nolin.1@ens.etsmtl.ca + * + */ + +#include +#include +#include "MatrixBase.h" + +namespace gti320 { + enum StorageType { + ColumnStorage = 0, + RowStorage = 1 + }; + + // Déclaration avancée + template + class SubMatrix; + + /** + * Classe Matrix spécialisé pour le cas générique. (defaut par colonne) + * + * (le cas d'un stockage par ligne fait l'objet d'une spécialisation de patron, voir plus bas) + */ + template + class Matrix : public MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile> { + public: + + /** + * Constructeur par défaut + */ + Matrix() : MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile>() {} + + /** + * Constructeur de copie + */ + Matrix(const Matrix &other) : MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile>(other) {} + + /** + * Constructeur avec spécification du nombre de ligne et de colonnes + */ + explicit Matrix(int _rows, int _cols) : MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile>(_rows, _cols) {} + + /** + * Destructeur + */ + ~Matrix() {} + + /** + * Opérateur de copie à partir d'une sous-matrice. + * + * Exemple : Matrix B = A.block(i,j,m,n); + */ + template + Matrix &operator=(const SubMatrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage> &submatrix) { + if (this->rows() != submatrix->rows() || this->cols() != submatrix->cols()) { + this->resize(submatrix->rows(), submatrix->cols()); + } + + for (int col = 0; col < this->cols(); col++) { + for (int row = 0; row < this->rows(); row++) { + this(row, col) = submatrix(row, col); + } + } + return *this; + } + + /** + * Accesseur à une entrée de la matrice (lecture seule) + */ + _Scalar operator()(int i, int j) const { + int index = i + j * this->rows(); + return this->m_storage.data()[index]; + } + + /** + * Accesseur à une entrée de la matrice (lecture ou écriture) + */ + _Scalar &operator()(int i, int j) { + int index = i + j * this->rows(); + return this->m_storage.data()[index]; + } + + /** + * Crée une sous-matrice pour un block de taille (rows, cols) à partir de l'index (i,j). + */ + SubMatrix<_Scalar, _RowsAtCompile, _ColsAtCompile, _StorageType> block(int i, int j, int rows, int cols) const { + return SubMatrix<_Scalar, _RowsAtCompile, _ColsAtCompile, _StorageType>(*this, i, j, rows, cols); + } + + /** + * Calcule l'inverse de la matrice + */ + Matrix inverse() const { + // Do nothing. + return *this; + } + + /** + * Retourne la transposée de la matrice + */ + template + Matrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage> transpose() const { + auto transposed = Matrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage>(this->cols(), this->rows()); + for (int col = 0; col < this->cols(); col++) { + for (int row = 0; row < this->rows(); row++) { + transposed(col, row) = (*this)(row, col); + } + } + return transposed; + } + + /** + * Affecte l'identité à la matrice + */ + inline void setIdentity() { + this->m_storage.setZero(); + int smallest = std::min(this->rows(), this->cols()); + + for (int i = 0; i < smallest; i++) { + (*this)(i, i) = 1; + } + } + + }; + + /** + * Classe Matrix spécialisée pour un stockage par lignes + */ + template + class Matrix<_Scalar, _RowsAtCompile, _ColsAtCompile, RowStorage> + : public MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile> { + + public: + /** + * Constructeur par défaut + */ + Matrix() : MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile>() {} + + /** + * Constructeur de copie + */ + Matrix(const Matrix &other) : MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile>(other) {} + + /** + * Constructeur avec spécification du nombre de ligne et de colonnes + */ + explicit Matrix(int rows, int cols) : MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile>(rows, cols) {} + + /** + * Destructeur + */ + ~Matrix() {} + + /** + * Opérateur de copie à partir d'une sous-matrice. + * + * Exemple : Matrix B = A.block(i,j,m,n); + */ + template + Matrix &operator=(const SubMatrix<_OtherScalar, OtherRows, _OtherCols, _OtherStorage> &submatrix) { + if (this->rows() != submatrix->rows() || this->cols() != submatrix->cols()) { + this->resize(submatrix->rows(), submatrix->cols()); + } + + for (int row = 0; row < this->rows(); row++) { + for (int col = 0; col < this->cols(); col++) { + this(row, col) = submatrix(row, col); + } + } + return *this; + } + + /** + * Accesseur à une entrée de la matrice (lecture seule) + */ + _Scalar operator()(int i, int j) const { + 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) { + int index = i * this->cols() + j; + return this->m_storage.data()[index]; + } + + /** + * Crée une sous-matrice pour un block de taille (rows, cols) à partir de l'index (i,j). + */ + SubMatrix<_Scalar, _RowsAtCompile, _ColsAtCompile, RowStorage> block(int i, int j, int rows, int cols) const { + return SubMatrix<_Scalar, _RowsAtCompile, _ColsAtCompile, RowStorage>(*this, i, j, rows, cols); + } + + /** + * Calcule l'inverse de la matrice + */ + Matrix inverse() const { + // Do nothing. + return *this; + } + + /** + * Retourne la transposée de la matrice + */ + Matrix<_Scalar, _RowsAtCompile, _ColsAtCompile, ColumnStorage> transpose() const { + auto t = Matrix<_Scalar, _RowsAtCompile, _ColsAtCompile, ColumnStorage>(this->cols(), this->rows()); + + for (int row = 0; row < this->rows(); row++) { + for (int col = 0; col < this->cols(); col++) { + t(col, row) = (*this)(row, col); + } + } + + return t; + } + + /** + * Affecte l'identité à la matrice + */ + inline void setIdentity() { + 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; + } + } + + }; + + /** + * Classe pour accéder à une sous-matrice. + * + * Un sous-matrice ne copie pas les données. Au lieu de cela, elle conserve une + * référence à la matrice originale. + */ + template + class SubMatrix { + private: + // Référence à la matrice originale + Matrix<_Scalar, _RowsAtCompile, _ColsAtCompile, _StorageType> &m_matrix; + + // Constructeur par défaut (privé) + SubMatrix() {} + + // (i,j) est le coin supérieur gauche de la sous-matrice + int m_i; // Décalage en ligne + int m_j; // Décalage en colonne + + // la sous-matrice est de dimension : m_rows x m_cols + int m_rows; // Hauteur de la sous-matrice (nombre de lignes) + int m_cols; // Largeur de la sous-matrice (nombre de colonnes) + + public: + + /** + * Constructeur à partir d'une référence en lecture seule à une matrice. + */ + SubMatrix(const Matrix<_Scalar, _RowsAtCompile, _ColsAtCompile, _StorageType> &_matrix, int _i, int _j, + int _rows, int _cols) : + m_matrix(const_cast &>(_matrix)), + m_i(_i), m_j(_j), m_rows(_rows), m_cols(_cols) { + } + + /** + * Constructeur à partir d'une référence en lecture et écriture à une matrice. + */ + explicit SubMatrix(Matrix<_Scalar, _RowsAtCompile, _ColsAtCompile, _StorageType> &_matrix, int _i, int _j, + int _rows, int _cols) : + m_matrix(_matrix), + m_i(_i), m_j(_j), m_rows(_rows), m_cols(_cols) { + + } + + /** + * Constructeur de copie + */ + SubMatrix(const SubMatrix &other) : + m_matrix(other.m_matrix), + m_i(other.m_i), m_j(other.m_j), m_rows(other.m_rows), m_cols(other.m_cols) { + } + + /** + * Destructeur + */ + ~SubMatrix() {} + + /** + * Opérateur de copie (à partir d'une matrice) + * + * Copies toutes les entrées de la matrice dans la sous-matrice. + * + * Note : la taille de la matrice doit correspondre à la taille de la + * sous-matrice. + */ + template + SubMatrix &operator=(const Matrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage> &matrix) { + assert(this->rows() == matrix.rows()); + assert(this->cols() == matrix.cols()); + + for (int col = 0; col < this->cols(); col++) { + for (int row = 0; row < this->rows(); row++) { + (*this)(row, col) = matrix(row, col); + } + } + + return *this; + } + + /** + * Opérateur de d'addition d'une autre matrice + * + * Ajoute toutes les entrées de la matrice dans la sous-matrice. + * + * Note : la taille de la matrice doit correspondre à la taille de la + * sous-matrice. + */ + template + SubMatrix &operator+=(const Matrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage> &matrix) { + assert(this->rows() == matrix.rows()); + assert(this->cols() == matrix.cols()); + + for (int col = 0; col < this->cols(); col++) { + for (int row = 0; row < this->rows(); row++) { + (*this)(row, col) = (*this)(row, col) + matrix(row, col); + } + } + + return *this; + } + + /** + * Accesseur aux entrées de la sous-matrice (lecture seule) + * + * Note : il faut s'assurer que les indices respectent la taille de la + * sous-matrice + */ + _Scalar operator()(int i, int j) const { + 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); + } + + /** + * Accesseur aux entrées de la sous-matrice (lecture et écriture) + * + * Note : il faut s'assurer que les indices respectent la taille de la + * sous-matrice + */ + _Scalar &operator()(int i, int j) { + 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); + } + + /** + * Retourne la transposée de la sous-matrice sous la forme d'une matrice. + */ + template + Matrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage> transpose() const { + auto t = Matrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage>(this->rows(), this->cols()); + + for (int col = 0; col < this->cols(); col++) { + for (int row = 0; row < this->rows(); row++) { + t(col, row) = (*this)(row, col); + } + } + + return t; + } + + inline int rows() const { return m_rows; } + + inline int cols() const { return m_cols; } + + }; + +} diff --git a/labo01/src/MatrixBase.h b/labo01/MatrixBase.h similarity index 93% rename from labo01/src/MatrixBase.h rename to labo01/MatrixBase.h index 2e5c46f..44d5ab4 100644 --- a/labo01/src/MatrixBase.h +++ b/labo01/MatrixBase.h @@ -5,9 +5,9 @@ * * @brief Classe contenant les éléments de base des matrices et des vecteurs. * - * Nom: - * Code permanent : - * Email : + * Nom: William Nolin + * Code permanent : NOLW76060101 + * Email : william.nolin.1@ens.etsmtl.ca * */ @@ -23,7 +23,7 @@ namespace gti320 class MatrixBase { protected: - DenseStorage<_Scalar, _Rows* _Cols> m_storage; + DenseStorage<_Scalar, _Rows * _Cols> m_storage; public: @@ -37,14 +37,18 @@ namespace gti320 /** * Constructeur de copie */ - MatrixBase(const MatrixBase& other) : m_storage(other.m_storage) { } + MatrixBase(const MatrixBase& other) : m_storage(other.m_storage) { + } - explicit MatrixBase(int _rows, int _cols) : m_storage() { } + explicit MatrixBase(int _rows, int _cols) : m_storage() { + setZero(); + } /** * Destructeur */ - ~MatrixBase() { } + ~MatrixBase() { + } /** @@ -118,7 +122,9 @@ namespace gti320 */ MatrixBase() : m_storage(), m_rows(0) { } - explicit MatrixBase(int _rows, int _cols) : m_storage(_rows* _Cols), m_rows(_rows) { } + explicit MatrixBase(int _rows, int _cols) : m_storage(_rows* _Cols), m_rows(_rows) { + setZero(); + } /** * Constructeur de copie @@ -204,7 +210,9 @@ namespace gti320 */ MatrixBase() : m_storage() { } - explicit MatrixBase(int _rows, int _cols) : m_storage(_rows* _cols), m_cols(_cols) { } + explicit MatrixBase(int _rows, int _cols) : m_storage(_rows* _cols), m_cols(_cols) { + setZero(); + } /** * Constructeur de copie @@ -290,7 +298,9 @@ namespace gti320 */ MatrixBase() : m_storage(), m_rows(0), m_cols(0) { } - explicit MatrixBase(int _rows, int _cols) : m_storage(_rows* _cols), m_rows(_rows), m_cols(_cols) { } + explicit MatrixBase(int _rows, int _cols) : m_storage(_rows* _cols), m_rows(_rows), m_cols(_cols) { + setZero(); + } /** * Constructeur de copie diff --git a/labo01/Operators.h b/labo01/Operators.h new file mode 100644 index 0000000..eff76bd --- /dev/null +++ b/labo01/Operators.h @@ -0,0 +1,364 @@ +#pragma once + +/** + * @file Operators.h + * + * @brief Opérateurs arithmétiques pour les matrices et les vecteurs. + * + * Nom: William Nolin + * Code permanent : NOLW76060101 + * Email : william.nolin.1@ens.etsmtl.ca + * + */ + +#include "Matrix.h" +#include "Vector.h" + +/** + * 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) { + assert(A.cols() == B.rows()); + + auto result = Matrix<_Scalar, RowsA, ColsB>(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(row, col) += A(row, k) * B(k, col); + } + } + } + + 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(row, k) += A(row, col) * B(col, k); + } + } + } + + 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(row, col) += A(row, k) * B(k, col); + } + } + } + + 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) { + assert(A.rows() == B.rows()); + assert(A.cols() == B.cols()); + + auto result = Matrix<_Scalar, Rows, Cols, StorageA>(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; + } + + /** + * 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()); + + auto result = Matrix<_Scalar, Dynamic, Dynamic, ColumnStorage>(A.rows(), A.cols()); + + 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); + } + } + + 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) { + assert(A.cols() == v.size()); + + auto result = Vector<_Scalar, _Rows>(A.rows()); + + for (int row = 0; row < A.rows(); row++) { + _Scalar dotP = 0; + + for (int col = 0; col < A.cols(); col++) { + dotP += A(col, row) * v(col); + } + + result(row) = dotP; + } + + return result; + } + + /** + * 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) { + assert(A.cols() == v.size()); + + auto result = Vector<_Scalar, _Rows>(A.rows()); + + for (int col = 0; col < A.cols(); col++) { + _Scalar v_col = v(col); + + for (int row = 0; row < A.rows(); row++) { + result(row) += A(row, col) * v_col; + } + } + + return result; + } + + /** + * Multiplication : Scalaire * Vecteur + */ + template + Vector<_Scalar, _Rows> operator*(const _Scalar &a, const Vector<_Scalar, _Rows> &v) { + auto result = Vector<_Scalar, _Rows>(v.rows()); + + for (int row = 0; row < v.rows(); row++) { + result(row) = a * v(row); + } + + return result; + } + + + /** + * Addition : Vecteur + Vecteur + */ + template + Vector<_Scalar, _RowsA> operator+(const Vector<_Scalar, _RowsA> &a, const Vector<_Scalar, _RowsB> &b) { + assert(a.rows() == b.rows()); + + auto result = Vector<_Scalar, _RowsA>(a.rows()); + + for (int row = 0; row < a.rows(); row++) { + result(row) = a(row) + b(row); + } + + return result; + } + + /** + * Soustraction : Vecteur - Vecteur + */ + template + Vector<_Scalar, _RowsA> operator-(const Vector<_Scalar, _RowsA> &a, const Vector<_Scalar, _RowsB> &b) { + assert(a.rows() == b.rows()); + + auto result = Vector<_Scalar, _RowsA>(a.rows()); + + for (int row = 0; row < a.rows(); row++) { + result(row) = a(row) - b(row); + } + + return result; + } + + template + void print_matrix(const Matrix<_Scalar, _Rows, _Cols> &m) { + std::cout << "+----" << '\n'; + std::cout.precision(2); + for (int row = 0; row < m.rows(); row++) { + for (int col = 0; col < m.cols(); col++) { + std::cout << m(row, col) << "," << "\t"; + } + std::cout << "\n"; + } + } + + template + _Scalar det(const Matrix<_Scalar, 1, 1> &m) { + return m(0, 0); + } + + template + _Scalar det(const Matrix<_Scalar, 2, 2> &m) { + _Scalar a = m(0, 0); + _Scalar b = m(0, 1); + _Scalar c = m(1, 0); + _Scalar d = m(1, 1); + + return (a * d) - (b * c); + } + + template + double det(const Matrix<_Scalar, _Rows, _Cols> &m) { + assert(m.rows() == m.cols()); + + auto l = Matrix(); + auto u = Matrix(); + + for (int j = 0; j < m.cols(); j++) { + for (int i = 0; i < m.rows(); i++) { + u(i, j) = m(i, j); + l(i, j) = m(i, j); + + for (int k = 0; k < i; k++) { + u(i, j) -= l(i, k) * u(k, j); + } + + for (int k = 0; k < j; k++) { + l(i, j) -= l(i, k) * u(k, j); + } + + l(i, j) = 1 / u(j, j); + } + } + + print_matrix(l); + print_matrix(u); + return det_tri(l) * det_tri(u); + } + + template + _Scalar det_tri(const Matrix<_Scalar, _Rows, _Cols> &m) { + int n = std::min(m.rows(), m.cols()); + + int det = 1; + for (int i = 0; i < n; i++) { + det *= m(i, i); + } + + return det; + } +} diff --git a/labo01/Vector.h b/labo01/Vector.h new file mode 100644 index 0000000..2945894 --- /dev/null +++ b/labo01/Vector.h @@ -0,0 +1,123 @@ +#pragma once + +/** + * @file Vector.h + * + * @brief Implémentation de vecteurs simples + * + * Nom: William Nolin + * Code permanent : NOLW76060101 + * Email : william.nolin.1@ens.etsmtl.ca + * + */ + +#include +#include "MatrixBase.h" + +namespace gti320 { + + /** + * Classe vecteur générique. + * + * Cette classe réutilise la classe `MatrixBase` et ses spécialisations de + * templates pour les manipulation bas niveau. + */ + template + class Vector : public MatrixBase<_Scalar, _Rows, 1> { + public: + + /** + * Constructeur par défaut + */ + Vector() : MatrixBase<_Scalar, _Rows, 1>() {} + + /** + * Contructeur à partir d'un taille (rows). + */ + explicit Vector(int rows) : MatrixBase<_Scalar, _Rows, 1>(rows, 1) {} + + /** + * Constructeur de copie + */ + Vector(const Vector &other) : MatrixBase<_Scalar, _Rows, 1>(other) {} + + /** + * Constructeur de copie avec une grandeur différente + * @tparam _OtherRows + * @param other + */ + template + Vector(const Vector<_Scalar, _OtherRows> &other) : MatrixBase<_Scalar, _Rows, 1>() { + int n = std::min(other.size(), _Rows); + const _Scalar *src = other.data(); + _Scalar *dest = this->m_storage.data(); + memcpy(dest, src, n * sizeof(_Scalar)); + + if (n < _Rows) { + memset(&dest[n], 0, (_Rows - n) * sizeof(_Scalar)); + } + } + + /** + * Destructeur + */ + ~Vector() {} + + /** + * Opérateur de copie + */ + Vector &operator=(const Vector &other) { + this->m_storage = other.m_storage; + this->m_rows = other.rows(); + return *this; + } + + /** + * Accesseur à une entrée du vecteur (lecture seule) + */ + _Scalar operator()(int i) const { + return this->m_storage.data()[i]; + } + + /** + * Accesseur à une entrée du vecteur (lecture et écriture) + */ + _Scalar &operator()(int i) { + return this->m_storage.data()[i]; + } + + /** + * Modifie le nombre de lignes du vecteur + */ + void resize(int _rows) { + MatrixBase<_Scalar, _Rows, 1>::resize(_rows, 1); + } + + /** + * Produit scalaire de *this et other. + */ + inline _Scalar dot(const Vector &other) const { + assert(this->size() == other.size()); + + _Scalar product = 0; + for (int i = 0; i < this->size(); i++) { + product += (*this)(i) * other(i); + } + + return product; + } + + /** + * Retourne la norme euclidienne du vecteur + */ + inline _Scalar norm() const { + _Scalar norm = 0; + + for (int i = 0; i < this->size(); i++) { + norm += std::pow((*this)(i), 2); + } + + return std::sqrt(norm); + } + }; +} diff --git a/labo01/main.cpp b/labo01/main.cpp index 5b3200c..61da7a4 100644 --- a/labo01/main.cpp +++ b/labo01/main.cpp @@ -1,28 +1,704 @@ /** * @file main.cpp * - * @brief Execute unit tests for a simple linear algebra library. + * @brief Unit tests for a simple linear algebra library. * - * Nom: - * Code permanent : - * Email : + * Nom: William Nolin + * Code permanent : NOLW76060101 + * Email : william.nolin.1@ens.etsmtl.ca * */ +#include "Matrix.h" +#include "Vector.h" +#include "Math3D.h" +#include "Operators.h" + #include +#include -int main(int argc, char** argv) -{ - // Executer tous les tests unitaires. - // - // Les tests sont écrites dans les fichiers: - // tests/Tests1a.cpp - // tests/Tests1b.cpp - // tests/TestsSupplementaire1a.cpp - // tests/TestsSupplementaire1b.cpp - // - ::testing::InitGoogleTest(&argc, argv); - const int ret = RUN_ALL_TESTS(); +using namespace gti320; - return ret; +/** + * Multiplication matrice * vecteur, utilisant une implémentation naive + */ +template +static inline Vector<_Scalar, Dynamic> +naiveMatrixMult(const Matrix<_Scalar, Dynamic, Dynamic, ColumnStorage> &A, const Vector<_Scalar, Dynamic> &v) { + assert(A.cols() == v.rows()); + + Vector<_Scalar, Dynamic> b(A.rows()); + assert(b.rows() == A.rows()); + + for (int i = 0; i < A.rows(); ++i) { + b(i) = 0.0; + for (int j = 0; j < A.cols(); ++j) { + b(i) += A(i, j) * v(j); + } + } + + return b; +} + +/** + * Addition matrice + matrice, utilisant une implémentation naive + */ +template +static inline Matrix<_Scalar, Dynamic, Dynamic, ColumnStorage> +naiveMatrixAddition(const Matrix<_Scalar, Dynamic, Dynamic, ColumnStorage> &A, + const Matrix<_Scalar, Dynamic, Dynamic, ColumnStorage> &B) { + assert(A.cols() == B.cols() && A.rows() == B.rows()); + + Matrix<_Scalar, Dynamic, Dynamic, ColumnStorage> C(A.rows(), A.cols()); + assert(C.rows() == A.rows() && C.cols() == A.cols()); + for (int i = 0; i < C.rows(); ++i) { + for (int j = 0; j < C.cols(); ++j) { + C(i, j) = A(i, j) + B(i, j); + } + } + return C; +} + +/** + * Multiplication matrice * matrice, utilisant une implémentation naive. + */ +template +static inline Matrix<_Scalar, Dynamic, Dynamic, _Storage> +naiveMatrixMult(const Matrix<_Scalar, Dynamic, Dynamic, _Storage> &A, + const Matrix<_Scalar, Dynamic, Dynamic, _Storage> &B) { + assert(A.cols() == B.rows()); + Matrix<_Scalar, Dynamic, Dynamic> product(A.rows(), B.cols()); + for (int i = 0; i < A.rows(); ++i) { + for (int j = 0; j < B.cols(); ++j) { + for (int k = 0; k < A.cols(); ++k) { + product(i, j) += A(i, k) * B(k, j); + } + } + } + return product; +} + +// Test les matrice avec redimensionnement dynamique +TEST(TestLabo1, DynamicMatrixTests) { + // Crée une matrice à taille dynamique + // (note : les valeurs par défaut du patron de la classe `Matrix` mettent le + // le nombre de ligne et de colonnes à `Dynamic`) + Matrix M(3, 5); + EXPECT_EQ(M.cols(), 5); + EXPECT_EQ(M.rows(), 3); + + // Redimensionne la matrice + M.resize(100, 1000); + EXPECT_EQ(M.cols(), 1000); + EXPECT_EQ(M.rows(), 100); + + // Test - stockage par colonnes + Matrix ColM(100, 100); + ColM.setZero(); + ColM(0, 0) = 1.0; + ColM(99, 99) = 99.0; + ColM(10, 33) = 5.0; + EXPECT_EQ(ColM(0, 0), 1.0); + EXPECT_EQ(ColM(10, 33), 5.0); + EXPECT_EQ(ColM(99, 99), 99.0); + + // Test - stockage par lignes + Matrix RowM(5, 4); + RowM.setZero(); + RowM(0, 0) = 2.1; + RowM(3, 3) = -0.2; + RowM(4, 3) = 1.2; + EXPECT_EQ(RowM.rows(), 5); + EXPECT_EQ(RowM.cols(), 4); + EXPECT_DOUBLE_EQ(RowM(0, 0), 2.1); + EXPECT_DOUBLE_EQ(RowM(3, 3), -0.2); + EXPECT_DOUBLE_EQ(RowM(4, 3), 1.2); + EXPECT_DOUBLE_EQ(RowM(3, 2), 0.0); + + // Transposée + const auto RowMT = RowM.transpose(); + EXPECT_EQ(RowMT.rows(), 4); + EXPECT_EQ(RowMT.cols(), 5); + EXPECT_DOUBLE_EQ(RowMT(0, 0), 2.1); + EXPECT_DOUBLE_EQ(RowMT(3, 3), -0.2); + EXPECT_DOUBLE_EQ(RowMT(3, 4), 1.2); + EXPECT_DOUBLE_EQ(RowMT(2, 3), 0.0); +} + + + +/** + * Test pour les vecteurs à taille dynamique + */ +TEST(TestLabo1, DynamicVectorSizeTest) { + Vector v(5); + v.setZero(); + + EXPECT_EQ(v.rows(), 5); + + v.resize(3); + EXPECT_EQ(v.rows(), 3); + + v(0) = 1.0; + v(1) = 2.0; + v(2) = 3.0; + + EXPECT_DOUBLE_EQ(v.norm(), 3.7416573867739413855837487323165); + + Vector v2(3); + v2.setZero(); + v2(1) = 2.0; + + EXPECT_DOUBLE_EQ(v2.dot(v), 4.0); + EXPECT_DOUBLE_EQ(v2(0), 0.0); + EXPECT_DOUBLE_EQ(v2(1), 2.0); + EXPECT_DOUBLE_EQ(v2(2), 0.0); +} + +/** + * Test pour les matrice à taille fixe + */ +TEST(TestLabo1, Matrix4x4SizeTest) { + Matrix4d M; + M.setZero(); + + EXPECT_EQ(M.cols(), 4); + EXPECT_EQ(M.rows(), 4); +} + +/** + * Test pour les opérateurs d'arithmétique matricielle. + */ +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); + } + + // Opérations arithmétique avec matrices à stockage par lignes et par + // colonnes. + { + // Création d'un matrice à stockage par lignes + Matrix A(5, 5); + A(0, 0) = 0.8147; + A(0, 1) = 0.0975; + A(0, 2) = 0.1576; + A(0, 3) = 0.1419; + A(0, 4) = 0.6557; + A(1, 0) = 0.9058; + A(1, 1) = 0.2785; + A(1, 2) = 0.9706; + A(1, 3) = 0.4218; + A(1, 4) = 0.0357; + A(2, 0) = 0.1270; + A(2, 1) = 0.5469; + A(2, 2) = 0.9572; + A(2, 3) = 0.9157; + A(2, 4) = 0.8491; + A(3, 0) = 0.9134; + A(3, 1) = 0.9575; + A(3, 2) = 0.4854; + A(3, 3) = 0.7922; + A(3, 4) = 0.9340; + A(4, 0) = 0.6324; + A(4, 1) = 0.9649; + A(4, 2) = 0.8003; + A(4, 3) = 0.9595; + A(4, 4) = 0.6787; + + // Test : transposée (le résultat est une matrice à stockage par + // colonnes) + Matrix B = A.transpose(); + + // Test : multiplication matrix(ligne) * matrice(colonne) + // Note : teste seulement la première et la dernière colonne + const auto C = A * B; + EXPECT_NEAR(C(0, 0), 1.14815820000000, 1e-3); + EXPECT_NEAR(C(0, 4), 1.31659795000000, 1e-3); + EXPECT_NEAR(C(1, 0), 1.00133748000000, 1e-3); + EXPECT_NEAR(C(1, 4), 2.04727044000000, 1e-3); + EXPECT_NEAR(C(2, 0), 0.99433707000000, 1e-3); + EXPECT_NEAR(C(2, 4), 2.82896409000000, 1e-3); + EXPECT_NEAR(C(3, 0), 1.63883925000000, 1e-3); + EXPECT_NEAR(C(3, 4), 3.28401323000000, 1e-3); + EXPECT_NEAR(C(4, 0), 1.31659795000000, 1e-3); + EXPECT_NEAR(C(4, 4), 3.35271580000000, 1e-3); + + + // Test : multiplication matrice(colonne) * matrice(ligne) + // Note : teste seulement la première et la dernière colonne + const auto C2 = B * A; + EXPECT_NEAR(C2(0, 0), 2.73456805000000, 1e-3); + EXPECT_NEAR(C2(0, 4), 1.95669703000000, 1e-3); + EXPECT_NEAR(C2(1, 0), 1.88593811000000, 1e-3); + EXPECT_NEAR(C2(1, 4), 2.08742862000000, 1e-3); + EXPECT_NEAR(C2(2, 0), 2.07860468000000, 1e-3); + EXPECT_NEAR(C2(2, 4), 1.94727447000000, 1e-3); + EXPECT_NEAR(C2(3, 0), 1.94434955000000, 1e-3); + EXPECT_NEAR(C2(3, 4), 2.27675041000000, 1e-3); + EXPECT_NEAR(C2(4, 0), 1.95669703000000, 1e-3); + EXPECT_NEAR(C2(4, 4), 2.48517748000000, 1e-3); + + // Test : addition matrice(ligne) + matrice(ligne) + // Note : teste seulement la première et la dernière colonne + const auto A_plus_A = A + A; + EXPECT_DOUBLE_EQ(A_plus_A(0, 0), A(0, 0) + A(0, 0)); + EXPECT_DOUBLE_EQ(A_plus_A(0, 4), A(0, 4) + A(0, 4)); + EXPECT_DOUBLE_EQ(A_plus_A(1, 0), A(1, 0) + A(1, 0)); + EXPECT_DOUBLE_EQ(A_plus_A(1, 4), A(1, 4) + A(1, 4)); + EXPECT_DOUBLE_EQ(A_plus_A(2, 0), A(2, 0) + A(2, 0)); + EXPECT_DOUBLE_EQ(A_plus_A(2, 4), A(2, 4) + A(2, 4)); + EXPECT_DOUBLE_EQ(A_plus_A(3, 0), A(3, 0) + A(3, 0)); + EXPECT_DOUBLE_EQ(A_plus_A(3, 4), A(3, 4) + A(3, 4)); + EXPECT_DOUBLE_EQ(A_plus_A(4, 0), A(4, 0) + A(4, 0)); + EXPECT_DOUBLE_EQ(A_plus_A(4, 4), A(4, 4) + A(4, 4)); + + // Test : addition matrice(colonne) + matrice(colonne) + // Note : teste seulement la première et la dernière colonne + const auto B_plus_B = B + B; + EXPECT_DOUBLE_EQ(B_plus_B(0, 0), B(0, 0) + B(0, 0)); + EXPECT_DOUBLE_EQ(B_plus_B(0, 4), B(0, 4) + B(0, 4)); + EXPECT_DOUBLE_EQ(B_plus_B(1, 0), B(1, 0) + B(1, 0)); + EXPECT_DOUBLE_EQ(B_plus_B(1, 4), B(1, 4) + B(1, 4)); + EXPECT_DOUBLE_EQ(B_plus_B(2, 0), B(2, 0) + B(2, 0)); + EXPECT_DOUBLE_EQ(B_plus_B(2, 4), B(2, 4) + B(2, 4)); + EXPECT_DOUBLE_EQ(B_plus_B(3, 0), B(3, 0) + B(3, 0)); + EXPECT_DOUBLE_EQ(B_plus_B(3, 4), B(3, 4) + B(3, 4)); + EXPECT_DOUBLE_EQ(B_plus_B(4, 0), B(4, 0) + B(4, 0)); + EXPECT_DOUBLE_EQ(B_plus_B(4, 4), B(4, 4) + B(4, 4)); + + } +} + +/** + * Test pour la multiplication matrice * vecteur + */ +TEST(TestLabo1, MatrixVectorOperators) { + // Vecteur à taille dynamique + Vector v(5); + v(0) = 1.0; + v(1) = 2.0; + v(2) = 4.0; + v(3) = 8.0; + v(4) = 16.0; + + // Test : multiplication par la matrice identité + { + Matrix M(5, 5); + M.setIdentity(); + + const auto b = M * v; + EXPECT_DOUBLE_EQ(b(0), 1.0); + EXPECT_DOUBLE_EQ(b(1), 2.0); + EXPECT_DOUBLE_EQ(b(2), 4.0); + EXPECT_DOUBLE_EQ(b(3), 8.0); + EXPECT_DOUBLE_EQ(b(4), 16.0); + } + + // Test : multiplication par une matrice à taille dynamique avec stockage par ligne. + { + Matrix M(5, 5); + M.setIdentity(); + M = 2.0 * M; + + Vector b2 = M * v; + EXPECT_DOUBLE_EQ(b2(0), 2.0); + EXPECT_DOUBLE_EQ(b2(1), 4.0); + EXPECT_DOUBLE_EQ(b2(2), 8.0); + EXPECT_DOUBLE_EQ(b2(3), 16.0); + EXPECT_DOUBLE_EQ(b2(4), 32.0); + } +} + +/** + * Opérateurs d'arithmétique vectorielle + */ +TEST(TestLabo1, VectorOperators) { + Vector v(5); + v(0) = 0.1; + v(1) = 0.2; + v(2) = 0.4; + v(3) = 0.8; + v(4) = 1.6; + + // Test : multiplication scalaire * vecteur + const double alpha = 4.0; + const auto v2 = alpha * v; + EXPECT_DOUBLE_EQ(v2(0), alpha * v(0)); + EXPECT_DOUBLE_EQ(v2(1), alpha * v(1)); + EXPECT_DOUBLE_EQ(v2(2), alpha * v(2)); + EXPECT_DOUBLE_EQ(v2(3), alpha * v(3)); + EXPECT_DOUBLE_EQ(v2(4), alpha * v(4)); + + // Test : addition vecteur + vecteur + const auto v3 = v + v2; + EXPECT_DOUBLE_EQ(v3(0), v(0) + v2(0)); + EXPECT_DOUBLE_EQ(v3(1), v(1) + v2(1)); + EXPECT_DOUBLE_EQ(v3(2), v(2) + v2(2)); + EXPECT_DOUBLE_EQ(v3(3), v(3) + v2(3)); + EXPECT_DOUBLE_EQ(v3(4), v(4) + v2(4)); +} + + +/** + * Mathématiques 3D + */ +TEST(TestLabo1, Math3D) { + // Test : norme d'un vecteur de dimension 3 + Vector3d v; + v.setZero(); + v(1) = 2.0; + EXPECT_EQ(v.rows(), 3); + EXPECT_EQ(v.cols(), 1); + EXPECT_DOUBLE_EQ(v(0), 0.0); + EXPECT_DOUBLE_EQ(v(1), 2.0); + EXPECT_DOUBLE_EQ(v(2), 0.0); + EXPECT_DOUBLE_EQ(v.norm(), 2.0); + + // Test : calcul de la norme d'un deuxième vecteur 3D + Vector3d v2; + v2(0) = 4.0; + v2(1) = 2.0; + v2(2) = 5.0; + EXPECT_EQ(v2.rows(), 3); + EXPECT_EQ(v2.cols(), 1); + EXPECT_DOUBLE_EQ(v2(0), 4.0); + EXPECT_DOUBLE_EQ(v2(1), 2.0); + EXPECT_DOUBLE_EQ(v2(2), 5.0); + EXPECT_DOUBLE_EQ(v2.norm(), 6.7082039324993690892275210061938); + + // Test : produit scalaire + EXPECT_DOUBLE_EQ(v.dot(v2), 4.0); + + // Test : matrice identité 4x4 + Matrix4d M; + M.setIdentity(); + EXPECT_DOUBLE_EQ(M(0, 0), 1.0); + EXPECT_DOUBLE_EQ(M(0, 1), 0.0); + EXPECT_DOUBLE_EQ(M(0, 2), 0.0); + EXPECT_DOUBLE_EQ(M(1, 1), 1.0); + EXPECT_DOUBLE_EQ(M(1, 0), 0.0); + EXPECT_DOUBLE_EQ(M(1, 2), 0.0); + EXPECT_DOUBLE_EQ(M(2, 0), 0.0); + EXPECT_DOUBLE_EQ(M(2, 1), 0.0); + EXPECT_DOUBLE_EQ(M(2, 2), 1.0); + + // Test : création d'une matrice de rotation de 45 degrés autour de l'axe des x + const auto Rx = makeRotation(M_PI / 4.0, 0, 0); + EXPECT_NEAR(Rx(0, 0), 1, 1e-3); + EXPECT_NEAR(Rx(0, 1), 0, 1e-3); + EXPECT_NEAR(Rx(0, 2), 0, 1e-3); + EXPECT_NEAR(Rx(1, 0), 0, 1e-3); + EXPECT_NEAR(Rx(1, 1), 0.7071, 1e-3); + EXPECT_NEAR(Rx(1, 2), -0.7071, 1e-3); + EXPECT_NEAR(Rx(2, 0), 0, 1e-3); + EXPECT_NEAR(Rx(2, 1), 0.7071, 1e-3); + EXPECT_NEAR(Rx(2, 2), 0.7071, 1e-3); + + // Test : création d'une matrice de rotation de 45 degrés autour de l'axe des y + const auto Ry = makeRotation(0, M_PI / 4.0, 0); + EXPECT_NEAR(Ry(0, 0), 0.7071, 1e-3); + EXPECT_NEAR(Ry(0, 1), 0, 1e-3); + EXPECT_NEAR(Ry(0, 2), 0.7071, 1e-3); + EXPECT_NEAR(Ry(1, 0), 0, 1e-3); + EXPECT_NEAR(Ry(1, 1), 1, 1e-3); + EXPECT_NEAR(Ry(1, 2), 0, 1e-3); + EXPECT_NEAR(Ry(2, 0), -0.7071, 1e-3); + EXPECT_NEAR(Ry(2, 1), 0, 1e-3); + EXPECT_NEAR(Ry(2, 2), 0.7071, 1e-3); + + // Test : création d'une matrice de rotation de 45 degrés autour de l'axe des z + const auto Rz = makeRotation(0, 0, M_PI / 4.0); + EXPECT_NEAR(Rz(0, 0), 0.7071, 1e-3); + EXPECT_NEAR(Rz(0, 1), -0.7071, 1e-3); + EXPECT_NEAR(Rz(0, 2), 0, 1e-3); + EXPECT_NEAR(Rz(1, 0), 0.7071, 1e-3); + EXPECT_NEAR(Rz(1, 1), 0.7071, 1e-3); + EXPECT_NEAR(Rz(1, 2), 0, 1e-3); + EXPECT_NEAR(Rz(2, 0), 0, 1e-3); + EXPECT_NEAR(Rz(2, 1), 0, 1e-3); + EXPECT_NEAR(Rz(2, 2), 1, 1e-3); + + // Test : création d'une matrice de rotation quelconque. + const auto Rxyz = makeRotation(M_PI / 3.0, -M_PI / 6.0, M_PI / 4.0); + EXPECT_NEAR(Rxyz(0, 0), 0.6124, 1e-3); + EXPECT_NEAR(Rxyz(0, 1), -0.6597, 1e-3); + EXPECT_NEAR(Rxyz(0, 2), 0.4356, 1e-3); + EXPECT_NEAR(Rxyz(1, 0), 0.6124, 1e-3); + EXPECT_NEAR(Rxyz(1, 1), 0.0474, 1e-3); + EXPECT_NEAR(Rxyz(1, 2), -0.7891, 1e-3); + EXPECT_NEAR(Rxyz(2, 0), 0.5, 1e-3); + EXPECT_NEAR(Rxyz(2, 1), 0.75, 1e-3); + EXPECT_NEAR(Rxyz(2, 2), 0.4330, 1e-3); + + // Test : création d'une transformation homogène via la sous-matrice 3x3 en + // utilisant la fonction `block` + M.block(0, 0, 3, 3) = Rxyz; + M(0, 3) = -0.1; + M(1, 3) = 1.0; + M(2, 3) = 2.1; + + // Test : calcule l'inverse de la matrice M et vérifie que M^(-1) * M * v = v + const Matrix4d Minv = M.inverse(); + const Vector3d v3 = Minv * (M * v2); + EXPECT_DOUBLE_EQ(v3(0), v2(0)); + EXPECT_DOUBLE_EQ(v3(1), v2(1)); + EXPECT_DOUBLE_EQ(v3(2), v2(2)); + + // Test : translation d'un vecteur 3D effectuée avec une matrice 4x4 en coordonnées homogènes + Matrix4d T; + T.setIdentity(); + T(0, 3) = 1.2; + T(1, 3) = 2.5; + T(2, 3) = -4.0; + const Vector3d t = T * v3; + EXPECT_DOUBLE_EQ(t(0), v3(0) + 1.2); + EXPECT_DOUBLE_EQ(t(1), v3(1) + 2.5); + EXPECT_DOUBLE_EQ(t(2), v3(2) - 4.0); + + // Test : inverse d'un matrice de rotation + const Matrix3d Rinv = Rxyz.inverse(); + const Matrix3d RT = Rxyz.transpose(); + EXPECT_DOUBLE_EQ(Rinv(0, 0), RT(0, 0)); + EXPECT_DOUBLE_EQ(Rinv(1, 1), RT(1, 1)); + EXPECT_DOUBLE_EQ(Rinv(0, 2), RT(0, 2)); +} + +/** + * Test des performance de la multiplication matrice * vecteur + * pour de grandes dimensions. + */ +TEST(TestLabo1, PerformanceMatrixVector) { + Matrix A(16384, 16384); // grande matrice avec stockage colonne + Vector v(16384); // grand vecteur + + using namespace std::chrono; + // Test : multiplication avec l'algorithme naif. + high_resolution_clock::time_point t = high_resolution_clock::now(); + naiveMatrixMult(A, v); + const duration naive_t = duration_cast>(high_resolution_clock::now() - t); + + // Test : multiplication avec l'implémentation spécifique pour les matrices avec + // stockage par colonnes. + t = high_resolution_clock::now(); + A * v; + const duration optimal_t = duration_cast>(high_resolution_clock::now() - t); + + EXPECT_TRUE(optimal_t < 0.4 * naive_t) + << "Naive time: " << duration_cast(naive_t).count() << " ms, " + << "optimized time: " << duration_cast(optimal_t).count() << " ms"; +} + +/** + * Test des performances de l'addition matrice + matrice + * pour de grandes dimensions. + */ +TEST(TestLabo1, PerformanceLargeMatrixMatrix) { + // deux grandes matrices à stockage par colonnes + Matrix A(16384, 16384); + Matrix B(16384, 16384); + + using namespace std::chrono; + high_resolution_clock::time_point t = high_resolution_clock::now(); + // Test : addition avec l'algorithme naif + naiveMatrixAddition(A, B); + const duration naive_t = duration_cast>(high_resolution_clock::now() - t); + + // Test : addition avec l'implémentation spécifique pour les matrices à + // stockage par colonnes. + t = high_resolution_clock::now(); + A + B; + const duration optimal_t = duration_cast>(high_resolution_clock::now() - t); + + EXPECT_TRUE(optimal_t < 0.4 * naive_t); +} + +TEST(TestLabo1, Supplementaires) { + // === Stockage === + // Test 1: Set zero + DenseStorage 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 S2; + S2.resize(size); + EXPECT_EQ(S2.size(), 10); + + // Test 4: Copie + DenseStorage 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 MC(4, 6); + MC.setIdentity(); + for (int col = 0; col < MC.cols(); col++) { + for (int row = 0; row < MC.rows(); row++) { + int expected = 0; + if (row == col) { + expected = 1; + } + + EXPECT_EQ(MC(row, col), 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 s = MC.block(1, 1, 3, 3); + for (int col = 0; col < s.cols(); col++) { + for (int row = 0; row < s.rows(); row++) { + EXPECT_EQ(s(col, row), MC(col + 1, row + 1)); + } + } + + // Test 7: Transposée d'une sous-matrice + const Matrix t = s.transpose(); + for (int col = 0; col < t.cols(); col++) { + for (int row = 0; row < t.rows(); row++) { + EXPECT_EQ(t(col, row), s(row, col)); + } + } + + // 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(1, 0)); + + // Test 9: Stockage par rangée + Matrix 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(0, 1)); + + // === Vecteurs === + // Test 10: Copie + Vector V1(10); + Vector V2(16); + V2(12) = 543; + V1 = V2; + EXPECT_EQ(V1.size(), V2.size()); + EXPECT_EQ(V1(12), V2(12)); + + // === Copie de vecteurs de grandeur différente === + // Test 11: Petit vers grand + Vector V3; + for (int i = 0; i < V3.size(); i++) { + V3(i) = i; + } + Vector V4(V3); + + for (int i = 0; i < V3.size(); i++) { + EXPECT_EQ(V4(i), V3(i)); + } + for (int i = V3.size(); i < V4.size(); i++) { + EXPECT_EQ(V4(i), 0); + } + + // Test 12: Grand vers petit + Vector V5(V4); + for (int i = 0; i < V5.size(); i++) { + EXPECT_EQ(V5(i), V4(i)); + } + + // === Déterminants === + Matrix MD1x1; + MD1x1(0, 0) = 1; + + Matrix MD2x2; + MD2x2(0, 0) = 1; MD2x2(0, 1) = 2; + MD2x2(1, 0) = 3; MD2x2(1, 1) = 4; + + Matrix MD3x3; + MD3x3(0, 0) = 1; MD3x3(0, 1) = 2; MD3x3(0, 2) = 3; + MD3x3(1, 0) = 4; MD3x3(1, 1) = 5; MD3x3(1, 2) = 6; + MD3x3(2, 0) = 7; MD3x3(2, 1) = 9; MD3x3(2, 2) = 0; + + // Test 13: 1x1 + int det1 = det(MD1x1); + EXPECT_EQ(det1, MD1x1(0, 0)); + + // Test 14: 2x2 + int det2 = det(MD2x2); + EXPECT_EQ(det2, -2); + + // Test 15: 3x3 + int det3 = det(MD3x3); + EXPECT_EQ(det3, 33); +} + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + const int ret = RUN_ALL_TESTS(); + + return ret; } diff --git a/labo01/src/Math3D.h b/labo01/src/Math3D.h deleted file mode 100644 index d58e333..0000000 --- a/labo01/src/Math3D.h +++ /dev/null @@ -1,110 +0,0 @@ -#pragma once - -/** - * @file Math3D.h - * - * @brief Fonctions pour l'intinialisation et la manipulation de matrices de - * rotation, des matrices de transformations en coordonnées homogènes et les - * vecteurs 3D. - * - * Nom: - * Code permanent : - * Email : - * - */ - -#include "Matrix.h" -#include "Vector.h" -#include "Operators.h" - -#ifndef _USE_MATH_DEFINES -#define _USE_MATH_DEFINES -#endif - -#include - - -namespace gti320 { - - // Deux types de vecteurs 3D considérés ici - typedef Vector Vector3d; - typedef Vector Vector3f; - - // Dans le cadre de ce projet, nous considérons seulement deux - // cas : - // - // - les rotations - // - les translations - // - // Deux types de matrices en coordonnées homogèes : - typedef Matrix Matrix4d; - typedef Matrix Matrix4f; - // - // Deux types de matrices pour les rotations - typedef Matrix Matrix3d; - typedef Matrix Matrix3f; - - /** - * Initialise et retourne la matrice identité - */ - template<> - inline void Matrix4d::setIdentity() - { - // TODO affecter la valeur 0.0 partout, sauf sur la diagonale principale où c'est 1.0. - // Note: ceci est une redéfinition d'une fonction membre! - } - - /** - * Calcul de la matrice inverse, SPÉCIALISÉ pour le cas d'une matrice de - * transformation en coordonnées homogènes. - * - * TODO (vous pouvez supposer qu'il s'agit d'une matrice de transformation - * en coordonnées homogènes) - */ - template<> - inline Matrix4d Matrix4d::inverse() const - { - // TODO : implémenter - return Matrix4d(); // Pas bon, à changer - } - - /** - * Calcul de la matrice inverse, SPÉCIALISÉ pour le cas d'une matrice de rotation. - * - * (vous pouvez supposer qu'il s'agit d'une matrice de rotation) - */ - template<> - inline Matrix3d Matrix3d::inverse() const - { - // TODO : implémenter - return Matrix3d(); - } - - - /** - * Multiplication d'une matrice 4x4 avec un vecteur 3D où la matrice - * représente une transformation en coordonnées homogène. - */ - template - Vector<_Scalar, 3> operator*(const Matrix<_Scalar, 4, 4, ColumnStorage>& A, const Vector<_Scalar, 3>& v) - { - // TODO : implémenter - return Vector<_Scalar, 3>(); // pas bon, à changer - } - - - /** - * Initialise et retourne la matrice de rotation définie par les angles - * d'Euler XYZ exprimés en radians. - * - * La matrice doit correspondre au produit : Rz*Ry*Rx. - */ - template - static Matrix<_Scalar, 3, 3> makeRotation(_Scalar x, _Scalar y, _Scalar z) - { - // TODO : implémenter - - return Matrix<_Scalar, 3, 3>(); // pas bon, à changer - } - -} diff --git a/labo01/src/Matrix.h b/labo01/src/Matrix.h deleted file mode 100644 index d3f83ec..0000000 --- a/labo01/src/Matrix.h +++ /dev/null @@ -1,350 +0,0 @@ -#pragma once - -/** - * @file Matrix.h - * - * @brief Implémentation de matrices simples. - * - * Nom: - * Code permanent : - * Email : - * - */ - -#include "MatrixBase.h" - -namespace gti320 -{ - enum StorageType - { - ColumnStorage = 0, - RowStorage = 1 - }; - - // Déclaration avancée - template class SubMatrix; - - /** - * Classe Matrix spécialisé pour le cas générique. (defaut par colonne) - * - * (le cas d'un stockage par ligne fait l'objet d'une spécialisation de patron, voir plus bas) - */ - template - class Matrix : public MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile> { - public: - - /** - * Constructeur par défaut - */ - Matrix() : MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile>() { } - - /** - * Constructeur de copie - */ - Matrix(const Matrix& other) : MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile>(other) { } - - /** - * Constructeur avec spécification du nombre de ligne et de colonnes - */ - explicit Matrix(int _rows, int _cols) : MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile>(_rows, _cols) { } - - /** - * Destructeur - */ - ~Matrix() { } - - /** - * Opérateur de copie à partir d'une sous-matrice. - * - * Exemple : - * Matrix<...> A(...); - * Matrix<...> B(...); - * B = A.block(i,j,m,n); - - */ - template - Matrix& operator= (const SubMatrix<_OtherScalar, OtherRows, _OtherCols, _OtherStorage>& submatrix) - { - // 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. - return *this; - } - - /** - * Accesseur à une entrée de la matrice (lecture seule) - */ - _Scalar operator()(int i, int j) const - { - // TODO implementer - return (double)(i + j); - } - - /** - * 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; - } - - /** - * Crée une sous-matrice pour un block de taille (rows, cols) à partir de l'index (i,j). - */ - SubMatrix<_Scalar, _RowsAtCompile, _ColsAtCompile, _StorageType> block(int i, int j, int rows, int cols) const - { - return SubMatrix<_Scalar, _RowsAtCompile, _ColsAtCompile, _StorageType>(*this, i, j, rows, cols); - } - - /** - * Calcule l'inverse de la matrice - */ - Matrix inverse() const - { - // Do nothing. - return *this; - } - - /** - * Retourne la transposée de la matrice - */ - template - 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 - } - - /** - * 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. - } - - }; - - /** - * Classe Matrix spécialisée pour un stockage par lignes - */ - template - class Matrix< _Scalar, _RowsAtCompile, _ColsAtCompile, RowStorage> : public MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile> { - - public: - /** - * Constructeur par défaut - */ - Matrix() : MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile>() { } - - /** - * Constructeur de copie - */ - Matrix(const Matrix& other) : MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile>(other) { } - - /** - * Constructeur avec spécification du nombre de ligne et de colonnes - */ - explicit Matrix(int rows, int cols) : MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile>(rows, cols) { } - - /** - * Destructeur - */ - ~Matrix() { } - - /** - * Opérateur de copie à partir d'une sous-matrice. - * - * Exemple : - * Matrix<...> A(...); - * Matrix<...> B(...); - * B = A.block(i,j,m,n); - */ - template - Matrix& operator= (const SubMatrix<_OtherScalar, OtherRows, _OtherCols, _OtherStorage>& submatrix) - { - // 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. - return *this; - } - - /** - * Accesseur à une entrée de la matrice (lecture seule) - */ - _Scalar operator()(int i, int j) const - { - // TODO implementer - return 0.0; - } - - /** - * Accesseur à une entrée de la matrice (lecture ou écriture) - */ - _Scalar& operator()(int i, int j) - { - // TODO implementer - _Scalar x = 0.0; - return x; - } - - /** - * Crée une sous-matrice pour un block de taille (rows, cols) à partir de l'index (i,j). - */ - SubMatrix<_Scalar, _RowsAtCompile, _ColsAtCompile, RowStorage> block(int i, int j, int rows, int cols) const { - return SubMatrix<_Scalar, _RowsAtCompile, _ColsAtCompile, RowStorage>(*this, i, j, rows, cols); - } - - /** - * Calcule l'inverse de la matrice - */ - Matrix inverse() const - { - // Do nothing. - return *this; - } - - /** - * 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é. - - return Matrix<_Scalar, _ColsAtCompile, _RowsAtCompile, ColumnStorage>(); - } - - /** - * 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. - } - - }; - - /** - * Classe pour accéder à une sous-matrice. - * - * Un sous-matrice ne copie pas les données. Au lieu de cela, elle conserve une - * référence à la matrice originale. - */ - template - class SubMatrix - { - private: - // Référence à la matrice originale - Matrix<_Scalar, _RowsAtCompile, _ColsAtCompile, _StorageType>& m_matrix; - - // Constructeur par défaut (privé) - SubMatrix() {} - - // (i,j) est le coin supérieur gauche de la sous-matrice - int m_i; // Décalage en ligne - int m_j; // Décalage en colonne - - // la sous-matrice est de dimension : m_rows x m_cols - int m_rows; // Hauteur de la sous-matrice (nombre de lignes) - int m_cols; // Largeur de la sous-matrice (nombre de colonnes) - - public: - - /** - * Constructeur à partir d'une référence en lecture seule à une matrice. - */ - SubMatrix(const Matrix<_Scalar, _RowsAtCompile, _ColsAtCompile, _StorageType>& _matrix, int _i, int _j, int _rows, int _cols) : - m_matrix(const_cast&>(_matrix)), - m_i(_i), m_j(_j), m_rows(_rows), m_cols(_cols) - { - } - - /** - * Constructeur à partir d'une référence en lecture et écriture à une matrice. - */ - explicit SubMatrix(Matrix<_Scalar, _RowsAtCompile, _ColsAtCompile, _StorageType>& _matrix, int _i, int _j, int _rows, int _cols) : - m_matrix(_matrix), - m_i(_i), m_j(_j), m_rows(_rows), m_cols(_cols) - { - - } - - /** - * Constructeur de copie - */ - SubMatrix(const SubMatrix& other) : - m_matrix(other.m_matrix), - m_i(other.m_i), m_j(other.m_j), m_rows(other.m_rows), m_cols(other.m_cols) - { - } - - /** - * Destructeur - */ - ~SubMatrix() { } - - /** - * Opérateur de copie (à partir d'une matrice) - * - * Copies toutes les entrées de la matrice dans la sous-matrice. - * - * Note : la taille de la matrice doit correspondre à la taille de la - * sous-matrice. - */ - template - 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. - return *this; - } - - /** - * Accesseur aux entrées de la sous-matrice (lecture seule) - * - * Note : il faut s'assurer que les indices respectent la taille de la - * sous-matrice - */ - _Scalar operator()(int i, int j) const - { - // TODO implémenter - return 0.0; - } - - /** - * Accesseur aux entrées de la sous-matrice (lecture et écriture) - * - * Note : il faut s'assurer que les indices respectent la taille de la - * sous-matrice - */ - _Scalar& operator()(int i, int j) - { - // TODO implémenter - _Scalar x = 0.0; - return x; - } - - /** - * Retourne la transposée de la sous-matrice sous la forme d'une matrice. - */ - template - Matrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage> transpose() const - { - // TODO implémenter - return Matrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage>(); - } - - inline int rows() const { return m_rows; } - inline int cols() const { return m_cols; } - - }; - -} diff --git a/labo01/src/Operators.h b/labo01/src/Operators.h deleted file mode 100644 index 7fa2f3b..0000000 --- a/labo01/src/Operators.h +++ /dev/null @@ -1,179 +0,0 @@ -#pragma once - -/** - * @file Operators.h - * - * @brief Opérateurs arithmétiques pour les matrices et les vecteurs. - * - * Nom: - * Code permanent : - * Email : - * - */ - -#include "Matrix.h" -#include "Vector.h" - - /** - * 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 (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>(); - } - - /** - * 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>(); - } - - - /** - * 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 (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>(); - } - - /** - * 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>(); - } - - /** - * 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>(); - } - - /** - * 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>(); - } - - /** - * 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>(); - } - - /** - * 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/src/Vector.h b/labo01/src/Vector.h deleted file mode 100644 index 6f1e4e2..0000000 --- a/labo01/src/Vector.h +++ /dev/null @@ -1,104 +0,0 @@ -#pragma once - -/** - * @file Vector.h - * - * @brief Implémentation de vecteurs simples - * - * Nom: - * Code permanent : - * Email : - * - */ - -#include -#include "MatrixBase.h" - -namespace gti320 { - - /** - * Classe vecteur générique. - * - * Cette classe réutilise la classe `MatrixBase` et ses spécialisations de - * templates pour les manipulation bas niveau. - */ - template - class Vector : public MatrixBase<_Scalar, _Rows, 1> { - public: - - /** - * Constructeur par défaut - */ - Vector() : MatrixBase<_Scalar, _Rows, 1>() { } - - /** - * Contructeur à partir d'un taille (rows). - */ - explicit Vector(int rows) : MatrixBase<_Scalar, _Rows, 1>(rows, 1) { } - - /** - * Constructeur de copie - */ - Vector(const Vector& other) : MatrixBase<_Scalar, _Rows, 1>(other) { } - - /** - * Destructeur - */ - ~Vector() { } - - /** - * Opérateur de copie - */ - Vector& operator=(const Vector& other) - { - // TODO implémenter - this->m_storage = other.m_storage; - return *this; - } - - /** - * Accesseur à une entrée du vecteur (lecture seule) - */ - _Scalar operator()(int i) const - { - // TODO implémenter - return (double)i; - } - - /** - * Accesseur à une entrée du vecteur (lecture et écriture) - */ - _Scalar& operator()(int i) - { - // TODO implémenter - _Scalar x = (double)i; - return x; - } - - /** - * Modifie le nombre de lignes du vecteur - */ - void resize(int _rows) - { - MatrixBase<_Scalar, _Rows, 1>::resize(_rows, 1); - } - - /** - * Produit scalaire de *this et other. - */ - inline _Scalar dot(const Vector& other) const - { - // TODO implémenter - return 0.0; - } - - /** - * Retourne la norme euclidienne du vecteur - */ - inline _Scalar norm() const - { - // TODO implémenter - return 0.0; - } - }; -} diff --git a/labo01/tests/Tests1a.cpp b/labo01/tests/Tests1a.cpp deleted file mode 100644 index c383d3b..0000000 --- a/labo01/tests/Tests1a.cpp +++ /dev/null @@ -1,398 +0,0 @@ -/** - * @file Tests1a.cpp - * - * @brief Tests unitaires de la partie 1b - * - * Nom: - * Code permanent : - * Email : - * - */ - -#include "Matrix.h" -#include "Vector.h" - -#include -#include - -using namespace gti320; - -TEST(TestLabo1a, DotAndNorm) { - { - Vector u; u(0) = 81.74804972455644; u(1) = -74.09304417781078; u(2) = -91.38202093790602; - Vector v; v(0) = 81.1462118959985; v(1) = 29.763442976156085; v(2) = 39.00787276684184; - EXPECT_NEAR(u.dot(v), 863.662223794679, 1e-4) << "(u=(81.74804972455644, -74.09304417781078, -91.38202093790602), v= (81.1462118959985, 29.763442976156085, 39.00787276684184))"; - EXPECT_NEAR(u.norm(), 143.25919370148452, 1e-4) << "(u=(81.74804972455644, -74.09304417781078, -91.38202093790602))"; - u = v; - EXPECT_NEAR(u.norm(), 94.82712892764025, 1e-4) << "u=(81.74804972455644, -74.09304417781078, -91.38202093790602)"; - } - { - Vector u; u(0) = 13.087936541928485; u(1) = -26.541934227528046; u(2) = -48.13859302157102; - Vector v; v(0) = -66.28108277028942; v(1) = 11.919000480625243; v(2) = -96.21367167640467; - EXPECT_NEAR(u.dot(v), 3447.7548518990116, 1e-4) << "(u=(13.087936541928485, -26.541934227528046, -48.13859302157102), v= (-66.28108277028942, 11.919000480625243, -96.21367167640467))"; - EXPECT_NEAR(u.norm(), 56.50745520336602, 1e-4) << "(u=(13.087936541928485, -26.541934227528046, -48.13859302157102))"; - u = v; - EXPECT_NEAR(u.norm(), 117.44068768154457, 1e-4) << "u=(13.087936541928485, -26.541934227528046, -48.13859302157102)"; - } - { - Vector u; u(0) = -79.56972852806103; u(1) = -64.04761691711548; u(2) = 75.76398532227091; - Vector v; v(0) = 68.1521534060019; v(1) = -38.02548546805114; v(2) = 44.66242384133133; - EXPECT_NEAR(u.dot(v), 396.3966055984092, 1e-4) << "(u=(-79.56972852806103, -64.04761691711548, 75.76398532227091), v= (68.1521534060019, -38.02548546805114, 44.66242384133133))"; - EXPECT_NEAR(u.norm(), 127.17554954748255, 1e-4) << "(u=(-79.56972852806103, -64.04761691711548, 75.76398532227091))"; - u = v; - EXPECT_NEAR(u.norm(), 89.91877258025103, 1e-4) << "u=(-79.56972852806103, -64.04761691711548, 75.76398532227091)"; - } - { - Vector u; u(0) = -27.829925590795995; u(1) = 97.52374799957443; u(2) = -71.29949583706774; - Vector v; v(0) = 15.413123773966177; v(1) = -25.9678191712148; v(2) = -70.46329734352945; - EXPECT_NEAR(u.dot(v), 2062.5724349077673, 1e-4) << "(u=(-27.829925590795995, 97.52374799957443, -71.29949583706774), v= (15.413123773966177, -25.9678191712148, -70.46329734352945))"; - EXPECT_NEAR(u.norm(), 123.97178827819569, 1e-4) << "(u=(-27.829925590795995, 97.52374799957443, -71.29949583706774))"; - u = v; - EXPECT_NEAR(u.norm(), 76.66138721353245, 1e-4) << "u=(-27.829925590795995, 97.52374799957443, -71.29949583706774)"; - } - { - Vector u; u(0) = 46.94969707999718; u(1) = 92.7292896206543; u(2) = 61.3890905084975; - Vector v; v(0) = 91.40236621394195; v(1) = -23.911909695536067; v(2) = -66.18706904017846; - EXPECT_NEAR(u.dot(v), -1989.1849652004407, 1e-4) << "(u=(46.94969707999718, 92.7292896206543, 61.3890905084975), v= (91.40236621394195, -23.911909695536067, -66.18706904017846))"; - EXPECT_NEAR(u.norm(), 120.71294728783312, 1e-4) << "(u=(46.94969707999718, 92.7292896206543, 61.3890905084975))"; - u = v; - EXPECT_NEAR(u.norm(), 115.3555377211011, 1e-4) << "u=(46.94969707999718, 92.7292896206543, 61.3890905084975)"; - } - { - Vector u; u(0) = 9.836648455487577; u(1) = 27.373779624683323; u(2) = 33.47163213808042; - Vector v; v(0) = -17.904556153169437; v(1) = -10.39159035574184; v(2) = 36.045191146582226; - EXPECT_NEAR(u.dot(v), 745.913449426867, 1e-4) << "(u=(9.836648455487577, 27.373779624683323, 33.47163213808042), v= (-17.904556153169437, -10.39159035574184, 36.045191146582226))"; - EXPECT_NEAR(u.norm(), 44.344488065198725, 1e-4) << "(u=(9.836648455487577, 27.373779624683323, 33.47163213808042))"; - u = v; - EXPECT_NEAR(u.norm(), 41.566983123113395, 1e-4) << "u=(9.836648455487577, 27.373779624683323, 33.47163213808042)"; - } - { - Vector u; u(0) = 77.34524968701723; u(1) = -86.53838659054598; u(2) = 52.511893628372974; - Vector v; v(0) = 39.390038592378005; v(1) = -53.13512176642368; v(2) = 60.23922457130902; - EXPECT_NEAR(u.dot(v), 10808.13583201148, 1e-4) << "(u=(77.34524968701723, -86.53838659054598, 52.511893628372974), v= (39.390038592378005, -53.13512176642368, 60.23922457130902))"; - EXPECT_NEAR(u.norm(), 127.39183245121873, 1e-4) << "(u=(77.34524968701723, -86.53838659054598, 52.511893628372974))"; - u = v; - EXPECT_NEAR(u.norm(), 89.4632912562147, 1e-4) << "u=(77.34524968701723, -86.53838659054598, 52.511893628372974)"; - } - { - Vector u; u(0) = 72.58764125601218; u(1) = 13.004884623782146; u(2) = 6.688195585248067; - Vector v; v(0) = -41.68110389567836; v(1) = 65.83906651972734; v(2) = 64.45916748876758; - EXPECT_NEAR(u.dot(v), -1738.1880334803595, 1e-4) << "(u=(72.58764125601218, 13.004884623782146, 6.688195585248067), v= (-41.68110389567836, 65.83906651972734, 64.45916748876758))"; - EXPECT_NEAR(u.norm(), 74.04609812391155, 1e-4) << "(u=(72.58764125601218, 13.004884623782146, 6.688195585248067))"; - u = v; - EXPECT_NEAR(u.norm(), 101.12903329655835, 1e-4) << "u=(72.58764125601218, 13.004884623782146, 6.688195585248067)"; - } - { - Vector u; u(0) = 44.123038783178856; u(1) = 59.032307289173275; u(2) = -96.45920641599031; - Vector v; v(0) = -23.433056105942327; v(1) = -95.82287577132844; v(2) = -87.71884659805113; - EXPECT_NEAR(u.dot(v), 1770.7072393377675, 1e-4) << "(u=(44.123038783178856, 59.032307289173275, -96.45920641599031), v= (-23.433056105942327, -95.82287577132844, -87.71884659805113))"; - EXPECT_NEAR(u.norm(), 121.39206875965131, 1e-4) << "(u=(44.123038783178856, 59.032307289173275, -96.45920641599031))"; - u = v; - EXPECT_NEAR(u.norm(), 132.006544110677, 1e-4) << "u=(44.123038783178856, 59.032307289173275, -96.45920641599031)"; - } - { - Vector u; u(0) = -7.594864170286073; u(1) = -92.12702535387345; u(2) = 10.61833019724412; - Vector v; v(0) = -57.88532008253067; v(1) = -61.95047768934079; v(2) = -50.9801175870505; - EXPECT_NEAR(u.dot(v), 5605.620650217189, 1e-4) << "(u=(-7.594864170286073, -92.12702535387345, 10.61833019724412), v= (-57.88532008253067, -61.95047768934079, -50.9801175870505))"; - EXPECT_NEAR(u.norm(), 93.04740565161417, 1e-4) << "(u=(-7.594864170286073, -92.12702535387345, 10.61833019724412))"; - u = v; - EXPECT_NEAR(u.norm(), 98.9320188623685, 1e-4) << "u=(-7.594864170286073, -92.12702535387345, 10.61833019724412)"; - } - { - Vector u; u(0) = 28.01623276831728; u(1) = -35.47111447521442; u(2) = -80.09707278049716; - Vector v; v(0) = 62.23810927998369; v(1) = -69.45561657190204; v(2) = -17.998932897185853; - EXPECT_NEAR(u.dot(v), 5649.007321253708, 1e-4) << "(u=(28.01623276831728, -35.47111447521442, -80.09707278049716), v= (62.23810927998369, -69.45561657190204, -17.998932897185853))"; - EXPECT_NEAR(u.norm(), 91.97092110361056, 1e-4) << "(u=(28.01623276831728, -35.47111447521442, -80.09707278049716))"; - u = v; - EXPECT_NEAR(u.norm(), 94.98224310663369, 1e-4) << "u=(28.01623276831728, -35.47111447521442, -80.09707278049716)"; - } - { - Vector u; u(0) = 17.056114318144637; u(1) = -47.87236586884536; u(2) = -66.233990996889; - Vector v; v(0) = -16.5274983107699; v(1) = -61.98159750757431; v(2) = -95.73085862430288; - EXPECT_NEAR(u.dot(v), 9025.947640683207, 1e-4) << "(u=(17.056114318144637, -47.87236586884536, -66.233990996889), v= (-16.5274983107699, -61.98159750757431, -95.73085862430288))"; - EXPECT_NEAR(u.norm(), 83.48422613218729, 1e-4) << "(u=(17.056114318144637, -47.87236586884536, -66.233990996889))"; - u = v; - EXPECT_NEAR(u.norm(), 115.23573197124973, 1e-4) << "u=(17.056114318144637, -47.87236586884536, -66.233990996889)"; - } - { - Vector u; u(0) = 53.68514451573557; u(1) = 40.487633535881685; u(2) = -34.39102876903675; - Vector v; v(0) = 5.723467714467617; v(1) = -11.984939376053532; v(2) = 71.57117734380691; - EXPECT_NEAR(u.dot(v), -2639.3830610897676, 1e-4) << "(u=(53.68514451573557, 40.487633535881685, -34.39102876903675), v= (5.723467714467617, -11.984939376053532, 71.57117734380691))"; - EXPECT_NEAR(u.norm(), 75.52540016977055, 1e-4) << "(u=(53.68514451573557, 40.487633535881685, -34.39102876903675))"; - u = v; - EXPECT_NEAR(u.norm(), 72.79306478576713, 1e-4) << "u=(53.68514451573557, 40.487633535881685, -34.39102876903675)"; - } - { - Vector u; u(0) = -19.41880304735801; u(1) = 80.15388147841654; u(2) = 18.762371448279836; - Vector v; v(0) = 56.544323419883455; v(1) = 37.75922627098413; v(2) = -45.767718603712495; - EXPECT_NEAR(u.dot(v), 1069.8145305211428, 1e-4) << "(u=(-19.41880304735801, 80.15388147841654, 18.762371448279836), v= (56.544323419883455, 37.75922627098413, -45.767718603712495))"; - EXPECT_NEAR(u.norm(), 84.57991020455952, 1e-4) << "(u=(-19.41880304735801, 80.15388147841654, 18.762371448279836))"; - u = v; - EXPECT_NEAR(u.norm(), 81.96159921441485, 1e-4) << "u=(-19.41880304735801, 80.15388147841654, 18.762371448279836)"; - } - { - Vector u; u(0) = 14.53101118226931; u(1) = -87.12123268098249; u(2) = -12.733552633138217; - Vector v; v(0) = -96.36370344463752; v(1) = -81.8797705320039; v(2) = -25.593956628649764; - EXPECT_NEAR(u.dot(v), 6059.106481886422, 1e-4) << "(u=(14.53101118226931, -87.12123268098249, -12.733552633138217), v= (-96.36370344463752, -81.8797705320039, -25.593956628649764))"; - EXPECT_NEAR(u.norm(), 89.23790020217884, 1e-4) << "(u=(14.53101118226931, -87.12123268098249, -12.733552633138217))"; - u = v; - EXPECT_NEAR(u.norm(), 129.01670736710366, 1e-4) << "u=(14.53101118226931, -87.12123268098249, -12.733552633138217)"; - } - { - Vector u; u(0) = -68.15128360202914; u(1) = -35.22142681790423; u(2) = -80.20820520692742; - Vector v; v(0) = -71.59083714955358; v(1) = -22.11220916087268; v(2) = -41.412146034892785; - EXPECT_NEAR(u.dot(v), 8979.424909853704, 1e-4) << "(u=(-68.15128360202914, -35.22142681790423, -80.20820520692742), v= (-71.59083714955358, -22.11220916087268, -41.412146034892785))"; - EXPECT_NEAR(u.norm(), 110.98874963801407, 1e-4) << "(u=(-68.15128360202914, -35.22142681790423, -80.20820520692742))"; - u = v; - EXPECT_NEAR(u.norm(), 85.61053438078382, 1e-4) << "u=(-68.15128360202914, -35.22142681790423, -80.20820520692742)"; - } - { - Vector u; u(0) = 32.15880264107108; u(1) = -27.044272757999167; u(2) = -21.93384224298498; - Vector v; v(0) = 94.98651607465004; v(1) = 96.25601423462368; v(2) = -4.364871517549744; - EXPECT_NEAR(u.dot(v), 547.2171237254174, 1e-4) << "(u=(32.15880264107108, -27.044272757999167, -21.93384224298498), v= (94.98651607465004, 96.25601423462368, -4.364871517549744))"; - EXPECT_NEAR(u.norm(), 47.399100327501664, 1e-4) << "(u=(32.15880264107108, -27.044272757999167, -21.93384224298498))"; - u = v; - EXPECT_NEAR(u.norm(), 135.3022934606082, 1e-4) << "u=(32.15880264107108, -27.044272757999167, -21.93384224298498)"; - } - { - Vector u; u(0) = -38.55884639660741; u(1) = -32.44768663392304; u(2) = -86.51014461651837; - Vector v; v(0) = -32.975270310868936; v(1) = -48.59524328395069; v(2) = -92.16520328196806; - EXPECT_NEAR(u.dot(v), 10821.51667331416, 1e-4) << "(u=(-38.55884639660741, -32.44768663392304, -86.51014461651837), v= (-32.975270310868936, -48.59524328395069, -92.16520328196806))"; - EXPECT_NEAR(u.norm(), 100.1181408382185, 1e-4) << "(u=(-38.55884639660741, -32.44768663392304, -86.51014461651837))"; - u = v; - EXPECT_NEAR(u.norm(), 109.2853641523316, 1e-4) << "u=(-38.55884639660741, -32.44768663392304, -86.51014461651837)"; - } - { - Vector u; u(0) = -93.94403064987613; u(1) = -22.806019440495206; u(2) = -6.186803379242534; - Vector v; v(0) = 99.58719003758503; v(1) = 11.426147026760503; v(2) = 89.17338366240898; - EXPECT_NEAR(u.dot(v), -10167.905155829267, 1e-4) << "(u=(-93.94403064987613, -22.806019440495206, -6.186803379242534), v= (99.58719003758503, 11.426147026760503, 89.17338366240898))"; - EXPECT_NEAR(u.norm(), 96.87038739221866, 1e-4) << "(u=(-93.94403064987613, -22.806019440495206, -6.186803379242534))"; - u = v; - EXPECT_NEAR(u.norm(), 134.1642933468604, 1e-4) << "u=(-93.94403064987613, -22.806019440495206, -6.186803379242534)"; - } - { - Vector u; u(0) = 49.70172009239852; u(1) = 35.23095832735339; u(2) = -95.645812626239; - Vector v; v(0) = -26.17330847186834; v(1) = -13.328976428902024; v(2) = 43.288466758804674; - EXPECT_NEAR(u.dot(v), -5910.811645163534, 1e-4) << "(u=(49.70172009239852, 35.23095832735339, -95.645812626239), v= (-26.17330847186834, -13.328976428902024, 43.288466758804674))"; - EXPECT_NEAR(u.norm(), 113.40018905513546, 1e-4) << "(u=(49.70172009239852, 35.23095832735339, -95.645812626239))"; - u = v; - EXPECT_NEAR(u.norm(), 52.31247502588592, 1e-4) << "u=(49.70172009239852, 35.23095832735339, -95.645812626239)"; - } -} - -// Test les matrice avec redimensionnement dynamique -TEST(TestLabo1a, StaticMatrixTests) -{ - // Crée une matrice à taille fixe - Matrix M; - EXPECT_EQ(M.cols(), 5); - EXPECT_EQ(M.rows(), 3); - - // Redimensionne la matrice (la taille ne doit pas changer). - M.resize(100, 1000); - EXPECT_EQ(M.cols(), 5); - EXPECT_EQ(M.rows(), 3); - - // Test - stockage par colonnes - Matrix ColM; - ColM.setZero(); - ColM(0, 0) = 1.0; - ColM(90, 17) = 99.0; - ColM(10, 33) = 7.2; - EXPECT_EQ(ColM(0, 0), 1.0); - EXPECT_EQ(ColM(90, 17), 99.0); - EXPECT_EQ(ColM(10, 33), 7.2); - - // Test - stockage par lignes - Matrix RowM; - RowM.setZero(); - RowM(0, 0) = 2.1; - RowM(3, 3) = -0.2; - RowM(4, 3) = 1.2; - EXPECT_EQ(RowM.rows(), 5); - EXPECT_EQ(RowM.cols(), 4); - EXPECT_DOUBLE_EQ(RowM(0, 0), 2.1); - EXPECT_DOUBLE_EQ(RowM(3, 3), -0.2); - EXPECT_DOUBLE_EQ(RowM(4, 3), 1.2); - EXPECT_DOUBLE_EQ(RowM(3, 2), 0.0); - - // Transposée - const auto RowMT = RowM.transpose(); - EXPECT_EQ(RowMT.rows(), 4); - EXPECT_EQ(RowMT.cols(), 5); - EXPECT_DOUBLE_EQ(RowMT(0, 0), 2.1); - EXPECT_DOUBLE_EQ(RowMT(3, 3), -0.2); - EXPECT_DOUBLE_EQ(RowMT(3, 4), 1.2); - EXPECT_DOUBLE_EQ(RowMT(2, 3), 0.0); -} - - -// Test les matrice avec redimensionnement dynamique -TEST(TestLabo1a, DynamicMatrixTests) -{ - // Crée une matrice à taille dynamique - // (note : les valeurs par défaut du patron de la classe `Matrix` mettent le - // le nombre de ligne et de colonnes à `Dynamic`) - Matrix M(3, 5); - EXPECT_EQ(M.cols(), 5); - EXPECT_EQ(M.rows(), 3); - - // Redimensionne la matrice - M.resize(100, 1000); - EXPECT_EQ(M.cols(), 1000); - EXPECT_EQ(M.rows(), 100); - - // Test - stockage par colonnes - Matrix ColM(100, 100); - ColM.setZero(); - ColM(0, 0) = 1.0; - ColM(99, 99) = 99.0; - ColM(10, 33) = 5.0; - EXPECT_EQ(ColM(0, 0), 1.0); - EXPECT_EQ(ColM(10, 33), 5.0); - EXPECT_EQ(ColM(99, 99), 99.0); - - // Test - stockage par lignes - Matrix RowM(5, 4); - RowM.setZero(); - RowM(0, 0) = 2.1; - RowM(3, 3) = -0.2; - RowM(4, 3) = 1.2; - EXPECT_EQ(RowM.rows(), 5); - EXPECT_EQ(RowM.cols(), 4); - EXPECT_DOUBLE_EQ(RowM(0, 0), 2.1); - EXPECT_DOUBLE_EQ(RowM(3, 3), -0.2); - EXPECT_DOUBLE_EQ(RowM(4, 3), 1.2); - EXPECT_DOUBLE_EQ(RowM(3, 2), 0.0); - - // Transposée - const auto RowMT = RowM.transpose(); - EXPECT_EQ(RowMT.rows(), 4); - EXPECT_EQ(RowMT.cols(), 5); - EXPECT_DOUBLE_EQ(RowMT(0, 0), 2.1); - EXPECT_DOUBLE_EQ(RowMT(3, 3), -0.2); - EXPECT_DOUBLE_EQ(RowMT(3, 4), 1.2); - EXPECT_DOUBLE_EQ(RowMT(2, 3), 0.0); -} - -/** - * Test pour les vecteurs à taille dynamique - */ -TEST(TestLabo1a, DynamicVectorSizeTest) -{ - Vector v(5); - v.setZero(); - - EXPECT_EQ(v.rows(), 5); - - v.resize(3); - EXPECT_EQ(v.rows(), 3); - - v(0) = 1.0; - v(1) = 2.0; - v(2) = 3.0; - - EXPECT_DOUBLE_EQ(v.norm(), 3.7416573867739413855837487323165); - - Vector v2(3); - v2.setZero(); - v2(1) = 2.0; - - EXPECT_DOUBLE_EQ(v2.dot(v), 4.0); - EXPECT_DOUBLE_EQ(v2(0), 0.0); - EXPECT_DOUBLE_EQ(v2(1), 2.0); - EXPECT_DOUBLE_EQ(v2(2), 0.0); -} - -TEST(TestLabo1a, Transpose) { - { - Matrix m; m.resize(3, 2); - m(0, 0) = 96.65562704596559; m(0, 1) = -5.374125981819006; m(1, 0) = 64.81364389648456; m(1, 1) = -69.97868420900502; m(2, 0) = -48.298014749653696; m(2, 1) = 81.5535983882881; - Matrix mtr = m.transpose(); - EXPECT_DOUBLE_EQ(mtr(0, 0), 96.65562704596559); EXPECT_DOUBLE_EQ(mtr(0, 1), 64.81364389648456); EXPECT_DOUBLE_EQ(mtr(0, 2), -48.298014749653696); EXPECT_DOUBLE_EQ(mtr(1, 0), -5.374125981819006); EXPECT_DOUBLE_EQ(mtr(1, 1), -69.97868420900502); EXPECT_DOUBLE_EQ(mtr(1, 2), 81.5535983882881); - Matrix mtc = m.transpose(); - EXPECT_DOUBLE_EQ(mtc(0, 0), 96.65562704596559); EXPECT_DOUBLE_EQ(mtc(0, 1), 64.81364389648456); EXPECT_DOUBLE_EQ(mtc(0, 2), -48.298014749653696); EXPECT_DOUBLE_EQ(mtc(1, 0), -5.374125981819006); EXPECT_DOUBLE_EQ(mtc(1, 1), -69.97868420900502); EXPECT_DOUBLE_EQ(mtc(1, 2), 81.5535983882881); - } - { - Matrix m; m.resize(3, 11); - m(0, 0) = -93.11774348806081; m(0, 1) = -98.38480859022877; m(0, 2) = -70.06261616604155; m(0, 3) = 84.87535684986423; m(0, 4) = -99.9818642210925; m(0, 5) = -25.11185567441916; m(0, 6) = 8.85590979917103; m(0, 7) = 32.717509759851936; m(0, 8) = 12.677927494307738; m(0, 9) = -76.92757015087707; m(0, 10) = -80.99502606313347; m(1, 0) = -14.108330840223957; m(1, 1) = -94.81883611699344; m(1, 2) = -45.060719301725285; m(1, 3) = -41.383939879963094; m(1, 4) = 80.36741308691853; m(1, 5) = -87.50961508738959; m(1, 6) = -32.65290161505921; m(1, 7) = 18.529868291798238; m(1, 8) = -46.169755352790595; m(1, 9) = 83.67078184672366; m(1, 10) = -30.02053885691531; m(2, 0) = 5.8022044043901815; m(2, 1) = -39.507965223996266; m(2, 2) = 38.099939917456425; m(2, 3) = -11.891042873050296; m(2, 4) = 53.89070563872062; m(2, 5) = 23.280098882479578; m(2, 6) = -5.0318917624474295; m(2, 7) = 31.50255873280196; m(2, 8) = 22.629046207699318; m(2, 9) = 3.5102931218199416; m(2, 10) = -95.03021938861154; - Matrix mtr = m.transpose(); - EXPECT_DOUBLE_EQ(mtr(0, 0), -93.11774348806081); EXPECT_DOUBLE_EQ(mtr(0, 1), -14.108330840223957); EXPECT_DOUBLE_EQ(mtr(0, 2), 5.8022044043901815); EXPECT_DOUBLE_EQ(mtr(1, 0), -98.38480859022877); EXPECT_DOUBLE_EQ(mtr(1, 1), -94.81883611699344); EXPECT_DOUBLE_EQ(mtr(1, 2), -39.507965223996266); EXPECT_DOUBLE_EQ(mtr(2, 0), -70.06261616604155); EXPECT_DOUBLE_EQ(mtr(2, 1), -45.060719301725285); EXPECT_DOUBLE_EQ(mtr(2, 2), 38.099939917456425); EXPECT_DOUBLE_EQ(mtr(3, 0), 84.87535684986423); EXPECT_DOUBLE_EQ(mtr(3, 1), -41.383939879963094); EXPECT_DOUBLE_EQ(mtr(3, 2), -11.891042873050296); EXPECT_DOUBLE_EQ(mtr(4, 0), -99.9818642210925); EXPECT_DOUBLE_EQ(mtr(4, 1), 80.36741308691853); EXPECT_DOUBLE_EQ(mtr(4, 2), 53.89070563872062); EXPECT_DOUBLE_EQ(mtr(5, 0), -25.11185567441916); EXPECT_DOUBLE_EQ(mtr(5, 1), -87.50961508738959); EXPECT_DOUBLE_EQ(mtr(5, 2), 23.280098882479578); EXPECT_DOUBLE_EQ(mtr(6, 0), 8.85590979917103); EXPECT_DOUBLE_EQ(mtr(6, 1), -32.65290161505921); EXPECT_DOUBLE_EQ(mtr(6, 2), -5.0318917624474295); EXPECT_DOUBLE_EQ(mtr(7, 0), 32.717509759851936); EXPECT_DOUBLE_EQ(mtr(7, 1), 18.529868291798238); EXPECT_DOUBLE_EQ(mtr(7, 2), 31.50255873280196); EXPECT_DOUBLE_EQ(mtr(8, 0), 12.677927494307738); EXPECT_DOUBLE_EQ(mtr(8, 1), -46.169755352790595); EXPECT_DOUBLE_EQ(mtr(8, 2), 22.629046207699318); EXPECT_DOUBLE_EQ(mtr(9, 0), -76.92757015087707); EXPECT_DOUBLE_EQ(mtr(9, 1), 83.67078184672366); EXPECT_DOUBLE_EQ(mtr(9, 2), 3.5102931218199416); EXPECT_DOUBLE_EQ(mtr(10, 0), -80.99502606313347); EXPECT_DOUBLE_EQ(mtr(10, 1), -30.02053885691531); EXPECT_DOUBLE_EQ(mtr(10, 2), -95.03021938861154); - Matrix mtc = m.transpose(); - EXPECT_DOUBLE_EQ(mtc(0, 0), -93.11774348806081); EXPECT_DOUBLE_EQ(mtc(0, 1), -14.108330840223957); EXPECT_DOUBLE_EQ(mtc(0, 2), 5.8022044043901815); EXPECT_DOUBLE_EQ(mtc(1, 0), -98.38480859022877); EXPECT_DOUBLE_EQ(mtc(1, 1), -94.81883611699344); EXPECT_DOUBLE_EQ(mtc(1, 2), -39.507965223996266); EXPECT_DOUBLE_EQ(mtc(2, 0), -70.06261616604155); EXPECT_DOUBLE_EQ(mtc(2, 1), -45.060719301725285); EXPECT_DOUBLE_EQ(mtc(2, 2), 38.099939917456425); EXPECT_DOUBLE_EQ(mtc(3, 0), 84.87535684986423); EXPECT_DOUBLE_EQ(mtc(3, 1), -41.383939879963094); EXPECT_DOUBLE_EQ(mtc(3, 2), -11.891042873050296); EXPECT_DOUBLE_EQ(mtc(4, 0), -99.9818642210925); EXPECT_DOUBLE_EQ(mtc(4, 1), 80.36741308691853); EXPECT_DOUBLE_EQ(mtc(4, 2), 53.89070563872062); EXPECT_DOUBLE_EQ(mtc(5, 0), -25.11185567441916); EXPECT_DOUBLE_EQ(mtc(5, 1), -87.50961508738959); EXPECT_DOUBLE_EQ(mtc(5, 2), 23.280098882479578); EXPECT_DOUBLE_EQ(mtc(6, 0), 8.85590979917103); EXPECT_DOUBLE_EQ(mtc(6, 1), -32.65290161505921); EXPECT_DOUBLE_EQ(mtc(6, 2), -5.0318917624474295); EXPECT_DOUBLE_EQ(mtc(7, 0), 32.717509759851936); EXPECT_DOUBLE_EQ(mtc(7, 1), 18.529868291798238); EXPECT_DOUBLE_EQ(mtc(7, 2), 31.50255873280196); EXPECT_DOUBLE_EQ(mtc(8, 0), 12.677927494307738); EXPECT_DOUBLE_EQ(mtc(8, 1), -46.169755352790595); EXPECT_DOUBLE_EQ(mtc(8, 2), 22.629046207699318); EXPECT_DOUBLE_EQ(mtc(9, 0), -76.92757015087707); EXPECT_DOUBLE_EQ(mtc(9, 1), 83.67078184672366); EXPECT_DOUBLE_EQ(mtc(9, 2), 3.5102931218199416); EXPECT_DOUBLE_EQ(mtc(10, 0), -80.99502606313347); EXPECT_DOUBLE_EQ(mtc(10, 1), -30.02053885691531); EXPECT_DOUBLE_EQ(mtc(10, 2), -95.03021938861154); - } - { - Matrix m; m.resize(3, 19); - m(0, 0) = 50.864090811708934; m(0, 1) = 86.72545584739655; m(0, 2) = -59.41096188367827; m(0, 3) = -81.01855448213378; m(0, 4) = -44.75527142333435; m(0, 5) = 6.881484559867502; m(0, 6) = 75.66386662485408; m(0, 7) = -56.002568995946575; m(0, 8) = -44.600865729883445; m(0, 9) = -18.413408652944696; m(0, 10) = -97.11569037525811; m(0, 11) = 53.19666636708692; m(0, 12) = -64.58909530248837; m(0, 13) = -13.336152508799714; m(0, 14) = -69.12350514623267; m(0, 15) = 56.52730125536351; m(0, 16) = 89.92552663330136; m(0, 17) = 94.33106257780301; m(0, 18) = 76.55814809986282; m(1, 0) = 14.747374583026797; m(1, 1) = -12.087041962746213; m(1, 2) = -63.3966872965287; m(1, 3) = -11.386504830855642; m(1, 4) = -76.29669292020178; m(1, 5) = -66.38097797841678; m(1, 6) = -20.191218640024687; m(1, 7) = -48.05245125934678; m(1, 8) = -83.87380388512868; m(1, 9) = -21.25569067138788; m(1, 10) = 4.889708648539596; m(1, 11) = -85.80217867074691; m(1, 12) = -85.26796006798745; m(1, 13) = 3.8169098134350605; m(1, 14) = 73.4920467291056; m(1, 15) = 98.24187210950205; m(1, 16) = -9.878913280704495; m(1, 17) = -63.027946780158196; m(1, 18) = 55.64310458734482; m(2, 0) = -75.20410363410058; m(2, 1) = 45.30781974344674; m(2, 2) = -43.85391331821933; m(2, 3) = 67.45134132003074; m(2, 4) = 55.35009554124747; m(2, 5) = -24.1599830304106; m(2, 6) = 89.85022708733555; m(2, 7) = 63.770995127367826; m(2, 8) = -7.388429976036122; m(2, 9) = 8.073425560498507; m(2, 10) = 76.76129649290999; m(2, 11) = -50.19697292034915; m(2, 12) = -25.310526646715076; m(2, 13) = 14.496228473119118; m(2, 14) = 46.35572803496012; m(2, 15) = -43.2905212948518; m(2, 16) = 72.28250601709692; m(2, 17) = 59.72857548888601; m(2, 18) = 39.776820197984875; - Matrix mtr = m.transpose(); - EXPECT_DOUBLE_EQ(mtr(0, 0), 50.864090811708934); EXPECT_DOUBLE_EQ(mtr(0, 1), 14.747374583026797); EXPECT_DOUBLE_EQ(mtr(0, 2), -75.20410363410058); EXPECT_DOUBLE_EQ(mtr(1, 0), 86.72545584739655); EXPECT_DOUBLE_EQ(mtr(1, 1), -12.087041962746213); EXPECT_DOUBLE_EQ(mtr(1, 2), 45.30781974344674); EXPECT_DOUBLE_EQ(mtr(2, 0), -59.41096188367827); EXPECT_DOUBLE_EQ(mtr(2, 1), -63.3966872965287); EXPECT_DOUBLE_EQ(mtr(2, 2), -43.85391331821933); EXPECT_DOUBLE_EQ(mtr(3, 0), -81.01855448213378); EXPECT_DOUBLE_EQ(mtr(3, 1), -11.386504830855642); EXPECT_DOUBLE_EQ(mtr(3, 2), 67.45134132003074); EXPECT_DOUBLE_EQ(mtr(4, 0), -44.75527142333435); EXPECT_DOUBLE_EQ(mtr(4, 1), -76.29669292020178); EXPECT_DOUBLE_EQ(mtr(4, 2), 55.35009554124747); EXPECT_DOUBLE_EQ(mtr(5, 0), 6.881484559867502); EXPECT_DOUBLE_EQ(mtr(5, 1), -66.38097797841678); EXPECT_DOUBLE_EQ(mtr(5, 2), -24.1599830304106); EXPECT_DOUBLE_EQ(mtr(6, 0), 75.66386662485408); EXPECT_DOUBLE_EQ(mtr(6, 1), -20.191218640024687); EXPECT_DOUBLE_EQ(mtr(6, 2), 89.85022708733555); EXPECT_DOUBLE_EQ(mtr(7, 0), -56.002568995946575); EXPECT_DOUBLE_EQ(mtr(7, 1), -48.05245125934678); EXPECT_DOUBLE_EQ(mtr(7, 2), 63.770995127367826); EXPECT_DOUBLE_EQ(mtr(8, 0), -44.600865729883445); EXPECT_DOUBLE_EQ(mtr(8, 1), -83.87380388512868); EXPECT_DOUBLE_EQ(mtr(8, 2), -7.388429976036122); EXPECT_DOUBLE_EQ(mtr(9, 0), -18.413408652944696); EXPECT_DOUBLE_EQ(mtr(9, 1), -21.25569067138788); EXPECT_DOUBLE_EQ(mtr(9, 2), 8.073425560498507); EXPECT_DOUBLE_EQ(mtr(10, 0), -97.11569037525811); EXPECT_DOUBLE_EQ(mtr(10, 1), 4.889708648539596); EXPECT_DOUBLE_EQ(mtr(10, 2), 76.76129649290999); EXPECT_DOUBLE_EQ(mtr(11, 0), 53.19666636708692); EXPECT_DOUBLE_EQ(mtr(11, 1), -85.80217867074691); EXPECT_DOUBLE_EQ(mtr(11, 2), -50.19697292034915); EXPECT_DOUBLE_EQ(mtr(12, 0), -64.58909530248837); EXPECT_DOUBLE_EQ(mtr(12, 1), -85.26796006798745); EXPECT_DOUBLE_EQ(mtr(12, 2), -25.310526646715076); EXPECT_DOUBLE_EQ(mtr(13, 0), -13.336152508799714); EXPECT_DOUBLE_EQ(mtr(13, 1), 3.8169098134350605); EXPECT_DOUBLE_EQ(mtr(13, 2), 14.496228473119118); EXPECT_DOUBLE_EQ(mtr(14, 0), -69.12350514623267); EXPECT_DOUBLE_EQ(mtr(14, 1), 73.4920467291056); EXPECT_DOUBLE_EQ(mtr(14, 2), 46.35572803496012); EXPECT_DOUBLE_EQ(mtr(15, 0), 56.52730125536351); EXPECT_DOUBLE_EQ(mtr(15, 1), 98.24187210950205); EXPECT_DOUBLE_EQ(mtr(15, 2), -43.2905212948518); EXPECT_DOUBLE_EQ(mtr(16, 0), 89.92552663330136); EXPECT_DOUBLE_EQ(mtr(16, 1), -9.878913280704495); EXPECT_DOUBLE_EQ(mtr(16, 2), 72.28250601709692); EXPECT_DOUBLE_EQ(mtr(17, 0), 94.33106257780301); EXPECT_DOUBLE_EQ(mtr(17, 1), -63.027946780158196); EXPECT_DOUBLE_EQ(mtr(17, 2), 59.72857548888601); EXPECT_DOUBLE_EQ(mtr(18, 0), 76.55814809986282); EXPECT_DOUBLE_EQ(mtr(18, 1), 55.64310458734482); EXPECT_DOUBLE_EQ(mtr(18, 2), 39.776820197984875); - Matrix mtc = m.transpose(); - EXPECT_DOUBLE_EQ(mtc(0, 0), 50.864090811708934); EXPECT_DOUBLE_EQ(mtc(0, 1), 14.747374583026797); EXPECT_DOUBLE_EQ(mtc(0, 2), -75.20410363410058); EXPECT_DOUBLE_EQ(mtc(1, 0), 86.72545584739655); EXPECT_DOUBLE_EQ(mtc(1, 1), -12.087041962746213); EXPECT_DOUBLE_EQ(mtc(1, 2), 45.30781974344674); EXPECT_DOUBLE_EQ(mtc(2, 0), -59.41096188367827); EXPECT_DOUBLE_EQ(mtc(2, 1), -63.3966872965287); EXPECT_DOUBLE_EQ(mtc(2, 2), -43.85391331821933); EXPECT_DOUBLE_EQ(mtc(3, 0), -81.01855448213378); EXPECT_DOUBLE_EQ(mtc(3, 1), -11.386504830855642); EXPECT_DOUBLE_EQ(mtc(3, 2), 67.45134132003074); EXPECT_DOUBLE_EQ(mtc(4, 0), -44.75527142333435); EXPECT_DOUBLE_EQ(mtc(4, 1), -76.29669292020178); EXPECT_DOUBLE_EQ(mtc(4, 2), 55.35009554124747); EXPECT_DOUBLE_EQ(mtc(5, 0), 6.881484559867502); EXPECT_DOUBLE_EQ(mtc(5, 1), -66.38097797841678); EXPECT_DOUBLE_EQ(mtc(5, 2), -24.1599830304106); EXPECT_DOUBLE_EQ(mtc(6, 0), 75.66386662485408); EXPECT_DOUBLE_EQ(mtc(6, 1), -20.191218640024687); EXPECT_DOUBLE_EQ(mtc(6, 2), 89.85022708733555); EXPECT_DOUBLE_EQ(mtc(7, 0), -56.002568995946575); EXPECT_DOUBLE_EQ(mtc(7, 1), -48.05245125934678); EXPECT_DOUBLE_EQ(mtc(7, 2), 63.770995127367826); EXPECT_DOUBLE_EQ(mtc(8, 0), -44.600865729883445); EXPECT_DOUBLE_EQ(mtc(8, 1), -83.87380388512868); EXPECT_DOUBLE_EQ(mtc(8, 2), -7.388429976036122); EXPECT_DOUBLE_EQ(mtc(9, 0), -18.413408652944696); EXPECT_DOUBLE_EQ(mtc(9, 1), -21.25569067138788); EXPECT_DOUBLE_EQ(mtc(9, 2), 8.073425560498507); EXPECT_DOUBLE_EQ(mtc(10, 0), -97.11569037525811); EXPECT_DOUBLE_EQ(mtc(10, 1), 4.889708648539596); EXPECT_DOUBLE_EQ(mtc(10, 2), 76.76129649290999); EXPECT_DOUBLE_EQ(mtc(11, 0), 53.19666636708692); EXPECT_DOUBLE_EQ(mtc(11, 1), -85.80217867074691); EXPECT_DOUBLE_EQ(mtc(11, 2), -50.19697292034915); EXPECT_DOUBLE_EQ(mtc(12, 0), -64.58909530248837); EXPECT_DOUBLE_EQ(mtc(12, 1), -85.26796006798745); EXPECT_DOUBLE_EQ(mtc(12, 2), -25.310526646715076); EXPECT_DOUBLE_EQ(mtc(13, 0), -13.336152508799714); EXPECT_DOUBLE_EQ(mtc(13, 1), 3.8169098134350605); EXPECT_DOUBLE_EQ(mtc(13, 2), 14.496228473119118); EXPECT_DOUBLE_EQ(mtc(14, 0), -69.12350514623267); EXPECT_DOUBLE_EQ(mtc(14, 1), 73.4920467291056); EXPECT_DOUBLE_EQ(mtc(14, 2), 46.35572803496012); EXPECT_DOUBLE_EQ(mtc(15, 0), 56.52730125536351); EXPECT_DOUBLE_EQ(mtc(15, 1), 98.24187210950205); EXPECT_DOUBLE_EQ(mtc(15, 2), -43.2905212948518); EXPECT_DOUBLE_EQ(mtc(16, 0), 89.92552663330136); EXPECT_DOUBLE_EQ(mtc(16, 1), -9.878913280704495); EXPECT_DOUBLE_EQ(mtc(16, 2), 72.28250601709692); EXPECT_DOUBLE_EQ(mtc(17, 0), 94.33106257780301); EXPECT_DOUBLE_EQ(mtc(17, 1), -63.027946780158196); EXPECT_DOUBLE_EQ(mtc(17, 2), 59.72857548888601); EXPECT_DOUBLE_EQ(mtc(18, 0), 76.55814809986282); EXPECT_DOUBLE_EQ(mtc(18, 1), 55.64310458734482); EXPECT_DOUBLE_EQ(mtc(18, 2), 39.776820197984875); - } - { - Matrix m; m.resize(3, 12); - m(0, 0) = -32.75375661346618; m(0, 1) = -13.6098421772042; m(0, 2) = -46.86521220477553; m(0, 3) = 59.00702831249865; m(0, 4) = -4.564740481250126; m(0, 5) = 16.232920948792312; m(0, 6) = -65.0828541930055; m(0, 7) = -57.88248367433246; m(0, 8) = -81.72734394349992; m(0, 9) = 28.080964462881383; m(0, 10) = 36.6937632974539; m(0, 11) = 41.35837714070166; m(1, 0) = -47.68004182743719; m(1, 1) = -64.19046526329765; m(1, 2) = -75.66374889412242; m(1, 3) = -82.35155489863575; m(1, 4) = -75.40948179339736; m(1, 5) = -21.839837867220055; m(1, 6) = -7.047883213897393; m(1, 7) = -28.576424866142986; m(1, 8) = 36.45450614900494; m(1, 9) = -9.122226758045997; m(1, 10) = 39.94779111587877; m(1, 11) = 9.684112064820866; m(2, 0) = 34.000255287178476; m(2, 1) = 64.99966038549962; m(2, 2) = -11.973673265362649; m(2, 3) = 80.2812674443403; m(2, 4) = 95.91223898270886; m(2, 5) = -27.634369350449873; m(2, 6) = -75.21066302899243; m(2, 7) = -20.700089950120855; m(2, 8) = 86.68513293601455; m(2, 9) = 75.43854998281424; m(2, 10) = -88.06922362937304; m(2, 11) = -92.34886576586136; - Matrix mtr = m.transpose(); - EXPECT_DOUBLE_EQ(mtr(0, 0), -32.75375661346618); EXPECT_DOUBLE_EQ(mtr(0, 1), -47.68004182743719); EXPECT_DOUBLE_EQ(mtr(0, 2), 34.000255287178476); EXPECT_DOUBLE_EQ(mtr(1, 0), -13.6098421772042); EXPECT_DOUBLE_EQ(mtr(1, 1), -64.19046526329765); EXPECT_DOUBLE_EQ(mtr(1, 2), 64.99966038549962); EXPECT_DOUBLE_EQ(mtr(2, 0), -46.86521220477553); EXPECT_DOUBLE_EQ(mtr(2, 1), -75.66374889412242); EXPECT_DOUBLE_EQ(mtr(2, 2), -11.973673265362649); EXPECT_DOUBLE_EQ(mtr(3, 0), 59.00702831249865); EXPECT_DOUBLE_EQ(mtr(3, 1), -82.35155489863575); EXPECT_DOUBLE_EQ(mtr(3, 2), 80.2812674443403); EXPECT_DOUBLE_EQ(mtr(4, 0), -4.564740481250126); EXPECT_DOUBLE_EQ(mtr(4, 1), -75.40948179339736); EXPECT_DOUBLE_EQ(mtr(4, 2), 95.91223898270886); EXPECT_DOUBLE_EQ(mtr(5, 0), 16.232920948792312); EXPECT_DOUBLE_EQ(mtr(5, 1), -21.839837867220055); EXPECT_DOUBLE_EQ(mtr(5, 2), -27.634369350449873); EXPECT_DOUBLE_EQ(mtr(6, 0), -65.0828541930055); EXPECT_DOUBLE_EQ(mtr(6, 1), -7.047883213897393); EXPECT_DOUBLE_EQ(mtr(6, 2), -75.21066302899243); EXPECT_DOUBLE_EQ(mtr(7, 0), -57.88248367433246); EXPECT_DOUBLE_EQ(mtr(7, 1), -28.576424866142986); EXPECT_DOUBLE_EQ(mtr(7, 2), -20.700089950120855); EXPECT_DOUBLE_EQ(mtr(8, 0), -81.72734394349992); EXPECT_DOUBLE_EQ(mtr(8, 1), 36.45450614900494); EXPECT_DOUBLE_EQ(mtr(8, 2), 86.68513293601455); EXPECT_DOUBLE_EQ(mtr(9, 0), 28.080964462881383); EXPECT_DOUBLE_EQ(mtr(9, 1), -9.122226758045997); EXPECT_DOUBLE_EQ(mtr(9, 2), 75.43854998281424); EXPECT_DOUBLE_EQ(mtr(10, 0), 36.6937632974539); EXPECT_DOUBLE_EQ(mtr(10, 1), 39.94779111587877); EXPECT_DOUBLE_EQ(mtr(10, 2), -88.06922362937304); EXPECT_DOUBLE_EQ(mtr(11, 0), 41.35837714070166); EXPECT_DOUBLE_EQ(mtr(11, 1), 9.684112064820866); EXPECT_DOUBLE_EQ(mtr(11, 2), -92.34886576586136); - Matrix mtc = m.transpose(); - EXPECT_DOUBLE_EQ(mtc(0, 0), -32.75375661346618); EXPECT_DOUBLE_EQ(mtc(0, 1), -47.68004182743719); EXPECT_DOUBLE_EQ(mtc(0, 2), 34.000255287178476); EXPECT_DOUBLE_EQ(mtc(1, 0), -13.6098421772042); EXPECT_DOUBLE_EQ(mtc(1, 1), -64.19046526329765); EXPECT_DOUBLE_EQ(mtc(1, 2), 64.99966038549962); EXPECT_DOUBLE_EQ(mtc(2, 0), -46.86521220477553); EXPECT_DOUBLE_EQ(mtc(2, 1), -75.66374889412242); EXPECT_DOUBLE_EQ(mtc(2, 2), -11.973673265362649); EXPECT_DOUBLE_EQ(mtc(3, 0), 59.00702831249865); EXPECT_DOUBLE_EQ(mtc(3, 1), -82.35155489863575); EXPECT_DOUBLE_EQ(mtc(3, 2), 80.2812674443403); EXPECT_DOUBLE_EQ(mtc(4, 0), -4.564740481250126); EXPECT_DOUBLE_EQ(mtc(4, 1), -75.40948179339736); EXPECT_DOUBLE_EQ(mtc(4, 2), 95.91223898270886); EXPECT_DOUBLE_EQ(mtc(5, 0), 16.232920948792312); EXPECT_DOUBLE_EQ(mtc(5, 1), -21.839837867220055); EXPECT_DOUBLE_EQ(mtc(5, 2), -27.634369350449873); EXPECT_DOUBLE_EQ(mtc(6, 0), -65.0828541930055); EXPECT_DOUBLE_EQ(mtc(6, 1), -7.047883213897393); EXPECT_DOUBLE_EQ(mtc(6, 2), -75.21066302899243); EXPECT_DOUBLE_EQ(mtc(7, 0), -57.88248367433246); EXPECT_DOUBLE_EQ(mtc(7, 1), -28.576424866142986); EXPECT_DOUBLE_EQ(mtc(7, 2), -20.700089950120855); EXPECT_DOUBLE_EQ(mtc(8, 0), -81.72734394349992); EXPECT_DOUBLE_EQ(mtc(8, 1), 36.45450614900494); EXPECT_DOUBLE_EQ(mtc(8, 2), 86.68513293601455); EXPECT_DOUBLE_EQ(mtc(9, 0), 28.080964462881383); EXPECT_DOUBLE_EQ(mtc(9, 1), -9.122226758045997); EXPECT_DOUBLE_EQ(mtc(9, 2), 75.43854998281424); EXPECT_DOUBLE_EQ(mtc(10, 0), 36.6937632974539); EXPECT_DOUBLE_EQ(mtc(10, 1), 39.94779111587877); EXPECT_DOUBLE_EQ(mtc(10, 2), -88.06922362937304); EXPECT_DOUBLE_EQ(mtc(11, 0), 41.35837714070166); EXPECT_DOUBLE_EQ(mtc(11, 1), 9.684112064820866); EXPECT_DOUBLE_EQ(mtc(11, 2), -92.34886576586136); - } - { - Matrix m; m.resize(3, 17); - m(0, 0) = 41.19222807334356; m(0, 1) = -9.647827035990119; m(0, 2) = 79.08578232010518; m(0, 3) = -81.30050511004372; m(0, 4) = 5.2008331502779725; m(0, 5) = -94.16930980955891; m(0, 6) = -13.738166181380976; m(0, 7) = 31.708028058804274; m(0, 8) = -98.07812519655093; m(0, 9) = -51.718134217817926; m(0, 10) = -81.49405897174573; m(0, 11) = 86.09136014594006; m(0, 12) = -23.14506976740256; m(0, 13) = 76.3616884219812; m(0, 14) = 60.28344358729666; m(0, 15) = -35.34123633864937; m(0, 16) = -87.33936780992902; m(1, 0) = 25.563530352835954; m(1, 1) = -43.62388501728416; m(1, 2) = 0.5379451108277209; m(1, 3) = 40.11963964000961; m(1, 4) = -63.945471933511236; m(1, 5) = 25.47334071885645; m(1, 6) = 20.998951793092573; m(1, 7) = 23.964236092014318; m(1, 8) = -53.69611952912465; m(1, 9) = -48.45849352784126; m(1, 10) = 0.03386109792266723; m(1, 11) = -43.90344163766924; m(1, 12) = -6.698621092523396; m(1, 13) = -99.37831178796779; m(1, 14) = -9.64088536276411; m(1, 15) = 3.118955974716698; m(1, 16) = -81.5481380106742; m(2, 0) = 62.07279507925867; m(2, 1) = 90.29145840318458; m(2, 2) = -25.71415288702252; m(2, 3) = 74.7395459171091; m(2, 4) = 24.394997421168824; m(2, 5) = -58.2301634354434; m(2, 6) = -4.768291835922895; m(2, 7) = 49.704487303266575; m(2, 8) = 18.65157355854312; m(2, 9) = 98.9073219636636; m(2, 10) = -45.19000115648366; m(2, 11) = -45.249286237965315; m(2, 12) = 97.09143831741096; m(2, 13) = -31.80834068260583; m(2, 14) = -78.03982967131924; m(2, 15) = -14.844621355572116; m(2, 16) = -66.64707457523824; - Matrix mtr = m.transpose(); - EXPECT_DOUBLE_EQ(mtr(0, 0), 41.19222807334356); EXPECT_DOUBLE_EQ(mtr(0, 1), 25.563530352835954); EXPECT_DOUBLE_EQ(mtr(0, 2), 62.07279507925867); EXPECT_DOUBLE_EQ(mtr(1, 0), -9.647827035990119); EXPECT_DOUBLE_EQ(mtr(1, 1), -43.62388501728416); EXPECT_DOUBLE_EQ(mtr(1, 2), 90.29145840318458); EXPECT_DOUBLE_EQ(mtr(2, 0), 79.08578232010518); EXPECT_DOUBLE_EQ(mtr(2, 1), 0.5379451108277209); EXPECT_DOUBLE_EQ(mtr(2, 2), -25.71415288702252); EXPECT_DOUBLE_EQ(mtr(3, 0), -81.30050511004372); EXPECT_DOUBLE_EQ(mtr(3, 1), 40.11963964000961); EXPECT_DOUBLE_EQ(mtr(3, 2), 74.7395459171091); EXPECT_DOUBLE_EQ(mtr(4, 0), 5.2008331502779725); EXPECT_DOUBLE_EQ(mtr(4, 1), -63.945471933511236); EXPECT_DOUBLE_EQ(mtr(4, 2), 24.394997421168824); EXPECT_DOUBLE_EQ(mtr(5, 0), -94.16930980955891); EXPECT_DOUBLE_EQ(mtr(5, 1), 25.47334071885645); EXPECT_DOUBLE_EQ(mtr(5, 2), -58.2301634354434); EXPECT_DOUBLE_EQ(mtr(6, 0), -13.738166181380976); EXPECT_DOUBLE_EQ(mtr(6, 1), 20.998951793092573); EXPECT_DOUBLE_EQ(mtr(6, 2), -4.768291835922895); EXPECT_DOUBLE_EQ(mtr(7, 0), 31.708028058804274); EXPECT_DOUBLE_EQ(mtr(7, 1), 23.964236092014318); EXPECT_DOUBLE_EQ(mtr(7, 2), 49.704487303266575); EXPECT_DOUBLE_EQ(mtr(8, 0), -98.07812519655093); EXPECT_DOUBLE_EQ(mtr(8, 1), -53.69611952912465); EXPECT_DOUBLE_EQ(mtr(8, 2), 18.65157355854312); EXPECT_DOUBLE_EQ(mtr(9, 0), -51.718134217817926); EXPECT_DOUBLE_EQ(mtr(9, 1), -48.45849352784126); EXPECT_DOUBLE_EQ(mtr(9, 2), 98.9073219636636); EXPECT_DOUBLE_EQ(mtr(10, 0), -81.49405897174573); EXPECT_DOUBLE_EQ(mtr(10, 1), 0.03386109792266723); EXPECT_DOUBLE_EQ(mtr(10, 2), -45.19000115648366); EXPECT_DOUBLE_EQ(mtr(11, 0), 86.09136014594006); EXPECT_DOUBLE_EQ(mtr(11, 1), -43.90344163766924); EXPECT_DOUBLE_EQ(mtr(11, 2), -45.249286237965315); EXPECT_DOUBLE_EQ(mtr(12, 0), -23.14506976740256); EXPECT_DOUBLE_EQ(mtr(12, 1), -6.698621092523396); EXPECT_DOUBLE_EQ(mtr(12, 2), 97.09143831741096); EXPECT_DOUBLE_EQ(mtr(13, 0), 76.3616884219812); EXPECT_DOUBLE_EQ(mtr(13, 1), -99.37831178796779); EXPECT_DOUBLE_EQ(mtr(13, 2), -31.80834068260583); EXPECT_DOUBLE_EQ(mtr(14, 0), 60.28344358729666); EXPECT_DOUBLE_EQ(mtr(14, 1), -9.64088536276411); EXPECT_DOUBLE_EQ(mtr(14, 2), -78.03982967131924); EXPECT_DOUBLE_EQ(mtr(15, 0), -35.34123633864937); EXPECT_DOUBLE_EQ(mtr(15, 1), 3.118955974716698); EXPECT_DOUBLE_EQ(mtr(15, 2), -14.844621355572116); EXPECT_DOUBLE_EQ(mtr(16, 0), -87.33936780992902); EXPECT_DOUBLE_EQ(mtr(16, 1), -81.5481380106742); EXPECT_DOUBLE_EQ(mtr(16, 2), -66.64707457523824); - Matrix mtc = m.transpose(); - EXPECT_DOUBLE_EQ(mtc(0, 0), 41.19222807334356); EXPECT_DOUBLE_EQ(mtc(0, 1), 25.563530352835954); EXPECT_DOUBLE_EQ(mtc(0, 2), 62.07279507925867); EXPECT_DOUBLE_EQ(mtc(1, 0), -9.647827035990119); EXPECT_DOUBLE_EQ(mtc(1, 1), -43.62388501728416); EXPECT_DOUBLE_EQ(mtc(1, 2), 90.29145840318458); EXPECT_DOUBLE_EQ(mtc(2, 0), 79.08578232010518); EXPECT_DOUBLE_EQ(mtc(2, 1), 0.5379451108277209); EXPECT_DOUBLE_EQ(mtc(2, 2), -25.71415288702252); EXPECT_DOUBLE_EQ(mtc(3, 0), -81.30050511004372); EXPECT_DOUBLE_EQ(mtc(3, 1), 40.11963964000961); EXPECT_DOUBLE_EQ(mtc(3, 2), 74.7395459171091); EXPECT_DOUBLE_EQ(mtc(4, 0), 5.2008331502779725); EXPECT_DOUBLE_EQ(mtc(4, 1), -63.945471933511236); EXPECT_DOUBLE_EQ(mtc(4, 2), 24.394997421168824); EXPECT_DOUBLE_EQ(mtc(5, 0), -94.16930980955891); EXPECT_DOUBLE_EQ(mtc(5, 1), 25.47334071885645); EXPECT_DOUBLE_EQ(mtc(5, 2), -58.2301634354434); EXPECT_DOUBLE_EQ(mtc(6, 0), -13.738166181380976); EXPECT_DOUBLE_EQ(mtc(6, 1), 20.998951793092573); EXPECT_DOUBLE_EQ(mtc(6, 2), -4.768291835922895); EXPECT_DOUBLE_EQ(mtc(7, 0), 31.708028058804274); EXPECT_DOUBLE_EQ(mtc(7, 1), 23.964236092014318); EXPECT_DOUBLE_EQ(mtc(7, 2), 49.704487303266575); EXPECT_DOUBLE_EQ(mtc(8, 0), -98.07812519655093); EXPECT_DOUBLE_EQ(mtc(8, 1), -53.69611952912465); EXPECT_DOUBLE_EQ(mtc(8, 2), 18.65157355854312); EXPECT_DOUBLE_EQ(mtc(9, 0), -51.718134217817926); EXPECT_DOUBLE_EQ(mtc(9, 1), -48.45849352784126); EXPECT_DOUBLE_EQ(mtc(9, 2), 98.9073219636636); EXPECT_DOUBLE_EQ(mtc(10, 0), -81.49405897174573); EXPECT_DOUBLE_EQ(mtc(10, 1), 0.03386109792266723); EXPECT_DOUBLE_EQ(mtc(10, 2), -45.19000115648366); EXPECT_DOUBLE_EQ(mtc(11, 0), 86.09136014594006); EXPECT_DOUBLE_EQ(mtc(11, 1), -43.90344163766924); EXPECT_DOUBLE_EQ(mtc(11, 2), -45.249286237965315); EXPECT_DOUBLE_EQ(mtc(12, 0), -23.14506976740256); EXPECT_DOUBLE_EQ(mtc(12, 1), -6.698621092523396); EXPECT_DOUBLE_EQ(mtc(12, 2), 97.09143831741096); EXPECT_DOUBLE_EQ(mtc(13, 0), 76.3616884219812); EXPECT_DOUBLE_EQ(mtc(13, 1), -99.37831178796779); EXPECT_DOUBLE_EQ(mtc(13, 2), -31.80834068260583); EXPECT_DOUBLE_EQ(mtc(14, 0), 60.28344358729666); EXPECT_DOUBLE_EQ(mtc(14, 1), -9.64088536276411); EXPECT_DOUBLE_EQ(mtc(14, 2), -78.03982967131924); EXPECT_DOUBLE_EQ(mtc(15, 0), -35.34123633864937); EXPECT_DOUBLE_EQ(mtc(15, 1), 3.118955974716698); EXPECT_DOUBLE_EQ(mtc(15, 2), -14.844621355572116); EXPECT_DOUBLE_EQ(mtc(16, 0), -87.33936780992902); EXPECT_DOUBLE_EQ(mtc(16, 1), -81.5481380106742); EXPECT_DOUBLE_EQ(mtc(16, 2), -66.64707457523824); - } - { - Matrix m; m.resize(3, 11); - m(0, 0) = -44.385915446696366; m(0, 1) = 28.793505461441015; m(0, 2) = 71.2114986465838; m(0, 3) = 51.14773880111491; m(0, 4) = -7.958682467368476; m(0, 5) = -83.09905041318346; m(0, 6) = -22.191719125506793; m(0, 7) = -2.2844026553076873; m(0, 8) = -85.89049887253955; m(0, 9) = 7.359151344016439; m(0, 10) = -12.836173824817394; m(1, 0) = 60.864624834962456; m(1, 1) = 55.31797716120735; m(1, 2) = 54.86505134841502; m(1, 3) = 1.2088001265842365; m(1, 4) = 51.71783583087824; m(1, 5) = -97.7984372019131; m(1, 6) = -21.276052450577225; m(1, 7) = -38.9853136735308; m(1, 8) = -83.47696130822689; m(1, 9) = 3.197398523431062; m(1, 10) = -81.03476411018644; m(2, 0) = 78.17495315633076; m(2, 1) = -81.81693970564498; m(2, 2) = -30.34183030075195; m(2, 3) = -15.609525205781651; m(2, 4) = -27.0093291175411; m(2, 5) = 42.95413233280735; m(2, 6) = -72.61359152573652; m(2, 7) = 78.95917814822454; m(2, 8) = -83.12124753315223; m(2, 9) = 74.1286028999458; m(2, 10) = -87.09605709830836; - Matrix mtr = m.transpose(); - EXPECT_DOUBLE_EQ(mtr(0, 0), -44.385915446696366); EXPECT_DOUBLE_EQ(mtr(0, 1), 60.864624834962456); EXPECT_DOUBLE_EQ(mtr(0, 2), 78.17495315633076); EXPECT_DOUBLE_EQ(mtr(1, 0), 28.793505461441015); EXPECT_DOUBLE_EQ(mtr(1, 1), 55.31797716120735); EXPECT_DOUBLE_EQ(mtr(1, 2), -81.81693970564498); EXPECT_DOUBLE_EQ(mtr(2, 0), 71.2114986465838); EXPECT_DOUBLE_EQ(mtr(2, 1), 54.86505134841502); EXPECT_DOUBLE_EQ(mtr(2, 2), -30.34183030075195); EXPECT_DOUBLE_EQ(mtr(3, 0), 51.14773880111491); EXPECT_DOUBLE_EQ(mtr(3, 1), 1.2088001265842365); EXPECT_DOUBLE_EQ(mtr(3, 2), -15.609525205781651); EXPECT_DOUBLE_EQ(mtr(4, 0), -7.958682467368476); EXPECT_DOUBLE_EQ(mtr(4, 1), 51.71783583087824); EXPECT_DOUBLE_EQ(mtr(4, 2), -27.0093291175411); EXPECT_DOUBLE_EQ(mtr(5, 0), -83.09905041318346); EXPECT_DOUBLE_EQ(mtr(5, 1), -97.7984372019131); EXPECT_DOUBLE_EQ(mtr(5, 2), 42.95413233280735); EXPECT_DOUBLE_EQ(mtr(6, 0), -22.191719125506793); EXPECT_DOUBLE_EQ(mtr(6, 1), -21.276052450577225); EXPECT_DOUBLE_EQ(mtr(6, 2), -72.61359152573652); EXPECT_DOUBLE_EQ(mtr(7, 0), -2.2844026553076873); EXPECT_DOUBLE_EQ(mtr(7, 1), -38.9853136735308); EXPECT_DOUBLE_EQ(mtr(7, 2), 78.95917814822454); EXPECT_DOUBLE_EQ(mtr(8, 0), -85.89049887253955); EXPECT_DOUBLE_EQ(mtr(8, 1), -83.47696130822689); EXPECT_DOUBLE_EQ(mtr(8, 2), -83.12124753315223); EXPECT_DOUBLE_EQ(mtr(9, 0), 7.359151344016439); EXPECT_DOUBLE_EQ(mtr(9, 1), 3.197398523431062); EXPECT_DOUBLE_EQ(mtr(9, 2), 74.1286028999458); EXPECT_DOUBLE_EQ(mtr(10, 0), -12.836173824817394); EXPECT_DOUBLE_EQ(mtr(10, 1), -81.03476411018644); EXPECT_DOUBLE_EQ(mtr(10, 2), -87.09605709830836); - Matrix mtc = m.transpose(); - EXPECT_DOUBLE_EQ(mtc(0, 0), -44.385915446696366); EXPECT_DOUBLE_EQ(mtc(0, 1), 60.864624834962456); EXPECT_DOUBLE_EQ(mtc(0, 2), 78.17495315633076); EXPECT_DOUBLE_EQ(mtc(1, 0), 28.793505461441015); EXPECT_DOUBLE_EQ(mtc(1, 1), 55.31797716120735); EXPECT_DOUBLE_EQ(mtc(1, 2), -81.81693970564498); EXPECT_DOUBLE_EQ(mtc(2, 0), 71.2114986465838); EXPECT_DOUBLE_EQ(mtc(2, 1), 54.86505134841502); EXPECT_DOUBLE_EQ(mtc(2, 2), -30.34183030075195); EXPECT_DOUBLE_EQ(mtc(3, 0), 51.14773880111491); EXPECT_DOUBLE_EQ(mtc(3, 1), 1.2088001265842365); EXPECT_DOUBLE_EQ(mtc(3, 2), -15.609525205781651); EXPECT_DOUBLE_EQ(mtc(4, 0), -7.958682467368476); EXPECT_DOUBLE_EQ(mtc(4, 1), 51.71783583087824); EXPECT_DOUBLE_EQ(mtc(4, 2), -27.0093291175411); EXPECT_DOUBLE_EQ(mtc(5, 0), -83.09905041318346); EXPECT_DOUBLE_EQ(mtc(5, 1), -97.7984372019131); EXPECT_DOUBLE_EQ(mtc(5, 2), 42.95413233280735); EXPECT_DOUBLE_EQ(mtc(6, 0), -22.191719125506793); EXPECT_DOUBLE_EQ(mtc(6, 1), -21.276052450577225); EXPECT_DOUBLE_EQ(mtc(6, 2), -72.61359152573652); EXPECT_DOUBLE_EQ(mtc(7, 0), -2.2844026553076873); EXPECT_DOUBLE_EQ(mtc(7, 1), -38.9853136735308); EXPECT_DOUBLE_EQ(mtc(7, 2), 78.95917814822454); EXPECT_DOUBLE_EQ(mtc(8, 0), -85.89049887253955); EXPECT_DOUBLE_EQ(mtc(8, 1), -83.47696130822689); EXPECT_DOUBLE_EQ(mtc(8, 2), -83.12124753315223); EXPECT_DOUBLE_EQ(mtc(9, 0), 7.359151344016439); EXPECT_DOUBLE_EQ(mtc(9, 1), 3.197398523431062); EXPECT_DOUBLE_EQ(mtc(9, 2), 74.1286028999458); EXPECT_DOUBLE_EQ(mtc(10, 0), -12.836173824817394); EXPECT_DOUBLE_EQ(mtc(10, 1), -81.03476411018644); EXPECT_DOUBLE_EQ(mtc(10, 2), -87.09605709830836); - } -} - -TEST(TestLabo1a, AffectationBySubMatrix) -{ - { - Matrix m; - m.setIdentity(); - EXPECT_DOUBLE_EQ(m(0, 0), 1); EXPECT_DOUBLE_EQ(m(0, 1), 0); EXPECT_DOUBLE_EQ(m(0, 2), 0); EXPECT_DOUBLE_EQ(m(0, 3), 0); EXPECT_DOUBLE_EQ(m(1, 0), 0); EXPECT_DOUBLE_EQ(m(1, 1), 1); EXPECT_DOUBLE_EQ(m(1, 2), 0); EXPECT_DOUBLE_EQ(m(1, 3), 0); EXPECT_DOUBLE_EQ(m(2, 0), 0); EXPECT_DOUBLE_EQ(m(2, 1), 0); EXPECT_DOUBLE_EQ(m(2, 2), 1); EXPECT_DOUBLE_EQ(m(2, 3), 0); EXPECT_DOUBLE_EQ(m(3, 0), 0); EXPECT_DOUBLE_EQ(m(3, 1), 0); EXPECT_DOUBLE_EQ(m(3, 2), 0); EXPECT_DOUBLE_EQ(m(3, 3), 1); - Matrix c; - c(0, 0) = 1.0; c(1, 0) = 2.0; c(2, 0) = 3.0; c(3, 0) = 4.0; - m.block(0, 0, 4, 1) = c; - m.block(0, 1, 4, 1) = c; - m.block(0, 2, 4, 1) = c; - m.block(0, 3, 4, 1) = c; - EXPECT_DOUBLE_EQ(m(0, 0), 1); EXPECT_DOUBLE_EQ(m(0, 1), 1); EXPECT_DOUBLE_EQ(m(0, 2), 1); EXPECT_DOUBLE_EQ(m(0, 3), 1); EXPECT_DOUBLE_EQ(m(1, 0), 2); EXPECT_DOUBLE_EQ(m(1, 1), 2); EXPECT_DOUBLE_EQ(m(1, 2), 2); EXPECT_DOUBLE_EQ(m(1, 3), 2); EXPECT_DOUBLE_EQ(m(2, 0), 3); EXPECT_DOUBLE_EQ(m(2, 1), 3); EXPECT_DOUBLE_EQ(m(2, 2), 3); EXPECT_DOUBLE_EQ(m(2, 3), 3); EXPECT_DOUBLE_EQ(m(3, 0), 4); EXPECT_DOUBLE_EQ(m(3, 1), 4); EXPECT_DOUBLE_EQ(m(3, 2), 4); EXPECT_DOUBLE_EQ(m(3, 3), 4); - Matrix b; - b(0, 0) = 0.0; b(1, 0) = 1.0; b(0, 1) = 2.0; b(1, 1) = 3.0; - m.block(0, 0, 2, 2) = b; - m.block(2, 0, 2, 2) = b; - m.block(0, 2, 2, 2) = b; - m.block(2, 2, 2, 2) = b; - EXPECT_DOUBLE_EQ(m(0, 0), 0); EXPECT_DOUBLE_EQ(m(0, 1), 2); EXPECT_DOUBLE_EQ(m(0, 2), 0); EXPECT_DOUBLE_EQ(m(0, 3), 2); EXPECT_DOUBLE_EQ(m(1, 0), 1); EXPECT_DOUBLE_EQ(m(1, 1), 3); EXPECT_DOUBLE_EQ(m(1, 2), 1); EXPECT_DOUBLE_EQ(m(1, 3), 3); EXPECT_DOUBLE_EQ(m(2, 0), 0); EXPECT_DOUBLE_EQ(m(2, 1), 2); EXPECT_DOUBLE_EQ(m(2, 2), 0); EXPECT_DOUBLE_EQ(m(2, 3), 2); EXPECT_DOUBLE_EQ(m(3, 0), 1); EXPECT_DOUBLE_EQ(m(3, 1), 3); EXPECT_DOUBLE_EQ(m(3, 2), 1); EXPECT_DOUBLE_EQ(m(3, 3), 3); - } - { - Matrix m; - m.setIdentity(); - EXPECT_DOUBLE_EQ(m(0, 0), 1); EXPECT_DOUBLE_EQ(m(0, 1), 0); EXPECT_DOUBLE_EQ(m(0, 2), 0); EXPECT_DOUBLE_EQ(m(0, 3), 0); EXPECT_DOUBLE_EQ(m(1, 0), 0); EXPECT_DOUBLE_EQ(m(1, 1), 1); EXPECT_DOUBLE_EQ(m(1, 2), 0); EXPECT_DOUBLE_EQ(m(1, 3), 0); EXPECT_DOUBLE_EQ(m(2, 0), 0); EXPECT_DOUBLE_EQ(m(2, 1), 0); EXPECT_DOUBLE_EQ(m(2, 2), 1); EXPECT_DOUBLE_EQ(m(2, 3), 0); EXPECT_DOUBLE_EQ(m(3, 0), 0); EXPECT_DOUBLE_EQ(m(3, 1), 0); EXPECT_DOUBLE_EQ(m(3, 2), 0); EXPECT_DOUBLE_EQ(m(3, 3), 1); - Matrix c; - c(0, 0) = 1.0; c(1, 0) = 2.0; c(2, 0) = 3.0; c(3, 0) = 4.0; - m.block(0, 0, 4, 1) = c; - m.block(0, 1, 4, 1) = c; - m.block(0, 2, 4, 1) = c; - m.block(0, 3, 4, 1) = c; - EXPECT_DOUBLE_EQ(m(0, 0), 1); EXPECT_DOUBLE_EQ(m(0, 1), 1); EXPECT_DOUBLE_EQ(m(0, 2), 1); EXPECT_DOUBLE_EQ(m(0, 3), 1); EXPECT_DOUBLE_EQ(m(1, 0), 2); EXPECT_DOUBLE_EQ(m(1, 1), 2); EXPECT_DOUBLE_EQ(m(1, 2), 2); EXPECT_DOUBLE_EQ(m(1, 3), 2); EXPECT_DOUBLE_EQ(m(2, 0), 3); EXPECT_DOUBLE_EQ(m(2, 1), 3); EXPECT_DOUBLE_EQ(m(2, 2), 3); EXPECT_DOUBLE_EQ(m(2, 3), 3); EXPECT_DOUBLE_EQ(m(3, 0), 4); EXPECT_DOUBLE_EQ(m(3, 1), 4); EXPECT_DOUBLE_EQ(m(3, 2), 4); EXPECT_DOUBLE_EQ(m(3, 3), 4); - Matrix b; - b(0, 0) = 0.0; b(1, 0) = 1.0; b(0, 1) = 2.0; b(1, 1) = 3.0; - m.block(0, 0, 2, 2) = b; - m.block(2, 0, 2, 2) = b; - m.block(0, 2, 2, 2) = b; - m.block(2, 2, 2, 2) = b; - EXPECT_DOUBLE_EQ(m(0, 0), 0); EXPECT_DOUBLE_EQ(m(0, 1), 2); EXPECT_DOUBLE_EQ(m(0, 2), 0); EXPECT_DOUBLE_EQ(m(0, 3), 2); EXPECT_DOUBLE_EQ(m(1, 0), 1); EXPECT_DOUBLE_EQ(m(1, 1), 3); EXPECT_DOUBLE_EQ(m(1, 2), 1); EXPECT_DOUBLE_EQ(m(1, 3), 3); EXPECT_DOUBLE_EQ(m(2, 0), 0); EXPECT_DOUBLE_EQ(m(2, 1), 2); EXPECT_DOUBLE_EQ(m(2, 2), 0); EXPECT_DOUBLE_EQ(m(2, 3), 2); EXPECT_DOUBLE_EQ(m(3, 0), 1); EXPECT_DOUBLE_EQ(m(3, 1), 3); EXPECT_DOUBLE_EQ(m(3, 2), 1); EXPECT_DOUBLE_EQ(m(3, 3), 3); - } -} diff --git a/labo01/tests/Tests1b.cpp b/labo01/tests/Tests1b.cpp deleted file mode 100644 index b625751..0000000 --- a/labo01/tests/Tests1b.cpp +++ /dev/null @@ -1,801 +0,0 @@ -/** - * @file Tests1b.cpp - * - * @brief Tests unitaires de la partie 1b - * - * Nom: - * Code permanent : - * Email : - * - */ - -#include "Matrix.h" -#include "Vector.h" -#include "Math3D.h" -#include "Operators.h" - -#include -#include - -using namespace gti320; - -namespace -{ - /** - * Multiplication matrice * vecteur, utilisant une implémentation naive - */ - template - static inline Vector<_Scalar, Dynamic> naiveMatrixMult(const Matrix<_Scalar, Dynamic, Dynamic, ColumnStorage>& A, const Vector<_Scalar, Dynamic>& v) - { - assert(A.cols() == v.rows()); - - Vector<_Scalar, Dynamic> b(A.rows()); - assert(b.rows() == A.rows()); - - for (int i = 0; i < A.rows(); ++i) { - b(i) = 0.0; - for (int j = 0; j < A.cols(); ++j) { - b(i) += A(i, j) * v(j); - } - } - - return b; - } - - /** - * Addition matrice + matrice, utilisant une implémentation naive - */ - template - static inline Matrix<_Scalar, Dynamic, Dynamic, ColumnStorage> naiveMatrixAddition(const Matrix<_Scalar, Dynamic, Dynamic, ColumnStorage>& A, const Matrix<_Scalar, Dynamic, Dynamic, ColumnStorage>& B) - { - assert(A.cols() == B.cols() && A.rows() == B.rows()); - - Matrix<_Scalar, Dynamic, Dynamic, ColumnStorage> C(A.rows(), A.cols()); - assert(C.rows() == A.rows() && C.cols() == A.cols()); - for (int i = 0; i < C.rows(); ++i) { - for (int j = 0; j < C.cols(); ++j) { - C(i, j) = A(i, j) + B(i, j); - } - } - return C; - } - - /** - * Multiplication matrice * matrice, utilisant une implémentation naive. - */ - template - static inline Matrix<_Scalar, Dynamic, Dynamic, _Storage> naiveMatrixMult(const Matrix<_Scalar, Dynamic, Dynamic, _Storage>& A, const Matrix<_Scalar, Dynamic, Dynamic, _Storage>& B) - { - assert(A.cols() == B.rows()); - Matrix<_Scalar, Dynamic, Dynamic> product(A.rows(), B.cols()); - for (int i = 0; i < A.rows(); ++i) - { - for (int j = 0; j < B.cols(); ++j) - { - for (int k = 0; k < A.cols(); ++k) - { - product(i, j) += A(i, k) * B(k, j); - } - } - } - return product; - } -} - -/** - * Test pour les opérateurs d'arithmétique matricielle. - */ -TEST(TestLabo1b, 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); - } - - // Opérations arithmétique avec matrices à stockage par lignes et par - // colonnes. - { - // Création d'un matrice à stockage par lignes - Matrix A(5, 5); - A(0, 0) = 0.8147; A(0, 1) = 0.0975; A(0, 2) = 0.1576; A(0, 3) = 0.1419; A(0, 4) = 0.6557; - A(1, 0) = 0.9058; A(1, 1) = 0.2785; A(1, 2) = 0.9706; A(1, 3) = 0.4218; A(1, 4) = 0.0357; - A(2, 0) = 0.1270; A(2, 1) = 0.5469; A(2, 2) = 0.9572; A(2, 3) = 0.9157; A(2, 4) = 0.8491; - A(3, 0) = 0.9134; A(3, 1) = 0.9575; A(3, 2) = 0.4854; A(3, 3) = 0.7922; A(3, 4) = 0.9340; - A(4, 0) = 0.6324; A(4, 1) = 0.9649; A(4, 2) = 0.8003; A(4, 3) = 0.9595; A(4, 4) = 0.6787; - - // Test : transposée (le résultat est une matrice à stockage par - // colonnes) - Matrix B = A.transpose(); - - // Test : multiplication matrix(ligne) * matrice(colonne) - // Note : teste seulement la première et la dernière colonne - const auto C = A * B; - EXPECT_NEAR(C(0, 0), 1.14815820000000, 1e-3); EXPECT_NEAR(C(0, 4), 1.31659795000000, 1e-3); - EXPECT_NEAR(C(1, 0), 1.00133748000000, 1e-3); EXPECT_NEAR(C(1, 4), 2.04727044000000, 1e-3); - EXPECT_NEAR(C(2, 0), 0.99433707000000, 1e-3); EXPECT_NEAR(C(2, 4), 2.82896409000000, 1e-3); - EXPECT_NEAR(C(3, 0), 1.63883925000000, 1e-3); EXPECT_NEAR(C(3, 4), 3.28401323000000, 1e-3); - EXPECT_NEAR(C(4, 0), 1.31659795000000, 1e-3); EXPECT_NEAR(C(4, 4), 3.35271580000000, 1e-3); - - - // Test : multiplication matrice(colonne) * matrice(ligne) - // Note : teste seulement la première et la dernière colonne - const auto C2 = B * A; - EXPECT_NEAR(C2(0, 0), 2.73456805000000, 1e-3); EXPECT_NEAR(C2(0, 4), 1.95669703000000, 1e-3); - EXPECT_NEAR(C2(1, 0), 1.88593811000000, 1e-3); EXPECT_NEAR(C2(1, 4), 2.08742862000000, 1e-3); - EXPECT_NEAR(C2(2, 0), 2.07860468000000, 1e-3); EXPECT_NEAR(C2(2, 4), 1.94727447000000, 1e-3); - EXPECT_NEAR(C2(3, 0), 1.94434955000000, 1e-3); EXPECT_NEAR(C2(3, 4), 2.27675041000000, 1e-3); - EXPECT_NEAR(C2(4, 0), 1.95669703000000, 1e-3); EXPECT_NEAR(C2(4, 4), 2.48517748000000, 1e-3); - - // Test : addition matrice(ligne) + matrice(ligne) - // Note : teste seulement la première et la dernière colonne - const auto A_plus_A = A + A; - EXPECT_DOUBLE_EQ(A_plus_A(0, 0), A(0, 0) + A(0, 0)); EXPECT_DOUBLE_EQ(A_plus_A(0, 4), A(0, 4) + A(0, 4)); - EXPECT_DOUBLE_EQ(A_plus_A(1, 0), A(1, 0) + A(1, 0)); EXPECT_DOUBLE_EQ(A_plus_A(1, 4), A(1, 4) + A(1, 4)); - EXPECT_DOUBLE_EQ(A_plus_A(2, 0), A(2, 0) + A(2, 0)); EXPECT_DOUBLE_EQ(A_plus_A(2, 4), A(2, 4) + A(2, 4)); - EXPECT_DOUBLE_EQ(A_plus_A(3, 0), A(3, 0) + A(3, 0)); EXPECT_DOUBLE_EQ(A_plus_A(3, 4), A(3, 4) + A(3, 4)); - EXPECT_DOUBLE_EQ(A_plus_A(4, 0), A(4, 0) + A(4, 0)); EXPECT_DOUBLE_EQ(A_plus_A(4, 4), A(4, 4) + A(4, 4)); - - // Test : addition matrice(colonne) + matrice(colonne) - // Note : teste seulement la première et la dernière colonne - const auto B_plus_B = B + B; - EXPECT_DOUBLE_EQ(B_plus_B(0, 0), B(0, 0) + B(0, 0)); EXPECT_DOUBLE_EQ(B_plus_B(0, 4), B(0, 4) + B(0, 4)); - EXPECT_DOUBLE_EQ(B_plus_B(1, 0), B(1, 0) + B(1, 0)); EXPECT_DOUBLE_EQ(B_plus_B(1, 4), B(1, 4) + B(1, 4)); - EXPECT_DOUBLE_EQ(B_plus_B(2, 0), B(2, 0) + B(2, 0)); EXPECT_DOUBLE_EQ(B_plus_B(2, 4), B(2, 4) + B(2, 4)); - EXPECT_DOUBLE_EQ(B_plus_B(3, 0), B(3, 0) + B(3, 0)); EXPECT_DOUBLE_EQ(B_plus_B(3, 4), B(3, 4) + B(3, 4)); - EXPECT_DOUBLE_EQ(B_plus_B(4, 0), B(4, 0) + B(4, 0)); EXPECT_DOUBLE_EQ(B_plus_B(4, 4), B(4, 4) + B(4, 4)); - - } -} - -/** - * Test pour la multiplication matrice * vecteur - */ -TEST(TestLabo1b, MatrixVectorOperators) -{ - // Vecteur à taille dynamique - Vector v(5); - v(0) = 1.0; - v(1) = 2.0; - v(2) = 4.0; - v(3) = 8.0; - v(4) = 16.0; - - // Test : multiplication par la matrice identité - { - Matrix M(5, 5); - M.setIdentity(); - - const auto b = M * v; - EXPECT_DOUBLE_EQ(b(0), 1.0); - EXPECT_DOUBLE_EQ(b(1), 2.0); - EXPECT_DOUBLE_EQ(b(2), 4.0); - EXPECT_DOUBLE_EQ(b(3), 8.0); - EXPECT_DOUBLE_EQ(b(4), 16.0); - } - - // Test : multiplication par une matrice à taille dynamique avec stockage par ligne. - { - Matrix M(5, 5); - M.setIdentity(); - M = 2.0 * M; - - Vector b2 = M * v; - EXPECT_DOUBLE_EQ(b2(0), 2.0); - EXPECT_DOUBLE_EQ(b2(1), 4.0); - EXPECT_DOUBLE_EQ(b2(2), 8.0); - EXPECT_DOUBLE_EQ(b2(3), 16.0); - EXPECT_DOUBLE_EQ(b2(4), 32.0); - } - // Test : autres - { - Vector u; u(0) = 89.63885274026418; u(1) = 33.98267508829284; u(2) = 58.18085749457168; - Matrix m33; - m33(0, 0) = -37.761291293282206; m33(0, 1) = -58.77833883088219; m33(0, 2) = -80.31292383738193; m33(1, 0) = 82.42200051847567; m33(1, 1) = -21.616077216647483; m33(1, 2) = -81.41765352024458; m33(2, 0) = -1.826095889555674; m33(2, 1) = -72.65845670305742; m33(2, 2) = -68.43559055076148; - Matrix m44; - m44(0, 0) = -0.6810804556978075; m44(0, 1) = -0.3717461369121619; m44(0, 2) = -0.6308202775413543; m44(0, 3) = 65.25663257716863; m44(1, 0) = -0.7322085856273928; m44(1, 1) = 0.3457881173505905; m44(1, 2) = 0.5867718168356992; m44(1, 3) = -72.82746334890318; m44(2, 0) = 0.0; m44(2, 1) = 0.8615308396047228; m44(2, 2) = -0.5077052416609282; m44(2, 3) = -50.951590508183095; m44(3, 0) = 0.0; m44(3, 1) = 0.0; m44(3, 2) = 0.0; m44(3, 3) = 1.0; - Vector v = m33 * u; - EXPECT_NEAR(v(0), -10054.998796995307, 1e-3); - EXPECT_NEAR(v(1), 1916.692541293076, 1e-3); - EXPECT_NEAR(v(2), -6614.459208480986, 1e-3); - Vector w = m44 * u; - EXPECT_NEAR(w(0), -45.129230953732865, 1e-3); - EXPECT_NEAR(w(1), -92.57210823264782, 1e-3); - EXPECT_NEAR(w(2), -51.21319422167322, 1e-3); - } - { - Vector u; u(0) = 21.26102327359945; u(1) = -63.632003812151375; u(2) = 21.749676556807557; - Matrix m33; - m33(0, 0) = -72.46587508929531; m33(0, 1) = 26.74413795088728; m33(0, 2) = 66.40155978725781; m33(1, 0) = 30.554539344667063; m33(1, 1) = 34.707428553000256; m33(1, 2) = -78.73225643210714; m33(2, 0) = 29.88002386285075; m33(2, 1) = 84.40743250651678; m33(2, 2) = 89.33116036637102; - Matrix m44; - m44(0, 0) = -0.8156253236747055; m44(0, 1) = 0.0; m44(0, 2) = 0.5785804450381398; m44(0, 3) = -36.44550865077372; m44(1, 0) = -0.4886547783002762; m44(1, 1) = 0.5354367269787551; m44(1, 2) = -0.6888570381774334; m44(1, 3) = 26.24571159164249; m44(2, 0) = -0.3097932197851331; m44(2, 1) = -0.8445753438280554; m44(2, 2) = -0.43671575374937205; m44(2, 3) = 58.09911341828064; m44(3, 0) = 0.0; m44(3, 1) = 0.0; m44(3, 2) = 0.0; m44(3, 3) = 1.0; - Vector v = m33 * u; - EXPECT_NEAR(v(0), -1798.269296618443, 1e-3); - EXPECT_NEAR(v(1), -3271.2835658593685, 1e-3); - EXPECT_NEAR(v(2), -2792.8103398519333, 1e-3); - Vector w = m44 * u; - EXPECT_NEAR(w(0), -41.2026000982854, 1e-3); - EXPECT_NEAR(w(1), -33.19691864907287, 1e-3); - EXPECT_NEAR(w(2), 95.75618766923024, 1e-3); - } - { - Vector u; u(0) = 60.89920397428068; u(1) = 41.99263628824008; u(2) = 2.8397811977043403; - Matrix m33; - m33(0, 0) = 37.756340946034896; m33(0, 1) = 34.695096214807364; m33(0, 2) = 71.82563147437446; m33(1, 0) = 74.91874228380777; m33(1, 1) = 11.371524438829937; m33(1, 2) = 22.662878030996694; m33(2, 0) = -33.183135422386044; m33(2, 1) = -48.81237469926953; m33(2, 2) = 77.28631280104915; - Matrix m44; - m44(0, 0) = 0.09071108841607319; m44(0, 1) = 0.15875989354807826; m44(0, 2) = -0.9831412892555038; m44(0, 3) = -20.28034322391565; m44(1, 0) = 0.8682639927927074; m44(1, 1) = -0.49610244790735053; m44(1, 2) = 0.0; m44(1, 3) = -65.91591665493024; m44(2, 0) = -0.487738800238444; m44(2, 1) = -0.8536261812883538; m44(2, 2) = -0.18284749208295362; m44(2, 3) = -28.08938117342305; m44(3, 0) = 0.0; m44(3, 1) = 0.0; m44(3, 2) = 0.0; m44(3, 3) = 1.0; - Vector v = m33 * u; - EXPECT_NEAR(v(0), 3960.2387427031354, 1e-3); - EXPECT_NEAR(v(1), 5104.369672559086, 1e-3); - EXPECT_NEAR(v(2), -3851.1106117734685, 1e-3); - Vector w = m44 * u; - EXPECT_NEAR(w(0), -10.881269828726621, 1e-3); - EXPECT_NEAR(w(1), -33.87198031100272, 1e-3); - EXPECT_NEAR(w(2), -94.15754648234068, 1e-3); - } - { - Vector u; u(0) = 5.188467455547638; u(1) = 18.80451508110363; u(2) = -21.656727889135595; - Matrix m33; - m33(0, 0) = 87.9457818703861; m33(0, 1) = 73.05874068692381; m33(0, 2) = 39.940251688233246; m33(1, 0) = 75.10237717805055; m33(1, 1) = 72.18489393198146; m33(1, 2) = 99.55423077694917; m33(2, 0) = -23.406607601688265; m33(2, 1) = 36.642344803461384; m33(2, 2) = 59.655570064408465; - Matrix m44; - m44(0, 0) = 0.17067228277067772; m44(0, 1) = -0.6737686724718157; m44(0, 2) = -0.7189622715340582; m44(0, 3) = -18.335201879756795; m44(1, 0) = -0.9693828421385298; m44(1, 1) = -0.24555428191629253; m44(1, 2) = 0.0; m44(1, 3) = 29.845708309352148; m44(2, 0) = -0.1765442643114522; m44(2, 1) = 0.6969496901700587; m44(2, 2) = -0.6950491005034012; m44(2, 3) = -31.894796135192152; m44(3, 0) = 0.0; m44(3, 1) = 0.0; m44(3, 2) = 0.0; m44(3, 3) = 1.0; - Vector v = m33 * u; - EXPECT_NEAR(v(0), 965.1628555052321, 1e-3); - EXPECT_NEAR(v(1), -408.9507197542059, 1e-3); - EXPECT_NEAR(v(2), -724.347344278602, 1e-3); - Vector w = m44 * u; - EXPECT_NEAR(w(0), -14.549197180540624, 1e-3); - EXPECT_NEAR(w(1), 20.198567783425617, 1e-3); - EXPECT_NEAR(w(2), -4.652500106271733, 1e-3); - } - { - Vector u; u(0) = 37.47349664672282; u(1) = -60.74514266373965; u(2) = -40.46471876369226; - Matrix m33; - m33(0, 0) = -18.595918421354753; m33(0, 1) = -63.34971612297557; m33(0, 2) = 51.78315639657973; m33(1, 0) = 60.68830258069576; m33(1, 1) = -63.44130757420927; m33(1, 2) = 0.1227343978225548; m33(2, 0) = 69.14823593166864; m33(2, 1) = 49.45675635266332; m33(2, 2) = 81.76280170074256; - Matrix m44; - m44(0, 0) = -0.250151688477416; m44(0, 1) = -0.2581347286114716; m44(0, 2) = -0.9331616122819132; m44(0, 3) = 15.902624286413442; m44(1, 0) = -0.7181238873483027; m44(1, 1) = 0.6959152839389017; m44(1, 2) = 0.0; m44(1, 3) = -12.358184768214258; m44(2, 0) = 0.6494014283720508; m44(2, 1) = 0.6701256445360971; m44(2, 2) = -0.3594570980846258; m44(2, 3) = -95.12313555065694; m44(3, 0) = 0.0; m44(3, 1) = 0.0; m44(3, 2) = 0.0; m44(3, 3) = 1.0; - Vector v = m33 * u; - EXPECT_NEAR(v(0), 1055.9425967082998, 1e-3); - EXPECT_NEAR(v(1), 6122.987769732011, 1e-3); - EXPECT_NEAR(v(2), -3721.5403091682488, 1e-3); - Vector w = m44 * u; - EXPECT_NEAR(w(0), 59.969118945113756, 1e-3); - EXPECT_NEAR(w(1), -81.54227105743792, 1e-3); - EXPECT_NEAR(w(2), -96.94934080054827, 1e-3); - } - { - Vector u; u(0) = -18.242981648343232; u(1) = 56.21809486615007; u(2) = 68.42388784251386; - Matrix m33; - m33(0, 0) = 72.32617531563085; m33(0, 1) = 16.921578626504015; m33(0, 2) = -27.34080821434577; m33(1, 0) = 75.31926937290174; m33(1, 1) = -81.4337114340538; m33(1, 2) = 49.516021610363254; m33(2, 0) = 40.651084247784695; m33(2, 1) = -19.615350275581747; m33(2, 2) = 96.61096468197644; - Matrix m44; - m44(0, 0) = 0.8628144975844739; m44(0, 1) = -0.39604187777629973; m44(0, 2) = 0.3141687027784186; m44(0, 3) = -15.592609294116613; m44(1, 0) = -0.5055206650158348; m44(1, 1) = -0.6759578736217757; m44(1, 2) = 0.5362180622943203; m44(1, 3) = 10.857285613068584; m44(2, 0) = 0.0; m44(2, 1) = -0.6214754895699024; m44(2, 2) = -0.7834336065448367; m44(2, 3) = -95.09026591014809; m44(3, 0) = 0.0; m44(3, 1) = 0.0; m44(3, 2) = 0.0; m44(3, 3) = 1.0; - Vector v = m33 * u; - EXPECT_NEAR(v(0), -2238.9105712501655, 1e-3); - EXPECT_NEAR(v(1), -2564.0174545638056, 1e-3); - EXPECT_NEAR(v(2), 4766.163205213616, 1e-3); - Vector w = m44 * u; - EXPECT_NEAR(w(0), -32.1009941127323, 1e-3); - EXPECT_NEAR(w(1), 18.768550516577342, 1e-3); - EXPECT_NEAR(w(2), -183.634007166056, 1e-3); - } - { - Vector u; u(0) = -59.27939726364973; u(1) = 96.57872437189005; u(2) = -50.71931054476342; - Matrix m33; - m33(0, 0) = -53.51188145034156; m33(0, 1) = -39.773533094835024; m33(0, 2) = -81.91533947789623; m33(1, 0) = -48.98656664587613; m33(1, 1) = -30.35481126192778; m33(1, 2) = -24.41812181189411; m33(2, 0) = 50.987332445586844; m33(2, 1) = -15.614790715203753; m33(2, 2) = 1.953005394977339; - Matrix m44; - m44(0, 0) = -0.9781360701985449; m44(0, 1) = 0.0; m44(0, 2) = -0.20796593032645286; m44(0, 3) = 31.079492180635583; m44(1, 0) = 0.17988007252338098; m44(1, 1) = 0.5018585333987298; m44(1, 2) = -0.846038516832336; m44(1, 3) = 89.95140758767585; m44(2, 0) = 0.10436947679053606; m44(2, 1) = -0.8649497167205016; m44(2, 2) = -0.4908859336542387; m44(2, 3) = -66.61272043333199; m44(3, 0) = 0.0; m44(3, 1) = 0.0; m44(3, 2) = 0.0; m44(3, 3) = 1.0; - Vector v = m33 * u; - EXPECT_NEAR(v(0), 3485.5645301169448, 1e-3); - EXPECT_NEAR(v(1), 1210.7354976539962, 1e-3); - EXPECT_NEAR(v(2), -4629.6099911875845, 1e-3); - Vector w = m44 * u; - EXPECT_NEAR(w(0), 99.6106974667983, 1e-3); - EXPECT_NEAR(w(1), 170.66757254759543, 1e-3); - EXPECT_NEAR(w(2), -131.4380242858257, 1e-3); - } - { - Vector u; u(0) = -33.64679408120854; u(1) = 57.74585710730173; u(2) = -38.78100535372986; - Matrix m33; - m33(0, 0) = -48.76215910463826; m33(0, 1) = -17.88064937607517; m33(0, 2) = -10.666843689761578; m33(1, 0) = 54.129177432133815; m33(1, 1) = -50.3409670888066; m33(1, 2) = 67.92880818886752; m33(2, 0) = -36.14536761608753; m33(2, 1) = 92.53432169416001; m33(2, 2) = 68.69365938680332; - Matrix m44; - m44(0, 0) = 0.4751126538005149; m44(0, 1) = 0.5241078534879362; m44(0, 2) = -0.7068089728568109; m44(0, 3) = 7.21266115268952; m44(1, 0) = -0.7408885299063788; m44(1, 1) = 0.671628011813954; m44(1, 2) = 0.0; m44(1, 3) = -99.71424185587028; m44(2, 0) = 0.4747127051720829; m44(2, 1) = 0.5236666608245202; m44(2, 2) = 0.7074044641427562; m44(2, 3) = -11.057694172067542; m44(3, 0) = 0.0; m44(3, 1) = 0.0; m44(3, 2) = 0.0; m44(3, 3) = 1.0; - Vector v = m33 * u; - EXPECT_NEAR(v(0), 1021.8278247323343, 1e-3); - EXPECT_NEAR(v(1), -7362.603053042772, 1e-3); - EXPECT_NEAR(v(2), 3895.640286793221, 1e-3); - Vector w = m44 * u; - EXPECT_NEAR(w(0), 48.90246330164035, 1e-3); - EXPECT_NEAR(w(1), -36.001982853511294, 1e-3); - EXPECT_NEAR(w(2), -24.22453095406812, 1e-3); - } - { - Vector u; u(0) = 15.282052878141911; u(1) = -2.259998336973041; u(2) = 91.08586195638563; - Matrix m33; - m33(0, 0) = -88.39582865245377; m33(0, 1) = -64.58071224128338; m33(0, 2) = -4.675696828923634; m33(1, 0) = -86.1584474938788; m33(1, 1) = -34.543435043656444; m33(1, 2) = -62.495745585883625; m33(2, 0) = -59.183456388092395; m33(2, 1) = -57.14307430989349; m33(2, 2) = 44.41751022537625; - Matrix m44; - m44(0, 0) = 0.44386855289227883; m44(0, 1) = 0.5950916475208161; m44(0, 2) = 0.6699601770286612; m44(0, 3) = -72.72024311218823; m44(1, 0) = -0.8960919080949868; m44(1, 1) = 0.29477162558569525; m44(1, 2) = 0.33185686823727545; m44(1, 3) = 15.476209050615353; m44(2, 0) = 0.0; m44(2, 1) = -0.7476467212531113; m44(2, 2) = 0.6640966648007446; m44(2, 3) = 99.8824543736142; m44(3, 0) = 0.0; m44(3, 1) = 0.0; m44(3, 2) = 0.0; m44(3, 3) = 1.0; - Vector v = m33 * u; - EXPECT_NEAR(v(0), -1630.8073013173835, 1e-3); - EXPECT_NEAR(v(1), -6931.088700045262, 1e-3); - EXPECT_NEAR(v(2), 3270.5057477108207, 1e-3); - Vector w = m44 * u; - EXPECT_NEAR(w(0), -6.258026348579378, 1e-3); - EXPECT_NEAR(w(1), 31.343370633361097, 1e-3); - EXPECT_NEAR(w(2), 162.0619518560263, 1e-3); - } - { - Vector u; u(0) = -45.53190350588168; u(1) = 98.18869916536156; u(2) = 82.67567746788419; - Matrix m33; - m33(0, 0) = -51.297389589304785; m33(0, 1) = -66.59459838930371; m33(0, 2) = 27.56805306675247; m33(1, 0) = 96.48690448918092; m33(1, 1) = 9.10079699500524; m33(1, 2) = 83.88487605323621; m33(2, 0) = 41.570057963368356; m33(2, 1) = 24.52264689542079; m33(2, 2) = -76.44940699537474; - Matrix m44; - m44(0, 0) = 0.774965095070908; m44(0, 1) = 0.0; m44(0, 2) = 0.6320040359220331; m44(0, 3) = -94.78257020280037; m44(1, 0) = -0.5539089538751407; m44(1, 1) = 0.4815245168438749; m44(1, 2) = 0.6792046896887713; m44(1, 3) = 63.87247725975902; m44(2, 0) = -0.3043254380407359; m44(2, 1) = -0.8764326212997054; m44(2, 2) = 0.3731646929748866; m44(2, 3) = -95.85244653326883; m44(3, 0) = 0.0; m44(3, 1) = 0.0; m44(3, 2) = 0.0; m44(3, 3) = 1.0; - Vector v = m33 * u; - EXPECT_NEAR(v(0), -1923.9617306372265, 1e-3); - EXPECT_NEAR(v(1), 3435.6019505357876, 1e-3); - EXPECT_NEAR(v(2), -5805.423584529748, 1e-3); - Vector w = m44 * u; - EXPECT_NEAR(w(0), -77.81684429970429, 1e-3); - EXPECT_NEAR(w(1), 192.52698008315832, 1e-3); - EXPECT_NEAR(w(2), -137.20006524672516, 1e-3); - } -} - -/** - * Opérateurs d'arithmétique vectorielle - */ -TEST(TestLabo1b, VectorOperators) -{ - Vector v(5); - v(0) = 0.1; - v(1) = 0.2; - v(2) = 0.4; - v(3) = 0.8; - v(4) = 1.6; - - // Test : multiplication scalaire * vecteur - const double alpha = 4.0; - const auto v2 = alpha * v; - EXPECT_DOUBLE_EQ(v2(0), alpha * v(0)); - EXPECT_DOUBLE_EQ(v2(1), alpha * v(1)); - EXPECT_DOUBLE_EQ(v2(2), alpha * v(2)); - EXPECT_DOUBLE_EQ(v2(3), alpha * v(3)); - EXPECT_DOUBLE_EQ(v2(4), alpha * v(4)); - - // Test : addition vecteur + vecteur - const auto v3 = v + v2; - EXPECT_DOUBLE_EQ(v3(0), v(0) + v2(0)); - EXPECT_DOUBLE_EQ(v3(1), v(1) + v2(1)); - EXPECT_DOUBLE_EQ(v3(2), v(2) + v2(2)); - EXPECT_DOUBLE_EQ(v3(3), v(3) + v2(3)); - EXPECT_DOUBLE_EQ(v3(4), v(4) + v2(4)); -} - -/** - * Mathématiques 3D - */ -TEST(TestLabo1b, Math3D) -{ - // Test : norme d'un vecteur de dimension 3 - Vector3d v; - v.setZero(); - v(1) = 2.0; - EXPECT_EQ(v.rows(), 3); - EXPECT_EQ(v.cols(), 1); - EXPECT_DOUBLE_EQ(v(0), 0.0); - EXPECT_DOUBLE_EQ(v(1), 2.0); - EXPECT_DOUBLE_EQ(v(2), 0.0); - EXPECT_DOUBLE_EQ(v.norm(), 2.0); - - // Test : calcul de la norme d'un deuxième vecteur 3D - Vector3d v2; - v2(0) = 4.0; - v2(1) = 2.0; - v2(2) = 5.0; - EXPECT_EQ(v2.rows(), 3); - EXPECT_EQ(v2.cols(), 1); - EXPECT_DOUBLE_EQ(v2(0), 4.0); - EXPECT_DOUBLE_EQ(v2(1), 2.0); - EXPECT_DOUBLE_EQ(v2(2), 5.0); - EXPECT_DOUBLE_EQ(v2.norm(), 6.7082039324993690892275210061938); - - // Test : produit scalaire - EXPECT_DOUBLE_EQ(v.dot(v2), 4.0); - - // Test : matrice identité 4x4 - Matrix4d M; - M.setIdentity(); - EXPECT_DOUBLE_EQ(M(0, 0), 1.0); - EXPECT_DOUBLE_EQ(M(0, 1), 0.0); - EXPECT_DOUBLE_EQ(M(0, 2), 0.0); - EXPECT_DOUBLE_EQ(M(1, 1), 1.0); - EXPECT_DOUBLE_EQ(M(1, 0), 0.0); - EXPECT_DOUBLE_EQ(M(1, 2), 0.0); - EXPECT_DOUBLE_EQ(M(2, 0), 0.0); - EXPECT_DOUBLE_EQ(M(2, 1), 0.0); - EXPECT_DOUBLE_EQ(M(2, 2), 1.0); - - // Test : création d'une matrice de rotation de 45 degrés autour de l'axe des x - const auto Rx = makeRotation(M_PI / 4.0, 0, 0); - EXPECT_NEAR(Rx(0, 0), 1, 1e-3); EXPECT_NEAR(Rx(0, 1), 0, 1e-3); EXPECT_NEAR(Rx(0, 2), 0, 1e-3); - EXPECT_NEAR(Rx(1, 0), 0, 1e-3); EXPECT_NEAR(Rx(1, 1), 0.7071, 1e-3); EXPECT_NEAR(Rx(1, 2), -0.7071, 1e-3); - EXPECT_NEAR(Rx(2, 0), 0, 1e-3); EXPECT_NEAR(Rx(2, 1), 0.7071, 1e-3); EXPECT_NEAR(Rx(2, 2), 0.7071, 1e-3); - - // Test : création d'une matrice de rotation de 45 degrés autour de l'axe des y - const auto Ry = makeRotation(0, M_PI / 4.0, 0); - EXPECT_NEAR(Ry(0, 0), 0.7071, 1e-3); EXPECT_NEAR(Ry(0, 1), 0, 1e-3); EXPECT_NEAR(Ry(0, 2), 0.7071, 1e-3); - EXPECT_NEAR(Ry(1, 0), 0, 1e-3); EXPECT_NEAR(Ry(1, 1), 1, 1e-3); EXPECT_NEAR(Ry(1, 2), 0, 1e-3); - EXPECT_NEAR(Ry(2, 0), -0.7071, 1e-3); EXPECT_NEAR(Ry(2, 1), 0, 1e-3); EXPECT_NEAR(Ry(2, 2), 0.7071, 1e-3); - - // Test : création d'une matrice de rotation de 45 degrés autour de l'axe des z - const auto Rz = makeRotation(0, 0, M_PI / 4.0); - EXPECT_NEAR(Rz(0, 0), 0.7071, 1e-3); EXPECT_NEAR(Rz(0, 1), -0.7071, 1e-3); EXPECT_NEAR(Rz(0, 2), 0, 1e-3); - EXPECT_NEAR(Rz(1, 0), 0.7071, 1e-3); EXPECT_NEAR(Rz(1, 1), 0.7071, 1e-3); EXPECT_NEAR(Rz(1, 2), 0, 1e-3); - EXPECT_NEAR(Rz(2, 0), 0, 1e-3); EXPECT_NEAR(Rz(2, 1), 0, 1e-3); EXPECT_NEAR(Rz(2, 2), 1, 1e-3); - - // Test : création d'une matrice de rotation quelconque. - const auto Rxyz = makeRotation(M_PI / 3.0, -M_PI / 6.0, M_PI / 4.0); - EXPECT_NEAR(Rxyz(0, 0), 0.6124, 1e-3); EXPECT_NEAR(Rxyz(0, 1), -0.6597, 1e-3); EXPECT_NEAR(Rxyz(0, 2), 0.4356, 1e-3); - EXPECT_NEAR(Rxyz(1, 0), 0.6124, 1e-3); EXPECT_NEAR(Rxyz(1, 1), 0.0474, 1e-3); EXPECT_NEAR(Rxyz(1, 2), -0.7891, 1e-3); - EXPECT_NEAR(Rxyz(2, 0), 0.5, 1e-3); EXPECT_NEAR(Rxyz(2, 1), 0.75, 1e-3); EXPECT_NEAR(Rxyz(2, 2), 0.4330, 1e-3); - - // Test : création d'une transformation homogène via la sous-matrice 3x3 en - // utilisant la fonction `block` - M.block(0, 0, 3, 3) = Rxyz; - M(0, 3) = -0.1; - M(1, 3) = 1.0; - M(2, 3) = 2.1; - - // Test : calcule l'inverse de la matrice M et vérifie que M^(-1) * M * v = v - const Matrix4d Minv = M.inverse(); - const Vector3d v3 = Minv * (M * v2); - EXPECT_DOUBLE_EQ(v3(0), v2(0)); - EXPECT_DOUBLE_EQ(v3(1), v2(1)); - EXPECT_DOUBLE_EQ(v3(2), v2(2)); - - // Test : translation d'un vecteur 3D effectuée avec une matrice 4x4 en coordonnées homogènes - Matrix4d T; - T.setIdentity(); - T(0, 3) = 1.2; - T(1, 3) = 2.5; - T(2, 3) = -4.0; - const Vector3d t = T * v3; - EXPECT_DOUBLE_EQ(t(0), v3(0) + 1.2); - EXPECT_DOUBLE_EQ(t(1), v3(1) + 2.5); - EXPECT_DOUBLE_EQ(t(2), v3(2) - 4.0); - - // Test : inverse d'un matrice de rotation - const Matrix3d Rinv = Rxyz.inverse(); - const Matrix3d RT = Rxyz.transpose(); - EXPECT_DOUBLE_EQ(Rinv(0, 0), RT(0, 0)); - EXPECT_DOUBLE_EQ(Rinv(1, 1), RT(1, 1)); - EXPECT_DOUBLE_EQ(Rinv(0, 2), RT(0, 2)); -} - -TEST(TestLabo1b, RigidTransformInverse) { - { - Matrix m; - m(0, 0) = -0.7899179842354741; m(0, 1) = 0.5558875173441905; m(0, 2) = 0.2588795979645317; m(0, 3) = 63.53646575655944; m(1, 0) = -0.6132125065435026; m(1, 1) = -0.7160740240561843; m(1, 2) = -0.3334792555626483; m(1, 3) = 46.40415080808421; m(2, 0) = 0.0; m(2, 1) = -0.4221694684991984; m(2, 2) = 0.9065169275127214; m(2, 3) = 37.91755407005138; m(3, 0) = 0.0; m(3, 1) = 0.0; m(3, 2) = 0.0; m(3, 3) = 1.0; - Matrix mi = m.inverse(); - EXPECT_NEAR(mi(0, 0), -0.7899179842354742, 1e-3); - EXPECT_NEAR(mi(0, 1), -0.6132125065435026, 1e-3); - EXPECT_NEAR(mi(0, 2), 5.0321798256853854e-17, 1e-3); - EXPECT_NEAR(mi(0, 3), 78.64420258691568, 1e-3); - EXPECT_NEAR(mi(1, 0), 0.5558875173441905, 1e-3); - EXPECT_NEAR(mi(1, 1), -0.7160740240561843, 1e-3); - EXPECT_NEAR(mi(1, 2), -0.42216946849919834, 1e-3); - EXPECT_NEAR(mi(1, 3), 13.917312440360101, 1e-3); - EXPECT_NEAR(mi(2, 0), 0.25887959796453164, 1e-3); - EXPECT_NEAR(mi(2, 1), -0.33347925556264824, 1e-3); - EXPECT_NEAR(mi(2, 2), 0.9065169275127212, 1e-3); - EXPECT_NEAR(mi(2, 3), -35.34637765902901, 1e-3); - EXPECT_NEAR(mi(3, 0), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 1), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 2), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 3), 1.0, 1e-3); - } - { - Matrix m; - m(0, 0) = 0.6589112893907124; m(0, 1) = -0.32720889915223983; m(0, 2) = 0.6773258071482646; m(0, 3) = -47.579657162583366; m(1, 0) = -0.7522206542720485; m(1, 1) = -0.2866202043457096; m(1, 2) = 0.5933067888937011; m(1, 3) = 30.029355381737275; m(2, 0) = 0.0; m(2, 1) = -0.9004350030826229; m(2, 2) = -0.4349905806147956; m(2, 3) = 80.66547089822612; m(3, 0) = 0.0; m(3, 1) = 0.0; m(3, 2) = 0.0; m(3, 3) = 1.0; - Matrix mi = m.inverse(); - EXPECT_NEAR(mi(0, 0), 0.6589112893907124, 1e-3); - EXPECT_NEAR(mi(0, 1), -0.7522206542720486, 1e-3); - EXPECT_NEAR(mi(0, 2), 5.551115123125783e-17, 1e-3); - EXPECT_NEAR(mi(0, 3), 53.939474602384124, 1e-3); - EXPECT_NEAR(mi(1, 0), -0.3272088991522398, 1e-3); - EXPECT_NEAR(mi(1, 1), -0.28662020434570956, 1e-3); - EXPECT_NEAR(mi(1, 2), -0.9004350030826228, 1e-3); - EXPECT_NEAR(mi(1, 3), 65.67254627057903, 1e-3); - EXPECT_NEAR(mi(2, 0), 0.6773258071482645, 1e-3); - EXPECT_NEAR(mi(2, 1), 0.5933067888937011, 1e-3); - EXPECT_NEAR(mi(2, 2), -0.43499058061479545, 1e-3); - EXPECT_NEAR(mi(2, 3), 49.49902929898342, 1e-3); - EXPECT_NEAR(mi(3, 0), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 1), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 2), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 3), 1.0, 1e-3); - } - { - Matrix m; - m(0, 0) = -0.12921677297502387; m(0, 1) = 0.0; m(0, 2) = -0.9916163701663668; m(0, 3) = -85.67624239250289; m(1, 0) = 0.5536164401240612; m(1, 1) = -0.8296411663169171; m(1, 2) = -0.07214133611645579; m(1, 3) = -80.61895745285052; m(2, 0) = -0.8226857618837724; m(2, 1) = -0.5582969954713223; m(2, 2) = 0.1072035542387071; m(2, 3) = -59.16846832515195; m(3, 0) = 0.0; m(3, 1) = 0.0; m(3, 2) = 0.0; m(3, 3) = 1.0; - Matrix mi = m.inverse(); - EXPECT_NEAR(mi(0, 0), -0.12921677297502387, 1e-3); - EXPECT_NEAR(mi(0, 1), 0.5536164401240611, 1e-3); - EXPECT_NEAR(mi(0, 2), -0.8226857618837723, 1e-3); - EXPECT_NEAR(mi(0, 3), -15.115883774598393, 1e-3); - EXPECT_NEAR(mi(1, 0), -0.0, 1e-3); - EXPECT_NEAR(mi(1, 1), -0.829641166316917, 1e-3); - EXPECT_NEAR(mi(1, 2), -0.5582969954713222, 1e-3); - EXPECT_NEAR(mi(1, 3), -99.91838398100924, 1e-3); - EXPECT_NEAR(mi(2, 0), -0.991616370166367, 1e-3); - EXPECT_NEAR(mi(2, 1), -0.07214133611645579, 1e-3); - EXPECT_NEAR(mi(2, 2), 0.10720355423870709, 1e-3); - EXPECT_NEAR(mi(2, 3), -84.43085369439521, 1e-3); - EXPECT_NEAR(mi(3, 0), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 1), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 2), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 3), 1.0, 1e-3); - } - { - Matrix m; - m(0, 0) = 0.6178488588834932; m(0, 1) = 0.656563779114608; m(0, 2) = 0.4326508887441579; m(0, 3) = -3.573389719025613; m(1, 0) = -0.7862968825935693; m(1, 1) = 0.5159084191865928; m(1, 2) = 0.33996428553015007; m(1, 3) = 9.98340634305292; m(2, 0) = 0.0; m(2, 1) = -0.5502385909468138; m(2, 2) = 0.8350074808244923; m(2, 3) = 57.03623931292819; m(3, 0) = 0.0; m(3, 1) = 0.0; m(3, 2) = 0.0; m(3, 3) = 1.0; - Matrix mi = m.inverse(); - EXPECT_NEAR(mi(0, 0), 0.6178488588834931, 1e-3); - EXPECT_NEAR(mi(0, 1), -0.7862968825935694, 1e-3); - EXPECT_NEAR(mi(0, 2), -0.0, 1e-3); - EXPECT_NEAR(mi(0, 3), 10.057736045453359, 1e-3); - EXPECT_NEAR(mi(1, 0), 0.656563779114608, 1e-3); - EXPECT_NEAR(mi(1, 1), 0.5159084191865929, 1e-3); - EXPECT_NEAR(mi(1, 2), -0.5502385909468138, 1e-3); - EXPECT_NEAR(mi(1, 3), 28.57917482608178, 1e-3); - EXPECT_NEAR(mi(2, 0), 0.4326508887441579, 1e-3); - EXPECT_NEAR(mi(2, 1), 0.33996428553015007, 1e-3); - EXPECT_NEAR(mi(2, 2), 0.8350074808244924, 1e-3); - EXPECT_NEAR(mi(2, 3), -49.473657871198526, 1e-3); - EXPECT_NEAR(mi(3, 0), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 1), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 2), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 3), 1.0, 1e-3); - } - { - Matrix m; - m(0, 0) = -0.30532791727234754; m(0, 1) = 0.42993321248800975; m(0, 2) = -0.8496659906892062; m(0, 3) = -4.900019523419871; m(1, 0) = -0.9522472698486095; m(1, 1) = -0.13785349298616878; m(1, 2) = 0.272436325656807; m(1, 3) = 61.254180348498465; m(2, 0) = 0.0; m(2, 1) = 0.8922745358191345; m(2, 2) = 0.45149324771113447; m(2, 3) = 41.98722428204593; m(3, 0) = 0.0; m(3, 1) = 0.0; m(3, 2) = 0.0; m(3, 3) = 1.0; - Matrix mi = m.inverse(); - EXPECT_NEAR(mi(0, 0), -0.3053279172723474, 1e-3); - EXPECT_NEAR(mi(0, 1), -0.9522472698486094, 1e-3); - EXPECT_NEAR(mi(0, 2), 0.0, 1e-3); - EXPECT_NEAR(mi(0, 3), 56.83301324799237, 1e-3); - EXPECT_NEAR(mi(1, 0), 0.42993321248800975, 1e-3); - EXPECT_NEAR(mi(1, 1), -0.13785349298616878, 1e-3); - EXPECT_NEAR(mi(1, 2), 0.8922745358191346, 1e-3); - EXPECT_NEAR(mi(1, 3), -26.91334720059331, 1e-3); - EXPECT_NEAR(mi(2, 0), -0.8496659906892063, 1e-3); - EXPECT_NEAR(mi(2, 1), 0.27243632565680703, 1e-3); - EXPECT_NEAR(mi(2, 2), 0.4514932477111345, 1e-3); - EXPECT_NEAR(mi(2, 3), -39.80819202150404, 1e-3); - EXPECT_NEAR(mi(3, 0), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 1), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 2), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 3), 1.0, 1e-3); - } - { - Matrix m; - m(0, 0) = -0.8426665329724763; m(0, 1) = -0.13329457405486883; m(0, 2) = 0.5216758291656588; m(0, 3) = 54.75958681320196; m(1, 0) = -0.5384358032376251; m(1, 1) = 0.20860959822407732; m(1, 2) = -0.81643672217793; m(1, 3) = 91.96965943681118; m(2, 0) = 0.0; m(2, 1) = -0.9688728461755547; m(2, 2) = -0.24755889792871488; m(2, 3) = 99.00199341303772; m(3, 0) = 0.0; m(3, 1) = 0.0; m(3, 2) = 0.0; m(3, 3) = 1.0; - Matrix mi = m.inverse(); - EXPECT_NEAR(mi(0, 0), -0.8426665329724762, 1e-3); - EXPECT_NEAR(mi(0, 1), -0.5384358032376252, 1e-3); - EXPECT_NEAR(mi(0, 2), -2.7755575615628914e-17, 1e-3); - EXPECT_NEAR(mi(0, 3), 95.66382861923651, 1e-3); - EXPECT_NEAR(mi(1, 0), -0.13329457405486886, 1e-3); - EXPECT_NEAR(mi(1, 1), 0.20860959822407737, 1e-3); - EXPECT_NEAR(mi(1, 2), -0.9688728461755547, 1e-3); - EXPECT_NEAR(mi(1, 3), 84.03374523091135, 1e-3); - EXPECT_NEAR(mi(2, 0), 0.5216758291656588, 1e-3); - EXPECT_NEAR(mi(2, 1), -0.8164367221779302, 1e-3); - EXPECT_NEAR(mi(2, 2), -0.2475588979287149, 1e-3); - EXPECT_NEAR(mi(2, 3), 71.02947881694217, 1e-3); - EXPECT_NEAR(mi(3, 0), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 1), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 2), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 3), 1.0, 1e-3); - } - { - Matrix m; - m(0, 0) = -0.7135830808790772; m(0, 1) = 0.0; m(0, 2) = -0.7005706150582712; m(0, 3) = 46.98894352455778; m(1, 0) = 0.5815768734392242; m(1, 1) = 0.5575439866421585; m(1, 2) = -0.5923791380862643; m(1, 3) = -32.31315706340996; m(2, 0) = 0.39059893364393755; m(2, 1) = -0.8301473983330724; m(2, 2) = -0.39785395571371457; m(2, 3) = 7.702713412699751; m(3, 0) = 0.0; m(3, 1) = 0.0; m(3, 2) = 0.0; m(3, 3) = 1.0; - Matrix mi = m.inverse(); - EXPECT_NEAR(mi(0, 0), -0.7135830808790772, 1e-3); - EXPECT_NEAR(mi(0, 1), 0.581576873439224, 1e-3); - EXPECT_NEAR(mi(0, 2), 0.39059893364393744, 1e-3); - EXPECT_NEAR(mi(0, 3), 49.314428298230084, 1e-3); - EXPECT_NEAR(mi(1, 0), -5.551115123125783e-17, 1e-3); - EXPECT_NEAR(mi(1, 1), 0.5575439866421584, 1e-3); - EXPECT_NEAR(mi(1, 2), -0.8301473983330723, 1e-3); - EXPECT_NEAR(mi(1, 3), 24.41039390978577, 1e-3); - EXPECT_NEAR(mi(2, 0), -0.7005706150582711, 1e-3); - EXPECT_NEAR(mi(2, 1), -0.5923791380862641, 1e-3); - EXPECT_NEAR(mi(2, 2), -0.3978539557137144, 1e-3); - EXPECT_NEAR(mi(2, 3), 16.841987936840617, 1e-3); - EXPECT_NEAR(mi(3, 0), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 1), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 2), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 3), 1.0, 1e-3); - } - { - Matrix m; - m(0, 0) = 0.655199358191179; m(0, 1) = -0.7015590749923188; m(0, 2) = 0.2802296653136303; m(0, 3) = -24.378695814492147; m(1, 0) = -0.7554560219005917; m(1, 1) = -0.6084550818878111; m(1, 2) = 0.24304035117451178; m(1, 3) = 36.943036725120294; m(2, 0) = 0.0; m(2, 1) = -0.3709410702804682; m(2, 2) = -0.928656407063011; m(2, 3) = -32.64950630748629; m(3, 0) = 0.0; m(3, 1) = 0.0; m(3, 2) = 0.0; m(3, 3) = 1.0; - Matrix mi = m.inverse(); - EXPECT_NEAR(mi(0, 0), 0.6551993581911789, 1e-3); - EXPECT_NEAR(mi(0, 1), -0.7554560219005915, 1e-3); - EXPECT_NEAR(mi(0, 2), 5.1550786254351327e-17, 1e-3); - EXPECT_NEAR(mi(0, 3), 43.88174541248007, 1e-3); - EXPECT_NEAR(mi(1, 0), -0.7015590749923187, 1e-3); - EXPECT_NEAR(mi(1, 1), -0.6084550818878111, 1e-3); - EXPECT_NEAR(mi(1, 2), -0.37094107028046824, 1e-3); - EXPECT_NEAR(mi(1, 3), -6.735959663194609, 1e-3); - EXPECT_NEAR(mi(2, 0), 0.28022966531363025, 1e-3); - EXPECT_NEAR(mi(2, 1), 0.24304035117451175, 1e-3); - EXPECT_NEAR(mi(2, 2), -0.9286564070630109, 1e-3); - EXPECT_NEAR(mi(2, 3), -32.467188070139514, 1e-3); - EXPECT_NEAR(mi(3, 0), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 1), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 2), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 3), 1.0, 1e-3); - } - { - Matrix m; - m(0, 0) = -0.12316316348384228; m(0, 1) = 0.47851608243384774; m(0, 2) = -0.8693981792095123; m(0, 3) = -97.68194268706864; m(1, 0) = -0.9684362001788849; m(1, 1) = -0.24926156178416892; m(1, 2) = 0.0; m(1, 3) = -93.30408292578261; m(2, 0) = -0.2167075479620758; m(2, 1) = 0.8419566691161013; m(2, 2) = 0.4941121390809829; m(2, 3) = -48.17348057895294; m(3, 0) = 0.0; m(3, 1) = 0.0; m(3, 2) = 0.0; m(3, 3) = 1.0; - Matrix mi = m.inverse(); - EXPECT_NEAR(mi(0, 0), -0.12316316348384225, 1e-3); - EXPECT_NEAR(mi(0, 1), -0.9684362001788847, 1e-3); - EXPECT_NEAR(mi(0, 2), -0.2167075479620758, 1e-3); - EXPECT_NEAR(mi(0, 3), -112.82942545947078, 1e-3); - EXPECT_NEAR(mi(1, 0), 0.47851608243384763, 1e-3); - EXPECT_NEAR(mi(1, 1), -0.2492615617841688, 1e-3); - EXPECT_NEAR(mi(1, 2), 0.8419566691161011, 1e-3); - EXPECT_NEAR(mi(1, 3), 64.04524235620795, 1e-3); - EXPECT_NEAR(mi(2, 0), -0.8693981792095123, 1e-3); - EXPECT_NEAR(mi(2, 1), 0.0, 1e-3); - EXPECT_NEAR(mi(2, 2), 0.49411213908098284, 1e-3); - EXPECT_NEAR(mi(2, 3), -61.12140157794279, 1e-3); - EXPECT_NEAR(mi(3, 0), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 1), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 2), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 3), 1.0, 1e-3); - } - { - Matrix m; - m(0, 0) = -0.8820615884895145; m(0, 1) = -0.11346792289034995; m(0, 2) = -0.45726620757093356; m(0, 3) = -48.8253349197771; m(1, 0) = -0.12758811649101956; m(1, 1) = 0.9918272392560481; m(1, 2) = 0.0; m(1, 3) = 50.033634014775515; m(2, 0) = 0.4535290802601621; m(2, 1) = 0.058341734158967; m(2, 2) = -0.8893298687290875; m(2, 3) = 92.22065810812657; m(3, 0) = 0.0; m(3, 1) = 0.0; m(3, 2) = 0.0; m(3, 3) = 1.0; - Matrix mi = m.inverse(); - EXPECT_NEAR(mi(0, 0), -0.8820615884895142, 1e-3); - EXPECT_NEAR(mi(0, 1), -0.12758811649101953, 1e-3); - EXPECT_NEAR(mi(0, 2), 0.453529080260162, 1e-3); - EXPECT_NEAR(mi(0, 3), -78.50800560549041, 1e-3); - EXPECT_NEAR(mi(1, 0), -0.11346792289034992, 1e-3); - EXPECT_NEAR(mi(1, 1), 0.991827239256048, 1e-3); - EXPECT_NEAR(mi(1, 2), 0.05834173415896697, 1e-3); - EXPECT_NEAR(mi(1, 3), -60.545143551904374, 1e-3); - EXPECT_NEAR(mi(2, 0), -0.45726620757093345, 1e-3); - EXPECT_NEAR(mi(2, 1), 6.120531779240618e-18, 1e-3); - EXPECT_NEAR(mi(2, 2), -0.8893298687290875, 1e-3); - EXPECT_NEAR(mi(2, 3), 59.68841003726312, 1e-3); - EXPECT_NEAR(mi(3, 0), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 1), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 2), 0.0, 1e-3); - EXPECT_NEAR(mi(3, 3), 1.0, 1e-3); - } -} - -/** - * Test des performance de la multiplication matrice * vecteur - * pour de grandes dimensions. - */ -TEST(TestLabo1b, PerformanceMatrixVector) -{ - Matrix A(16384, 16384); // grande matrice avec stockage colonne - Vector v(16384); // grand vecteur - - using namespace std::chrono; - // Test : multiplication avec l'algorithme naif. - high_resolution_clock::time_point t = high_resolution_clock::now(); - naiveMatrixMult(A, v); - const duration naive_t = duration_cast>(high_resolution_clock::now() - t); - - // Test : multiplication avec l'implémentation spécifique pour les matrices avec - // stockage par colonnes. - t = high_resolution_clock::now(); - A* v; - const duration optimal_t = duration_cast>(high_resolution_clock::now() - t); - - EXPECT_TRUE(optimal_t < 0.4 * naive_t) - << "Naive time: " << duration_cast(naive_t).count() << " ms, " - << "optimized time: " << duration_cast(optimal_t).count() << " ms"; -} - -/** - * Test des performances de l'addition matrice + matrice - * pour de grandes dimensions. - */ -TEST(TestLabo1b, PerformanceLargeMatrixMatrix) -{ - // deux grandes matrices à stockage par colonnes - Matrix A(16384, 16384); - Matrix B(16384, 16384); - - using namespace std::chrono; - high_resolution_clock::time_point t = high_resolution_clock::now(); - // Test : addition avec l'algorithme naif - naiveMatrixAddition(A, B); - const duration naive_t = duration_cast>(high_resolution_clock::now() - t); - - // Test : addition avec l'implémentation spécifique pour les matrices à - // stockage par colonnes. - t = high_resolution_clock::now(); - A + B; - const duration optimal_t = duration_cast>(high_resolution_clock::now() - t); - - EXPECT_TRUE(optimal_t < 0.4 * naive_t); -} - -/** - * Test pour la matrice à taille fixe 4D - */ -TEST(TestLabo1b, Matrix4x4SizeTest) -{ - Matrix4d M; - - EXPECT_EQ(M.cols(), 4); - EXPECT_EQ(M.rows(), 4); -} - -/** - * Test pour la matrice à taille fixe 3D - */ -TEST(TestLabo1b, Matrix3x3SizeTest) -{ - Matrix3d M; - - EXPECT_EQ(M.cols(), 3); - EXPECT_EQ(M.rows(), 3); -} diff --git a/labo01/tests/TestsSupplementaire1a.cpp b/labo01/tests/TestsSupplementaire1a.cpp deleted file mode 100644 index 23a2c46..0000000 --- a/labo01/tests/TestsSupplementaire1a.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @file TestsSupplementaire1a.cpp - * - * @brief Tests unitaires supplémentaires de la partie 1a - * - * Nom: - * Code permanent : - * Email : - * - */ - -#include "Matrix.h" -#include "Vector.h" - -#include - -using namespace gti320; - -TEST(TestLabo1a, Supplementaires) -{ - // TODO vos propres tests ici - - // TEST 1 - // - - // TEST 2 - // - - // TEST 3 - // - - // TEST 4 - // - - // TEST 5 - // - - // TEST 6 - // - - // TEST 7 - // - - // TEST 8 - // - - // TEST 9 - // - - // TEST 10 - // - - EXPECT_TRUE(false); -} diff --git a/labo01/tests/TestsSupplementaire1b.cpp b/labo01/tests/TestsSupplementaire1b.cpp deleted file mode 100644 index 0da8450..0000000 --- a/labo01/tests/TestsSupplementaire1b.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/** - * @file TestsSupplementaire1b.cpp - * - * @brief Tests unitaires supplémentaires de la partie 1b - * - * Nom: - * Code permanent : - * Email : - * - */ - -#include "Matrix.h" -#include "Vector.h" -#include "Math3D.h" -#include "Operators.h" - -#include - -using namespace gti320; - -TEST(TestLabo1b, Supplementaires) -{ - // TODO vos propres tests ici - - // TEST 1 - // - - // TEST 2 - // - - // TEST 3 - // - - // TEST 4 - // - - // TEST 5 - // - - // TEST 6 - // - - // TEST 7 - // - - // TEST 8 - // - - // TEST 9 - // - - // TEST 10 - // - - EXPECT_TRUE(false); -} diff --git a/labo_ik/IKApplication.cpp b/labo_ik/IKApplication.cpp index c7fb27c..1c5c409 100644 --- a/labo_ik/IKApplication.cpp +++ b/labo_ik/IKApplication.cpp @@ -20,6 +20,7 @@ #define _USE_MATH_DEFINES #include +#include #include "IKSolver.h" diff --git a/labo_ik/IKApplication.h b/labo_ik/IKApplication.h index 1bc20dd..0470f05 100644 --- a/labo_ik/IKApplication.h +++ b/labo_ik/IKApplication.h @@ -18,6 +18,7 @@ #include #include #include +#include #include "Armature.h" #include "LinkUI.h"