本征稀疏求解器错误结果

问题描述

我正在尝试使用C ++中的Eigen库解决稀疏线性系统 Ax = B ,但是以下简单示例似乎给出了错误解决方案:

func queryUserMovies(_ req: Request) throws -> Future<[Users]> {
    guard let movie = req.query[String.self,at: "movie"] else {
        throw Abort(.badRequest,reason: "Not such movie")
    }
    return Movies.query(on: req).filter(\.title,.like,movie).first().unwrap(or:Abort(.notFound,reason: "There's no movie")).flatMap{ movie in
        return movie.users.query(on: req).all()
    }
}

我没有看到任何错误,算法返回“ 0”表示“成功”,但是我得到的解决方法

#include <Eigen/SparseCholesky>
#include <Eigen/Dense>
#include <Eigen/Sparse>
#include <iostream>
#include <vector>

using namespace std;
using namespace Eigen;

int main(){

    SimplicialLDLT<SparseMatrix<double>> solver;
    SparseMatrix<double> A(9,9);
    typedef Triplet<double> T;
    vector<T> triplet;
    VectorXd B(9);

    for(int i=0; i<4; i++){
        triplet.push_back(T(i,i,1));
        triplet.push_back(T(i+5,i+5,1));
    }

    triplet.push_back(T(4,1,-1));
    triplet.push_back(T(4,3,5,7,4,4));

    A.setFromTriplets(triplet.begin(),triplet.end());
    B << 0,0.387049,0;

    solver.compute(A);
    VectorXd x = solver.solve(B);

    cout << "A\n" << A << "\n";
    cout << "B\n" << B << "\n";
    cout << "x\n" << x << "\n";

    return 0;
}

这显然不是该系统的解决方案,正确的是

x = 0 0.193524 0 0.193524 0.193524 0 0 0 0

解决方法

Here's documentation for SimplicialLDLT求解器:

此类提供了LDL ^ T Cholesky因式分解,而没有稀疏矩阵的平方根,这些稀疏矩阵是自伴且正定的。。

当矩阵在元素中存储实数时,自伴==对称。您的矩阵显然不对称。另外,并非每个对称矩阵都是正定的see examples

简而言之,您选择的求解器仅适用于非常狭窄的一类矩阵。如您所知,SparseLU求解器可用于您的输入数据。

ConjugateGradient求解器也不起作用,它不需要矩阵是正定的,但是it does要求矩阵是自伴随的。