2017-08-29 7 views
0

Aを特異行列とするAx = 0の形式の小さな(n = 4)均質な線形システムを解く必要があります。私は現在次のコードを使用しています:固有値を持つ小さな均質線形システムを解く最速の方法

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分解を使用することです。プラクシスでは、LUの代わりにHouseholder QR分解を使用しています。なぜなら、入力行列が完全に特異なものでないと安定しているように見えるからです。 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(); 
} 
関連する問題