c - 设置 LAPACKE 的带状矩阵格式

标签 c matrix lapack intel-mkl lapacke

我正在尝试使用英特尔 MKL 中称为 LAPACKE 的 LAPACK C 接口(interface)来求解一般带状矩阵。我尝试调用的函数是 *gbsv,其中 * 表示格式。不幸的是,我发现非常很难找到有关如何使用 C 接口(interface)格式化带状矩阵的工作示例。如果有人可以为所有 C 用户提供一个工作示例,我向您保证这将会有所帮助。

以 Fortran 布局为例 here ,但我不太确定如何将其格式化以输入 LAPACKE。我还应该注意,在我的问题中,我必须动态构建带状矩阵。所以我有 5 个系数,每个 i 节点 A、B、C、D、E,必须将其放入带状矩阵形式,然后传递给 LAPACKE。

最佳答案

函数LAPACKE_dgbsv()的原型(prototype)如下:

lapack_int LAPACKE_dgbsv( int matrix_layout, lapack_int n, lapack_int kl,
                      lapack_int ku, lapack_int nrhs, double* ab,
                      lapack_int ldab, lapack_int* ipiv, double* b,
                      lapack_int ldb )

与Lapack的函数dgbsv()的主要区别在于参数matrix_layout,它可以是LAPACK_ROW_MAJOR(C排序)或LAPACK_COL_MAJOR(Fortran 排序)。如果LAPACK_ROW_MAJORLAPACKE_dgbsv将转置矩阵,调用dgbsv(),然后将矩阵转置回C排序。

其他参数的含义与函数 dgbsv() 相同。如果使用 LAPACK_ROW_MAJOR,则 dgbsv() 的正确 ldab 将由 LAPACKE_dgbsv() 计算,并且参数ldab可以设置为n。然而,就像dgbsv()一样,必须为矩阵ab分配额外的空间来存储因式分解的详细信息。

以下示例利用 LAPACKE_dgbsv() 通过中心有限差分求解一维平稳扩散。考虑零温度边界条件,并使用正弦波之一作为源项来检查正确性。 gcc main3.c -o main3 -llapacke -llapack -lblas -Wall编译出以下程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>

#include <lapacke.h>

int main(void){

    srand (time(NULL));

    //size of the matrix
    int n=10;
    // number of right-hand size
    int nrhs=4;

    int ku=2;
    int kl=2;
    // ldab is larger than the number of bands, 
    // to store the details of factorization
    int ldab = 2*kl+ku+1;

    //memory initialization
    double *a=malloc(n*ldab*sizeof(double));
    if(a==NULL){fprintf(stderr,"malloc failed\n");exit(1);}

    double *b=malloc(n*nrhs*sizeof(double));
    if(b==NULL){fprintf(stderr,"malloc failed\n");exit(1);}

    int *ipiv=malloc(n*sizeof(int));
    if(ipiv==NULL){fprintf(stderr,"malloc failed\n");exit(1);}

    int i,j;

    double fact=1*((n+1.)*(n+1.));
    //matrix initialization : the different bands
    // are stored in rows kl <= j< 2kl+ku+1
    for(i=0;i<n;i++){
        a[(0+kl)*n+i]=0;
        a[(1+kl)*n+i]=-1*fact;
        a[(2+kl)*n+i]=2*fact;
        a[(3+kl)*n+i]=-1*fact;
        a[(4+kl)*n+i]=0;

        //initialize source terms 
        for(j=0;j<nrhs;j++){
            b[i*nrhs+j]=sin(M_PI*(i+1)/(n+1.));
        }
    }
    printf("end ini \n");

    int ierr;


    // ROW_MAJOR is C order, Lapacke will compute ldab by himself.
    ierr=LAPACKE_dgbsv(LAPACK_ROW_MAJOR, n, kl,ku,nrhs, a,n, ipiv,  b,nrhs );


    if(ierr<0){LAPACKE_xerbla( "LAPACKE_dgbsv", ierr );}

    printf("output of LAPACKE_dgbsv\n");
    for(i=0;i<n;i++){
        for(j=0;j<nrhs;j++){
            printf("%g ",b[i*nrhs+j]);
        }
        printf("\n");
    }

    //checking correctness
    double norm=0;
    double diffnorm=0;
    for(i=0;i<n;i++){
        for(j=0;j<nrhs;j++){
            norm+=b[i*nrhs+j]*b[i*nrhs+j];
            diffnorm+=(b[i*nrhs+j]-1./(M_PI*M_PI)*sin(M_PI*(i+1)/(n+1.)))*(b[i*nrhs+j]-1./(M_PI*M_PI)*sin(M_PI*(i+1)/(n+1.)));
        }
    }
    printf("analical solution is 1/(PI*PI)*sin(x)\n");
    printf("relative difference is %g\n",sqrt(diffnorm/norm));


    free(a);
    free(b);
    free(ipiv);

    return 0;
}

关于c - 设置 LAPACKE 的带状矩阵格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36345090/

相关文章:

c - 将除\r 之外的所有字符添加到新字符串

c - 如何查找表达式的哪个索引与正则表达式匹配

具有 GSL、LAPACK 或 CBLAS 等数学库的 C++ 性能与具有 R 函数的 Rinside 的 C++ 相比?

mpi - 分割 Scalapack 网格

python - 通过 pyCharm windows 8 安装 scipy 时遇到问题 - 找不到 lapack/blas 资源

c - 16 字节无符号字符数组作为数字?

c - 如何使用 gio/glib 在 C 中列出 dbus 服务下的所有对象路径?

arrays - 在 Matlab 中向量化和分离查找操作

opencv - 将 CV_32FC1 类型的矩阵转换为 CV_64FC1

matlab - 在 MATLAB 中获取 0 数组中随机 1 的位置