我需要求解很多小(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();
}
有没有更快的方法呢?
答案 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();
}