本征:如果 innerIndexPtr 向量排序不正确,则 selfadjointView 不起作用

Eigen: selfadjointView does not work if innerIndexPtr vector is not well ordered

在实时系统上工作,我使用低级别 API 来操作特征稀疏矩阵,以提高特定问题集的性能。 特别是我将 Eigen 与 CSparse cs_symperm 算法的变体混合以获得 A 矩阵的排列:Ap = PAP'。 cs_symperm 对稀疏矩阵使用相同的低级结构,但对于固定列,行索引可能排序不当。

这是一个手工构建的简单示例,说明可能发生的情况:

SparseMatrix<double> A( 2, 2 );
A.insert( 0, 0 ) = 1.0;
A.insert( 0, 1 ) = 2.0;
A.insert( 1, 1 ) = 3.0;
A.makeCompressed();
SparseMatrix<double> B = A;
B.innerIndexPtr()[0] = 0;
B.innerIndexPtr()[1] = 1; // <-- Not ordered
B.innerIndexPtr()[2] = 0; // <-- Not ordered
B.valuePtr()[0] = 1.0;
B.valuePtr()[1] = 3.0; // <-- Not ordered
B.valuePtr()[2] = 2.0; // <-- Not ordered

这里A和B是同一个矩阵。唯一的区别是数据顺序。

矩阵向量乘积正确工作:

VectorXd x( 2 );
x << 1.0, 2.0;
VectorXd y = A * x;
VectorXd w = B * x;
assert( y( 0 ) == w( 0 ) ); // <-- OK
assert( y( 1 ) == w( 1 ) ); // <-- OK

selfadjointView 不起作用:

y = A.selfadjointView<Upper>() * x;
w = B.selfadjointView<Upper>() * x;
assert( y( 0 ) == w( 0 ) ); // <-- Fail!

Eigen 文档 (https://eigen.tuxfamily.org/dox/group__TutorialSparse.html) 中的示例显示了有序数据,但没有明确指示。

不幸的是,由于临时对象的动态分配,我无法使用 Eigen 获取 Ap。有什么想法吗?

已使用 Eigen v3.3.7 执行测试。

要对矩阵的条目进行排序,您可以将其转置两次:

B = B.transpose(); B = B.transpose();

或者您可以将其转置一次并使用 selfadjointView<Lower>(),或者您可以将其分配给行主矩阵(这也会隐式转置):

SparseMatrix<double, RowMajor> C = B;

w = C.selfadjointView<Upper>() * x;