首页 > 解决方案 > 对 Matrix<> 或 Block<> 执行数组操作的特征函数

问题描述

我想做一个可以同时接受 Matrix<> 或 Block<> 对象的函数。

例子:

#include <iostream>
#include <Eigen/Dense>

//A simplified example of the function I'm making
double example_function(const Eigen::MatrixXd & input){
    double d1 = input.array().pow(2).sum();
    double d2 = input.rowwise().norm().sum();
    return d1 + d2;
}


int main(){
    Eigen::MatrixXd m1(3,2);
    m1.setRandom();

    // This works
    example_function(m1);

    // I'd like to make this work
    example_function(m1.block(1,0,2,2));

    return 0;
}

以下不起作用因为 DenseBase 没有 'array' 方法:

template<typename Derived>
double example_function(const Eigen::DenseBase<Derived> & input){
    double d1 = input.array().pow(2).sum();  // array() method invalid 
    double d2 = input.rowwise().norm().sum();
    return d1 + d2;
}

我该怎么办?

标签: c++eigen

解决方案


首先,您的原始代码(带有const MatrixXd&)确实有效,但它会生成不必要的副本。要通过模板函数同时接受Matrix<...>和对象,请使用代替:Block<Matrix<...> >MatrixBaseDenseBase

template<class Derived>
double example_function(const Eigen::MatrixBase<Derived> & input){
    double d1 = input.array().abs2().sum(); // abs2() is simpler/more efficient than pow(2)
    double d2 = input.rowwise().norm().sum();
    return d1 + d2;
}

但是,在您的示例代码m1.block(1,0)中是无效的,因为您需要指定大小以及起始索引,例如,这些工作:

m1.block<1,2>(1,0);
m1.block(1,0, 1,2);

并且m1.Random()应该是m1.setRandom()


推荐阅读