用特征

时间:2017-08-29 17:53:30

标签: c++ linear-algebra eigen

我需要求解很多小(n = 4)形式为Ax = 0的均匀线性系统,其中A是奇异矩阵。我目前正在使用以下代码:

void solve(const matrix_t& A, vector_t& x){
    auto svd = A.jacobiSvd(Eigen::ComputeFullU | Eigen::ComputeFullV);
    auto V = svd.matrixV();
    x = V.col( A.rows() - 1 );
    x.normalize();
}

有没有更快的方法呢?

1 个答案:

答案 0 :(得分:3)

获得具有特征的一般矩阵的零空间的最快方法是使用其LU分解。在praxis中,我使用Householder QR分解而不是LU,因为当输入矩阵不是完全单数时它看起来更稳定。 QR仍然比问题中提出的SVD快很多,并且为我的问题提供了非常类似的结果。可以在此处找到不同特征分解的基准:https://eigen.tuxfamily.org/dox/group__DenseDecompositionBenchmark.html

使用LU,QR和SVD计算零空间的代码(注意:x.normalize()不是必需的,但有助于比较解决方案):

template<typename matrix_t, typename vector_t>
void solveNullspaceLU(const matrix_t& A, vector_t& x){
    x = A.fullPivLu().kernel();
    x.normalize();
}

template<typename matrix_t, typename vector_t>
void solveNullspaceQR(const matrix_t& A, vector_t& x){
    auto qr = A.transpose().colPivHouseholderQr();
    matrix_t Q = qr.householderQ();
    x = Q.col(A.rows() - 1);
    x.normalize();
}

template<typename matrix_t, typename vector_t>
void solveNullspaceSVD(const matrix_t& A, vector_t& x){
    x = A.jacobiSvd(Eigen::ComputeFullV).matrixV().col( A.rows() - 1 );
    x.normalize();
}