2017-08-29 40 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(); 
} 
相關問題