示例#1
0
        /// <summary>
        /// Computes the eigenvalues and eigenvectors of the matrix.
        /// </summary>
        /// <returns>A decomposition that makes the eigenvalues and eigenvectors manifest.</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 = &#x3BB;z, i.e. multiplying an eigenvector by a
        /// matrix reproduces the same vector, up to a proportionality constant &#x3BB; called the eigenvalue.</para>
        /// <para>For v to be an eigenvector of M with eigenvalue &#x3BB;, (M - &#x3BB;I)z = 0. But for a matrix to
        /// annihilate any non-zero vector, that matrix's determinant must vanish, so det(M - &#x3BB;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 corresponding 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 delicate 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>
        /// <seealso href="https://en.wikipedia.org/wiki/Eigendecomposition_of_a_matrix"/>
        public ComplexEigendecomposition Eigendecomposition()
        {
            //double[] aStore = MatrixAlgorithms.Copy(store, dimension, dimension);
            double[] aStore = MatrixAlgorithms.Copy(store, offset, rowStride, colStride, 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);

            //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;
            }

            ComplexEigendecomposition eigensystem = new ComplexEigendecomposition(dimension, eigenvalues, eigenvectors);

            return(eigensystem);
        }
示例#2
0
 internal ComplexEigenpairCollection(ComplexEigendecomposition system)
 {
     Debug.Assert(system != null);
     this.system = system;
 }