Warm tip: This article is reproduced from stackoverflow.com, please click
matlab mex lapack eigenvalue eigenvector

LAPACK dgeev function doesn't work in eigenvectors estimation

发布于 2020-03-30 21:13:57

I have that code to calculate eigenvelues and eigenvectors in MEX with Lapack library:

char *JOBVL="N";
char *JOBVR="V";    

mwSignedIndex LDA, LDVL, LDVR, LWORK, INFO;
LDA = dim;
LDVL = dim;
LDVR = dim;    
LWORK = 4*dim;    

double *Awork, *WR, *WI, *VL, *VR, *WORK;
Awork = (double*)mxCalloc(LDA*dim,sizeof(double));
memcpy(Awork, A, dim*dim*sizeof(double));
WR = (double *)mxCalloc(dim,sizeof(double)); 
WI = (double *)mxCalloc(dim,sizeof(double)); 
VL = (double *)mxCalloc(LDVL*dim,sizeof(double)); 
VR = (double *)mxCalloc(LDVR*dim,sizeof(double)); 
WORK = (double *)mxCalloc(LWORK,sizeof(double)); 

dgeev(JOBVL, JOBVR, &dim, Awork, &LDA, WR, WI, VL, &LDVL, VR, &LDVR, WORK, &LWORK, &INFO);

LWORK = (mwSignedIndex)WORK[0];    
memcpy(Awork, A, dim*dim*sizeof(double));
mxFree(WORK);
WORK = (double *)mxCalloc(LWORK,sizeof(double)); 

dgeev(JOBVL, JOBVR, &dim, Awork, &LDA, WR, WI, VL, &LDVL, VR, &LDVR, WORK, &LWORK, &INFO);
LWORK = (mwSignedIndex)WORK[0];    
memcpy(Awork, A, dim*dim*sizeof(double));
mxFree(WORK);
WORK = (double *)mxCalloc(LWORK,sizeof(double)); 

dgeev(JOBVL, JOBVR, &dim, Awork, &LDA, WR, WI, VL, &LDVL, VR, &LDVR, WORK, &LWORK, &INFO);

mxFree(Awork);
mxFree(WR);
mxFree(WI);    
mxFree(VL);
mxFree(VR);
mxFree(WORK);

memcpy(AvaW, WR, dim*sizeof(double));
memcpy(AveW, VR, dim*dim*sizeof(double));

Where AvaW and AveW are output eigenvalues and eigenvectors respectively.

My problem is: I have a input matrix A. When A = H (H is a nonsymmetric normal matrix of NxN dimension), dgeev works well. I have compared with the eig function of matlab and in a function f(AvaW,AveW) that I know the correct result. But when A = M, where M is:

M = [H I;
     Z Z];

I = eye matrix, Z is a zeros matrix and M is a square matrix of 2Nx2N dimension. In that case dgeev works well to calculate eigenvalues, but in different order than Matlab (AvaW(1:N) = AvaMatlab(N+1:2N) and AvaW(N+1:2N) = AvaMatlab(1:N)). The calculation of the autovectors using dgeev is wrong, does not match autovectors of Matlab and the result of f(AvaW,AveW) isn't correct.

Does anyone know what the problem is?

Thank you very much, greetings.

PD: In all cases the value of INFO is 0, that means that the solution is correct. And I check that M and H matrix are correct.

Questioner
jualsevi
Viewed
86
jualsevi 2020-01-31 18:04

The problem was the position of the I-matrix and the Z-matrix (bottom left) at M. The assignment was wrong due to an error in the indices. It was not a problem of the dgeev function.

The code to create M that works well is:

 for(i=0; i<ny; i++){
    for(j=0; j<ny; j++){
        M[2*i*ny+j] = A[i*ny+j];
        M[2*i*ny+ny+j] = Z[i*ny+j];            
        M[2*ny*ny+2*i*ny+j] = Ipos[i*ny+j];             
        M[2*ny*ny+2*i*ny+ny+j] = Z[i*ny+j];
    }
}