繁体   English   中英

Eigen:获取稀疏矩阵的核

[英]Eigen: Obtain the kernel of a sparse matrix

给定一个稀疏矩阵A和向量b ,我想以获得溶液x等式A * x = b以及所述的内核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⁻¹。

我们可以看到 Range(Aᵀ) = Range(Q₁ * R * P⁻¹) = Range(Q₁)(因为 P 和 R 都是可逆的)。

由于 Aᵀ 和 Q₁ 具有相同的范围空间,这意味着 A 和 Q₁ᵀ 也将具有相同的零空间,即 Null(A) = Null(Q₁ᵀ)。 (这里我们使用 Range(M) 和 Null(Mᵀ) 对任何矩阵M互补的性质,因此 Null(A) = completion(Range(Aᵀ)) = completion(Range(Q₁)) = Null( Q₁ᵀ))。

另一方面,由于矩阵 [Q₁ Q₂] 是正交矩阵,所以 Null(Q₁ᵀ) = Range(Q₂),因此 Null(A) = Range(Q₂),即 kernal(A) = Q₂。

由于 Q₂ 是正确的 A.cols() - qr.rank() 列,您可以调用rightCols(A.cols() - qr.rank())来检索 A 的内核。

有关内核空间的更多信息,您可以参考https://en.wikipedia.org/wiki/Kernel_(linear_algebra)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM