i am trying to write code to calculate eign vector and eign values for a symmetric matrix. I understand how to calculate evalues using pen & paper but i am slightly confused with the api!. I am a beginner so i may be wrong in interpreting the api parameters.
int main() {
char jobz='V',uplo='U';
int lda=3,n=3,info=8,lwork=9;
// lapack_int lda=3,n=3,info=8;
int i;
double w[3],work[3];
double a[9] = {
3,2,4,
2,0,2,
4,2,3
};
info=LAPACKE_dsyev(LAPACK_ROW_MAJOR,jobz,uplo, n ,a, lda , w);
//dsyev_( &jobz,&uplo,&n, a, &lda, w,work , &lwork, &info );
if( info > 0 ) {
printf( "The algorithm failed to compute eigenvalues.\n" );
exit( 1 );
}
for(i=0;i<3;i++)
{
printf("%f\n",w[i]);
}
for(i=0;i<9;i++)
{
printf("%f\n",a[i]);
}
exit( 0 );
}
output:
-1.000000
-1.000000
8.000000
0.617945
1.999713
-0.016938
0.010468
0.033876
0.999857
1.381966
0.618034
0.000000
whereas i expected k=-1: [1,-2,0] ,[4,2,-5] and k=8: [2,1,2] somewhere in the output!
am i using api incorrectly or am i reading the output incorrectly?
also please suggest how do i do the same task with fortran api ?
as with fortran i am unable to get proper eign values !.
i.e. eign values i get with fortran:
-0.134742
0.050742
0.523036
eign vectors:
0.617945
1.999713
-0.016938
0.010468
0.033876
0.999857
1.381966
0.618034
0.000000
As suggested by @francis in the comment, the program works if you modify work[3]
to work[9]
. The obtained result is
Eigenvalues: w[0],w[1],w[2] => -1.000000 -1.000000 8.000000
1st eigenvector: a[0], a[1], a[2] => -0.494101 -0.472019 0.730111
2nd eigenvector: a[3], a[4], a[5] => -0.558050 0.816142 0.149979
3rd eigenvector: a[6], a[7], a[8] => 0.666667 0.333333 0.666667
For comparison, let's diagonalize the same matrix with different programs. For example, Python/Numpy gives the result
>>> import numpy as np
>>> a = np.array([[3,2,4], [2,0,2], [4,2,3]], dtype=np.float )
>>> np.linalg.eig( a )
(array([-1., 8., -1.]),
array([[-0.74535599, 0.66666667, -0.09414024],
[ 0.2981424 , 0.33333333, -0.84960833],
[ 0.59628479, 0.66666667, 0.5189444 ]]))
while Julia gives
julia> a = Float64[ 3 2 4 ; 2 0 2 ; 4 2 3 ]
3x3 Array{Float64,2}:
3.0 2.0 4.0
2.0 0.0 2.0
4.0 2.0 3.0
julia> eig( a )
([-0.9999999999999996,-0.9999999999999947,8.0],
3x3 Array{Float64,2}:
0.447214 -0.596285 -0.666667
-0.894427 -0.298142 -0.333333
0.0 0.745356 -0.666667)
In both cases, the first three numbers are eigenvalues {-1,-1,8}
and the following matrix are the corresponding eigenvectors (in their columns). You will see that all the programs give different results for eigenvectors. Because there are two degenerate eigenvalues (-1), any linear combination of the corresponding eigenvectors is also an eigenvector with the same eivenvalue, so the result is not unique. We can confirm that the degenerate eigenvectors obtained from C are related to those of Julia by a 2x2 orthogonal transformation (or a "rotation" by 101.6 degrees).
Interestingly, your expected eigenvectors [-1,2,0]
and [4,2,-5]
correspond exactly to the eigenvectors obtained from Julia (after normalization), but this is probably accidental and one cannot expect such agreement of degenerate eigenvectors.