+
+def eigenvalues(symmat):
+ """
+ Return the eigenvalues of the given symmetric real matrix.
+
+ On the surface, this appears redundant to the :func:`eigenvalues_re`
+ function. However, if we know in advance that our input is
+ symmetric, a better algorithm can be used.
+
+ Parameters
+ ----------
+
+ symmat : matrix
+ The real symmetric matrix whose eigenvalues you want.
+
+ Returns
+ -------
+
+ list of float
+ A list of the eigenvalues (in no particular order) of ``symmat``.
+
+ Raises
+ ------
+
+ TypeError
+ If the input matrix is not symmetric.
+
+ Examples
+ --------
+
+ >>> A = matrix([[2,1],[1,2]], tc='d')
+ >>> eigenvalues(A)
+ [1.0, 3.0]
+
+ If the input matrix is not symmetric, it may not have real
+ eigenvalues, and we don't know what to do::
+
+ >>> A = matrix([[1,2],[3,4]])
+ >>> eigenvalues(A)
+ Traceback (most recent call last):
+ ...
+ TypeError: input must be a symmetric real matrix
+
+ """
+ if not norm(symmat.trans() - symmat) < options.ABS_TOL:
+ # Ensure that ``symmat`` is symmetric (and thus square).
+ raise TypeError('input must be a symmetric real matrix')
+
+ domain_dim = symmat.size[0]
+ eigs = matrix(0, (domain_dim, 1), tc='d')
+ syevr(symmat, eigs)
+ return list(eigs)
+
+
+def eigenvalues_re(anymat):
+ """
+ Return the real parts of the eigenvalues of the given square matrix.
+
+ Parameters
+ ----------
+
+ anymat : matrix
+ The square matrix whose eigenvalues you want.
+
+ Returns
+ -------
+
+ list of float
+ A list of the real parts (in no particular order) of the
+ eigenvalues of ``anymat``.
+
+ Raises
+ ------
+
+ TypeError
+ If the input matrix is not square.
+
+ Examples
+ --------
+
+ This is symmetric and has two real eigenvalues:
+
+ >>> A = matrix([[2,1],[1,2]], tc='d')
+ >>> sorted(eigenvalues_re(A))
+ [1.0, 3.0]
+
+ But this rotation matrix has eigenvalues `i` and `-i`, both of whose
+ real parts are zero:
+
+ >>> A = matrix([[0,-1],[1,0]])
+ >>> eigenvalues_re(A)
+ [0.0, 0.0]
+
+ If the input matrix is not square, it doesn't have eigenvalues::
+
+ >>> A = matrix([[1,2],[3,4],[5,6]])
+ >>> eigenvalues_re(A)
+ Traceback (most recent call last):
+ ...
+ TypeError: input matrix must be square
+
+ """
+ if not anymat.size[0] == anymat.size[1]:
+ raise TypeError('input matrix must be square')
+
+ domain_dim = anymat.size[0]
+ eigs = matrix(0, (domain_dim, 1), tc='z')
+
+ # Create a copy of ``anymat`` here for two reasons:
+ #
+ # 1. ``gees`` clobbers its input.
+ # 2. We need to ensure that the type code of ``dummy`` is 'd' or 'z'.
+ #
+ dummy = matrix(anymat, anymat.size, tc='d')
+
+ gees(dummy, eigs)
+ return [eig.real for eig in eigs]
+
+