在访问Eigen::VectorXd时使用0作为第二个索引是否安全?

Is it safe to use zero as second index in accessing Eigen::VectorXd?

本文关键字:第二个 索引 是否 安全 Eigen 访问 VectorXd      更新时间:2023-10-16

Eigen::VectorXd有一个Scalar operator()(Index i),它返回向量中索引i处的系数。但是,由于Eigen::VectorXdEigen::Matrix的特殊类型,即Eigen::Matrix<Scalar, Eigen::Dynamic, 1>;类型,因此还存在Scalar operator()(Index i, Index j)

问题:

我可以假设它是安全的(即没有未定义的行为)使用第二个版本,如果我设置j为零?换句话说,下面的代码可以吗?

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

看起来很好,在调试模式下编译时没有失败的断言或警告,但我不是100%确定。

只要v是列向量是安全的,而使用v(i)对列向量和行向量都有效,例如:

template<typename T>
void foo(const T &v) {
  v(2);   // OK
  v(2,0); // -> out of bounds runtime assertion
}
MatrixXd mat(10,10);
foo(mat.row(5));

我将详细说明@ggaels的答案。如果您查看DenseCoeffsBase.h中的operator()定义(我引用3.2.10),您将看到它们都调用coeff(或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);
}

查看PlainObjectBase.h中coeffRef的定义,我们看到偏移量的计算很简单:

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

因此,在行向量的情况下,您必须编写v(0,2)以避免可能的断言失败/越界错误。

相关文章: