余白の書きなぐり

aueweのブログ

LAPACKを導入してC言語からコンパイル (Linux, Windows)

Fortran には LAPACK と呼ばれる密行列用の線形演算パッケージが存在する。 行列の固有値を求めたり連立方程式を解いたりしてくれる。便利。 疎行列にはARPACKを使ったほうがいいらしい。 今回は LAPACK を導入して C言語から呼び出す方法を書くよ。

Linux

LAPACK のインストールは、たとえばDebian系のディストリビューションなら

$ sudo apt-get install gfortran   #これはいらないかも
$ sudo apt-get install libblas-dev liblapack-dev libatlas-base-dev

Fedora なら yum を使うなど、うまいこと導入する。

コンパイルは、LAPACK ルーチンを使用した C言語のソースファイル hoge.c を用意して

$ gcc hoge.c -llapack -lblas -lgfortran -lm

Windows (MinGW)

MinGW の環境は導入済みとする。 mingw32-lapack-3.2.1-1.zip をダウンロードして解凍すると、 /bin/blas.dll/bin/lapack.dll が生成される。 この生成された C:\path\to\binディレクトリにパスを通す。 パスが通ってなくてもコンパイルは通るものの、 実行に blas.dlllapack.dll が呼び出せずエラーになるので、面倒臭がらずにパスを通しましょう。 通常の環境だと、zipファイルを解凍して得られたbinlibディレクトリの中身を、C:\Mingw\binC:\Mingw\libに入れるのが良いと思う。 パスを通した後に LAPACK ルーチンを使用した hoge.c を用意して、

gcc hoge.c C:/path/to/bin/blas.dll C:/path/to/bin/lapack.dll

すればコンパイルされ、実行ファイル a.exe が生成される。

LAPACK を使用した C言語のサンプルコード

/* 連立方程式
 * (1 2)(x) -- (5)
 * (3 4)(y) -- (6)
 * の解
 */

#include <stdio.h>
#define SIZE 2

int main(void) {
  int     n             = SIZE;// 正方行列Aの次元
  int     nrhs          = 1   ;// Ax=b の縦ベクトルbの列数
  double  A[SIZE*SIZE]        ;// Ax=bの正方行列A
  A[0]=1; A[2]=2;
  A[1]=3; A[3]=4;
  int     lda           = SIZE;// 普通はSIZEにする
  int     ipiv[SIZE]          ;// LU分解の交換行列のピポット要素。[SIZE]にしておく
  double  b[SIZE]             ;// Ax=bの縦ベクトルb。計算終了後はxベクトルが入る。
  b[0]=5;
  b[1]=6;
  int     ldb           = SIZE;// 普通はSIZEにする
  int     info                ;// 0なら正常終了

  dgesv_(&n,&nrhs,A,&lda,ipiv,b,&ldb,&info);

  printf("x = %5.3lf\n",b[0]);
  printf("y = %5.3lf\n",b[1]);
  return 0;
}

コンパイルと実行結果

$ gcc hoge.c -lm -lblas -llapack
$ a.out
x = -4.000
y = 4.500