来自LAPACK的Schur输出与MATLAB不匹配

时间:2018-01-23 15:35:45

标签: matlab matrix lapack lapacke

我正在尝试使用LAPACK重现schur函数,但是在获得与MATLAB匹配的结果时遇到了困难,尽管MATLAB内部使用LAPACK作为其schur。我尝试使用LAPACK_dgehrd和LAPACK_dhseqr,但是T的最后一列与MATLAB不匹配。然后我尝试使用dge,但是矩阵T中的特征值的排序与MATLAB给出的排序不同,这反过来导致T矩阵的其余部分不同。我插入了用于LAPACK的C代码。 dgehrd和dhesqr部分被评论。附加的是一个图像,结果是使用三种方式的小型4x4矩阵:

  1. MATLAB
  2. dgehrd& dhesqr
  3. dgees
  4. 我使用的MATLAB函数非常简单:[Q,T] = schur(A);

    请注意,当我使用dgehrd和dhesqr时,输出甚至不满足U T U'= schur的条件;而dgees和MATLAB输出满足要求。

    你能指导一下我使用dgehrd& dhesqr做错了什么导致只有T的最后一列不正确吗?我在LAPACK_dhseqr之前尝试过使用dgebal之前的LAPACK_dgehrd和LAPACK_dorghr,但这也没有帮助。另外,我尝试使用带有dgees的排序“S”选项,使用C代码末尾的lapack_logical函数,将sdim设置为nrows-1和;但这导致了崩溃,你能指导我哪里出错吗?

    schur comparison from MATLAB and two LAPACK packages

    #include "lapacke.h"
    #include <stdio.h>
    #include <stdlib.h>
    #ifndef free_NULL
        #define free_NULL(T) {free(T); T = NULL;}
    #endif
    
    int schur(double *val, int nrows, double *U, double *T)
    {
        int i, j, lwork = -1;
        int info;
        int sdim = 0;//nrows-1;//
        int ilo = 1, ihi = nrows -1;
        double *tau = NULL;
        double wkopt;
        double *wr = NULL, *wi = NULL, *Z = NULL;
        double  *work = NULL;
        extern LAPACK_D_SELECT2          SELECT;
        lapack_logical    *bwork;
        FILE *file = NULL;  
        file = fopen("Schurpack.csv","w");
        wr = (double *)calloc(nrows,sizeof(double));
        wi = (double *)calloc(nrows,sizeof(double));
        Z  = (double *)calloc(nrows*nrows,sizeof(double));
        bwork  = (lapack_logical *)calloc(nrows,sizeof(lapack_logical));
    
        LAPACK_dgees ( "V", "N", SELECT, &nrows, val, &nrows, &sdim, wr, wi, Z, &nrows, &wkopt, &lwork, bwork, &info ); 
        lwork = (int)wkopt;
        work = (double*)malloc( lwork*sizeof(double) );
        LAPACK_dgees ( "V", "N", SELECT, &nrows, val, &nrows, &sdim, wr, wi, Z, &nrows, work, &lwork, bwork, &info ); 
    
    
        //tau = (double *)calloc(nrows-1,sizeof(double));
        //lwork = -1; 
        //LAPACK_dgehrd( &nrows, &ilo, &ihi, val, &nrows, tau, &wkopt, &lwork, &info);
        //
        //lwork = (int)wkopt;
        //work = (double *)calloc(lwork,sizeof(double));
        //LAPACK_dgehrd( &nrows, &ilo, &ihi, val, &nrows, tau, work, &lwork, &info);
    
        //lwork = nrows;
        //work = (double *)calloc(nrows,sizeof(double));
        //LAPACK_dhseqr ( "S", "I", &nrows, &ilo, &ihi, val, &nrows, wr, wi, Z, &nrows, work, &lwork, &info );   
        if( info > 0 ) 
        {
            printf( "The algorithm computing Schur Decompsition failed to converge.\n" );
            exit( 1 );
        }
    
        for( i = 0; i < nrows; i++)
        {
            for ( j = 0; j < nrows; j++)
            { 
                U[i*nrows+j] = Z[j*nrows+i];
                T[i*nrows+j] = val[j*nrows+i];
            }
        }
    
        fprintf(file, "U\n\n");
        for (j = 0; j < nrows; j++)
        {
            for (i = 0; i < nrows; i++)
                fprintf(file,"%f,",U[j*(nrows)+i]);
            fprintf(file,"\n");
        }
    
    
        fprintf(file,"T\n\n");
        for (j = 0; j < nrows; j++)
        {
            for (i = 0; i < nrows; i++)
                fprintf(file,"%f,",T[j*(nrows)+i]);
            fprintf(file,"\n");
        }
        fclose(file);
        file = NULL;
    
    
        if (tau)
            free_NULL(tau);
        if (wr)
            free_NULL(wr);
        if (wi)
            free_NULL(wi);
        if (Z)
            free_NULL(Z);
        if (work)
            free_NULL(work);
    
        return(0);
    }
    
    
    lapack_logical SELECT ( double ER, double EI)
    {
        if ((ER==1) && (EI==0))
            return(0);
        else
            return(1);
    }
    

0 个答案:

没有答案