寻找更好的方法来初始化Eigen3矩阵

时间:2013-11-15 15:14:01

标签: c++ eigen3

我有一种情况,我从一个带有双元素的复杂元素中导出一个Eigen3矩阵。目前我只是循环遍历行和列并逐个填写条目。我想知道是否有人知道任何方法:

 complexMatrix = doubleMatrix.unaryExpr(transform)

2 个答案:

答案 0 :(得分:1)

Eigen中有一个名为cast的运算符。由于模板的原因,声明看起来很可怕,但使用非常简单。

我认为这应该有用

complexMatrix = doubleMatrix.cast< std::complex<double> >();

编辑,嗯,好吧......有办法做到这一点。文档中有一个示例:http://eigen.tuxfamily.org/dox/classEigen_1_1MatrixBase.html#a23fc4bf97168dee2516f85edcfd4cfe7

但是我相信,要获得正确的类型,您需要将cast和仿函数结合起来。

complexMatrix = doubleMatrix.cast< std::complex<double> >().unaryExpr( FUNCTOR );

当然,仿函数应该设计为使用复杂的Scalar类型。您还可以使用带有普通函数的fnc_ptr包装器,如示例所示。

注意:当使用接受double并返回复杂的functor类时,可能会跳过cast,但我没有设法完成它。这会很棘手。我也认为没有必要因为cast可能不会引入任何实际开销。

编辑:工作示例。

它确实会引入一些开销,从x来回转换doublecomplex 2次,但我认为与实际的函子体相比,它可以忽略不计。

#include <Eigen/Core>
#include <iostream>
using namespace Eigen;
using namespace std;

std::complex<double> functor(double x){
  //complicated stuff
  return std::complex<double> (x, -2*x) ;
}

std::complex<double> wrapper(std::complex<double> x)
{
    //nothing is lost here, as we expect x to have only real part 
    //from being upcasted from the original matrix
    double xReal = x.real();
    return functor(xReal);
}

int main(int, char**)
{
  Matrix4d m1 = Matrix4d::Random();
  cout << m1 << endl << "becomes: " << endl 
       << m1.cast< std::complex<double> >().unaryExpr(ptr_fun(wrapper)) << endl;
  return 0;
}

答案 1 :(得分:1)

unaryExpr可以从仿函数推导出返回类型,因此可以这样做:

#include <Eigen/Core>
std::complex<double> functor(double x){
  return std::complex<double> (-x, x) ;
}
int main(int, char**)
{
  Eigen::Matrix3d m1 = Eigen::Matrix3d::Random();
  Eigen::Matrix3cd m2 = m1.unaryExpr(std::ptr_fun(functor));
}

并使用仿函数类:

#include <Eigen/Core>
struct Functor {
  typedef std::complex<double> result_type;
  std::complex<double> operator()(double x) const {
    return std::complex<double> (-x, x) ;
  }
};
int main(int, char**)
{
  Eigen::Matrix3d m1 = Eigen::Matrix3d::Random();
  Eigen::Matrix3cd m2 = m1.unaryExpr(Functor());
}