Example #1
0
        /// <summary>
        /// Calculates the eigenvalues and optionally the eigenvectors of a symmetric matrix. Does not check if the matrix is
        /// symmetric.
        /// </summary>
        /// <param name="order">The number of rows/columns of the original symmetric matrix.</param>
        /// <param name="matrix">
        /// The original matrix in full column major format. Will be overwritten.
        /// </param>
        /// <param name="calcEigenvectors">
        /// If true, both eigenvalues and eigenvectors will be computed. Else only eigenvalues will be computed.
        /// </param>
        /// <returns>An object holding the eigensystem of the matrix.</returns>
        public static SymmetricEigensystemFull Create(int order, double[] matrix, bool calcEigenvectors)
        {
            EigensystemJob job         = calcEigenvectors ? EigensystemJob.EigenvaluesAndEigenVectors : EigensystemJob.OnlyEigenvalues;
            int            leadingDimA = order;
            var            eigenvalues = new double[order];  // symmetric matrices have as many eigenvalues as their size

            LapackEigensystems.Dsyev(job, StoredTriangle.Upper, order, matrix, 0, leadingDimA, eigenvalues, 0);

            if (calcEigenvectors)
            {
                // The original matrix is overwritten by the eigenvectors
                var eigenvectors = Matrix.CreateFromArray(matrix, order, order);
                return(new SymmetricEigensystemFull(order, Vector.CreateFromArray(eigenvalues), eigenvectors));
            }
            else
            {
                return(new SymmetricEigensystemFull(order, Vector.CreateFromArray(eigenvalues), null));
            }
        }
Example #2
0
        /// <summary>
        /// Calculates the eigenvalues and optionally the left and right eigenvectors of a square matrix. Does not check if the
        /// matrix is square.
        /// </summary>
        /// <param name="order">The number of rows/columns of the original square matrix.</param>
        /// <param name="matrix">
        /// The original matrix in full column major format. Will be overwritten.
        /// </param>
        /// <param name="calcLeftEigenvectors">
        /// If true, left eigenvectors will be computed, in addition to eigenvalues and possibly right eigenvectors.
        /// Else left eigenvectors will not be computed.
        /// </param>
        /// <param name="calcRightEigenvectors">
        /// If true, right eigenvectors will be computed, in addition to eigenvalues and possibly left eigenvectors.
        /// Else right eigenvectors will not be computed.
        /// </param>
        /// <returns>An object holding the eigensystem of the matrix.</returns>
        public static NonSymmetricEigensystemFull Create(
            int order, double[] matrix, bool calcLeftEigenvectors, bool calcRightEigenvectors)
        {
            // Prepare LAPACK input
            int leadingDimA = order;

            // There as many eigenvalues as the order of the matrix, but some the complex eigenvalues come in conjugate pairs.
            var eigenvaluesReal      = new double[order];
            var eigenvaluesImaginary = new double[order];

            EigensystemJob jobLeft;

            double[] eigenvectorsLeft;
            int      leadingDimEigenvectorsLeft;

            if (calcLeftEigenvectors)
            {
                jobLeft                    = EigensystemJob.EigenvaluesAndEigenVectors;
                eigenvectorsLeft           = new double[order * order];
                leadingDimEigenvectorsLeft = order;
            }
            else
            {
                jobLeft                    = EigensystemJob.OnlyEigenvalues;
                eigenvectorsLeft           = new double[1];
                leadingDimEigenvectorsLeft = 1;
            }

            EigensystemJob jobRight;

            double[] eigenvectorsRight;
            int      leadingDimEigenvectorsRight;

            if (calcRightEigenvectors)
            {
                jobRight                    = EigensystemJob.EigenvaluesAndEigenVectors;
                eigenvectorsRight           = new double[order * order];
                leadingDimEigenvectorsRight = order;
            }
            else
            {
                jobRight                    = EigensystemJob.OnlyEigenvalues;
                eigenvectorsRight           = new double[1];
                leadingDimEigenvectorsRight = 1;
            }

            // Call Lapack
            LapackEigensystems.Dgeev(jobLeft, jobRight, order, matrix, 0, leadingDimA,
                                     eigenvaluesReal, 0, eigenvaluesImaginary, 0,
                                     eigenvectorsLeft, 0, leadingDimEigenvectorsLeft,
                                     eigenvectorsRight, 0, leadingDimEigenvectorsRight);

            // Repack LAPACK output into usable classes
            if (!calcLeftEigenvectors)
            {
                eigenvectorsLeft = null;
            }
            if (!calcRightEigenvectors)
            {
                eigenvectorsRight = null;
            }
            return(new NonSymmetricEigensystemFull(
                       order, eigenvaluesReal, eigenvaluesImaginary, eigenvectorsLeft, eigenvectorsRight));
        }