6

I have N eigenvalues in column vector form. Thus there are N eigenvectors corresponding to these eigenvalues, forming an eigenvector matrix.

Now, the problem I am working on requires me to sort the eigenvalues column vector in descending order. How do I sort the eigenvectors matrix in the same order as their eigenvalues in order to preserve correspondence?

Sjoerd C. de Vries
  • 16,122
  • 3
  • 42
  • 94
Bonk
  • 1,859
  • 9
  • 28
  • 46
  • Note that when machine numbers are used in Mathematica, `Eigensystem` already returns the eigenvalues/vectors sorted in descending order. – Szabolcs Jul 05 '11 at 21:53
  • Eigensystem will return eigenvalues and eigenvectors with the latter in order that corresponds to the former. Daniel Lichtblau – Daniel Lichtblau Jul 05 '11 at 23:31
  • 5
    I do want to point out one thing, for degenerate eigenvectors (i.e. same eigenvalue) of a numerical matrix, `Eigenvectors` and `Eigensystem` return vectors that are linearly independent, not orthogonal. This bit me more than once. But, you can use `Orthogonalize` on the degenerate set to give you an orthogonal set. – rcollyer Jul 06 '11 at 01:22
  • @rcollyer, just checked and you are right! I didn't know this ... – Szabolcs Jul 06 '11 at 05:50
  • @rcollyer, I believe you don't need to separate the degenerate set before orthogonalizing, a simple `Orthogonolize@Eigenvalues[m]` should do it. At least for as long as it uses Gram-Schmidt. Can someone confirm? – Szabolcs Jul 06 '11 at 06:03
  • 2
    @Szabolcs, yeah, nothing like relying on their orthogonality when they're not. And, you're right, you can use `Orthogonalize` on the whole set directly as it won't affect the orthogonality of the different subspaces. – rcollyer Jul 06 '11 at 12:46

4 Answers4

13

For example,

m = RandomReal[{0, 1}, {5, 5}];
{evals, evecs} = Eigensystem[m];
SortBy[Transpose[{evals, evecs}], First]

or if you want them in the same form, replace the last line by

Transpose@SortBy[Transpose[{evals, evecs}], First]

EDIT: while I used {evals,evecs}=Eigensystem[m], that's not necessary. I could just have used s=Eigensystem[m] and then used s wherever I currently have {evals,evecs}.

acl
  • 6,490
  • 1
  • 27
  • 33
9

While @acl and @yoda's ways of sorting (i.e. pairing the list elements then sorting together) is easy and commonly used, I'd like to show another generic method to easily sort an arbitrary number of lists based on one particular list (list1):

oo = Ordering[list1]; (* this finds the sorting order of list1 *)
list1[[oo]]
list2[[oo]]
list3[[oo]]  (* these order some other lists in the same way *)
Szabolcs
  • 24,728
  • 9
  • 85
  • 174
1

You can use the Sort function to sort the eigensystem according to the eigenvalues.

mat = (#*Transpose@#) &@RandomReal[NormalDistribution[], {4, 4}];
eigsys = Sort@Transpose@Eigensystem[mat];

Sort's default behavior is to sort by the first column.

abcd
  • 41,765
  • 7
  • 81
  • 98
  • I'm not sure; it's something I observed and after playing with a few test cases, I was satisfied and I've always used it for sorting by first column... I tend to do that till something goes horribly wrong which is when I go read the docs :) – abcd Jul 05 '11 at 23:48
  • I was under the impression that in sorting lists, it implements a lexical sort, i.e. `{1,0,3}` is before `{1,0,4}`. So, on a cursory examination, it would appear to be sorting by the first column, it is actually sorting by them all. – rcollyer Jul 06 '11 at 01:41
  • @rcollyer, it indeed does a lexicographic sort – Szabolcs Jul 06 '11 at 05:59
0

Using Mathematica:

matrix = RandomReal[{0, 1}, {4, 4}];
{evals, evecs} = Chop[Transpose[Sort[Transpose[Eigensystem[matrix]]]]];

OutPut:

evals
{-0.296769, 0.187003, 0.52714, 2.00376}

evecs 
{{-0.412673,0.844056,-0.0718614,-0.334823}, 
{-0.370973,  -0.472126, 0.76248, 0.241042},
{-0.253163,  0.1719,  -0.786782, 0.536034},
{0.557741,  0.381364,  0.65039, 0.347102}}
NAK
  • 341
  • 2
  • 10