1. CLAPACK簡介
要瞭解CLAPACK,就要Crowdsourced Security Testing道什麼是LAPACK。
LAPACK(Linear Algebra PACKage)是一個高效能的線性代數計算庫,以BLAS(Basic Linear Algebra Subprograms)為基礎,用Fortran語言編寫,可用於計算諸如求解線性代數方程、線性系統方程組的最小平方解、計算特徵值和特徵向量等問題。而CLAPACK則是LAPACK的C語言介面。
2. CLPACK的安裝
搜了不少網頁,終於找到一個方便的安裝方法(http://icl.cs.utk.edu/lapack-for-windows/clapack/index.html#running)。這個安裝方法在我的PC測試通過,PC的配置是Windows XP SP3,VC6。具體步驟如下:
- Download clapack-3.2.1-CMAKE.tgz and unzip.
- Download cmake and install it on your machine.
- Open CMAKE
- Point to your CLAPACK-3.2.1-CMAKE folder in the source code folder
- Point to a new folder where you want the build to be (not the same is better)
- Click configure, check the install path if you want to have the libraries and includes in a particular location.
- Choose Visual Studio Solution. You can also choose nmake or any other platform.
- You may have to click again configure until everything becomes white
- Click generate, that will create the Visual Studio for CLAPACK and you are done.
- Close CMAKE
- Look in your "build" folder, you have your CLAPACK Visual Studio Solution, just open it.
- Build the "ALL_BUILD" project, it will build the solution and create the librarires
- Build the "INSTALL". This will put the libraries and include in your install folder.
- Build the "RUN_TESTS". The BLAS and CLAPACK testings will be run.
如果沒修改CMAKE中的設定,那麼搞定第6個步驟後,你會在C:\Program Files\CLAPACK發現你所需要的*.h和*.lib
備忘:在RUN_TESTS有部分不能通過,也不影響其餘功能的正常使用
3. CLAPACK的使用
使用CLPACK前,要先清楚四點:
首先是Levels of Routines,即函數的層次。LAPACK將整個庫分為三大塊:driver, computional, auxiliary,具體哪塊是做什麼的,請自行看連結。
其次是Naming Scheme,即命名規則。LAPACK的driver 和 computational 的函數名通常為XYYZZZ,其中X指使用的資料類型,YY指矩陣類型,ZZZ指函數的功能。例如SGEBRD的意思是單精確度(S)的在一般的矩陣(GE)上執行bidiagonal reduction(BRD)操作,還是那句,具體的,請自行看連結。
再次是CLAPACK的函數不接收二維數組,即只能用一維數組代替二維數組,例如我想要個array[2][2] = { {1,2}, {3,4} },那麼正確的寫法是array[2*2] = { 1, 2, 3, 4}。
最後是行主序與列主序的問題。CLAPACK看一維數組時會將其看成是按列存放的。所以習慣將一維數組看成是按行存放的要特別注意了。如果說就是不爽按列存放呢?那麼可以在計算前,先將其轉置。
這裡以使用dgemm_函數為例,對CLAPACK的使用方法進行說明。從dgemm_的命名可以看出,這是雙精確度(d)的在一般矩陣(GE)執行matrix-matrix操作的函數,更具體來說,是執行C = alpha* op(A)* op(B) + beta * C操作。在clapack.h中的聲明如下:
int dgemm_(char *transa, char *transb, integer *m, integer *n, integer *k, doublereal *alpha, doublereal *a, integer *lda, doublereal *b, integer *ldb, doublereal *beta, doublereal *c__, integer *ldc);
其中
transa表示op(A)的操作,若transa = 'T',則表示對A進行轉置
transa表示op(B)的操作
m表示矩陣A的行數
n表示矩陣B的列數
k表示矩陣A的列數
alpha就是alpha的值
a就是矩陣A的一維儲存,注意調用的函數會認為其是列主序的
lda表示矩陣A的第一維(LDA specifies the first dimension of A),其值根據transa的值而變
b是矩陣B的一維儲存
ldb表示矩陣B的第一維,其值根據transb的值而變
c是矩陣C的一維儲存
ldc表示矩陣C的第一維。
以下程式將計算
//author: Zero#include "iostream"#include "f2c.h" #include "clapack.h"using namespace std;int main() { char transa = 'T', transb = 'T'; integer M = 2, N = 2, K = 2, LDA = K, LDB = N, LDC = M; double alpha = 1.0, A[4] = { 1, 2, 3, 4}, B[4] = { 5, 6, 7, 8 }, beta = 0.0, C[4]; //下面的函數的意思是C = 1.0 * T(A) * T(B) + 0 * C,其中T()表示將某個矩陣轉置 //注意此時得到的C是按列存放的 dgemm_(&transa, &transb, &M, &N, &K, &alpha, A, &LDA, B, &LDB, &beta, C, &LDC); cout<<C[0]<<" "<<C[2]<<endl; cout<<C[1]<<" "<<C[3]<<endl; return 0;}
要成功編譯這個程式,還要進行以下設定