數值線性代數:直接法

BLAS 與 LAPACK

/ BLASS / LAY-pack /

若你把矩陣乘法或高斯消去法自己寫成樸素的三重迴圈,它會正確,但往往比應有的速度慢十倍或百倍,而且可能較不準確。BLAS 與 LAPACK 是一勞永逸解決此事的標準、久經考驗的函式庫:BLAS 提供底層的構件,LAPACK 在其上提供高階求解器。它們是 MATLAB、NumPy、R、Julia 以及幾乎每個科學計算環境內部的引擎。

BLAS(基本線性代數副程式)是一套標準化運算,分成三個層級:第一級是向量-向量運算(如內積,O(n) 次浮點運算),第二級是矩陣-向量運算(如 A x,O(n^2) 次),第三級是矩陣-矩陣運算(如 A B,O(n^3) 次)。關鍵洞見是:第三級運算對只有 O(n^2) 的資料做 O(n^3) 的算術,所以它把每個數重用許多次,可做到快取高效——經大量調校的實作(OpenBLAS、Intel MKL、BLIS)幾乎達到硬體的尖峰速度。LAPACK(線性代數套件)構建你實際會呼叫的演算法——LU、喬列斯基、QR、特徵值、SVD、最小平方——關鍵是它把它們重組為「分塊」演算法,使大部分時間花在快速的第三級 BLAS 上,而非緩慢的逐元素迴圈。

實務教訓就是「別自己造輪子」這句箴言:對標準稠密線性代數,呼叫 LAPACK(它會呼叫調校過的 BLAS),而非自己寫迴圈,因為函式庫更快、更準、測試更徹底,且已處理樞紐選擇與邊界情況。分塊是即使你從不碰程式碼也值得理解的關鍵概念:它存在是因為現代硬體的瓶頸是資料在記憶體階層中的移動而非浮點運算,所以演算法被重構以最大化每從記憶體取一個位元組所做的算術。一個誠實的注意點:對稀疏或高度結構化的矩陣,稠密的 BLAS/LAPACK 是錯的工具——你應改用稀疏函式庫——且不同 BLAS 實作的結果在最後幾位可能不同,因為浮點加法不滿足結合律。

NumPy 的 numpy.linalg.solve(A, b) 會呼叫 LAPACK 的 dgesv,它透過分塊的第三級 BLAS 以部分樞紐選擇把 A 分解為 P A = L U,再回代——遠比手寫迴圈更快也更安全。

一行高階呼叫便轉派到數十年累積、經調校、含分塊與樞紐選擇的函式庫程式碼。

分塊之所以存在,是因為現代效能受限於記憶體移動而非浮點運算次數;但對稀疏或結構化矩陣,稠密的 BLAS/LAPACK 是錯的工具。由於浮點加法不滿足結合律,不同實作的結果在最後幾位可能有差異。

又称
Basic Linear Algebra SubprogramsLinear Algebra PACKage基本線性代數副程式線性代數套件