用本征求解线性方程组

时间:2018-09-04 02:55:52

标签: c++ linear-algebra eigen

我目前正在用C ++进行流体模拟,算法的一部分是解决稀疏的线性方程组。人们建议为此使用特征库。我决定使用我编写的这个简短程序对其进行测试:

#include <Eigen/SparseCholesky>

#include <vector>
#include <iostream>

int main() {
    std::vector<Eigen::Triplet<double>> triplets;
    triplets.push_back(Eigen::Triplet<double>(0, 0, 1));
    triplets.push_back(Eigen::Triplet<double>(0, 1, -2));
    triplets.push_back(Eigen::Triplet<double>(1, 0, 3));
    triplets.push_back(Eigen::Triplet<double>(1, 1, -2));

    Eigen::SparseMatrix<double> A(2, 2);
    A.setFromTriplets(triplets.begin(), triplets.end());

    Eigen::VectorXd b(2);
    b[0] = -2;
    b[1] = 2;

    Eigen::SimplicialCholesky<Eigen::SparseMatrix<double>> chol(A);
    Eigen::VectorXd x = chol.solve(b);

    std::cout << x[0] << ' ' << x[1] << std::endl;

    system("pause");
}

它给出了两个等式:

x-2y = -2

3x-2y = 2

正确的解决方法是:

x = 2

y = 2

但是问题是,程序运行时会输出: 0.181818 -0.727273

这是完全错误的!我已经调试了好几个小时,但这是一个非常简短的程序,我正完全按照Eigen网站上的教程进行操作。有人知道导致此问题的原因吗?

P.S。我知道我正在使用的类适用于稀疏矩阵,但是它们与普通Matrix类之间的唯一区别是元素的存储方式。

2 个答案:

答案 0 :(得分:4)

SimplicialCholesky用于对称正定(SPD)矩阵,您组装的矩阵甚至不是对称的。默认情况下,它只读取下部三角形部分中的条目而忽略其他条目,因此解决了问题:

x + 3y = -2
3x -2y = 2

您已经注意到,对于非对称平方问题,在迭代求解器的世界中,您需要使用基于LU或BICGSTAB的直接求解器。这些全部总结在doc中。

答案 1 :(得分:-1)

您应该使用能够处理非对称稀疏矩阵的求解器。另一种可能的方法是寻求不是原始系统[A] x = b的解决方案,而是[A] T * [A] x = [A] T * b的解决方案,其中[A] T代表[A]转置。后一个系统的矩阵是对称且正定的(只要[A]为非奇异)。唯一的缺点是,如果原始[A]在这种意义上不是“好”的话,[A] T [A]可能会病得很严重。只是旨在解决此类问题的软件的一个示例: http://members.ozemail.com.au/~comecau/CMA_LS_Sparse.htm