ホーム > 数値計算ソフトウェア > ライブラリ > LAPACK > CLAPACK > ルーチンの仕様 >

 BandStrage (CLAPACK)

帯格納形式

少ないメモリ量で行列[A]を保存し、効率良く計算できるような行列形体する。

<関数>

void klku(long int *n, long int *kl, long int *ku, double *a); //従来表示の行列[A]からkl,kuを獲得。

void cs2bs(long int *n, long int *kl, long int *ku, double *a, double *ab); //従来表示の行列[A]を帯格納形式の行列[AB]に格納。

<引数>

long int n - (input) 連立一次方程式の式数。正方行列[A]の次数。(n≧0) ここで、行列[A]はn行n列である。

long int kl - (output//input) 行列[A]の帯内の対角下要素の個数。(kl≧0)

long int ku - (output//input) 行列[A]の帯内の対角上要素の個数。(ku≧0)

                                   ku
                                      
                                                  kl                                                                                    n

double a - (input)n行n列の従来の表示形式であらわした行列(但し、行列Aは1次元配列である)。

double ab - (output)n行n列の係数行列[A]を行kl+1から行2*kl+ku+1に対格納形式で入れる。配列の1行〜kl行には値は入れなくても良い。

                 配列[AB]の第j列には次のように値を格納する(但し行列AおよびABは1次元配列である)。

                      max( 1, j-ku ) <= i <= min( N, j+kl ) に対して AB( kl+ku+1+i-j, j ) = A( i, j ) を行う。

帯行列状態の行列[A]

a11 a12   *    *    *    *
a21 a22 a23   *    *    *
a31 a32 a33 a34   *    *
 *   a42 a43 a44 a45   *
 *     *  a53 a54 a55 a56
 *     *    *  a64 a65 a66

行列[A]から作成された帯格納行列[AB]

 *     *      *     +     +     +
 *     *      +     +     +     +
 *    a12  a23  a34  a45  a56
a11  a22  a33  a44  a55  a66
a21  a32  a43  a54  a65   *
a31  a42  a53  a64   *     *

/* prototype                                 */
/* this program need a math header */

void klku(long int *n, long int *kl, long int *ku, double *a);

/* function */

void klku(long int *n, long int *kl, long int *ku, double *a)

{

        static long int i,j;

        static double eps = 1.0E-07;

        /* initialize */

        *kl = 0;

        *ku = 0;

        /* j = row , i = col, A[j][i]==a[(j-1)*n+i] */

        for( i = 0; i < (*n); i++ ){

                for( j = 0; j < (*n); j++){

                        if( fabs( a[ j * (*n) + i] ) >= eps && ( *ku < j - i )){

                                *ku = j - i;

                        }

                }

        }

        for( j = 0; j < (*n); j++ ){

                for( i = 0; i < (*n); i++){

                        if( fabs( a[ j * (*n) + i] ) >= eps && ( *kl < i - j )){

                                *kl = i - j;

                        }

                }

        }

}

/* define */

#define max(a,b) (a > b) ? a : b

#define min(a,b) (a < b) ? a : b

/* prototype */

void cs2bs(long int *n, long int *kl, long int *ku, double *a, double *ab);

/* function */

void cs2bs(long int *n, long int *kl, long int *ku, double *a, double *ab)

{

        static long int i,j;

        /* initialize */

        for( i = 0; i < (*n) * (2 * (*kl) + (*ku) +1); i++ ){

                        ab[i]= 0.0;

        }

        /* j = row , i = col, A[j][i]==a[(j-1)*n+i] */

        /* ab[kl+ku+1+i-j][j]=a[i][j] for max(1,j-ku) <= i <= min(n,j+kl) */

        for( j = 1; j <= (*n); j++ ){

                for( i = (max( 1, j - (*ku) )); i <= (min( (*n) , j + (*kl) )); i++){

                        ab[(j-1) * (2*(*kl)+(*ku)+1) + (*kl) + (*ku) + i - j ]= a[ (j-1) * (*n) + i - 1];

                }

        }

}

従来形式の帯行列をを帯格納形式に変形する。

#include<stdio.h>

#include<math.h>

#define N 6

int main(void)

{

        static long int i, ldab;

        static long int n = N;

        static double A[N*N];

        static double *AB;

        A[0]=1.;A[1]=3.;A[2]=1.;A[3]=0.;A[4]=0.;A[5]=0.;

        A[6]=2.;A[7]=2.;A[8]=1.;A[9]=2.;A[10]=0.;A[11]=0.;

        A[12]=0.;A[13]=1.;A[14]=1.;A[15]=1.;A[16]=-1.;A[17]=0.;

        A[18]=0.;A[19]=0.;A[20]=1.;A[21]=2.;A[22]=-1.;A[23]=1.;

        A[24]=0.;A[25]=0.;A[26]=0.;A[27]=-1.;A[28]=2.;A[29]=1.;

        A[30]=0.;A[31]=0.;A[32]=0.;A[33]=0.;A[34]=1.;A[35]=1.;

        klku(&n, &kl, &ku, A);

        ldab = 2*kl+ku+1

        AB = (double *)malloc(ldab*n*sizeof(double));

        cs2bs(&n, &kl, &ku, A, AB);

        for(i=0;i<36;i++){

                printf("%f \t",AB[i]);

        }

        printf("%d %d\t",kl,ku);

        free(AB);

        return 0;

}


Copyright (C) 2001 Keisuke ABE. All Rights Reserved.