gpt4 book ai didi

c++ - 使用Eigen::Transpose 的正确方法?

转载 作者:行者123 更新时间:2023-12-02 10:19:40 25 4
gpt4 key购买 nike

我有一个旋转类,可以使用四元数或旋转矩阵表示旋转。如下定义转置函数时,我没有问题:

Matrix3 Rot3::transpose() const {
// quaternion_ is a class variable of type `Quaternion`.
return quaternion_.toRotationMatrix().transpose();
}

当我使用 Eigen::Transpose切换到推荐版本时,我的单元测试失败(并且我得到了NaN)

Eigen::Transpose<const Matrix3> Rot3::transpose() const {
// quaternion_ is a class variable of type `Quaternion`.
return quaternion_.toRotationMatrix().eval().transpose();
}

我需要以这种怪异的方式使用 .eval(),否则编译器会发出模糊的错误消息。我的猜测是我对 Eigen::Transpose声明的使用与我返回的内容不符。关于此方法为何表现如此奇怪的任何帮助或建议,以及有关执行此方法的正确方法的任何建议?

最佳答案

Eigen::Transpose 只是围绕现有矩阵的包装器类。它保留对矩阵的引用,并在反转索引的同时中继调用以访问元素。此类的目标是能够使用转置矩阵,而不必实际复制矩阵本身。

换句话说,这是Transpose类的定义的非常简化的版本:

struct Transpose<const Matrix3> {

const Matrix3& m_matrix;

const float& coeffRef(int row, int col) const {
return m_matrix.coeffRef(col,row);
}
}

您可以看到实际的来源 here

关键部分是 Transpose类存储给定矩阵的 引用

现在,您的 transpose函数的第二个版本中会发生什么?
  • 您使用Matrix3创建一个临时quaternion.toRotationMatrix().eval()
  • 之后,您将围绕此临时矩阵创建一个Transpose包装器,并存储对该矩阵的引用。

  • 当您从函数返回时,返回的 Transpose具有对超出范围的对象的引用。这称为 dangling reference,它导致未定义的行为(看到 NaN的原因很可能是临时矩阵所在的内存已被其他数据覆盖)。该代码等效于此:
    Eigen::Transpose<const Matrix3> Rot3::transpose() const {
    // Equivalent to your second version
    Matrix3 temp = quaternion_.toRotationMatrix().eval();
    Transpose<const Matrix3> result = temp.transpose(); // Holds ref to temp -> Leads to UB
    return result;
    }

    请注意,在第一个版本中不会发生这种情况,因为您的返回类型为 Matrix3。在这种情况下,您创建的 Transpose对象将转换为要返回的新 Matrix3对象,该对象将复制系数。这是您的第一个功能的等效版本。
    Matrix3 Rot3::transpose() const {
    // Equivalent to your first version
    Matrix3 temp = quaternion_.toRotationMatrix().eval();
    Matrix3 result = temp.transpose(); // Does a full copy of the transpose of `temp`
    return result;
    }

    如果您仍然想继续使用 Eigen::Transpose作为返回类型(也许您真的想避免复制操作),则需要将旋转矩阵存储在一个永久位置(例如,在类中作为缓存的 Matrix3成员变量),以避免发生这种情况悬而未决的引用问题。

    另一种选择是传递预先存在的矩阵以进行填充,例如
    void Rot3::setToTranspose() (Matrix3& result)
    {
    result = quaternion_.toRotationMatrix().transpose();
    }

    关于c++ - 使用Eigen::Transpose <const Matrix3>的正确方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60749047/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com