Эйген: получить ядро ​​разреженной матрицы - PullRequest
0 голосов
/ 19 февраля 2019

Учитывая разреженную матрицу A и вектор b, я хотел бы получить решение x для уравнения A * x = b, а также ядро ​​A.

Oneвозможно преобразовать 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;
}

Возможно ли сделать то же самое непосредственно в разреженном представлении?Я не смог найти функцию kernel() нигде, кроме FullPivLu .

1 Ответ

0 голосов
/ 21 мая 2019

Я думаю, что ответ @ chtz почти верен, за исключением того, что нам нужно взять последние столбцы A.cols () - qr.rank ().Вот математический вывод.

Скажем, мы делаем QR-разложение вашей матрицы Aᵀ как

Aᵀ * P = [Q₁ Q₂] * [R;0] = Q₁ * R

, где P - матрица перестановок, таким образом

Aᵀ = Q₁ * R * P⁻¹.

Мы можем видеть, что Range (Aᵀ)= Диапазон (Q₁ * R * P⁻¹) = Диапазон (Q₁) (потому что оба P и R являются обратимыми).

Поскольку Aᵀ и Q₁ имеют одинаковое пространство диапазона, это означает, что A и Q also также будутимеют одинаковое нулевое пространство, а именно Null (A) = Null (Q₁ᵀ).(Здесь мы используем свойство, что Range (M) и Null (Mᵀ) дополняют друг друга для любой матрицы M, следовательно, Null (A) = дополнение (Range (Aᵀ)) = дополнение (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)

...