Exemplo n.º 1
0
        /// <summary>
        /// Check residuals of generalized eigenvalue problem.
        /// </summary>
        /// <param name="A">Symmetric matrix.</param>
        /// <param name="B">Symmetric matrix.</param>
        /// <param name="k">The number of converged eigenvalues.</param>
        /// <param name="v">The eigenvalues array.</param>
        /// <param name="X">The eigenvectors matrix.</param>
        /// <param name="print">If true, print residuals.</param>
        /// <returns>True, if all residuals are below threshold.</returns>
        public static bool CheckResiduals(SparseMatrix A, SparseMatrix B, int k, Complex[] v, Matrix <Complex> X, bool print)
        {
            int N = A.RowCount;

            // If more eigenvalues converged than were requested (real, non-symmetric case only).
            k = Math.Min(k, X.ColumnCount);

            if (print)
            {
                Console.WriteLine();
                Console.WriteLine("       Lambda         Residual");
            }

            var x = new Complex[N];
            var y = new Complex[N];

            bool ok = true;

            for (int i = 0; i < k; i++)
            {
                var lambda = v[i];

                X.Column(i, x);

                CVector.Copy(x, y);

                if (B != null)
                {
                    // y = B*x
                    B.Multiply(x, y);
                }

                // y = A*x - lambda*B*x
                A.Multiply(1.0, x, -lambda, y);

                double r = CVector.Norm(y) / Complex.Abs(lambda);

                if (r > ERROR_THRESHOLD)
                {
                    ok = false;
                }

                if (print)
                {
                    Console.WriteLine("{0,3}:   {1,10:0.00000000}   {2,10:0.00e+00}", i, lambda, r);
                }
            }

            return(ok);
        }
Exemplo n.º 2
0
            /// <summary>
            /// Prints eigenvalues and eigenvectors of nonsymmetric generalized eigen-problems.
            /// </summary>
            public static void General(SparseMatrix A, SparseMatrix B, SpectraResult result, bool shift, bool cshift = false)
            {
                if (!EnsureSuccess(result))
                {
                    return;
                }

                int n     = A.RowCount;
                int nconv = result.ConvergedEigenValues;

                Console.WriteLine();
                Console.WriteLine("Testing ARPACK++ class ARluNonSymGenEig");
                Console.WriteLine("Real nonsymmetric generalized eigenvalue problem: A*x - lambda*B*x");

                Console.WriteLine(!shift ? "Regular mode" :
                                  (cshift ? "Shift and invert mode (using the imaginary part of OP)" : "Shift and invert mode (using the real part of OP)"));
                Console.WriteLine();

                Console.WriteLine("Dimension of the system            : " + n);
                Console.WriteLine("Number of 'requested' eigenvalues  : " + result.Count);
                Console.WriteLine("Number of 'converged' eigenvalues  : " + nconv);
                Console.WriteLine("Number of Arnoldi vectors generated: " + result.ArnoldiCount);
                Console.WriteLine("Number of iterations taken         : " + result.IterationsTaken);
                Console.WriteLine();

                var evals = result.EigenValues;
                var evecs = result.EigenVectors;

                // Printing eigenvalues.

                Console.WriteLine("Eigenvalues:");

                for (int i = 0; i < nconv; i++)
                {
                    Console.WriteLine("  lambda[" + (i + 1) + "]: " + evals[i]);
                }

                Console.WriteLine();

                if (evecs != null)
                {
                    // Printing the residual norm || A*x - lambda*B*x ||
                    // for the nconv accurately computed eigenvectors.

                    var x = new Complex[n];
                    var y = new Complex[n];
                    var r = new double[nconv]; // residuals

                    for (int i = 0; i < nconv; i++)
                    {
                        var lambda = evals[i];

                        evecs.Column(i, x);

                        CVector.Copy(x, y);

                        // y = B*x
                        B.Multiply(x, y);

                        // y = A*x - lambda*B*x
                        A.Multiply(1.0, x, -lambda, y);

                        r[i] = CVector.Norm(y) / Complex.Abs(lambda);
                    }

                    for (int i = 0; i < nconv; i++)
                    {
                        Console.WriteLine("||A*x(" + i + ") - lambda(" + i + ")*B*x(" + i + ")||: " + r[i]);
                    }

                    Console.WriteLine();
                }
            }