internal void Dgeev(EigensystemJob jobLeft, EigensystemJob jobRight, int orderA,
                            double[] matrixA, int offsetA, int leadingDimA,
                            double[] eigvaluesReal, int offsetEigvaluesReal, double[] eigvaluesImaginary, int offsetEigvaluesImaginary,
                            double[] eigvectorsLeft, int offsetEigvectorsLeft, int leadingDimEigvectorsLeft,
                            double[] eigvectorsRight, int offsetEigvectorsRight, int leadingDimEigvectorsRight)
        {
            int info = DefaultInfo;

            QueryWorkspaceAndExecute((work, offsetWork, lWork) => Provider.Dgeev(jobLeft.Translate(), jobRight.Translate(),
                                                                                 orderA, ref matrixA, offsetA, leadingDimA,
                                                                                 ref eigvaluesReal, offsetEigvaluesReal, ref eigvaluesImaginary, offsetEigvaluesImaginary,
                                                                                 ref eigvectorsLeft, offsetEigvectorsLeft, leadingDimEigvectorsLeft,
                                                                                 ref eigvectorsRight, offsetEigvectorsRight, leadingDimEigvectorsRight,
                                                                                 ref work, offsetWork, lWork, ref info));

            if (info > 0)
            {
                throw new LapackException($"The QR algorithm failed to compute all the eigenvalues, and no eigenvectors have "
                                          + $"been computed. Elements {info+1:N} of the eigenvalues arrays (real and imaginary) contain eigenvalues which"
                                          + "have converged");
            }
            else if (info < 0)
            {
                ProcessNegativeInfo(info);
            }
        }
Beispiel #2
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));
            }
        }
        internal void Dsyev(EigensystemJob job, StoredTriangle triangle, int orderA, double[] matrixA, int offsetA,
                            int leadingDimA, double[] eigenvalues, int offsetEigenvalues)
        {
            int info = DefaultInfo;

            QueryWorkspaceAndExecute((work, offsetWork, lWork) => Provider.Dsyev(
                                         job.Translate(), triangle.Translate(), orderA, ref matrixA, offsetA, leadingDimA, ref eigenvalues,
                                         offsetEigenvalues, ref work, offsetWork, lWork, ref info));

            if (info > 0)
            {
                throw new LapackException($"The algorithm failed to converge. There were {info} elements of an intermediate"
                                          + " tridiagonal form which did not converge to zero");
            }
            else if (info < 0)
            {
                ProcessNegativeInfo(info);
            }
        }
Beispiel #4
0
 internal static string Translate(this EigensystemJob job) => (job == EigensystemJob.OnlyEigenvalues) ? "N" : "V";