跳轉到內容

線性代數/主題:計算行列式的速度/解法

來自華夏公益教科書

大多數這些問題假設可以訪問計算機。

問題 1

計算機系統生成隨機數(當然,這些只是偽隨機數,因為它們是由演算法生成的,但它們通過了許多合理的統計隨機性測試)。

  1. 用隨機數填充一個 陣列(例如,在範圍 內)。檢視它是否為奇異矩陣。重複此實驗幾次。奇異矩陣是頻繁出現的還是罕見的(在這個意義上)?
  2. 計時您的計算機代數系統計算十個 隨機數陣列的行列式。找到每個陣列的平均時間。針對 陣列、 陣列和 陣列重複前面的專案。(請注意,當一個數組為奇異時,有時可以很快地發現它,例如如果第一行等於第二行。根據您對第一部分的答案,您是否認為奇異系統在您的平均值中扮演重要角色?)
  3. 繪製輸入大小與平均時間的關係圖。
答案
  1. 在 Octave 中,rank(rand(5))找到一個 矩陣的秩,該矩陣的元素在 區間內(均勻分佈)。此迴圈執行測試octave:1> for i=1:5000
    > if rank(rand(5))<5 printf("That's one."); endif
    > endfor
    產生(經過幾秒鐘後)返回提示,沒有任何輸出。Octave 指令碼

    function elapsed_time = detspeed (size)
    a=rand(size);
    tic();
    for i=1:10
    det(a);
    endfor
    elapsed_time=toc();
    endfunction


    導致此會話。

    octave:1> detspeed(5)
    ans = 0.019505
    octave:2> detspeed(15)
    ans = 0.0054691
    octave:3> detspeed(25)
    ans = 0.0097431
    octave:4> detspeed(35)
    ans = 0.017398
  2. 以下是資料(略微四捨五入)和圖表。

    (此資料來自上述指令碼二十次執行的平均值,因為隨機選擇的矩陣可能恰好需要異常長或短的時間。即使如此,計時也不能過於依賴;這只是一個實驗。)

問題 2

使用上面討論的兩種方法,手動計算每個行列式。

對於每種方法,分別計算每種情況下使用的乘法和除法的次數。(在計算機中,乘法和除法比加法和減法需要更多時間,因此演算法設計人員會更多地關注它們。)

答案

操作的次數取決於操作的具體執行方式。

  1. 行列式為 。進行行簡化需要一個樞軸,有兩個乘法( 乘以 加上 ,以及 乘以 加上 ),對角線上的乘積還需要一次乘法。排列展開需要兩次乘法( 乘以 以及 乘以 )。
  2. 行列式為 。計算操作次數是例行公事。
  3. 行列式為
問題 3

你能想出一個 陣列,讓你的計算機系統需要最長時間才能簡化?最短時間?

答案

一個開始的方法是使用 Octave 比較:det(rand(10));,與det(hilb(10));,與det(eye(10));,與det(zeroes(10));。你可以像這樣計時它們:tic(); det(rand(10)); toc().

問題 4

編寫剩下的 FORTRAN 程式,以直接實現透過高斯方法計算行列式。(不要測試零樞軸。)比較你程式碼的速度和你的計算機代數系統中使用的程式碼的速度。

答案

這是一個簡單的例子。

DO 5 ROW=1, N
PIVINV=1.0/A(ROW,ROW)
DO 10 I=ROW+1, N
DO 20 J=I, N
A(I,J)=A(I,J)-PIVINV*A(ROW,J)
20 CONTINUE
10 CONTINUE
5 CONTINUE

問題 5

FORTRAN 語言規範要求陣列“按列”儲存,也就是說,整個第一列連續儲存,然後是第二列,等等。給定的程式碼片段是否利用了這一點,或者它是否可以重寫以使其更快,透過利用計算機從連續位置獲取資料的速度更快這一事實?

答案

是的,因為 在最內層迴圈中。

華夏公益教科書