行列が対称正定値かどうかの判別
このトピックでは、関数 chol
と eig
を使用して行列が対称正定値 (すべての固有値が正である対称行列) かどうかを判別する方法を説明します。
方法 1: コレスキー分解の試行
行列が対称正定値かどうかをチェックする最も効率的な方法は、行列で chol
を使用してみることです。分解が失敗した場合、行列は対称正定値ではありません。
対称正方行列を作成し、try
/catch
ブロックを使用して chol(A)
が成功するかどうかをテストします。
A = [1 -1 0; -1 5 0; 0 0 7]
A = 3×3
1 -1 0
-1 5 0
0 0 7
try chol(A) disp('Matrix is symmetric positive definite.') catch ME disp('Matrix is not symmetric positive definite') end
ans = 3×3
1.0000 -1.0000 0
0 2.0000 0
0 0 2.6458
Matrix is symmetric positive definite.
この方法の欠点は、行列が (固有値を正またはゼロにできる) 対称半正定値かどうかもチェックするように拡張できないことです。
方法 2: 固有値のチェック
eig
を使用して固有値すべてを計算し、それぞれの値をチェックするのは非効率的ですが、この方法を使用すると行列が対称半正定値かどうかをチェックすることもできるため、柔軟性が向上します。ただし、小さな行列の場合、これらの方法の計算時間における違いはわずかであり、行列が対称正定値かどうかはチェックされません。
この方法では、テストを実行する前に issymmetric
を使用して行列が対称かどうかをチェックする必要があります (行列が対称ではない場合、固有値を計算する必要はありません)。
tf = issymmetric(A)
tf = logical
1
d = eig(A)
d = 3×1
0.7639
5.2361
7.0000
isposdef = all(d > 0)
isposdef = logical
1
この方法を拡張し、コマンド all(d >= 0)
を使用して行列が対称半正定値かどうかをチェックできます。
数値の考慮事項
ここで概説する方法では、同じ行列に対して異なる結果が返される可能性があります。どちらの計算にも丸め誤差が含まれるため、各アルゴリズムは A
とは若干異なる行列の定性をチェックします。実際には、固有値はマシンの精度内で数値的にゼロになる場合があり、わずかに正またはわずかに負であるため、許容誤差の使用はよりロバストな比較方法です。
たとえば、行列に eps
の次数で固有値がある場合、固有値が数値的にゼロで、行列が対称 "半" 正定値としてより適切に分類された場合でも、比較 isposdef = all(d > 0)
を使用すると true
が返されます。
許容誤差を使用して比較を実行するために、変更されたコマンドを使用できます。
tf = issymmetric(A) d = eig(A) isposdef = all(d > tol) issemidef = all(d > -tol)
許容誤差は 0 付近の半径を定義し、その半径内のすべての固有値はゼロとして処理されます。ほとんどの場合、絶対値が最も大きい固有値を考慮する許容誤差 length(d)*eps(max(d))
が適しています。