C 和 C++ 的矩陣庫

C 和 C++ 的矩陣庫

  2005-05-11 18:51:12  
 


評估和比較 Meschach、Cooperware 矩陣和 Blitz

Andrew L. Blais([email protected]
研究員和作家

本文將介紹一些目前可在 Linux 環境中使用的開放源代碼 C/C++ 矩陣庫。在這裏具體討論的庫有三個:Meschach 庫爲 C 代碼編寫的項目提供例程,用於矩陣和向量的運算;Cooperware Matrix(CwMtx)庫可用於 C++ 代碼編寫;Blitz 庫爲 C++ 提供可用整數、浮點數、複數和規範的用戶定義的類型的 n 維數組類。Andrew Blais 是 Gnosis,Inc. 的研究員和作家,他在 developerWorks 已投稿多次,從事神經網絡方面的工作。
本文假設讀者對 C/C++ 有一定的瞭解並非常關注 C/C++ 本身沒有矩陣功能。您可能在分析計量經濟學的數據或模擬雨林。對於我來說,我正從事神經網絡的研究而一兩個矩陣可以大大簡化神經網絡的實現。雖然 C/C++ 包括可被看作矩陣(例如數組和標準庫中的向量、列表和圖)的容器,但是,真正是矩陣的容器將使手中的任務變得很容易。所以我們將介紹三個開放源代碼庫供您選擇,它們不要求您從頭開始構建矩陣,但的確讓您使用矩陣庫。如果您期望用從未見過的方法來使用它,那就太好了。

Meschach:用 C 的選擇
對於用 C 編寫代碼的項目,Meschach(讀作 me-shark)提供了例程,用於矩陣和向量的運算。它的優點是能在 Linux 和多數其它操作系統下編譯,並且在版權保護下可公開獲得,只要您作出例行的承認並報告錯誤。Meschach 可以解稠密或稀疏線性方程組、計算特徵值和特徵向量和解最小平方問題,另外還有其它功能。它爲雙精度數和複數提供了近 400 個函數。它提供的教程以說明性的小案例研究的形式介紹了這些函數。David Stewart 和 Zbigniew Leyk 通過一些主題的討論來介紹 Meschach,這些主題包括超定方程組的廣義的最小平方方程解答器(generalized least square equation solver for over-determined equations)和涉及稀疏矩陣的問題。他們的教程還包括三維矩陣和錯誤報告等稍稍高級的主題。

對象和類函數往往與代碼關聯,C 結構可能看起來有點神祕,所以 C 庫往往不被作爲可行的解決方案。但是作爲對此的反擊,這個庫的組織很合理,所以不應不加思索地就捨棄它。在下載 Meschach 後過了一刻鐘,我就可以製造、填充和顯示矩陣了(在概念上等同於創建 Hello World! 程序)。您可以參考一本名爲“Meschach: Matrix Computations in C”的便宜的印刷品手冊(請參閱本文末尾的參考資料)。特別是測試程序“torture”,其中包括不少有益的線索。

矩陣可被容易地發送到文件或標準輸出。Meschach 能計算快速傅立葉變換(Fast Fourier Transform)、提取列和行以及計算對稱矩陣的特徵值。您可以在矩陣中填充隨機整數和複數。信不信由您,該庫甚至還有矩陣相加的工具。Meschach 有一個返回在 [0,1) 之間的隨機雙精度數的函數,它是 Meschach 的一個特色,可用於簡化明顯的踏腳石程序的編寫。雖然 Meschach 有一個用 1.0 填充矩陣的函數,但不幸的是,它沒有用一個任意的雙精度數填充矩陣的函數,也沒有用隨機雙精度數填充矩陣的函數。不過,添加它們是容易的。

清單 1. 用一個任意的雙精度數或隨機雙精度數來填充矩陣
MAT *m_fill( MAT *A, double x)
/* MAT *m_random_fill( MAT *A ) */
{
int i, j;
for ( i = 0; i < A->m; i++ ) for ( j = 0; j < A->n; j++ )
{ A->me[i][j] = x ; }
/* { A->me[i][j] = m_random ; } */
return A;
}



所以,正如我們所看到的,Meschach 代碼可被容易地擴展,儘管在理想的世界中應該更加詳細地註釋代碼。但是如果您正好在用 C 做計算工作並且要用到矩陣,那麼這是很有用的庫。

Cooperware 矩陣:基礎知識
如果您要用 C++ 編寫面向對象的代碼並且您認爲概念的清晰比速度更重要,那麼 Harry Kuiper 的 Cooperware Matrix(CwMtx)能很好地運行。在這裏討論的三個矩陣庫中,我覺得它的概念性體系結構最容易理解。在構造矩陣時,您直接使用:

清單 2. 構造矩陣
CWMatrix A( rows, columns ) ;



在這裏考慮的三個庫中,以三個評估性任務爲標準,CwMtx 的性能最差,我們將在速度部分詳細地討論。但是如果清晰比性能更重要(例如當您要確信您的數據被正確地處理),那麼 CwMtx 是很好的選擇。先使它正確,再使它快速。

CwMtx 中的矩陣包括向量和方陣,其中向量包括空間向量和四元數。一個矩陣可被映射到另一個矩陣、用某個元素來填充、轉置和進行常見的數學運算。Kuiper 原先用 CwMtx 來模擬用離散的交互式狀態機器構建的系統。除了必須的矩陣類,還有四元數類。對於明顯問題的回答是,僅當 q = r + xi + yi + zi 時 q 纔是四元數,其中 r 是實數,i 是 -1 的平方根,x、y 和 z 是複數。四元數可能把三維旋轉的概念推廣到四維(請參閱參考資料,其中有四元數的參考資料的鏈接)。

CwMtx 沒有內置的隨機數生成器,也沒有用隨機元素填充矩陣的類函數。但是,它是免費的且它的發佈受 GNU LGPL 許可證的保護,所以如果您願意的話,您有創建這些(生成器和類函數)的自由。如果僅僅是用隨機元素填充矩陣,那麼以下代碼是不錯的和容易的選擇。

清單 3. 用隨機元素填充矩陣
#include
...
void random_fill( CWMatrix &M )
{
int SIZE = M.GetRows() ;
for ( int r=0; r



這裏的文檔並不詳細,但文檔是清楚的並且組織得也很好。您能容易地找到類層次結構、構造函數、成員函數選項等信息。雖然沒有教程,但您不會想念它;由於有了文檔和測試程序,您並不需要它。

Blitz:和 Fortran 一樣快?
Blitz 是另一個 C++ 庫,它的發行受 GNU GPL 的保護,您可以用它來免費地創建對象。它支持 KAI、Intel、gcc、Metroworks 和 Cray 3.0.0.0 C++ 編譯器,它還提供 n 維數組類,這些類可包括整數、浮點數、複數和用戶定義的表現良好的類型。它的構造函數比 CwMtx 的構造函數更復雜,下面的示例證明了這一點:

清單 4. Blitz 構造函數
Array A(4,7) ;



示例中創建了包含雙精度數的秩爲 2 的 4x7 數組。但是這樣有點不清楚,所以 Blitz 使您把數組看作矩陣。還有,它沒有實現許多矩陣函數。例如,它沒有返回矩陣的特徵值的函數。它也沒有用隨機雙精度數來填充數組或矩陣的函數。但是,Blitz 確實有兩個基本優點。

一個優點是它的廣度。通過使用它自身的功能可以容易地實現和構造隨機雙精度數填充函數,如下面的示例所示:

清單 5. Blitz 中的隨機雙精度數填充函數
template
void fill( Array &a, int size, Uniform &u )
{
for ( int i=0; i
for ( int j=0; j
{ a(i,j) = u.random() ; }
}



Blitz 的 Uniform 類提供返回在 [0,1) 間的雙精度數的成員函數。它還提供三種訪問數組元素的方法:標準索引、創建子數組和切片(slicing),切片能產生維數更小的數組片段的視圖。Blitz 還處理標準計算器類型函數,所以數組可在標準輸出上顯示,而且可從文件中讀入或發送到文件。Laplacian、坡度(gradient)和 Jacobian 運算符只是 Blitz 的模版(stencil)函數的三個示例。

Blitz 的另一個優點是它的速度。根據所用的編譯器,C++ 的性能可以趕上 Fortran,而 Fortran 在科學和工程計算方面所表現的高性能是出名的。看一看下錶中的比較,但是請閱讀後面的速度部分,其中分析了這些數據和基於這些數據的性能表現。

表 1. 在不同平臺上的 Blitz 性能 平臺 編譯器 高速緩存外 高速緩存內
HPC-160 KAI C++ 100.2% 97.5%
Pentium II egcs 98.4% 79.6%
Cray T3E KAI C++ 95.7% 98.1%
Origin 2000 KAI C++ 88.1% 79.8%


Blitz 帶有一本手冊,格式是 HTML 和 Postscript,但不幸的是沒有教程。然而,有不少說明性的代碼,從中可以瞭解 Blitz 語法的細微差別。類的參考資料提供通常的信息。還有幾個有用的郵件列表,已被歸檔,可供搜索(請參閱參考資料)。

速度
庫的評價標準有庫的功能性資源、文檔、庫的教程質量、庫的擴展難度等。庫的評價標準還有性能和/或速度。但是,有時候比較它們是困難的,因爲(我們的示例就是這種情況)它們並不是都用相同的語言來編寫的,而且它們相同的自身功能也不多。在我們這裏,三個庫有足夠的重複部分,這使我們能用三個比較簡單但能說明問題的任務來比較它們的速度,我們將在下面三個示例中顯示和討論這些任務。

清單 6. 第 1 個任務
For ( d=2; d<7; d++)
Construct 3 dxd matrices: A, B, C
Start Clock: Do the following one million times:
Fill A and B with 1.0s
Let C = A + B
Stop clock: Report elapsed time in seconds.



使用我們的庫來實現並執行這個算法產生以下結果:

表 2. 第 1 個任務的結果 庫 2x2 3x3 4x5 5x5 6x6
Blitz 0.40 0.48 0.62 0.75 0.91
CwMtx 2.64 3.57 4.58 5.60 6.60
Meschach 0.17 0.27 0.45 0.60 0.79


儘管 CwMtx 的體系結構易於理解,但不幸的是,它在這裏的表現並不好。雖然 Blitz 的表現不如 Meschach,但是值得注意的是 Blitz 的性能大大超過了它的面向對象的對手 CwMtx。

如前所述,Meschach 和 Blitz 有提供隨機雙精度數的函數(隨機數生成器),而 CwMtx 自身沒有產生隨機數的功能。考慮到隨機化在某些基於矩陣的模擬中的關鍵作用,研究這些庫在調用隨機化的情況下的表現是有益的。

清單 7. 第 2 個任務
For ( d=2; d<7; d++)
Construct 3 dxd matrices: A, B, C
Start Clock: Do the following one million times:
Fill A and B with random doubles (using library RNG, if any)
Let C = A + B
Stop clock: Report elapsed time in seconds.



我們的庫的表現如下:

表 3. 第 2 個任務的結果 庫 2x2 3x3 4x5 5x5 6x6
Blitz 0.87 1.71 2.83 4.34 6.13
CwMtx 3.67 5.87 8.59 11.93 15.61
Meschach 0.42 0.80 1.32 1.86 2.52


Blitz 的表現再次比 Meschach 差,但它的表現超過了它的面向對象的對手 CwMtx,而且這種差距令人吃驚。我們來看看第三個評價任務,以免您認爲這是因爲隨機數生成器的性能有所不同。

清單 8. 第 3 個任務
For ( d=2; d<7; d++)
Construct 3 dxd matrices: A, B, C
Start Clock: Do the following one million times:
Fill A and B with random doubles (using shared RNG)
Let C = A + B
Stop clock: Report elapsed time in seconds.



我們的庫的性能排行榜與前面兩個任務的相同:

表 4. 第 3 個任務的結果 庫 2x2 3x3 4x5 5x5 6x6
Blitz 1.31 2.62 4.50 6.85 9.71
CwMtx 3.67 5.87 8.59 11.93 15.61
Meschach 1.17 2.45 4.28 6.63 9.40


如您所預料的那樣,CwMtx 的性能排名沒有改變。而且,Blitz 和 Meschach 的排名先後順序也沒有變。如果原始速度是決定性因素,那麼這些庫的排名現在已經很清楚。

在 Red Hat Linux 7.1 上安裝和編譯
爲了您的方便,以下列出的是安裝和編譯這三個庫的註解。下載的鏈接可在參考資料中找到。

清單 9. Blitz
tar zxf blitz-0.5beta3.tar.gz
cd blitz-0.5beta3
./configure --with-cxx=gcc
make all
cp -a blitz/ /usr/local/include/ ( or whatever you wish )
cp -a lib/ /usr/local/include/blitz/
Compile with: g++ -O2 pgm.cpp -o pgm




清單 10. Meschach
unzip -q mesch12b.zip -d mesch12b
cd mesch12b
./configure
make basic
mkdir /usr/local/include/meschach ( or whatever you wish )
cp *.h meschach.a /usr/local/include/meschach/
Compile with: gcc -O2 pgm.c /usr/local/include/meschach/meschach.a -o pgm




清單 11. CwMtx
tar zxf cwmtx-0.3.0.tar.gz
cd cwmtx-0.3.0
Open Makefile, and set INSTALL_DIR to /usr/local/include/cwmtx ( or whatever you wish )
Execute: make install
Compile with: g++ -O2 pgm.cpp -o pgm




總結
我們已經瞭解了三個矩陣庫的特色和它們本身的功能的詳細信息。我們也看到了它們的一些功能缺點以及克服這些缺點的方法。我還爲您提供了一些簡單測試,這些測試所提供的原始的量化數據可能在您代碼編寫選擇時對您有所幫助,但最終的決定要由您來作出,而且應該依據您的項目的自身特點以及在給出的環境中庫的速度來作出決定。

參考資料

請在 David Stewart 的站點下載 Meschach,獲得關於 Meschach 的信息,或把電子郵件發送到 [email protected],在信的正文部分寫“send all from c/meschach”(別加引號)。該站點有怎樣購買 Meschach 手冊“Meschach: Matrix Computations in C”的信息。隨機數生成器是基於 Knuth 的滯後的基於 Fibonacci 的生成器。請參閱“Seminumerical Algorithms: The Art of Computer Programming”章節 3.2 到 3.3。


請參閱 The C++ Scalar, Vector, Matrix and Tensor Class Library Standard Page,瞭解定義矩陣的提議。


請下載 Cooperware Matrix 版本 0.4.2。Harry Kuiper 的網頁包含更多關於 Cooperware Matrix 的信息。


請閱讀Matrix and Quaternions FAQ,瞭解什麼是四元數。


如果您想了解更多關於四元數和四維旋轉的信息,請參閱Quaternion Powers。在爲 CwMtx 添加 random_fill 的時候,我用的是 drand48;如果您想了解這方面的更多信息,請參閱手冊頁 drand48.3。


請下載 Blitz,如果您想了解更多信息,請參閱 Blitz 主頁。


請看一個用 Blitz 實現矩陣的示例。


如果您想了解關於郵件列表的更多信息,請參閱Blitz 郵件列表。


如果您想了解更多關於 Blitz 中實現的隨機數生成器的信息,請閱讀“Mersenne Twister: A 623-Dimensionally Equidistributed Uniform Pseudo-Random Number Generator”,ACM Transactions on Modeling and Computer Simulation,第 8 卷,第 1 號,1998 年 1 月,第 3 到 30 頁。


請看一看Matrix TCL Lite(免費)或 Matrix TCL Pro(收費)。前者能在我喜歡的編譯器 g++ 2.96 上運行,但由於庫本身沒有優化,所以我的分析不適用它。後者是優化的,但不能在我的編譯器上運行,所以我的分析也不適用它。


獲得面向對象庫的列表,用於科學計算。


請閱讀 Andrew 的文章“An introduction to neural networks”(developerWorks,2001 年 7 月)。


Improving the memory-system performance of sparse-matrix vector multiplication 講述在超標量 RISC 處理器上用大於二的因子來提高矩陣相乘的速度的方法。


如果您想了解更多關於提高稀疏矩陣算法的信息,請閱讀Fast and effective algorithms for graph partitioning and sparse-matrix ordering。


請下載WebSphere Studio Application Developer Linux 版的基本版的試用版。


請在 developerWorks Linux 專區查閱更多 Linux 的文章和教程。

作者簡介
Andrew L. Blais 把他的時間分配在四件事上:對他的兒子 A. Van Blais 進行家教;當 K.J. Krawczyk-Blais 的丈夫;爲 Gnosis Software,Inc. 研究和寫作;在 Anna Maria College 教哲學和宗教。有時候,他會休息一下。您可以通過 [email protected] 與 Andrew 聯繫。

 
http://www.bios.net.cn/computer/SYSTEM/Linux/kf/2682.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章