4 votes

Est-il sûr d'utiliser zéro comme deuxième indice pour accéder à Eigen::VectorXd ?

Eigen::VectorXd a un Scalar operator()(Index i) qui renvoie le coefficient à l'index i dans le vecteur. Cependant, puisque Eigen::VectorXd est un type spécial d'un Eigen::Matrix, c'est-à-dire de type Eigen::Matrix;, il y a aussi un Scalar operator()(Index i, Index j).

Question :

Puis-je supposer que c'est sûr (c'est-à-dire qu'il n'y a pas de comportement indéfini) d'utiliser la deuxième version si je définis j à zéro ? En d'autres termes, le code ci-dessous est-il correct ?

Eigen::VectorXd v(4);
v << 1, 2, 3, 4;
std::cout << v(2, 0); // affiche 3

Il semble que ce soit correct, il n'y a pas d'assertions échouées ou d'avertissements lors de la compilation en mode débogage avec tous les avertissements activés, mais je ne suis pas sûr à 100%.

4voto

ggael Points 18968

C'est sûr tant que v est un vecteur colonne, alors que l'utilisation de v(i) fonctionne pour les vecteurs colonne et ligne, par exemple :

template
void foo(const T &v) {
  v(2);   // OK
  v(2,0); // -> assertion d'exécution hors limites
}
MatrixXd mat(10,10);
foo(mat.row(5));

2voto

Avi Ginsburg Points 6755

Je vais développer la réponse de @ggaels answer. Si vous regardez les définitions de operator() dans DenseCoeffsBase.h (je cite 3.2.10), vous verrez qu'elles appellent toutes deux coeff (ou coeffRef)

EIGEN_STRONG_INLINE CoeffReturnType operator()(Index row, Index col) const
{
  eigen_assert(row >= 0 && row < rows()
      && col >= 0 && col < cols());
  return derived().coeff(row, col);
}

EIGEN_STRONG_INLINE CoeffReturnType
operator()(Index index) const
{
  eigen_assert(index >= 0 && index < size());
  return derived().coeff(index);
}

En regardant les définitions de coeffRef dans PlainObjectBase.h, nous voyons que le décalage est simplement calculé :

EIGEN_STRONG_INLINE Scalar& coeffRef(Index rowId, Index colId)
{
  if(Flags & RowMajorBit)
    return m_storage.data()[colId + rowId * m_storage.cols()];
  else // en mode colonne
    return m_storage.data()[rowId + colId * m_storage.rows()];
}

EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
{
  return m_storage.data()[index];
}

Ainsi, dans le cas d'un vecteur ligne, vous devriez écrire v(0,2) pour éviter d'éventuelles erreurs d'assertion/ hors limites.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X