Discussion: History & Possible Deprecation/Removal of numpy.linalg.{eig(), eigvals()}?

Hi, I am catching up with an assigned task that I slipped. I am wondering a few things about the numpy.linalg.eig() API (eigvals() is also included in this discussion, but for simplicity let's focus on eig()). AFAIU the purpose of eig() is for handling general eigen-systems which have left and right eigenvectors (that could differ beyond transpose/conjugate). For this, I have two questions: 1. What's the history of NumPy adding this eig() routine? My guess would be NumPy added it because Matlab had it, but I couldn't tell from a quick commit search. 2. Would it be possible to deprecate/remove this API? From past discussions with users and developers, I found: - numpy.linalg.eig() only returns the right eigenvectors, so it's not very useful: * When the left eigenvectors are not needed --- which is the majority of the use cases --- eigh() is the right routine, but most users (especially those transitioning from Matlab) don't know it's there * When the left eigenvectors are needed, users have to use scipy.linalg.eig() anyway - A general support for eig() could be challenging (numerical issues), and doing SVDs instead is usually the better way out (in terms of both numerical stability and mathematical sense). Thanks, Leo

On Tue, May 3, 2022 at 6:41 PM Leo Fang <leo80042@gmail.com> wrote:
Hi, I am catching up with an assigned task that I slipped. I am wondering a few things about the numpy.linalg.eig() API (eigvals() is also included in this discussion, but for simplicity let's focus on eig()). AFAIU the purpose of eig() is for handling general eigen-systems which have left and right eigenvectors (that could differ beyond transpose/conjugate). For this, I have two questions:
1. What's the history of NumPy adding this eig() routine? My guess would be NumPy added it because Matlab had it, but I couldn't tell from a quick commit search. 2. Would it be possible to deprecate/remove this API? From past discussions with users and developers, I found: - numpy.linalg.eig() only returns the right eigenvectors, so it's not very useful: * When the left eigenvectors are not needed --- which is the majority of the use cases --- eigh() is the right routine, but most users (especially those transitioning from Matlab) don't know it's there
eigh() is for Hermitian matrices, the svd won't return eigenvectors in the general case, especially when they are not orthogonal or form a complete basis. The left eigenvectors can be obtained by passing the transpose to eig(). In my experience, the main problem with eig() is accuracy, and sometimes (IIRC) it doesn't find all the eigenvectors, so it should not be used when the matrix is Hermitian.
* When the left eigenvectors are needed, users have to use scipy.linalg.eig() anyway - A general support for eig() could be challenging (numerical issues), and doing SVDs instead is usually the better way out (in terms of both numerical stability and mathematical sense).
Chuck

On Tue, May 3, 2022 at 8:40 PM Leo Fang <leo80042@gmail.com> wrote:
Hi, I am catching up with an assigned task that I slipped. I am wondering a few things about the numpy.linalg.eig() API (eigvals() is also included in this discussion, but for simplicity let's focus on eig()). AFAIU the purpose of eig() is for handling general eigen-systems which have left and right eigenvectors (that could differ beyond transpose/conjugate).
For this, I have two questions:
1. What's the history of NumPy adding this eig() routine? My guess would be NumPy added it because Matlab had it, but I couldn't tell from a quick commit search.
It essentially dates back to Numeric, though the name was a bit different. But the core feature of only computing right-eigenvectors was there. scipy.linalg.eig() came along and expose both left- and right-eigenvalues (with close to the present signature, I think). Then numpy took over from Numeric and adopted the scipy.linalg names for the routines, but cut out a number of the features that made some of the interfaces complicated. Since Numeric only did right-eigenvalues (what most people want, even in the general-matrix case), so did numpy.
2. Would it be possible to deprecate/remove this API? From past discussions with users and developers, I found: - numpy.linalg.eig() only returns the right eigenvectors, so it's not very useful: * When the left eigenvectors are not needed --- which is the majority of the use cases --- eigh() is the right routine, but most users (especially those transitioning from Matlab) don't know it's there
eigh() is only for symmetric/Hermitian matrices.
* When the left eigenvectors are needed, users have to use scipy.linalg.eig() anyway
It seems to me that you are assuming that in the non-Hermitian case, the right-eigenvectors are useless without the left-eigenvectors. It isn't obvious to me why that would be the case. It is true that the left- and right-eigenvectors differ from each other, but it's not clear to me that in every application with a general matrix I need to compute both. - A general support for eig() could be challenging (numerical issues), and
doing SVDs instead is usually the better way out (in terms of both numerical stability and mathematical sense).
Computing the left-eigenvectors is no real problem. The underlying _GEEV LAPACK routine can do it if asked. It's the same routine under scipy.linalg.eig(). -- Robert Kern
participants (3)
-
Charles R Harris
-
Leo Fang
-
Robert Kern