LAPACK dgeev函数在特征向量估计中不起作用

问题描述 投票:0回答:1

我有使用Lapack库在MEX中计算本征维和本征向量的代码:

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));

其中AvaW和AveW分别是输出特征值和特征向量。

我的问题是:我有一个输入矩阵A。当A = H(H是NxN维的非对称法线矩阵)时,dgeev效果很好。我已将其与matlab的eig函数进行比较,并在函数f(AvaW,AveW)中进行了比较,得出了正确的结果。但是,当A = M时,其中M为:

M = [H I;
     Z Z];

I =眼矩阵,Z是零矩阵,M是2Nx2N尺寸的正方形矩阵。在那种情况下,dgeev可以很好地计算特征值,但顺序与Matlab不同(AvaW(1:N)= AvaMatlab(N + 1:2N)和AvaW(N + 1:2N)= AvaMatlab(1:N))。使用dgeev计算自动向量是错误的,与Matlab的自动向量不匹配,并且f(AvaW,AveW)的结果不正确。

有人知道这是什么问题吗?

非常感谢,问候。

PD:在所有情况下,INFO的值均为0,这意味着解决方案是正确的。然后检查M和H矩阵是否正确。

matlab mex lapack eigenvalue eigenvector
1个回答
0
投票

问题是I矩阵和Z矩阵的位置(左下)。由于索引错误,分配是错误的。这不是dgeev函数的问题。

创建运行良好的M的代码是:

 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];
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.