/// <summary> /// Computes the eigenvalues of the matrix. /// </summary> /// <returns>The eigenvalues of the matrix.</returns> /// <seealso cref="Eigendecomposition"/> public Complex[] Eigenvalues() { double[] aStore = MatrixAlgorithms.Copy(store, offset, rowStride, colStride, dimension, dimension); SquareMatrixAlgorithms.IsolateCheapEigenvalues(aStore, null, dimension); SquareMatrixAlgorithms.ReduceToHessenberg(aStore, null, dimension); Complex[] eigenvalues = SquareMatrixAlgorithms.ReduceToRealSchurForm(aStore, null, dimension); return(eigenvalues); }
/// <summary> /// Computes the eigenvalues and eigenvectors of the matrix. /// </summary> /// <returns>A representation of the eigenvalues and eigenvectors of the matrix.</returns> /// <remarks> /// <para>For a generic vector v and matrix M, Mv = u will point in some direction with no particular relationship to v. /// The eigenvectors of a matrix M are vectors z that satisfy Mz = λz, i.e. multiplying an eigenvector by a /// matrix reproduces the same vector, up to a prortionality constant λ called the eigenvalue.</para> /// <para>For v to be an eigenvector of M with eigenvalue λ, (M - λI)z = 0. But for a matrix to /// anihilate any non-zero vector, that matrix must have determinant, so det(M - λI)=0. For a matrix of /// order N, this is an equation for the roots of a polynomial of order N. Since an order-N polynomial always has exactly /// N roots, an order-N matrix always has exactly N eigenvalues.</para> /// <para>Since a polynomial with real coefficients can still have complex roots, a real square matrix can nonetheless /// have complex eigenvalues (and correspondly complex eigenvectors). However, again like the complex roots of a real /// polynomial, such eigenvalues will always occurs in complex-conjugate pairs.</para> /// <para>Although the eigenvalue polynomial ensures that an order-N matrix has N eigenvalues, it can occur that there /// are not N corresponding independent eigenvectors. A matrix with fewer eigenvectors than eigenvalues is called /// defective. Like singularity, defectiveness represents a delecate balance between the elements of a matrix that can /// typically be disturbed by just an infinitesimal perturbation of elements. Because of round-off-error, then, floating-point /// algorithms cannot reliably identify defective matrices. Instead, this method will return a full set of eigenvectors, /// but some eigenvectors, corresponding to very nearly equal eigenvalues, will be very nearly parallel.</para> /// <para>While a generic square matrix can be defective, many subspecies of square matrices are guaranteed not to be. /// This includes Markov matrices, orthogonal matrices, and symmetric matrices.</para> /// <para>Determining the eigenvalues and eigenvectors of a matrix is an O(N<sup>3</sup>) operation. If you need only the /// eigenvalues of a matrix, the <see cref="Eigenvalues"/> method is more efficient.</para> /// </remarks> public ComplexEigensystem Eigensystem() { double[] aStore = MatrixAlgorithms.Copy(store, dimension, dimension); int[] perm = new int[dimension]; for (int i = 0; i < perm.Length; i++) { perm[i] = i; } SquareMatrixAlgorithms.IsolateCheapEigenvalues(aStore, perm, dimension); double[] qStore = MatrixAlgorithms.AllocateStorage(dimension, dimension); for (int i = 0; i < perm.Length; i++) { MatrixAlgorithms.SetEntry(qStore, dimension, dimension, perm[i], i, 1.0); } //double[] qStore = SquareMatrixAlgorithms.CreateUnitMatrix(dimension); // Reduce the original matrix to Hessenberg form SquareMatrixAlgorithms.ReduceToHessenberg(aStore, qStore, dimension); // Reduce the Hessenberg matrix to real Schur form SquareMatrixAlgorithms.ReduceToRealSchurForm(aStore, qStore, dimension); //MatrixAlgorithms.PrintMatrix(aStore, dimension, dimension); //SquareMatrix A = new SquareMatrix(aStore, dimension); SquareMatrix Q = new SquareMatrix(qStore, dimension); Complex[] eigenvalues; Complex[][] eigenvectors; // Extract the eigenvalues and eigenvectors of the Schur form matrix SquareMatrixAlgorithms.SchurEigensystem(aStore, dimension, out eigenvalues, out eigenvectors); // transform eigenvectors of schur form into eigenvectors of original matrix // while we are at it, normalize so largest component has value 1 for (int i = 0; i < dimension; i++) { Complex[] v = new Complex[dimension]; double norm = 0.0; for (int j = 0; j < dimension; j++) { for (int k = 0; k < dimension; k++) { v[j] += Q[j, k] * eigenvectors[i][k]; } norm = Math.Max(norm, Math.Max(Math.Abs(v[j].Re), Math.Abs(v[j].Im))); } for (int j = 0; j < dimension; j++) { v[j] = v[j] / norm; } eigenvectors[i] = v; } ComplexEigensystem eigensystem = new ComplexEigensystem(dimension, eigenvalues, eigenvectors); return(eigensystem); }