给定稀疏的矩阵A
和向量b
,我想获得方程A * x = b
的解决方案x
以及A
的内核。
一种可能性是将A
转换为密集表示。
#include <iostream>
#include <Eigen/Dense>
#include <Eigen/SparseQR>
int main()
{
// This is a toy problem. My actual matrix
// is of course bigger and sparser.
Eigen::SparseMatrix<double> A(2,2);
A.insert(0,0) = 1;
A.insert(0,1) = 2;
A.insert(1,0) = 4;
A.insert(1,1) = 8;
A.makeCompressed();
Eigen::Vector2d b;
b << 3, 12;
Eigen::SparseQR<Eigen::SparseMatrix<double>,
Eigen::COLAMDOrdering<int> > solver;
solver.compute(A);
std::cout << "Solution:n" << solver.solve(b) << std::endl;
Eigen::Matrix2d A_dense(A);
std::cout << "Kernel:n" << A_dense.fullPivLu().kernel() << std::endl;
return 0;
}
是否可以直接在稀疏表示中进行相同的操作?除了在FullPivlu中以外,我找不到任何地方kernel()
。
我认为 @chtz的答案几乎是正确的,除了我们需要拿最后一个a.cols()-qr.rank()列。这是一个数学推导。
说我们对矩阵Aᵀ进行QR分解为
aᵀ * p = [q₁q₂] * [r;0] =q₁ * r
其中p是置换矩阵,因此
aᵀ=q₁ * r *p⁻。
我们可以看到该范围(aᵀ)= range(q₁ * r * p p⁻)=范围(q₁)(因为p和r都是可逆的)。
由于Aᵀ和Q₁具有相同的范围空间,因此这意味着A和Q₁ᵀ也将具有相同的空空间,即null(a)= null(q₁ᵀ)。(在这里,我们使用范围(m)和null(mᵀ)的属性是彼此补充的任何矩阵M
,因此null(a)= reflecterment(range(aᵀ))= reflectement(range(q₁))= null(null(null)(null)(q₁ᵀ))。
另一方面,由于矩阵[q₁q₂]是正顺序的,null(q₁ᵀ)= range(q₂),因此null(a)= range(q₂),即kernal(a)=q₂。p>由于q₂是右A.Cols()-qr.rank()列,您可以致电rightCols(A.cols() - qr.rank())
以检索A。
有关内核空间的更多信息,您可以参考https://en.wikipedia.org/wiki/kernel_(linear_algebra)