Things
This commit is contained in:
parent
1dd80d61bf
commit
cc8068b8fe
|
@ -5,213 +5,197 @@
|
||||||
*
|
*
|
||||||
* @brief Stockage dense pour des données à taille fixe ou dynamique.
|
* @brief Stockage dense pour des données à taille fixe ou dynamique.
|
||||||
*
|
*
|
||||||
* Nom:
|
* Nom: William Nolin
|
||||||
* Code permanent :
|
* Code permanent : NOLW76060101
|
||||||
* Email :
|
* Email : william.nolin.1@ens.etsmtl.ca
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
namespace gti320
|
namespace gti320 {
|
||||||
{
|
enum SizeType {
|
||||||
enum SizeType { Dynamic = -1 };
|
Dynamic = -1
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stockage à taille fixe.
|
* Stockage à taille fixe.
|
||||||
*
|
*
|
||||||
* Le nombre de données à stocker est connu au moment de la compilation.
|
* Le nombre de données à stocker est connu au moment de la compilation.
|
||||||
* Ce nombre est donné par le paramètre de patron : _Size
|
* Ce nombre est donné par le paramètre de patron : _Size
|
||||||
*
|
*
|
||||||
* Un tampon (tableau) de taille `_Size_` est alloué sur la pile d'exécution.
|
* Un tampon (tableau) de taille `_Size_` est alloué sur la pile d'exécution.
|
||||||
*/
|
*/
|
||||||
template<typename _Scalar, int _Size>
|
template<typename _Scalar, int _Size>
|
||||||
class DenseStorage
|
class DenseStorage {
|
||||||
{
|
private:
|
||||||
private:
|
|
||||||
|
|
||||||
// TODO déclarer une variable m_data et allouer la mémoire pour y stocker _Size éléments
|
_Scalar m_data[_Size];
|
||||||
_Scalar* m_data; // <-- Ceci n'est pas bon, à modifier
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructeur par défaut
|
* Constructeur par défaut
|
||||||
*/
|
*/
|
||||||
DenseStorage() { }
|
DenseStorage() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructeur de copie
|
* Constructeur de copie
|
||||||
*/
|
*/
|
||||||
DenseStorage(const DenseStorage& other)
|
DenseStorage(const DenseStorage &other) {
|
||||||
{
|
memcpy(m_data, other.m_data, sizeof(m_data));
|
||||||
memcpy(m_data, other.m_data, sizeof(m_data));
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructeur avec taille spécifiée
|
* Constructeur avec taille spécifiée
|
||||||
*
|
*
|
||||||
* (doit être la même que la taille spécifiée dans le patron)
|
* (doit être la même que la taille spécifiée dans le patron)
|
||||||
*/
|
*/
|
||||||
explicit DenseStorage(int _size) { }
|
explicit DenseStorage(int _size) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor 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);
|
||||||
assert(_size >= 0 && _size == _Size);
|
memcpy(m_data, _data, sizeof(_Scalar) * _size);
|
||||||
memcpy(m_data, _data, sizeof(_Scalar) * _size);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opérateur de copie
|
* Opérateur de copie
|
||||||
*/
|
*/
|
||||||
DenseStorage& operator=(const DenseStorage& other)
|
DenseStorage &operator=(const DenseStorage &other) {
|
||||||
{
|
if (this != &other) {
|
||||||
if (this != &other)
|
assert(other.size() == _Size);
|
||||||
{
|
memcpy(m_data, other.m_data, sizeof(m_data));
|
||||||
assert(other.size() == _Size);
|
}
|
||||||
memcpy(m_data, other.m_data, sizeof(m_data));
|
return *this;
|
||||||
}
|
}
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int size() { return _Size; }
|
static int size() { return _Size; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redimensionne le stockage pour qu'il contienne `size` élément.
|
* 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.
|
||||||
// Ne rien faire. Invalide pour les matrices à taille fixe.
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mets tous les éléments à zéro.
|
* Mets tous les éléments à zéro.
|
||||||
*/
|
*/
|
||||||
void setZero()
|
void setZero() {
|
||||||
{
|
memset(m_data, 0, sizeof(_Scalar) * _Size);
|
||||||
memset(m_data, 0, sizeof(_Scalar) * _Size);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accès au tampon de données (en lecteur seulement)
|
* Accès au tampon de données (en lecteur seulement)
|
||||||
*/
|
*/
|
||||||
const _Scalar* data() const
|
const _Scalar *data() const {
|
||||||
{
|
return &m_data[0];
|
||||||
return m_data;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accès au tampon de données (pour lecture et écriture)
|
* Accès au tampon de données (pour lecture et écriture)
|
||||||
*/
|
*/
|
||||||
_Scalar* data()
|
_Scalar *data() {
|
||||||
{
|
return &m_data[0];
|
||||||
return m_data;
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stockage à taille dynamique.
|
||||||
|
*
|
||||||
|
* Le nombre de données à stocker est déterminé à l'exécution.
|
||||||
|
* Un tampon de la taille demandée doit être alloué sur le tas via
|
||||||
|
* l'opérateur `new []` et la mémoire doit être libérée avec `delete[]`
|
||||||
|
*/
|
||||||
|
template<typename _Scalar>
|
||||||
|
class DenseStorage<_Scalar, Dynamic> {
|
||||||
|
private:
|
||||||
|
_Scalar *m_data;
|
||||||
|
int m_size;
|
||||||
|
|
||||||
/**
|
public:
|
||||||
* Stockage à taille dynamique.
|
|
||||||
*
|
|
||||||
* Le nombre de données à stocker est déterminé à l'exécution.
|
|
||||||
* Un tampon de la taille demandée doit être alloué sur le tas via
|
|
||||||
* l'opérateur `new []` et la mémoire doit être libérée avec `delete[]`
|
|
||||||
*/
|
|
||||||
template<typename _Scalar>
|
|
||||||
class DenseStorage<_Scalar, Dynamic>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
_Scalar* m_data;
|
|
||||||
int m_size;
|
|
||||||
|
|
||||||
public:
|
/**
|
||||||
|
* Constructeur par défaut
|
||||||
|
*/
|
||||||
|
DenseStorage() : m_data(nullptr), m_size(0) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructeur par défaut
|
* Constructeur avec taille spécifiée
|
||||||
*/
|
*/
|
||||||
DenseStorage() : m_data(nullptr), m_size(0) {}
|
explicit DenseStorage(int _size) : m_data(nullptr), m_size(_size) {
|
||||||
|
m_data = new _Scalar[_size];
|
||||||
|
setZero();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructeur avec taille spécifiée
|
* Constructeur de copie
|
||||||
*/
|
*/
|
||||||
explicit DenseStorage(int _size) : m_data(nullptr), m_size(_size)
|
DenseStorage(const DenseStorage &other)
|
||||||
{
|
: m_data(nullptr), m_size(other.m_size) {
|
||||||
// TODO allouer un tampon pour stocker _size éléments de type _Scalar.
|
m_data = new _Scalar[m_size];
|
||||||
|
memcpy(m_data, other.m_data, m_size);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO initialiser ce tampon à zéro.
|
/**
|
||||||
}
|
* Opérateur de copie
|
||||||
|
*/
|
||||||
|
DenseStorage &operator=(const DenseStorage &other) {
|
||||||
|
m_data = other.m_data;
|
||||||
|
m_size = other.m_size;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructeur de copie
|
* Destructeur
|
||||||
*/
|
*/
|
||||||
DenseStorage(const DenseStorage& other)
|
~DenseStorage() {
|
||||||
: m_data(nullptr)
|
delete[] m_data;
|
||||||
, 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.
|
/**
|
||||||
|
* Retourne la taille du tampon
|
||||||
|
*/
|
||||||
|
inline int size() const { return m_size; }
|
||||||
|
|
||||||
}
|
/**
|
||||||
|
* 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) {
|
||||||
|
auto *data = new _Scalar[_size];
|
||||||
|
// memcpy(data, m_data, m_size); // ???
|
||||||
|
|
||||||
/**
|
delete[] m_data;
|
||||||
* Opérateur de copie
|
m_data = data;
|
||||||
*/
|
m_size = _size;
|
||||||
DenseStorage& operator=(const DenseStorage& other)
|
}
|
||||||
{
|
|
||||||
// TODO implémenter !
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructeur
|
* Met tous les éléments à zéro.
|
||||||
*/
|
*/
|
||||||
~DenseStorage()
|
void setZero() {
|
||||||
{
|
memset(m_data, 0, m_size);
|
||||||
// TODO libérer la mémoire allouée
|
}
|
||||||
|
|
||||||
}
|
/**
|
||||||
|
* Accès au tampon de données (en lecteur seulement)
|
||||||
|
*/
|
||||||
|
const _Scalar *data() const { return m_data; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retourne la taille du tampon
|
* Accès au tampon de données (pour lecture et écriture)
|
||||||
*/
|
*/
|
||||||
inline int size() const { return m_size; }
|
_Scalar *data() { return m_data; }
|
||||||
|
};
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Met tous les éléments à zéro.
|
|
||||||
*/
|
|
||||||
void setZero()
|
|
||||||
{
|
|
||||||
// TODO implémenter !
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accès au tampon de données (en lecteur seulement)
|
|
||||||
*/
|
|
||||||
const _Scalar* data() const { return m_data; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accès au tampon de données (pour lecture et écriture)
|
|
||||||
*/
|
|
||||||
_Scalar* data() { return m_data; }
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
564
labo01/Matrix.h
564
labo01/Matrix.h
|
@ -5,339 +5,335 @@
|
||||||
*
|
*
|
||||||
* @brief Implémentation de matrices simples.
|
* @brief Implémentation de matrices simples.
|
||||||
*
|
*
|
||||||
* Nom:
|
* Nom: William Nolin
|
||||||
* Code permanent :
|
* Code permanent : NOLW76060101
|
||||||
* Email :
|
* Email : william.nolin.1@ens.etsmtl.ca
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "MatrixBase.h"
|
#include "MatrixBase.h"
|
||||||
|
|
||||||
namespace gti320
|
namespace gti320 {
|
||||||
{
|
enum StorageType {
|
||||||
enum StorageType
|
ColumnStorage = 0,
|
||||||
{
|
RowStorage = 1
|
||||||
ColumnStorage = 0,
|
};
|
||||||
RowStorage = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
// Déclaration avancée
|
// Déclaration avancée
|
||||||
template <typename _Scalar, int _RowsAtCompile, int _ColsAtCompile, int _StorageType> class SubMatrix;
|
template<typename _Scalar, int _RowsAtCompile, int _ColsAtCompile, int _StorageType>
|
||||||
|
class SubMatrix;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Classe Matrix spécialisé pour le cas générique. (defaut par colonne)
|
* 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)
|
* (le cas d'un stockage par ligne fait l'objet d'une spécialisation de patron, voir plus bas)
|
||||||
*/
|
*/
|
||||||
template <typename _Scalar = double, int _RowsAtCompile = Dynamic, int _ColsAtCompile = Dynamic, int _StorageType = ColumnStorage>
|
template<typename _Scalar = double, int _RowsAtCompile = Dynamic, int _ColsAtCompile = Dynamic, int _StorageType = ColumnStorage>
|
||||||
class Matrix : public MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile> {
|
class Matrix : public MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile> {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructeur par défaut
|
* Constructeur par défaut
|
||||||
*/
|
*/
|
||||||
Matrix() : MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile>() { }
|
Matrix() : MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile>() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructeur de copie
|
* Constructeur de copie
|
||||||
*/
|
*/
|
||||||
Matrix(const Matrix& other) : MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile>(other) { }
|
Matrix(const Matrix &other) : MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile>(other) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructeur avec spécification du nombre de ligne et de colonnes
|
* Constructeur avec spécification du nombre de ligne et de colonnes
|
||||||
*/
|
*/
|
||||||
explicit Matrix(int _rows, int _cols) : MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile>(_rows, _cols) { }
|
explicit Matrix(int _rows, int _cols) : MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile>(_rows, _cols) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructeur
|
* Destructeur
|
||||||
*/
|
*/
|
||||||
~Matrix() { }
|
~Matrix() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opérateur de copie à partir d'une sous-matrice.
|
* Opérateur de copie à partir d'une sous-matrice.
|
||||||
*
|
*
|
||||||
* Exemple : Matrix B = A.block(i,j,m,n);
|
* Exemple : Matrix B = A.block(i,j,m,n);
|
||||||
*/
|
*/
|
||||||
template<typename _OtherScalar, int OtherRows, int _OtherCols, int _OtherStorage>
|
template<typename _OtherScalar, int _OtherRows, int _OtherCols, int _OtherStorage>
|
||||||
Matrix& operator= (const SubMatrix<_OtherScalar, OtherRows, _OtherCols, _OtherStorage>& submatrix)
|
Matrix &operator=(const SubMatrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage> &submatrix) {
|
||||||
{
|
if (_RowsAtCompile != _OtherRows || _ColsAtCompile != _OtherCols) {
|
||||||
// TODO copier les données de la sous-matrice.
|
this->resize(_OtherRows, _OtherCols);
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
// TODO copier les données de la sous-matrice.
|
||||||
* Accesseur à une entrée de la matrice (lecture seule)
|
// 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.
|
||||||
_Scalar operator()(int i, int j) const
|
return *this;
|
||||||
{
|
}
|
||||||
// TODO implementer
|
|
||||||
return (double)(i + j);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accesseur à une entrée de la matrice (lecture ou écriture)
|
* Accesseur à une entrée de la matrice (lecture seule)
|
||||||
*/
|
*/
|
||||||
_Scalar& operator()(int i, int j)
|
_Scalar operator()(int i, int j) const {
|
||||||
{
|
// TODO implementer
|
||||||
// TODO implementer
|
return (double) (i + j);
|
||||||
// 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).
|
* Accesseur à une entrée de la matrice (lecture ou écriture)
|
||||||
*/
|
*/
|
||||||
SubMatrix<_Scalar, _RowsAtCompile, _ColsAtCompile, _StorageType> block(int i, int j, int rows, int cols) const
|
_Scalar &operator()(int i, int j) {
|
||||||
{
|
// TODO implementer
|
||||||
return SubMatrix<_Scalar, _RowsAtCompile, _ColsAtCompile, _StorageType>(*this, i, j, rows, cols);
|
// Indice : l'implémentation est identique à celle de la fonction précédente.
|
||||||
}
|
_Scalar x = (double) (i + j);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calcule l'inverse de la matrice
|
* Crée une sous-matrice pour un block de taille (rows, cols) à partir de l'index (i,j).
|
||||||
*/
|
*/
|
||||||
Matrix inverse() const
|
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);
|
||||||
// Do nothing.
|
}
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retourne la transposée de la matrice
|
* Calcule l'inverse de la matrice
|
||||||
*/
|
*/
|
||||||
template<typename _OtherScalar, int _OtherRows, int _OtherCols, int _OtherStorage>
|
Matrix inverse() const {
|
||||||
Matrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage> transpose() const
|
// Do nothing.
|
||||||
{
|
return *this;
|
||||||
// TODO calcule et retourne la transposée de la matrice.
|
}
|
||||||
|
|
||||||
return Matrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage>(); // pas bon, à changer
|
/**
|
||||||
}
|
* Retourne la transposée de la matrice
|
||||||
|
*/
|
||||||
|
template<typename _OtherScalar, int _OtherRows, int _OtherCols, int _OtherStorage>
|
||||||
|
Matrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage> transpose() const {
|
||||||
|
// TODO calcule et retourne la transposée de la matrice.
|
||||||
|
|
||||||
/**
|
return Matrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage>(); // pas bon, à changer
|
||||||
* 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.
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
/**
|
||||||
|
* 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 <typename _Scalar, int _RowsAtCompile, int _ColsAtCompile>
|
|
||||||
class Matrix< _Scalar, _RowsAtCompile, _ColsAtCompile, RowStorage> : public MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile> {
|
|
||||||
|
|
||||||
public:
|
/**
|
||||||
/**
|
* Classe Matrix spécialisée pour un stockage par lignes
|
||||||
* Constructeur par défaut
|
*/
|
||||||
*/
|
template<typename _Scalar, int _RowsAtCompile, int _ColsAtCompile>
|
||||||
Matrix() : MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile>() { }
|
class Matrix<_Scalar, _RowsAtCompile, _ColsAtCompile, RowStorage>
|
||||||
|
: public MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile> {
|
||||||
|
|
||||||
/**
|
public:
|
||||||
* Constructeur de copie
|
/**
|
||||||
*/
|
* Constructeur par défaut
|
||||||
Matrix(const Matrix& other) : MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile>(other) { }
|
*/
|
||||||
|
Matrix() : MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile>() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructeur avec spécification du nombre de ligne et de colonnes
|
* Constructeur de copie
|
||||||
*/
|
*/
|
||||||
explicit Matrix(int rows, int cols) : MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile>(rows, cols) { }
|
Matrix(const Matrix &other) : MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile>(other) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructeur
|
* Constructeur avec spécification du nombre de ligne et de colonnes
|
||||||
*/
|
*/
|
||||||
~Matrix() { }
|
explicit Matrix(int rows, int cols) : MatrixBase<_Scalar, _RowsAtCompile, _ColsAtCompile>(rows, cols) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opérateur de copie à partir d'une sous-matrice.
|
* Destructeur
|
||||||
*
|
*/
|
||||||
* Exemple : Matrix B = A.block(i,j,m,n);
|
~Matrix() {}
|
||||||
*/
|
|
||||||
template<typename _OtherScalar, int OtherRows, int _OtherCols, int _OtherStorage>
|
|
||||||
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)
|
* Opérateur de copie à partir d'une sous-matrice.
|
||||||
*/
|
*
|
||||||
_Scalar operator()(int i, int j) const
|
* Exemple : Matrix B = A.block(i,j,m,n);
|
||||||
{
|
*/
|
||||||
// TODO implementer
|
template<typename _OtherScalar, int OtherRows, int _OtherCols, int _OtherStorage>
|
||||||
return 0.0;
|
Matrix &operator=(const SubMatrix<_OtherScalar, OtherRows, _OtherCols, _OtherStorage> &submatrix) {
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accesseur à une entrée de la matrice (lecture ou écriture)
|
|
||||||
*/
|
|
||||||
_Scalar& operator()(int i, int j)
|
|
||||||
{
|
|
||||||
// TODO implementer
|
|
||||||
_Scalar x = 0.0;
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
// TODO copier les données de la sous-matrice.
|
||||||
* Crée une sous-matrice pour un block de taille (rows, cols) à partir de l'index (i,j).
|
// 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.
|
||||||
SubMatrix<_Scalar, _RowsAtCompile, _ColsAtCompile, RowStorage> block(int i, int j, int rows, int cols) const {
|
return *this;
|
||||||
return SubMatrix<_Scalar, _RowsAtCompile, _ColsAtCompile, RowStorage>(*this, i, j, rows, cols);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calcule l'inverse de la matrice
|
* Accesseur à une entrée de la matrice (lecture seule)
|
||||||
*/
|
*/
|
||||||
Matrix inverse() const
|
_Scalar operator()(int i, int j) const {
|
||||||
{
|
// TODO implementer
|
||||||
// Do nothing.
|
return 0.0;
|
||||||
return *this;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retourne la transposée de la matrice
|
* Accesseur à une entrée de la matrice (lecture ou écriture)
|
||||||
*/
|
*/
|
||||||
Matrix<_Scalar, _ColsAtCompile, _RowsAtCompile, ColumnStorage> transpose() const
|
_Scalar &operator()(int i, int j) {
|
||||||
{
|
// TODO implementer
|
||||||
// TODO calcule et retourne la transposée de la matrice.
|
_Scalar x = 0.0;
|
||||||
// Optimisez cette fonction en tenant compte du type de stockage utilisé.
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
return Matrix<_Scalar, _ColsAtCompile, _RowsAtCompile, ColumnStorage>();
|
/**
|
||||||
}
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Affecte l'identité à la matrice
|
* Calcule l'inverse de la matrice
|
||||||
*/
|
*/
|
||||||
inline void setIdentity()
|
Matrix inverse() const {
|
||||||
{
|
// Do nothing.
|
||||||
// TODO affecter la valeur 0.0 partour, sauf sur la diagonale principale où c'est 1.0..
|
return *this;
|
||||||
// Votre implémentation devrait aussi fonctionner pour des matrices qui ne sont pas carrées.
|
}
|
||||||
}
|
|
||||||
|
|
||||||
};
|
/**
|
||||||
|
* 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>();
|
||||||
* 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 <typename _Scalar, int _RowsAtCompile, int _ColsAtCompile, int _StorageType>
|
|
||||||
class SubMatrix
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
// Référence à la matrice originale
|
|
||||||
Matrix<_Scalar, _RowsAtCompile, _ColsAtCompile, _StorageType>& m_matrix;
|
|
||||||
|
|
||||||
// Constructeur par défaut (privé)
|
/**
|
||||||
SubMatrix() {}
|
* 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.
|
||||||
|
}
|
||||||
|
|
||||||
// (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)
|
* Classe pour accéder à une sous-matrice.
|
||||||
int m_cols; // Largeur de la sous-matrice (nombre de colonnes)
|
*
|
||||||
|
* Un sous-matrice ne copie pas les données. Au lieu de cela, elle conserve une
|
||||||
|
* référence à la matrice originale.
|
||||||
|
*/
|
||||||
|
template<typename _Scalar, int _RowsAtCompile, int _ColsAtCompile, int _StorageType>
|
||||||
|
class SubMatrix {
|
||||||
|
private:
|
||||||
|
// Référence à la matrice originale
|
||||||
|
Matrix<_Scalar, _RowsAtCompile, _ColsAtCompile, _StorageType> &m_matrix;
|
||||||
|
|
||||||
public:
|
// Constructeur par défaut (privé)
|
||||||
|
SubMatrix() {}
|
||||||
|
|
||||||
/**
|
// (i,j) est le coin supérieur gauche de la sous-matrice
|
||||||
* Constructeur à partir d'une référence en lecture seule à une matrice.
|
int m_i; // Décalage en ligne
|
||||||
*/
|
int m_j; // Décalage en colonne
|
||||||
SubMatrix(const Matrix<_Scalar, _RowsAtCompile, _ColsAtCompile, _StorageType>& _matrix, int _i, int _j, int _rows, int _cols) :
|
|
||||||
m_matrix(const_cast<Matrix<_Scalar, _RowsAtCompile, _ColsAtCompile, _StorageType>&>(_matrix)),
|
|
||||||
m_i(_i), m_j(_j), m_rows(_rows), m_cols(_cols)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
// la sous-matrice est de dimension : m_rows x m_cols
|
||||||
* Constructeur à partir d'une référence en lecture et écriture à une matrice.
|
int m_rows; // Hauteur de la sous-matrice (nombre de lignes)
|
||||||
*/
|
int m_cols; // Largeur de la sous-matrice (nombre de colonnes)
|
||||||
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)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructeur de copie
|
* Constructeur à partir d'une référence en lecture seule à une matrice.
|
||||||
*/
|
*/
|
||||||
SubMatrix(const SubMatrix& other) :
|
SubMatrix(const Matrix<_Scalar, _RowsAtCompile, _ColsAtCompile, _StorageType> &_matrix, int _i, int _j,
|
||||||
m_matrix(other.m_matrix),
|
int _rows, int _cols) :
|
||||||
m_i(other.m_i), m_j(other.m_j), m_rows(other.m_rows), m_cols(other.m_cols)
|
m_matrix(const_cast<Matrix<_Scalar, _RowsAtCompile, _ColsAtCompile, _StorageType> &>(_matrix)),
|
||||||
{
|
m_i(_i), m_j(_j), m_rows(_rows), m_cols(_cols) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructeur
|
* Constructeur à partir d'une référence en lecture et écriture à une matrice.
|
||||||
*/
|
*/
|
||||||
~SubMatrix() { }
|
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) {
|
||||||
|
|
||||||
/**
|
}
|
||||||
* 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<typename _OtherScalar, int _OtherRows, int _OtherCols, int _OtherStorage>
|
|
||||||
SubMatrix& operator= (const Matrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage>& matrix)
|
|
||||||
{
|
|
||||||
// TODO Cpopie les valeurs de la matrice dans la sous-matrice.
|
|
||||||
// Note les dimensions de la matrice doivent correspondre à celle de
|
|
||||||
// la sous-matrice.
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accesseur aux entrées de la sous-matrice (lecture seule)
|
* Constructeur de copie
|
||||||
*
|
*/
|
||||||
* Note : il faut s'assurer que les indices respectent la taille de la
|
SubMatrix(const SubMatrix &other) :
|
||||||
* sous-matrice
|
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) {
|
||||||
_Scalar operator()(int i, int j) const
|
}
|
||||||
{
|
|
||||||
// TODO implémenter
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accesseur aux entrées de la sous-matrice (lecture et écriture)
|
* Destructeur
|
||||||
*
|
*/
|
||||||
* Note : il faut s'assurer que les indices respectent la taille de la
|
~SubMatrix() {}
|
||||||
* 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.
|
* Opérateur de copie (à partir d'une matrice)
|
||||||
*/
|
*
|
||||||
template<typename _OtherScalar, int _OtherRows, int _OtherCols, int _OtherStorage>
|
* Copies toutes les entrées de la matrice dans la sous-matrice.
|
||||||
Matrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage> transpose() const
|
*
|
||||||
{
|
* Note : la taille de la matrice doit correspondre à la taille de la
|
||||||
// TODO implémenter
|
* sous-matrice.
|
||||||
return Matrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage>();
|
*/
|
||||||
}
|
template<typename _OtherScalar, int _OtherRows, int _OtherCols, int _OtherStorage>
|
||||||
|
SubMatrix &operator=(const Matrix<_OtherScalar, _OtherRows, _OtherCols, _OtherStorage> &matrix) {
|
||||||
|
// TODO Cpopie les valeurs de la matrice dans la sous-matrice.
|
||||||
|
// Note les dimensions de la matrice doivent correspondre à celle de
|
||||||
|
// la sous-matrice.
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
inline int rows() const { return m_rows; }
|
/**
|
||||||
inline int cols() const { return m_cols; }
|
* 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 <= m_rows);
|
||||||
|
assert(j > 0);
|
||||||
|
assert(j <= m_cols);
|
||||||
|
|
||||||
};
|
int full_i = this->m_i + i;
|
||||||
|
int full_j = this->m_j + j;
|
||||||
|
int storage_index = full_i * this->m_matrix.rows() + full_j;
|
||||||
|
|
||||||
|
return this->m_matrix.data()[storage_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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<typename _OtherScalar, int _OtherRows, int _OtherCols, int _OtherStorage>
|
||||||
|
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; }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
*
|
*
|
||||||
* @brief Classe contenant les éléments de base des matrices et des vecteurs.
|
* @brief Classe contenant les éléments de base des matrices et des vecteurs.
|
||||||
*
|
*
|
||||||
* Nom:
|
* Nom: William Nolin
|
||||||
* Code permanent :
|
* Code permanent : NOLW76060101
|
||||||
* Email :
|
* Email : william.nolin.1@ens.etsmtl.ca
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -44,7 +44,8 @@ namespace gti320
|
||||||
/**
|
/**
|
||||||
* Destructeur
|
* Destructeur
|
||||||
*/
|
*/
|
||||||
~MatrixBase() { }
|
~MatrixBase() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
158
labo01/Vector.h
158
labo01/Vector.h
|
@ -5,9 +5,9 @@
|
||||||
*
|
*
|
||||||
* @brief Implémentation de vecteurs simples
|
* @brief Implémentation de vecteurs simples
|
||||||
*
|
*
|
||||||
* Nom:
|
* Nom: William Nolin
|
||||||
* Code permanent :
|
* Code permanent : NOLW76060101
|
||||||
* Email :
|
* Email : William Nolin
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -16,89 +16,91 @@
|
||||||
|
|
||||||
namespace gti320 {
|
namespace gti320 {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Classe vecteur générique.
|
* Classe vecteur générique.
|
||||||
*
|
*
|
||||||
* Cette classe réutilise la classe `MatrixBase` et ses spécialisations de
|
* Cette classe réutilise la classe `MatrixBase` et ses spécialisations de
|
||||||
* templates pour les manipulation bas niveau.
|
* templates pour les manipulation bas niveau.
|
||||||
*/
|
*/
|
||||||
template <typename _Scalar = double, int _Rows = Dynamic>
|
template<typename _Scalar = double, int _Rows = Dynamic>
|
||||||
class Vector : public MatrixBase<_Scalar, _Rows, 1> {
|
class Vector : public MatrixBase<_Scalar, _Rows, 1> {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructeur par défaut
|
* Constructeur par défaut
|
||||||
*/
|
*/
|
||||||
Vector() : MatrixBase<_Scalar, _Rows, 1>() { }
|
Vector() : MatrixBase<_Scalar, _Rows, 1>() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contructeur à partir d'un taille (rows).
|
* Contructeur à partir d'un taille (rows).
|
||||||
*/
|
*/
|
||||||
explicit Vector(int rows) : MatrixBase<_Scalar, _Rows, 1>(rows, 1) { }
|
explicit Vector(int rows) : MatrixBase<_Scalar, _Rows, 1>(rows, 1) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructeur de copie
|
* Constructeur de copie
|
||||||
*/
|
*/
|
||||||
Vector(const Vector& other) : MatrixBase<_Scalar, _Rows, 1>(other) { }
|
Vector(const Vector &other) : MatrixBase<_Scalar, _Rows, 1>(other) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructeur
|
* Destructeur
|
||||||
*/
|
*/
|
||||||
~Vector() { }
|
~Vector() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opérateur de copie
|
* Opérateur de copie
|
||||||
*/
|
*/
|
||||||
Vector& operator=(const Vector& other)
|
Vector &operator=(const Vector &other) {
|
||||||
{
|
// TODO implémenter
|
||||||
// TODO implémenter
|
this->m_storage = other.m_storage;
|
||||||
this->m_storage = other.m_storage;
|
return *this;
|
||||||
return *this;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accesseur à une entrée du vecteur (lecture seule)
|
* Accesseur à une entrée du vecteur (lecture seule)
|
||||||
*/
|
*/
|
||||||
_Scalar operator()(int i) const
|
_Scalar operator()(int i) const {
|
||||||
{
|
return this->data()[i];
|
||||||
// TODO implémenter
|
}
|
||||||
return (double)i;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accesseur à une entrée du vecteur (lecture et écriture)
|
* Accesseur à une entrée du vecteur (lecture et écriture)
|
||||||
*/
|
*/
|
||||||
_Scalar& operator()(int i)
|
_Scalar &operator()(int i) {
|
||||||
{
|
return this->m_storage.data()[i];
|
||||||
// TODO implémenter
|
}
|
||||||
_Scalar x = (double)i;
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modifie le nombre de lignes du vecteur
|
* Modifie le nombre de lignes du vecteur
|
||||||
*/
|
*/
|
||||||
void resize(int _rows)
|
void resize(int _rows) {
|
||||||
{
|
MatrixBase<_Scalar, _Rows, 1>::resize(_rows, 1);
|
||||||
MatrixBase<_Scalar, _Rows, 1>::resize(_rows, 1);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Produit scalaire de *this et other.
|
* Produit scalaire de *this et other.
|
||||||
*/
|
*/
|
||||||
inline _Scalar dot(const Vector& other) const
|
inline _Scalar dot(const Vector &other) const {
|
||||||
{
|
assert(this->size() == other.size());
|
||||||
// TODO implémenter
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
_Scalar product = 0;
|
||||||
* Retourne la norme euclidienne du vecteur
|
for (int i = 0; i < this->size(); i++) {
|
||||||
*/
|
product += this->data()[i] * other.data()[i];
|
||||||
inline _Scalar norm() const
|
}
|
||||||
{
|
|
||||||
// TODO implémenter
|
return product;
|
||||||
return 0.0;
|
}
|
||||||
}
|
|
||||||
};
|
/**
|
||||||
|
* 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->data()[i], 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::sqrt(norm);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue