2017-08-29 41 views
0

我需要求解许多形如Ax = 0的小(n = 4)齐次线性系统,其中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(); 
} 

有没有更快的方法来做到这一点?

+0

这我会做什么。你的服务水平目标是什么?您是否根据代表性数据衡量了性能?第90百分位墙的时间与SLO相比如何? – duffymo

+1

为什么只在使用V时询问U?你需要复制V吗? –

+0

@MarcGlisse你说得对,U并不真正有用。我正在测试其他几种方法,发现使用LU或QR分解的速度要快得多。这些有什么缺点吗? – dari

回答

3

获得具有特征的一般矩阵的零空间的最快方法是使用其LU分解。在实践中,我使用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(); 
} 
相关问题