2012-01-07 4 views
0

を行っている鉱山のプログラムからの抜粋です。Matlabの決定機能は、次のゆがん

function [P] = abc(M,f); if det(M) ~= 1, disp(['Matrix M should have determinant 1'])

私は、ユーザーのためのオプションが「F」の値を入力しないようにできます。

私がabc([2 1; 1 1])を実行すると、プログラムはうまく動作し、それが想定していることをします。しかし、私がabc([13 13; 5 11])を実行すると、 "行列Mは行列式1を持つべきです"と言われます。

地球上で何が起こっていますか?

EDIT:コマンドウィンドウで、私は次のように入力された:

M = [6 13; 5 11]; if det(M) ~= 1, disp('Im broken'); end

MATLABは、それが壊れていること自体私に言いました。あなたは浮動小数点数の制限により発生する標準的な問題に実行されている

おかげ

+1

* Matrix LABoratory *の行列式関数が2x2行列に対して壊れていると大胆に主張する... – Kavka

+0

'format long; det([6 13; 5 11]) 'はあなたに1.000000000000007を与えます。 Numerical Analysisでクラスを受講すれば、コンピュータ上の数学はまったく新しい世界であることがわかります。私はあなたが[Cleve Molerのサイト](http://www.mathworks.com/moler/chapters.html)(Matlabの発明者)を覗いてみることができるテーマに興味があります – Batsu

答えて

4

det関数の結果はおそらく1.000000001のようなものです。

一般的な経験則:浮動小数点値が等しいかどうかは絶対にテストしないでください。

+0

何が最善の方法ですか? –

+2

@MattLab:いくつかの許容レベルを定義します。 'if abs(det(M)-1)

8

浮動小数点演算の素晴らしい世界へようこそ。 MATLABは、LU分解、すなわち線形代数を使用して行列式を計算します。行列式がそうでなければ、行列式が穏やかなサイズの配列に対しても非常に非効率的であるため、そうする。

そのLU分解の結果は、行列式が浮動小数点数として計算されるかどうかです。これは問題ではありません。あなたが持っているのと同じくらい簡単に問題を入力しないかぎり、小さな整数だけで構成される2x2行列の行列式です。その場合、行列式自体も(合理的に)小さな整数になります。したがって、教科書の公式を使用して、自分で2x2行列の行列式を計算するだけで問題を解決できます。 (1,1)* A(2,2)-A(1,2)* A(2,1); A(1,2);

これは小さな整数行列Aに対して正確になりますが、これも一部の行列の精度の低下を示すことがあります。

>> A = [1e8 1;1 1e8]; 

私たちは、この行列の行列が1e16-1であることを知っている:例えば、単純な、2×2行列Aを考えます。

>> det(A) 
ans = 
        1e+16 

もちろん、MATLABはこれを1e16と表示します。しかし実際、MATLABのdet関数で生成される数値は実際には9999999999999998なので、1e16-2です。悪いことに、上記の2x2行列式の式を使用しても、10000000000000000という結果はまだ間違っていました。どちらの結果も1ではありませんでした。これらの問題の詳細については、epsのヘルプを参照してください。

私の指摘は、行列式の計算には整数行列であっても、行列式の計算には問題があります。

行列が非整数になると、事実は整数ではなく真の浮動小数点数になります。つまり、正確な統一性のテストではなく、単に許容差のある比較を使用する必要があります。これはとにかく良いルールです。あなたが少なくともそのルールに従わないことを知るのに十分なことを学ぶまでは、平等のためのテストをするときは、常に許容値を使用してください!私は10で、EPSを掛けているという事実が可能に私たちは1に物事を比較しているので、私は(1)のEPSを使用しました

if abs(det(A) - 1) < (10*eps(1)) 
    warning('The sky is falling! det has failed me.') 
end 

注:

だから、あなたはこのようなテストを選択する場合があります行列式の計算では、スロープが少ししかない。

最後に、ここで行列式を使用しているテストであれば、しばしばBBBBBBBBBBAAAAAAAAAADDDDDDDDのことがわかります。はい、あなたの先生から教えてもらえましたか、教科書で何かを見つけたかもしれません。しかし、行列式は、数値計算に使うのは単なる悪いことです。行列式に代わるものはほとんど常にある。繰り返しますが、これは判断と呼ばれ、使用するように言われたことが実際には間違っていることを知っています。

0

あなたに洞察力を与えるには:detは、線形代数で研究した古い方程式を使用して計算するのではなく、より効率的なアルゴリズムを使用します。

たとえば、Gaussian eliminationを使用すると、対応する上三角行列のMを変換し、行列の主対角(下三角をすべてゼロ)の積として行列式を計算できます。

M = [6 13; 5 11] 
G = M - [0 0; M(2,1)/M(1,1) * M(1,:)]; 

理論det(M) = 1 6 * 1/6である、det(G)に等しいが、G浮動小数点なく数行列、G(1,1)*G(2,2)~=1あります!実際G(1,1)

G(2,2)は正確に1と1/6ではありませんが、(ほとんどのマシン上で周り2.22e-16である、epsを参照してください)非常に小さな相対誤差を持っています。その実際の価値は約6 *(1 + eps)と1/6 *(1 + eps)になるので、製品にも小さな誤差が生じます。

Matlabがガウス消去法などを使用しているかわかりません。LU decompositionです。

関連する問題