从 MATLAB 工作区映射 Eigen 中的复杂稀疏矩阵

Mapping complex sparse matrix in Eigen from MATLAB workspace

我正在通过 Matlab 的 mex 函数使用 Eigen 求解器求解线性代数方程 Ax = b。给定一个来自 Matlab 工作区的复杂稀疏矩阵 A 和一个稀疏向量 b,我想以特征稀疏矩阵格式映射矩阵 A 和向量 b。之后,我需要使用 Eigen 的线性方程求解器来求解它。最后我需要将结果 x 传输到 Matlab 工作区。

但是,由于本人C++不好,对Eigen也不熟悉。我停留在第一步,即以 Eigen 接受的格式构建复杂的稀疏矩阵。

我发现Eigen中有如下函数,

Eigen::MappedSparseMatrix<double,RowMajor>  mat(rows, cols, nnz, row_ptr, col_index, values);

我可以使用 mxGetPr、mxGetPi、mxGetIr、mxGetJc 等这些 mex 函数来获取上述 "rows, cols, nnz, row_ptr, col_index, values" 的信息。但是,由于在我的例子中,矩阵 A 是一个复杂的稀疏矩阵,所以我不确定 "MappedSparseMatrix" 是否可以做到这一点。

如果可以,"MappedSparseMatrix"的格式应该怎样?以下是正确的吗?

Eigen::MappedSparseMatrix<std::complex<double>> mat(rows, cols, nnz, row_ptr, col_index, values_complex);

如果是这样,我应该如何构造 values_complex ? 我之前发现了一个relevant topic。我可以使用以下代码来获得复杂的密集矩阵。

MatrixXcd mat(m,n);
mat.real() = Map<MatrixXd>(realData,m,n);
mat.imag() = Map<MatrixXd>(imagData,m,n);

但是,由于我的矩阵A是一个稀疏矩阵,如果我将mat定义为一个复杂的稀疏矩阵,似乎会产生错误,如下所示:

SparseMatrix<std::complex<double> > mat;
mat.real()  =  Map<SparseMatrix>(rows, cols, nnz, row_ptr, col_index, realData);
mat.imag() = Map<SparseMatrix>(rows, cols, nnz, row_ptr, col_index, imagData);

那么有人可以为此提供一些建议吗?

MatlLab 将复数条目存储在两个单独的缓冲区中:一个用于实部,一个用于虚部,而 Eigen 需要将它们交错:

value_ptr = [r0,i0,r1,i1,r2,i2,...]

以便与 std::complex<> 兼容。因此,在您的情况下,您必须自己创建一个临时缓冲区,其中包含要传递给 MappedSparseMatrix 的交错格式的值,或者,如果使用 Eigen 3.3,则传递给 Map<SparseMatrix<double,RowMajor> >.

此外,您必须调整索引的缓冲区,使它们从零开始。为此,将 col_ptr 和 row_ptr 的所有条目在传递给 Eigen 之前减一,然后将它们加一。