4x4行列が特異であるかどうかをどうやって知ることができますか?
与えられた行列を単位行列で拡張してから行演算を実行せずに、これを知ることができますか?
では、行列が本当に特異であるかどうかをどのように識別しますか?(MATLABでは、紙と鉛筆、記号計算、または手書きの行演算を使用せずに?)教科書は、行列式を使用するように学生に指示することがあるので、そこから始めます。
理論的には、行列式がゼロかどうかを簡単にテストできます。したがって
M = magic(4)
M =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
det(M)
ans =
-1.4495e-12
結局のところ、この行列は確かに特異であるため、Mの行を他の行の線形結合として書き込む方法があります(列にも当てはまります)。しかし、detから正確にゼロではない値を取得しました。 。それは本当にゼロであり、MATLABは混乱しましたか?何故ですか?シンボリック行列式は本当にゼロです。
det(sym(M))
ans =
0
結局のところ、行列式の計算は、より大きな配列では非常に非効率的なものです。したがって、優れた代替手段は、正方形配列の特定の行列因数分解の対角要素の積を使用することです。実際、これは、MATLABが非シンボリック入力に対してdet自体の内部で行うことです。
[L,U,P] = lu(M)
L =
1 0 0 0
0.25 1 0 0
0.3125 0.76852 1 0
0.5625 0.43519 1 1
U =
16 2 3 13
0 13.5 14.25 -2.25
0 0 -1.8889 5.6667
0 0 0 3.5527e-15
P =
1 0 0 0
0 0 0 1
0 1 0 0
0 0 1 0
Lの対角要素は1ですが、Uにはゼロ以外の対角要素があることを確認してください。そして、上三角行列または下三角行列の行列式だけでなく、行列の積の行列式についても優れた特性があります。
prod(diag(U))
ans =
-1.4495e-12
同じ答えが得られたのを見てください。LU分解は、大規模な配列でもかなり高速であるため、行列式を計算するための優れた方法です。問題は、浮動小数点演算を使用していることです。したがって、Uのこれらの対角要素は、実際の浮動小数点数です。製品を取得すると、正確にゼロではない結果が得られます。その最後の要素はわずかにゼロ以外でした。
detには他にも問題があります。たとえば、行列eye(100)は非常によく調整されていることがわかります。結局のところ、それは単位行列です。
det(eye(100))
ans =
1
ここで、行列に定数を掛けても、行列のステータスが特異なものとして変更されることはありません。しかし、行列式はどうなりますか?
det(.1*eye(100))
ans =
1e-100
では、この行列は特異ですか?結局のところ、det(magic(4))が1e-12を与える場合、1e-100は特異行列に対応する必要があります!しかし、そうではありません。さらに悪いことに、
det(.0001*eye(100))
ans =
0
実際、行列式は0.0001 ^ 100でスケーリングされ、matlabでは1e-400になります。少なくとも、matlabがdoubleを使用して非常に小さい数を表すことができれば、それは当てはまります。それはできません。その数はアンダーフローします。または、簡単にオーバーフローさせることができます。
det(10000*eye(100))
ans =
Inf
明らかに、これらのスケーリングされた単位行列はすべて等しく非特異ですが、detを作成して、見たい答えを得ることができます。したがって、行列式の計算は行列に対して行うのはひどいことであると結論付けなければなりません。あなたの教科書がずっと前にあなたに言ったことや、あなたの上司や先生があなたに言ったことは気にしません。誰かがコンピューターを使用してこの目的のために行列式を計算するようにあなたに言った場合、それはひどいアドバイスでした。限目。行列式には、単に問題が多すぎます。
特異点をテストするために他のことを行うことができます。最良のツールはランクを使用することです。したがって、NxM行列のランクがmin(N、M)未満の場合、行列は特異です。ここにいくつかのテストがあります:
rank(M)
ans =
3
rank(.0001*eye(100))
ans =
100
したがって、ランクは4x4魔方陣が特異であることを示しますが、スケーリングされた単位行列は特異ではありません。(良い点は、ランクが非正方行列の特異性をテストできることです。)
condを使用して、数値の特異性をテストすることもできます。可能な最小の条件数は1.0であり、これは非常に適切に動作する行列に対応します。条件数が大きいと悪いです。倍精度では、これは、条件数が約1e15より大きい場合、行列に非常に問題があることを意味します。
cond(M)
ans =
8.148e+16
cond(.0001*eye(100))
ans =
1
実際、condは、スケーリングされた単位行列が結局のところ十分に条件付けられていることを認識しています。条件数が大きいと悪いです。倍精度行列の場合、1e15程度に近い条件数は、おそらく数値的に特異な行列を示します。したがって、Mは明らかに特異であることがわかります。この場合も、condは非正方行列で機能します。
または、条件数の逆数を推定するツールであるrcondを使用することもできます。これは、非常に大きなアレイに適したツールです。rcondがepsに近い数値を示したら、注意してください。
rcond(M)
ans =
1.3061e-17
rcond(.0001*eye(100))
ans =
1
最後に、(私のような)数学的なギアヘッドの場合、svdを引き出すことができます。結局のところ、svdはcondとrankが基づいているツールです。行列の1つまたは複数の特異値が、最大の特異値と比較して小さい場合も、特異値があります。
svd(M)
ans =
34
17.889
4.4721
4.1728e-16
ここでは、行列の最大の特異値と比較して特異値が小さい場合を見ていきます。良いことは、svdが行列が特異値にどれだけ近いかを教えてくれることです。また、小さな特異値が複数ある場合は、行列のランクに関する情報を教えてくれます。
良い点は、私が示したツールのいずれも、ユーザーが基本行操作やその他の凝った操作を行う必要がないことです。
ただし、DETは使用しないでください。はい、教科書に載っています。はい、多分あなたのインストラクターかあなたの上司はあなたにそれを使うように言ったでしょう。このようなツールは、浮動小数点演算を使用するコンピューターに適用すると失敗するため、これらは間違っていました。そして、あなたは単にシンボリック行列式を計算したくありません。それはひどく非効率的です。
長い間読んでしまったらごめんなさい。今から石鹸箱から降ります。
ランクを計算し、ディメンションと比較します。ランクが次元よりも低い場合、行列は特異です。
最も信頼できるアプローチは、行列に対して特異値分解を実行することです。最大の特異値と最小の特異値の比率は、ある程度の許容範囲内にある必要があります。この比率は、行列の条件数です。倍精度値では、条件数が100万以上を超えると、倍精度値で非常に困難になります。これはかなり高い制限です。SVDを取得すると、条件数を計算するだけでなく、他の多くのことに役立ちます。
特異値分解は、数値解析のスイス軍チェーンソーです。マトリックスが特異でない/条件が悪いことがわかっている場合は、ツールを少し手間がかかる可能性があります。しかし、わからない場合は、知っておくとよいツールです。Matlabは組み込みツールであるため、特にそうです。
私は使用しますcond
。これにより、行列が特異行列にどれだけ近いかを数値で見積もることができます(Infは特異行列です)。
例えば:
m = randn(4);
cond(m) %Well conditioned, usually in the 10's
m = diag([1e-6 1 2 1e6]);
cond(m) %Less well conditioned, 1e12
m = diag([0 1 2 3]);
cond(m) %Singular: Inf