Convert symmetric matrix between packed and full storage?

前端 未结 1 810
感动是毒
感动是毒 2021-01-19 14:02

I\'m new to numerical linear algebra, and I have just started using LAPACK and BLAS.

Is there a routine that can copy/convert a symmetric matrix between packed and f

相关标签:
1条回答
  • 2021-01-19 14:47

    The obvious solution is to symmetrize the matrix by a "home-made/diy" code, the risk being to re-invent the wheel. It is pretty easy to write the for loops needed to symmetrize the matrix after dtpttr.

    for(i=0;i<n;i++){
      for(j=i+1;j<n;j++){
        a[i*n+j]=a[j*n+i];
      }
    }
    

    Is it efficient enough for your application ? On a 10000x10000 matrix, these for loops last 0.88s on my PC, while dtpttr lasts 0.24s.

    Here is the test code. Compile it with gcc main.c -o main -llapack -lblas -lm :

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    
    void dtrttp_(char* UPLO,int* N,double* A,int* LDA,double* AP,int* INFO);
    void dtpttr_(char* UPLO,int* N,double* AP,double* A,int* LDA,int* INFO);
    void daxpy_(int* N,double* DA,double* DX,int* INCX,double* DY,int* INCY);
    
    void dtpttf_(char* TRANSR,char* UPLO,int* N,double* AP,double* ARF,int* INFO);
    
    int main(int argc, char **argv)
    {
    
        int n=10;
        int info;
    
        double *a=malloc(n*n*sizeof(double));
        double *packed=malloc((n*(n+1))/2*sizeof(double));
    
        int i,j;
        for(i=0;i<n;i++){
            for(j=0;j<n;j++){
                a[i*n+j]=i+j;
            }
        }
    
        printf("matrix before pack\n");
        for(i=0;i<n;i++){
            for(j=0;j<n;j++){
                printf("%g ",a[i*n+j]);
            }
            printf("\n");
        }
    
        printf("\n");
        //pack
        dtrttp_("U",&n,a,&n,packed,&info);
    
        //unpack
        memset(a,0,n*n*sizeof(double));
        dtpttr_("U",&n,packed,a,&n,&info);
    
        for(i=0;i<n;i++){
            for(j=i+1;j<n;j++){
                a[i*n+j]=a[j*n+i];
            }
        }
    
        printf("matrix after unpack\n");
        for(i=0;i<n;i++){
            for(j=0;j<n;j++){
                printf("%g ",a[i*n+j]);
            }
            printf("\n");
        }
    
        free(a);
        free(packed);
    
        printf("timing...\n");
    
        n=10000;
    
        a=malloc(n*n*sizeof(double));
        packed=malloc((n*(n+1))/2*sizeof(double));
    
        for(i=0;i<n;i++){
            for(j=0;j<n;j++){
                a[i*n+j]=i+j;
            }
        }
    
        //pack
        dtrttp_("U",&n,a,&n,packed,&info);
    
        //unpack
        memset(a,0,n*n*sizeof(double));
        clock_t t;
        t = clock();
        dtpttr_("U",&n,packed,a,&n,&info);
        t = clock() - t;
        printf ("dtpttr took %f seconds.\n",((double)t)/CLOCKS_PER_SEC);
        t = clock();
        for(i=0;i<n;i++){
            for(j=i+1;j<n;j++){
                a[i*n+j]=a[j*n+i];
            }
        }
        t = clock() - t;
        printf ("symmetrize took %f seconds.\n",((double)t)/CLOCKS_PER_SEC);
        free(a);
        free(packed);
    
        return 0;
    }
    
    0 讨论(0)
提交回复
热议问题