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