コード例 #1
0
        public static void PreconditioningPosDefSparse()
        {
            Console.WriteLine("Assessing correctness and efficiency of preconditioned MINRES:\n");
            var A         = Matrix.CreateFromArray(SparsePosDef10by10.Matrix);
            var b         = Vector.CreateFromArray(SparsePosDef10by10.Rhs);
            var xExpected = Vector.CreateFromArray(SparsePosDef10by10.Lhs);
            var M         = new JacobiPreconditioner(A.GetDiagonalAsArray());
            var minres    = new MinRes(A.NumRows, 1e-10, 0, true, false);

            // Without preconditioning
            Console.WriteLine("Sparse pos-def system WITHOUT preconditioning:");
            (IVector xSimple, MinresStatistics statsSimple) = minres.Solve(A, b);
            Console.Write(statsSimple);
            if (xSimple != null)
            {
                CheckSolution(xExpected, xSimple);
            }
            Console.WriteLine();

            // With preconditioning
            Console.WriteLine("Sparse pos-def system WITH preconditioning:");
            (IVector xPrec, MinresStatistics statsPrec) = minres.Solve(A, b, M);
            Console.Write(statsPrec);
            if (xPrec != null)
            {
                CheckSolution(xExpected, xPrec);
            }
            Console.WriteLine();
        }
コード例 #2
0
        private static void TestPosDefSparseSystem()
        {
            var A         = Matrix.CreateFromArray(SparsePosDef10by10.Matrix);
            var b         = Vector.CreateFromArray(SparsePosDef10by10.Rhs);
            var xExpected = Vector.CreateFromArray(SparsePosDef10by10.Lhs);

            var builder = new ReorthogonalizedPcg.Builder();

            builder.ResidualTolerance     = 1E-7;
            builder.MaxIterationsProvider = new PercentageMaxIterationsProvider(1.0);
            var    pcg                = builder.Build();
            var    M                  = new JacobiPreconditioner(A.GetDiagonalAsArray());
            Vector xComputed          = Vector.CreateZero(A.NumRows);
            IterativeStatistics stats = pcg.Solve(A, M, b, xComputed, true, () => Vector.CreateZero(b.Length));

            comparer.AssertEqual(xExpected, xComputed);
        }
コード例 #3
0
        private static void TestPosDefSparseSystem(LinearAlgebraProviderChoice providers)
        {
            TestSettings.RunMultiproviderTest(providers, delegate()
            {
                var A         = Matrix.CreateFromArray(SparsePosDef10by10.Matrix);
                var b         = Vector.CreateFromArray(SparsePosDef10by10.Rhs);
                var xExpected = Vector.CreateFromArray(SparsePosDef10by10.Lhs);

                var builder = new PcgAlgorithm.Builder();
                builder.ResidualTolerance     = 1E-7;
                builder.MaxIterationsProvider = new PercentageMaxIterationsProvider(1.0);
                var pcg                   = builder.Build();
                var M                     = new JacobiPreconditioner(A.GetDiagonalAsArray());
                Vector xComputed          = Vector.CreateZero(A.NumRows);
                IterativeStatistics stats = pcg.Solve(A, M, b, xComputed, true, () => Vector.CreateZero(b.Length));
                comparer.AssertEqual(xExpected, xComputed);
            });
        }
コード例 #4
0
        private static void TestNearbyProblems(double noiseWidth, int maxIterations, int numRhsVectors)
        {
            int order   = SymmPosDef10by10.Order;
            var A       = Matrix.CreateFromArray(SymmPosDef10by10.Matrix);
            var builder = new ReorthogonalizedPcg.Builder();

            builder.ResidualTolerance     = 1E-6;
            builder.MaxIterationsProvider = new PercentageMaxIterationsProvider(1.0);
            builder.Convergence           = new RhsNormalizedConvergence();
            var pcg = builder.Build();
            var M   = new JacobiPreconditioner(A.GetDiagonalAsArray());

            // Initial run
            Vector x0                  = Vector.CreateWithValue(order, 1);
            Vector x0Expected          = x0.Copy();
            Vector b0                  = A * x0Expected;
            Vector x0Computed          = Vector.CreateZero(A.NumRows);
            IterativeStatistics stats0 = pcg.Solve(A, M, b0, x0Computed, true, () => Vector.CreateZero(order));

            Debug.WriteLine($"Initial run: iterations = {stats0.NumIterationsRequired}");
            comparer.AssertEqual(x0Expected, x0Computed);

            // Subsequent runs
            int seed = 345;

            for (int i = 0; i < numRhsVectors; ++i)
            {
                Vector dx        = Vector.CreateFromArray(RandomMatrices.CreateRandomVector(order, seed));
                Vector xExpected = x0 + noiseWidth * dx;
                Vector b         = A * xExpected;

                pcg.Clear();                 //TODO: preferably do not call this.
                //pcg.ReorthoCache.Clear();

                Vector xComputed          = Vector.CreateZero(A.NumRows);
                IterativeStatistics stats = pcg.Solve(A, M, b, xComputed, true, () => Vector.CreateZero(b.Length));
                Debug.WriteLine($"Subsequent run: iterations = {stats.NumIterationsRequired}");
                comparer.AssertEqual(xExpected, xComputed);
                Assert.InRange(stats.NumIterationsRequired, 1, maxIterations);
            }
        }
コード例 #5
0
        /// <summary>
        /// </summary>
        /// <param name="evenOrder">The number of rows/columns. It must be even.</param>
        internal static (Matrix A, Vector b, Vector x, IPreconditioner M) BuildIndefiniteSystem(int evenOrder)
        {
            // Example taken from Matlab docs. Creates a diagonal matrix with half its entries being negative.
            int n = evenOrder;
            var A = Matrix.CreateZero(n, n);

            for (int i = 0; i < n / 2; ++i)
            {
                A[i, i] = n / 2 - i;
            }
            for (int i = 0; i < n / 2; ++i)
            {
                A[n / 2 + i, n / 2 + i] = -1 - i;
            }

            // x = [1, 1, ... 1]
            var x = Vector.CreateWithValue(n, 1.0);

            // b[i] = A[i, i]
            var b = Vector.CreateZero(n);

            for (int i = 0; i < n; ++i)
            {
                b[i] = A[i, i];
            }

            // The usual Jacobi preconditioner worsens convergence. Modifications are needed.
            var positiveDiagonal = new double[n];

            for (int i = 0; i < n; ++i)
            {
                positiveDiagonal[i] = Math.Abs(A[i, i]);
            }
            var M = new JacobiPreconditioner(positiveDiagonal);

            return(A, b, x, M);
        }