C-拉帕克·dgeev变性特征向量非正交



我正在制作一个程序,该程序广泛使用特征值和特征向量。在测试程序时,我遇到了一个具有相同特征值的特征向量的情况,并不是完全正交的。我知道,在退化特征向量的情况下,该解决方案不是唯一的,并且不能保证求解程序会产生某个矢量,因为退化特征向量的线性组合仍然是具有相同特征值的特征向量。但是,我确实希望他们两个是正交的。

这是一个错误吗?Dgeev生产的所有特征向量是否应该是正交的?还有另一个例行程序会始终打印出正交矢量吗?

这是C:

中的测试用例
#include <stdio.h>
void ctofortran(double *matrix,double *fortranMatrix,int numberOfRows,int numberOfColumns)
{
/******************************************************************/
/* This function converts a row-major C matrix into a column-major*/
/* fortran "array".                                               */
/******************************************************************/
int columnNumber,rowNumber;
for (columnNumber = 0;columnNumber<numberOfColumns ;columnNumber++ )
{
    for (rowNumber = 0;rowNumber<numberOfRows ;rowNumber++ )
    {
        fortranMatrix[rowNumber+numberOfRows*columnNumber] = *(matrix + columnNumber+numberOfColumns*rowNumber);
    }
}
}

int main(int argc, char **argv)
{
double matrix[] = {4,   -1, 0,  -1, 0,  0,  0,  0,  
                  -1,   4,  -1, 0,  0,  0,  0,  0,  
                   0,   -1, 4,  0,  -1, 0,  0,  0,  
                  -1,   0,  0,  4,  0,  -1, 0,  0,  
                   0,   0,  -1, 0,  4,  0,  0,  -1,     
                   0,   0,  0,  -1, 0,  4,  -1, 0,  
                   0,   0,  0,  0,  0,  -1, 4,  -1,     
                   0,   0,  0,  0,  -1, 0,  -1, 4 };
int rows = 8, columns = 8;
double *fortranmatrix = malloc(rows*columns*sizeof(double));
ctofortran(matrix,fortranmatrix,rows,columns);

char jobvl ='v';
char jobvr = 'n';
//This symbolizes that the left eigenvectors will be found
double *realEigenValues,*imaginaryEigenValues;
realEigenValues = malloc(rows*sizeof(double));
imaginaryEigenValues = malloc(rows*sizeof(double));
double *leftEigenVectors = malloc(rows*columns*sizeof(double));
int lwork = rows * 4;
double *work = malloc(lwork*sizeof(double));
//This allocates workspace to be used by dgeev. The recomended space is 4 times the dimension
int info = 0;//After dgeev info = 0 if the calculation went correctly   

dgeev_(&jobvl,&jobvr,&rows,fortranmatrix,&rows,realEigenValues,imaginaryEigenValues,leftEigenVectors,&rows,NULL,&rows,work,&lwork,&info);
int index;
for(index = 0;index<rows;index++)
printf("Eigenvalue %d %g + %g * in",index,*(realEigenValues+index), *(imaginaryEigenValues+index));
int v1 = 1, v6 = 6;
double sum = 0;
printf("nv1tv6n");
for(index = 0;index<rows;index++)
{
printf("%gt%gn",*(leftEigenVectors+v1*rows+index),*(leftEigenVectors+v6*rows+index));
sum += *(leftEigenVectors+v1*rows+index) * *(leftEigenVectors+v6*rows+index);
}
printf("n Dot product between v1 and v6 %gn",sum);
return 0;
}

这是输出:

Eigenvalue 0 2 + 0 * i
Eigenvalue 1 2.58579 + 0 * i
Eigenvalue 2 4 + 0 * i
Eigenvalue 3 6 + 0 * i
Eigenvalue 4 5.41421 + 0 * i
Eigenvalue 5 5.41421 + 0 * i
Eigenvalue 6 2.58579 + 0 * i
Eigenvalue 7 4 + 0 * i
v1          v6
-0.499878   0
-0.345657   0.353553
0.0110458   0.5
-0.361278   -0.353553
0.361278    0.353553
-0.0110458  -0.5
0.345657    -0.353553
0.499878    -9.88042e-16
Dot product between v1 and v6 0.0220917

V6对我来说看起来更"正常"。

*这个矩阵是对称的,但并非总是如此。

尝试使用%lf打印,例如:

printf("n Dot product between v1 and v6 %lfn",sum);

类似于此处描述的:scanf/printf double variable c


如果那没有帮助,那么我猜这是一个浮点问题(因为它们的点产品很小)。

相关内容

  • 没有找到相关文章

最新更新