【问题标题】:how to create a vector of Eigen::Ref如何创建 Eigen::Ref 的向量
【发布时间】:2018-03-04 16:26:27
【问题描述】:

我想引用 Eigen::MatrixXd 中的不连续行。这将在函数中作为参数传递,而不更改 MatrixXd(行主要)值。 因为我总是需要选择某些行来传递给这个函数, 我想我可以使用对选定行的引用向量。

但即使创建这个向量似乎也是不可能的:点有P.rows() 行数但每一行都是相同的,即 P 中的最后一行。

你能告诉我为什么会发生这种情况以及如何解决它吗?

typedef Eigen::Ref<const Eigen::RowVector3d> OctreePoint;
typedef std::vector<OctreePoint> OctreePoints;

Eigen::MatrixXd P;
// load P from some file
OctreePoints points; 
for (int i = 0; i < P.rows(); ++i)
    {
            // OctreePoint p = P.row(i);
        points.push_back(P.row(i));
        // std::cout << p << std::endl;
     }
std::cout << points << std::endl;

【问题讨论】:

    标签: c++ vector reference eigen3


    【解决方案1】:

    这里的主要问题: P.row(i) 将有一个内在的步伐,因为 P 是(与您的假设相反)列专业。这使得每个 Eigen::Ref 都包含一个临时文件,其中包含该行的副本(即,它不是实际引用)。

    您在这里基本上有两个选择:

    1. 使用Eigen::Ref&lt;const Eigen::RowVector3d, 0, Eigen::InnerStride&lt;&gt; &gt; 获取实际参考。
    2. 使用Eigen::Matrix&lt;double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor&gt; P;P 设为rowmajor

    这是一个使用 1 的(非常量)变体的示例:

        typedef Eigen::Ref<Eigen::RowVector3d, 0, Eigen::InnerStride<> > OctreePoint;
        typedef std::vector<OctreePoint> OctreePoints;
    
        // Alternatively, use this for P:
        // Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> P;
        Eigen::MatrixXd P;
        P.setRandom(3,3);
        std::cout << P << " @ " << P.data() << "\n\n";
        OctreePoints points;
        points.reserve(1);
        for (int i = 0; i < P.rows(); ++i)
        {
            points.push_back(P.row(i));
        }
        points[0][0] = 42.0; // Modify an element of `points` for testing purposes
    
        for(auto p : points ) std::cout << p << " @ " << p.data() << '\n';
    
        std::cout << '\n' << P << '\n';
    

    这会产生类似以下的输出:

     0.680375   0.59688 -0.329554
    -0.211234  0.823295  0.536459
     0.566198 -0.604897 -0.444451 @ 0x25b8c20
    
           42   0.59688 -0.329554 @ 0x25b8c20
    -0.211234  0.823295  0.536459 @ 0x25b8c28
     0.566198 -0.604897 -0.444451 @ 0x25b8c30
    
           42   0.59688 -0.329554
    -0.211234  0.823295  0.536459
     0.566198 -0.604897 -0.444451
    

    一般来说,我会非常谨慎地将不可复制的成员存储到std::vector——只要你只是push_back(或者更好的emplace_back),一切都应该没问题。如果您开始在向量内移动元素,编译将失败或可能导致奇怪的结果。

    【讨论】:

    • 感谢您的回答。提供的解决方案解决了问题。不确定我是否理解为什么点中的旧元素被临时元素替换
    猜你喜欢
    • 1970-01-01
    • 2017-03-10
    • 1970-01-01
    • 2014-10-30
    • 1970-01-01
    • 2014-02-03
    • 2022-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多