トップページ -> コンピュータ -> Linux の C/C++ プログラミング用ツールとライブラリ -> Linux での CLAPACK の使い方
[サイトマップへ], サイト内検索:

Linux での CLAPACK の使い方

サイト構成 連絡先,業績など 実践知識 コンピュータ 教材 サポートページ

CLAPACK とは,元々 FORTRAN で書かれていた LAPACK の,C言語版 (C 言語に書き直されたもの) です. LAPACK とは,行列に関する種々の問題(連立1次方程式,固有値問題,などなど多数). FORTRAN で書かれています.

この Web ページでは,CLAPACK の下記の機能を C プログラムから呼び出す方法を,プログラム例を使って説明します.

BLAS とは?

BLAS(Basic Linear Algebra Subprograms)とは,行列演算,ベクトル演算の機能をもったプログラム群です. GotoBLASATLAS は,無料で使えるソフトウエアの中では,BLAS 実装の決定版といってよいでしょう.※ 他にも,優れた実装が複数あります.

<BLAS の機能の概要(ごく一部)>

※ GotoBLAS は素晴らしいプログラムで,しかも,無料で使えます.但し,GotoBLAS はフリーソフトウエアではない.「再配布や,商用・業務利用は原則不可」と明記されています. 再配布不可ですから,ソースコードやビルドしたバイナリを人にあげることはできません(パソコンを借りてインストールしてあげる,ということも難しい,という意味です).

※ GotoBLAS のライセンス条項に「不安」がある場合は,ATLAS を使うことも検討してください.(決して違法なことはしないように).

LAPACK とは?

LAPACK とは,行列に関する種々の計算(連立1次方程式,固有値問題,などなど多数)のソフトウエアです. LAPACK は,BLAS の機能を利用して,種々の機能を実現します.(BLAS を速いものに入れ替えれば,LAPACK も速くなるということです).


前準備

前もってインストールしておくべきソフトウエア

  1. BLAS のビルドとインストール

  2. GSL のビルドとインストール

    「Linux に GSL (GNU Scientific Library) をインストール」 の Web ページに従って, GSL (GNU Scientific Library) のインストールが終わっていること.


プログラムの見本

【要点】

※ ソースコードは,このリンクからダウンロードできます ⇒ eig_clapack.c

#include <stdio.h>

#include <f2c.h>
#include <clapack.h>


// CLAPACK ではなく LAPACK を直接呼び出す.
//  see http://www.netlib.org/clapack/clapack.h

// ?geev : simple driver for eigenvalues/vectors
//         see http://www.netlib.org/lapack/lug/node32.html

integer eigenvalues( integer n, doublereal *a, doublereal *wr, doublereal *wi ) {
  /* LAPACK の _dgeev() を使って固有値(だけ)を求める */

  integer n3 = n * n * n;
  integer info;

  doublereal *vl = (doublereal *)calloc(sizeof(doublereal), n * n);
  doublereal *vr = (doublereal *)calloc(sizeof(doublereal), n * n);
  doublereal *work = (doublereal *)calloc(sizeof(doublereal), n3);

  (void) dgeev_(
		/* char *jobvl */      "N",  /* "N" なので左固有ベクトルを計算しない */
		/* char *jobvr */      "N",  /* "N" なので右固有ベクトルを計算しない */
		/* integer *n */       &n,   /* 正方行列の次数 */
		/* doublereal *a, */   a,    /* A */
		/* integer *lda, */    &n,   /* A 用の作業領域 */
		/* doublereal *wr, */  wr,   /* 固有値の実部 */
		/* doublereal *wi, */  wi,   /* 固有値の虚部 */
		/* doublereal *vl, */  vl,   /* 左固有値 */
		/* integer *ldvl, */   &n,   /* 左固有値の作業用 */
		/* doublereal *vr, */  vr,   /* 右固有値 */
		/* integer *ldvr, */   &n,   /* 左固有値の作業用 */
		/* doublereal *work, */ work, /* 作業用 */
		/* integer *lwork, */  &n3,   /* 作業用の行列の次元 */
		/* integer *info */    &info);

  free( work );
  free( vr );
  free( vl );

  return info;

}

integer eigenvalues_rightvectors( integer n, doublereal *a, doublereal *wr, doublereal *wi, doublereal *vr ) {
  /* LAPACK の _dgeev() を使って固有値と右固有ベクトルを求める */
  /* A * v(j) = lambda(j) * v(j), v(j) is the right eigen vector */

  integer n3 = n * n * n;
  integer info;

  doublereal *vl = (doublereal *)calloc(sizeof(doublereal), n * n);
  doublereal *work = (doublereal *)calloc(sizeof(doublereal), n3);


  (void) dgeev_(
		/* char *jobvl */      "N",  /* "N" なので左固有ベクトルを計算しない */
		/* char *jobvr */      "V",  /* "V" なので右固有ベクトルを計算する */
		/* integer *n */       &n,   /* 正方行列の次数 */
		/* doublereal *a, */   a,    /* A */
		/* integer *lda, */    &n,   /* A 用の作業領域 */
		/* doublereal *wr, */  wr,   /* 固有値の実部 */
		/* doublereal *wi, */  wi,   /* 固有値の虚部 */
		/* doublereal *vl, */  vl,   /* 左固有値 */
		/* integer *ldvl, */   &n,   /* 左固有値の作業用 */
		/* doublereal *vr, */  vr,   /* 右固有値 */
		/* integer *ldvr, */   &n,   /* 左固有値の作業用 */
		/* doublereal *work, */ work, /* 作業用 */
		/* integer *lwork, */  &n3,   /* 作業用の行列の次元 */
		/* integer *info */    &info);

  free( work );
  free( vl );

  return info;
}

int main( integer argc, char **argv ) {
  int i;
  integer n = 10;
  doublereal *a  = (doublereal *)calloc(sizeof(doublereal), n * n);
  doublereal *wr = (doublereal *)calloc(sizeof(doublereal), n);
  doublereal *wi = (doublereal *)calloc(sizeof(doublereal), n); 
  /* doublereal *vr = (doublereal *)calloc(sizeof(doublereal), n * n); */

  eigenvalues( n, a, wr, wi );
  for(i = 0; i < n; i++) {
    printf("%5d %15.7e %15.7e\n", i + 1, *(wr + i), *(wi + i));
  }

  free(wi);
  free(wr);
  free(a);

  return 0;
}

ビルドの手順

ATLAS を使う場合

コンパイルコマンドの例

gcc -o a.out eig_clapack.c -L/usr/lib -lclapack_LINUX -lctmglib_LINUX -L/usr/atlas/lib -lptf77blas -latlas -lf2c -lpthread -lm