用Eigen映射复矩阵

时间:2015-01-12 15:32:24

标签: c++ matrix eigen

我有以下矩阵:

int N = 3;
complex<double>* complexvector = new complex<double>[N];
for(int i=0; i<N; i++)
        {
            complexvector[i]=complex<double>(i+1,i+1);
        }



complex<double>** complexMatrix = new complex<double>*[N];
    for(int i=0; i<N; i++)
    {
        complexMatrix[i] = new complex<double>[N];// allocate an array to each pointer
    }



complexMatrix[0][0] = complex<double>(1,1);
complexMatrix[0][1] = complex<double>(2,2);
complexMatrix[0][2] = complex<double>(3,3);

complexMatrix[1][0] = complex<double>(4,4);
complexMatrix[1][1] = complex<double>(5,5);
complexMatrix[1][2] = complex<double>(6,6);

complexMatrix[2][0] = complex<double>(7,7);
complexMatrix[2][1] = complex<double>(8,8);
complexMatrix[2][2] = complex<double>(9,9);


complex<double>* returnvector = new complex<double>[N];
returnvector = preformcholesky(complexMatrix, complexvector, N);

我在这里做Cholesky:

complex<double>* preformcholesky(complex<double>** matrix, complex<double>* vector, 
int  size)
{
std::cout << "start cholesky" << std::endl;
Map<MatrixXcd, RowMajor> mat(*matrix,size,size);
Map<VectorXcd> vec(vector,size);
printMatrix(matrix,size);
std::cout << "mat" << mat << std::endl;
std::cout << "vec" << vec << std::endl;
//mat.llt();
VectorXcd x = mat.llt().solve(vec);
std::cout << "coeff" << x << std::endl;
return x.data();
}

问题是当打印出“垫子”时,它是这样的:

mat           (1,1) (0,3.21143e-322)            (6,6)
       (2,2)            (4,4) (0,3.21143e-322)
       (3,3)            (5,5)            (7,7)

那些(0,3.21143e-322)来自哪里?如果我打印“矩阵”然后就可以了,所以我认为地图出了问题。如果您需要更多代码,请告诉我。我是Eigen的新手所以也许是一些基本错误。我正在使用C ++和Linux。

1 个答案:

答案 0 :(得分:2)

该代码有几个问题。例如,performcholesky的返回值是指向performcholesky返回后不再存在的局部变量的指针,并且用这个悬空指针覆盖指向已分配内存的指针,泄漏该内存。为什么不直接使用Eigen::MatrixXcd?你以后会为自己省去一个痛苦的调试世界。

无论如何,你遇到的问题是Eigen::Map构造函数需要一个平面数组,而不是一个指向指针的指针。它应该像这样使用:

// It would also work with naked new, but naked new leads to pain, fear, anger,
// and suffering. Also to long hours of debugging.
std::vector<std::complex<double> > data(N * N);

for(int i = 0; i < N * N; ++i) {
  data[i] = std::complex<double>(i, i);
}

Eigen::Map<Eigen::MatrixXcd, Eigen::RowMajor> mat(&data[0], N, N);

一个有趣的问题是,为什么你没有传递给构造函数的两个数组仍会显示在地图中,如果稍微移位的话。答案是:通过纯粹的偶然事件,new给了你三块内存,它们在堆上紧挨着。这也解释了你在地图中看到的奇怪文物;这些是相应分配块的堆实现的簿记数据,重新解释为double s。本质上,complexmatrix[0]周围的内存如下所示:

  the area that Eigen::Map uses
+-----------------------------------------------------------------+
|(1,1)|(2,2)|(3,3)|bookkeeping|(4,4)|(5,5)|(6,6)|bookkeeping|(7,7)|(8,8)|(9,9)|
+-----------------+           +-----------------+           +-----------------+
 ^-complexmatrix[0]            ^-complexmatrix[1]            ^-complexmatrix[2]

当然,这不是你可以依赖的行为。如果块new给出的块以不同的方式排列,代码也可以显示任何随机数据或崩溃与段错误。