2012-01-07 40 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([6 13; 5 11])時,我被告知「矩陣M應該有行列式1」。

地球上正在發生什麼?

編輯:在命令窗口中,我輸入了以下:

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

Matlab的然後告訴我自己,它的破碎。

感謝

+1

要這麼大膽地聲稱* MATrix LABoratory *的行列式函數在2x2矩陣中被破壞... – Kavka 2012-01-07 02:47:01

+0

'format long; det([6 13; 5 11])給你1.000000000000007。如果你在數值分析中上課,你會發現計算機上的數學是一個全新的世界。我對你可以在[Cleve Moler的網站](Matlab的發明者)(http://www.mathworks.com/moler/chapters.html)看到的主題感興趣。 – Batsu 2012-01-07 15:33:28

回答

4

您正在運行到的發生是由於浮點數的限制標準的問題。 det函數的結果可能類似於1.000000001。

一般規則:從不測試浮點值是否相等。

+0

圍繞它的最好方法是什麼? – 2012-01-07 01:25:44

+2

@MattLab:定義一些公差等級,並且例如'如果abs(det(M)-1) 2012-01-07 01:27:18

8

歡迎來到奇妙古怪的浮點運算世界。 MATLAB使用LU分解(即線性代數)計算行列式。它是這樣做的,因爲除非確實如此,否則行列式對於大小均勻的數組是非常低效的。

LU分解的結果是行列式被計算爲浮點數。這不是一個問題,除非你已經像你一樣簡單地輸入了一個問題 - 一個僅由小整數組成的2x2矩陣的行列式。在這種情況下,行列式本身也將是一個(合理的)小整數。所以你可以通過簡單地使用教科書公式計算2x2矩陣的行列式來解決問題。 D = A(1,1)* A(2,2)-A(1,2)* A(2,1);其中,

對於小整數矩陣A,這將是完全正確的,儘管這可能會顯示某些矩陣的某些精度損失。例如,考慮簡單的2×2矩陣A:

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

我們知道這個矩陣的行列式是1e16-1。

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

當然,MATLAB顯示爲1e16。但事實上,MATLAB中的det函數生成的數字實際上是9999999999999998,所以1e16-2。不好的是,如果我使用了上面給出的2x2行列式的公式,它會返回一個仍然不正確的結果,10000000000000000。兩個結果都是1.你可以通過查看eps的幫助來了解更多關於這些問題的信息。

我的觀點是,有一些2×2的矩陣,其中行列式的計算只會有問題,即使它們是整數矩陣。

一旦你的矩陣變成非整數,那麼事情確實變成了真正的浮點數,而不是整數。這意味着您只需使用它們上的容差進行比較,而不是使用精確統一的測試。無論如何,這是一條很好的規則。當你進行平等測試時,總是要使用寬容,至少在你已經學會了足夠的知識以便知道何時違反該規則!

所以,你可能會選擇這樣一個測試:

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

請注意,我用EPS(1),因爲我們是在比較東西1.我乘以10的EPS的事實允許在決定因素的計算中稍微有一點瑕疵。

最後,你應該知道,無論你在這裏使用行列式的測試,它通常是一個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)等於det(G),這是6 * 1/6 = 1,但作爲一個G浮點而不是數矩陣,G(1,1)*G(2,2)~=1

其實G(1,1)G(2,2)不完全是1和1/6,但它們有一個非常小的相對誤差(見eps,在大多數機器上大約是2.22e-16)。他們的真實價值將在6 *(1 + eps)和1/6 *(1 + eps)左右,因此他們的產品也會有一個小的錯誤。

我不確定Matlab是否使用了高斯消除或類似的LU decomposition