4

私のプログラムは連立一次方程式を解こうとします。そのために、行列coeff_matrixとベクトルvalue_vectorを組み立て、Eigenを使用して次のように解きます。

Eigen::VectorXd sol_vector = coeff_matrix
        .colPivHouseholderQr().solve(value_vector);

問題は、システムが過大評価と過小決定の両方になる可能性があることです。前者の場合、Eigenは正しい解または正しくない解を与え、私はを使用して解をチェックしcoeff_matrix * sol_vector - value_vectorます。

ただし、次の連立方程式を考慮してください。

a + b - c     =  0
        c - d =  0
        c     = 11
      - c + d =  0

aこの特定のケースでは、Eigenは後者の3つの方程式を正しく解きますが、との解も与えますb

私が達成したいのは、解が1つしかない方程式だけが解かれ、残りの方程式(ここでは最初の方程式)がシステムに保持されることです。

言い換えれば、私は、その時点で特定の連立方程式で解ける方程式と、複数の解があるために解けない方程式を見つける方法を探しています。

それを達成するための良い方法を提案できますか?

編集:ほとんどの場合、マトリックスは正方形ではないことに注意してください。過剰決定も発生する可能性があることに注意するために、ここにもう1行追加しました。

4

3 に答える 3

6

あなたが望むのは特異値分解(SVD)だと思います。これはあなたが望むものを正確に与えるでしょう。SVDの後、「解が1つしかない方程式が解かれ」、解は疑似逆行列になります。また、ヌル空間(無限の解が生じる場所)と左の零空間(矛盾が生じる場所、つまり解がない)も提供します。

于 2012-07-10T15:36:00.787 に答える
2

SVDコメントに基づいて、私は次のようなことを行うことができました。

Eigen::FullPivLU<Eigen::MatrixXd> lu = coeff_matrix.fullPivLu();

Eigen::VectorXd sol_vector = lu.solve(value_vector);
Eigen::VectorXd null_vector = lu.kernel().rowwise().sum();

AFAICSでは、null_vector単一の解に対応する行は0sであり、非決定的な解に対応する行は1sです。Eigenが持っているデフォルトのしきい値を使用して、すべての例でこれを再現できます。

しかし、私が何か正しいことをしているのか、それともランダムなパターンに気づいただけなのかはわかりません。

于 2012-07-10T17:49:12.097 に答える
1

必要なのは、システムの行列式を計算することです。行列式が0の場合、解の数は無限になります。行列式が非常に小さい場合、解決策は存在しますが、コンピューターによって検出された解決策を信頼することはできません(数値が不安定になる可能性があります)。

行列式とは何か、およびそれを計算する方法へのリンクは次のとおりです。http: //en.wikipedia.org/wiki/Determinant

ガウスの消去法も機能することに注意してください。http://en.wikipedia.org/wiki/Gaussian_elimination この方法では、解の数が無限である場合、0の行になります。

編集

行列が正方行列でない場合は、最初に正方行列を抽出する必要があります。2つのケースがあります:

  1. 方程式よりも多くの変数があります。その場合、解がないか、それらの数が無限になります。
  2. 変数よりも多くの方程式があります。この場合、null以外の行列式の正方行列を見つけます。この行列を解き、解を確認します。解決策が合わない場合は、解決策がないことを意味します。解が適合する場合、それは追加の方程式が抽出方程式に線形依存していたことを意味します。

どちらの場合も、行列の次元を確認する前に、0のみの行と列を削除してください。

ガウスの消去法に関しては、非正方行列で直接機能する必要があります。ただし、今回は、空でない行(つまり、0以外の値を持つ行)の数が変数の数と等しいことを確認する必要があります。それが少ない場合は解決策が無限にあり、多い場合は解決策がありません。

于 2012-07-10T14:24:20.197 に答える