从 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 之前减一,然后将它们加一。
我正在通过 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 之前减一,然后将它们加一。