|
|
|
|
CLAPACKの使用上の注意点 |
CLAPACKを使用する際の注意点
CLAPACKはLAPACKをf2cで変換したものなので、以下のような制約がある。
(例)
LAPACK (Fortran) で DGBSV という関数は、CLAPACKでは dgbsv_ となる。
関数の引数には全てポインタで渡さなければならない。値渡しは不可。
(例)
static long int n=N,inc=1,info,piv[N];
dgesv_(&n,&inc,A,&n,piv,x,&n,&info);
関数の整数の引数には基本的に long int 型のポインタを渡さなければならない。特に、配列を渡すときは long int型にしなければならない。
(例)
[A]{x}={b}を解く関数が以下で与えられる場合には、
dgesv_( integer *n, integer *nrhs, doublereal *a, integer *lda,
integer *ipiv, doublereal *b, integer *ldb, integer *info);
引数 nrhs, lda, ipiv, ldb, info には long int 型のポインタを渡す。
CLAPACKでは、行列も1次元配列に格納して各種関数の引数に渡す。ただし、1次元配列には列方式で格納していく。
(例) 行列
を1次元配列Aに格納する場合には以下のようにする。
double *A;
A = malloc(N*N*sizeof(double));
A[0] = 1; A[1] = 4;
A[2] = 7; A[3] = 2; A[4] = 5; A[5] = 8; A[6] = 3; A[7] = 6;A [8] = 9;
(理由)Fortranの場合には
DOUBLE PRECISION A(LDA, N)
と宣言された二次元 FORTRAN 配列は LDA x N
の倍語のメモリを取り、列方式に従って格納される。つまり、列内の要素は連続し、行内の要素はLDA 倍語の幅だけ離れる。
しかし C
言語では二次元配列は行方式に従う。さらに、二次元の C 配列の行は必ずしも連続である必要はない。
double
A[LDA][N];
は長さ N の行への LDA
ポインタを持つ。これらのポインタは原則的にはメモリのどこにあってもよい。このような二次元 C 配列を CLAPACK
ルーチンに引き渡すと確実に間違った結果をもたらす。
ポインタ渡しの都合上、関数の引数に文字列を指定できない。なお、関数の引数が文字列の場合であっても,その文字列の最初の文字だけが意味を持つ。
(例)
<Fortran>で
call dpotrf('Upper', n, a, lda, info)
こう書くものを
<CLAPACK>では
char
s = 'U';
dpotrf_(&s, &n, a, &lda, &info);
と書く。
(例)
aho.c というソースファイルをコンパイルする場合に
gcc aho.c -lm -llapack -lblas -lF77
のように、 lapack blas F77の順番で指定する。(Alphaマシンだとこの順番以外でのコンパイルはできません。)
LAPACKを使うときは、数値計算をしているのでマスライブラリはリンクしてるとは思いますが。 -lmを忘れないでください。
Copyright (C) 2001 Keisuke ABE. All Rights Reserved.