Search code examples
c++numerical-methodsgsl

GSL complex matrix - eigenvalues/eigenvectors


I've written a program which is computing the eigenvalues and eigenvectors of a hermitian matrix.

Does anyone know how this is done in GSL properly? Here is what I already have.

//hermitian matrix
0 1 0 -i
1 0 -i 0
0 i 0 1
i 0 1 0


#include <iostream>
#include <stdio.h>
#include <cmath>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_blas.h>
#include <gsl/gsl_linalg.h>
#include <gsl/gsl_complex.h>
#include <gsl/gsl_complex_math.h>
#include <gsl/gsl_eigen.h>
using namespace std;
const int N = 4;

int main(){

    gsl_eigen_hermv_workspace *workN = gsl_eigen_hermv_alloc(N);
    gsl_matrix_complex *A = gsl_matrix_complex_alloc(N, N);
    gsl_complex i = gsl_complex_rect(0.0,1.0);
    gsl_complex ii = gsl_complex_rect(0.0,-1.0);
    gsl_vector *eval = gsl_vector_alloc(N);
    gsl_matrix_complex *evec = gsl_matrix_complex_alloc(N, N);


    double mTab[] = { 
    0, 1, 0, 5, 
    1, 0, 5, 0, 
    0, 5, 0, 1,
    5, 0, 1, 0
    };

    gsl_matrix_complex_view tmpM = gsl_matrix_complex_view_array(mTab, N, N);

   gsl_matrix_complex_memcpy(A, &tmpM.matrix);
   gsl_matrix_complex_set(A, 0, 3, ii);
   gsl_matrix_complex_set(A, 1, 2, ii);
   gsl_matrix_complex_set(A, 2, 1, i);
   gsl_matrix_complex_set(A, 3, 0, i);
   gsl_eigen_hermv(A, eval, evec, workN);

   for(int i=0; i < N; i++){
       for(int j=0; j < N; j++){
           gsl_complex z = gsl_matrix_complex_get(A, i, j);
           cout << GSL_REAL(z) << "+ i" << GSL_IMAG(z) << " ";
       }
       cout << "\n";
   }

   cout << "\n";
   for(int i=0; i < N; i++){
       cout << gsl_vector_get(eval, i) << " ";
   }

   return 0;
}   

This is how I output the eigenvectors

  for(int i=0; i < N; i++){
       for(int j=0; j < N; j++){
           gsl_complex z = gsl_matrix_complex_get(A, i, j);
           cout << GSL_REAL(z) << "+ i" << GSL_IMAG(z) << " ";
       }
       cout << "\n";
   }

Finally, here's the way I declared the matrix in question.

  double mTab[] = { 
    0, 1, 0, 5, 
    1, 0, 5, 0, 
    0, 5, 0, 1,
    5, 0, 1, 0
    };

Later, I added the complex numbers.

I managed to print the eigenvectors but I don't know how to do that for the eigenvalues. Any help with that is appreciated?.


Solution

  • You have an error in using the double mTab for gsl_matrix_complex_view_array. This assumes an array of complex numbers represented as real parts followed by imaginary parts in one large array of double values. You can change your definition to:

    double mTab[] = {
    0, 0, 1, 0, 0, 0, 5, 0,
    1, 0, 0, 0, 5, 0, 0, 0,
    0, 0, 5, 0, 0, 0, 1, 0,
    5, 0, 0, 0, 1, 0, 0, 0,
    };
    

    (Which also means you don't need to use a "dummy" variable of 5 just to rewrite it by ±i later.) Then the code for printing eigenvalues works well.

    Also you have a typo in the eigenvector printing loop: it should be

    gsl_complex z = gsl_matrix_complex_get(evec, i, j);
    

    not

    gsl_complex z = gsl_matrix_complex_get(A, i, j);