# How to collect eigenvectors corresponding to only real eigenvalues?

I have a set of eigenvalues which consists of real and imaginary values. Among these, I have one purely positive real eigenvalue and one purely negative real eigenvalue. How do I collect these two eigenvalues' corresponding eigenvectors?

Thanks

• See mathematica.stackexchange.com/questions/182612/…, but you just need Thread[Im[vals] == 0] instead of Positive[vals]. Commented Dec 26, 2018 at 15:12
• Maybe {eigenvalues, eigenvectors} = Eigensystem[A]; Pick[eigenvectors, DeveloperRealQ/@eigenvalues]? Commented Dec 26, 2018 at 16:28

eigenvalues = Eigenvalues[A];
eigenvaluesReal = Select[eigenvalues, Im[#]==0&];


where A is your matrix (or equivalently, eigenvalues is your list)

Edit: OP wanted eigenvectors, not eigenvalues.

eigenvectors = Eigenvectors[A]
eigenvectorsReal = Pick[eigenvectors, Map[Im[#] == 0 &, eigenvalues]]

• The OP wanted the eigenvectors not eigenvalues Commented Dec 26, 2018 at 23:02
• @b3m2a1 Thanks for the remark, fixed it.
– Mat
Commented Dec 27, 2018 at 15:46

Try

A = RandomReal[{-1, 1}, {4, 4}]
Select[ Transpose[Eigensystem[A]], Im[#[[1]]] == 0 &] // Chop


which gives you pairs {eigenvalue, eigenvector} for real eigenvalues!

When you want to pick elements from one list according to criteria in another list, the function we use is Pick. When designing the spec, then, we want to be efficient and use vectorized operations. Here we just want to Pick the eigenvectors with Im[λ]==0. so we do:

A = BlockRandom[SeedRandom[0]; RandomReal[{-1, 1}, {1000, 1000}]];
{eigenvalues, eigenvectors} = Eigensystem[A];

Pick[eigenvectors, Unitize@Im@eigenvalues, 0] // Length

28


(I use Unitize here simply because Pick performs better with it and 0)

On the other hand, say you wanted those with non-zero imaginary part, here we can't just use 0., but that's okay because we can use Unitize to turn all non-zero components into 1:

Pick[eigenvectors, Unitize[Im@eigenvalues], 1] // Length

972


Or you can pull those within a region of zero, say 1 (the UnitStep windowing trick is very useful and can be used in many, many places):

Pick[
eigenvectors,
UnitStep[1 - #] - UnitStep[1 + #] &@Im@eigenvalues,
0
] // Length

76
`