Adapted from code by bmachiel, which in turn was based on matlab eigenshuffle.
Consistently sort eigenvalues and eigenvectors of a series of matrices based on initial ordering from low to high.
Includes eigenshuffle_eig
and eigenshuffle_eigh
for non-hermitian and hermitian matrices, respectively.
Install from pypi with:
pip install eigenshuffle
or clone repo and install with pip
or directly install from GitHub with:
pip install git+https://github.com/ograsdijk/CeNTREX-trajectories
import numpy as np
import numpy.typing as npt
import matplotlib.pyplot as plt
from eigenshuffle import eigenshuffle_eig
def eigenvalue_function(
t: float,
) -> npt.NDArray[np.float_]:
return np.array(
[
[1, 2 * t + 1, t**2, t**3],
[2 * t + 1, 2 - t, t**2, 1 - t**3],
[t**2, t**2, 3 - 2 * t, t**2],
[t**3, 1 - t**3, t**2, 4 - 3 * t],
]
)
tseq = np.arange(-1, 1.1, 0.1)
Aseq = np.array([eigenvalue_function(ti) for ti in tseq])
e, v = np.linalg.eig(Aseq)
es, vs = eigenshuffle_eig(Aseq)
# sorting original eig result from low to high
v[np.argsort(e)]
e = np.sort(e)
fig, ax = plt.subplots()
lines = ax.plot(tseq, e)
for i in range(ei.shape[-1]):
ax.plot(tseq, ei.real[:, i], "--", color=lines[i].get_color())
# for generating the legend
line1 = plt.Line2D([0, 1], [0, 1], linestyle="-", color="black")
line2 = plt.Line2D([0, 1], [0, 1], linestyle="--", color="black")
ax.set_xlabel("t")
ax.set_ylabel("eigenvalue")
ax.legend([line1, line2], ["sorted", "eigenshuffle"])
ax.grid()
Here the eigenvalues are consistently ordered, and are not switching positions after a level crossing (around t=0.3) when using eigenshuffle
.