Karol Borkowski - 10 months ago 58

C++ Question

I have a diagonal matrix with eigenvalues e.g. 1, 2 and 3. I disturb its values with some noise but it is small enough to change the sequence. When I obtain the eigenvalues of this matrix they are 1,2,3 in 50% cases and 1,3,2 in another 50%.

When I do the same thing without the noise the order is always 1,2,3.

I obtain the eigenvalues using:

`matrix.eigenvalues().real();`

or using:

`Eigen::EigenSolver<Eigen::Matrix3d> es(matrix, false);`

es.eigenvalues().real();

The result is the same. Any ideas how to fix it?

Answer Source

There is no "natural" order for eigenvalues of a non-selfadjoint matrix, since they are usually complex (even for real-valued matrices). One could sort them lexicographically (first by real then by complex) or by magnitude, but Eigen does neither. If you have a look at the documentation, you'll find:

The eigenvalues are repeated according to their algebraic multiplicity, so there are as many eigenvalues as rows in the matrix.

The eigenvalues are not sorted in any particular order.

If your matrix happens to be self-adjoint you should use the `SelfAdjointEigenSolver`

, of course (which does sort the eigenvalues, since they are all real and therefore sortable). Otherwise, you need to sort the eigenvalues manually by whatever criterion you prefer.

N.B.: The result of `matrix.eigenvalues()`

and `es.eigenvalues()`

should indeed be the same, since exactly the same algorithm is applied. Essentially the first variant is just a short-hand, if you are only interested in the eigenvalues.