I'm using LAPACK zgeev routine to get eigenvalues and eigenvectors of a symmetric matrix in C++. Problem is zgeev is being called in a loop but it sorts eigenvalues (and eigenvectors) differently sometimes.

For example, this is the eigenvalues from the first round of loop:

(-1.29007e-5 - 5.207e-6*i) (1.28782e-5 + 7.40505e-6*i)

And this is it's result from the second time:

(1.28782e-5 + 7.40505e-6*i) (-1.29007e-5 - 5.207e-6*i)

I need to plot the evolution of these eigenvalues and vectors as a function of the loop's variable but they keep getting swapped each time and gives me a combination of the plots I need.

How to fix this?

  • 2
    $\begingroup$ When eigenvalues are complex, sorting them becomes "problematic" because there is no notion of A>B for two complex numbers. You might want to multiply the eigen values by their complex conjugate and use that to "sort them" in order to recuperate a similar structure as a function of time. Otherwise, I do not see how you could prevent such swapping since by definition there is no way to "sort" the eigenvalues (like largest to smallest, etc.) $\endgroup$ – BlaB Jul 31 '17 at 14:32
  • $\begingroup$ @BlaisB So is there any way around it? $\endgroup$ – Alireza Jul 31 '17 at 14:33
  • $\begingroup$ see my edited comment. $\endgroup$ – BlaB Jul 31 '17 at 14:34
  • $\begingroup$ @BlaisB What about eigenvectors? They're my main problem and they get all normalized and there is no way of first sorting eigenvalues and then computing the vectors. $\endgroup$ – Alireza Jul 31 '17 at 14:40

You write, that you are computing the eigenvalues of a symmetric matrix. Does the matrix have real entries? In this case all eigenvalues are real, and you can use a symmetric eigenvalue solver, which returns only real entries. Hence, sorting them should not be a problem.

When your matrix has complex entries, you have to track the eigenvalues. I am assuming that your matrices change only slightly from one iteration of your loop to the next, meaning that the eigenvalues also change only slightly. Hence, you can find the eigenvalue of the next iteration that corresponds to the eigenvalue of the current iteration, by looking for the eigenvalue of the next iteration that is closest to the eigenvalue of the current iteration.

In general, sorting complex eigenvalues does not solve your problem. Consider the matrix \begin{equation} A(t) = \begin{bmatrix} e^{\mathrm{i} t} & 0 \\ 0 & e^{\mathrm{i} (t + \pi)} \end{bmatrix} \end{equation} for $t = [0, 2\pi)$. The matrix has two eigenvalues, both lie on the circle of radius one. The two eigenvalues lie on opposit sides of the circle and with increasing $t$ they rotate around zero. When $t$ is large enough the first eigenvalue reaches the point where the second eigenvalue has been, and vice versa. Hence, any sorting technique will (at latest) at that point, switch the roles of the two eigenvalues, even though the first eigenvalue moved slowly to the position of the second, meaning it has not changed its role.

If your eigenvalues vary only a little, you might get away with sorting the eigenvalues first by real part and then by imaginary part or by their absolute value. In general, however, this does not work.

  • $\begingroup$ My matrix has complex entries and it varies slightly per iteration. I could sort the eigenvalues with the method you said and managed to sort eigenvectors by keeping previous iteration's eigenvectors and comparing them. It worked. Thanks! $\endgroup$ – Alireza Aug 1 '17 at 15:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.