【问题标题】:Eigen library: return a matrix block in a function as lvalue特征库:将函数中的矩阵块作为左值返回
【发布时间】:2012-11-25 04:23:08
【问题描述】:

我正在尝试将矩阵块作为函数的左值返回。假设我的函数如下所示:

Block<Derived> getBlock(MatrixXd & m, int i, int j, int row, int column)
{
    return m.block(i,j,row,column);
}

事实证明,C++ 编译器似乎理解 block() 运算符仅提供临时值,因此编译器禁止将其作为左值返回。但是,在 Eigen 文档中有一些示例,我们可以将 Eigen 用作左值(http://eigen.tuxfamily.org/dox/TutorialBlockOperations.html#TutorialBlockOperationsUsing)所以我想知道我们如何不能对函数做同样的事情返回。

a.block(0,0,2,3) = a.block(2,1,2,3);

谢谢!

【问题讨论】:

    标签: function reference block eigen lvalue


    【解决方案1】:

    我想把自己发现的东西写出来,以便对其他人有所帮助:

    我的基本解决方案是知道您希望块是什么派生类型。在这种情况下:

    Block<MatrixXd> getBlock(MatrixXd & m, int i, int j, int row, int column)
    {
        return m.block(i,j,row,column);
    }
    

    有趣的是,这个方法默认会返回对矩阵 m 内容的引用。所以如果我们这样做:

    MatrixXd m = MatrixXd::Zero(10,10);
    Block<MatrixXd> myBlock = getBlock(m, 1, 1, 3, 3);
    myBlock << 1, 0, 0, 
               0, 1, 0, 
               0, 0, 1;
    

    矩阵 m 中的内容也会被修改。但是请注意,

    MatrixXd m = MatrixXd::Zero(10,10);
    MatrixXd myBlock = getBlock(m, 1, 1, 3, 3);
    myBlock << 1, 0, 0, 
               0, 1, 0, 
               0, 0, 1;
    

    不会工作。我的理解是,一旦我们将块转换为另一种类型,Eigen 会在转换之前复制数据。

    【讨论】:

    • 感谢表达式模板,block() 实际上并没有返回块的副本,而是只返回一个表达式
    • @user3183610 那么如何强制块(表达式)进行评估。我的意思是作为一个有效的左值。
    • @stanleyerror 通过调用 eval() 或将其分配给 Array 或 Matrix 类型(读取不是表达式的内容)。这就是为什么第二个示例不会更改原始矩阵的原因。 Block 是一个指向原始矩阵中元素的表达式,但是当您将块分配给另一个 MatrixXd 变量时,会计算表达式并将结果存储在变量中。与任何MatrixXd mat = other_mat 赋值一样,该变量现在显然拥有自己的内存。
    【解决方案2】:

    我正在尝试这样的事情,特别是返回 4 元素向量的最后 3 个元素,但我无法让它工作。

    解决方案结果不错,但如果您不熟悉尾随返回类型,可能会有点混乱:

    struct foo{
    
      Eigen::Vector4d e_;
    
      // const version
      auto get_tail() const -> const auto { return e_.tail<3>(); };
    
      // non-const version
      auto get_tail() -> auto { return e_.tail<3>(); };
    
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-17
      • 1970-01-01
      • 2022-01-23
      • 2014-12-08
      • 2016-01-01
      • 2012-02-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多