/// <summary> /// Check the result. /// </summary> /// <param name="preconditioner">Specific preconditioner.</param> /// <param name="matrix">Source matrix.</param> /// <param name="vector">Initial vector.</param> /// <param name="result">Result vector.</param> protected override void CheckResult(IPreconditioner<double> preconditioner, SparseMatrix matrix, Vector<double> vector, Vector<double> result) { Assert.AreEqual(typeof (DiagonalPreconditioner), preconditioner.GetType(), "#01"); // Compute M * result = product // compare vector and product. Should be equal var product = new DenseVector(result.Count); matrix.Multiply(result, product); for (var i = 0; i < product.Count; i++) { Assert.IsTrue(vector[i].AlmostEqualNumbersBetween(product[i], -Epsilon.Magnitude()), "#02-" + i); } }
public void SolvePoissonMatrixAndBackMultiply() { // Create the matrix var matrix = new SparseMatrix(100); // Assemble the matrix. We assume we're solving the Poisson equation // on a rectangular 10 x 10 grid const int GridSize = 10; // The pattern is: // 0 .... 0 -1 0 0 0 0 0 0 0 0 -1 4 -1 0 0 0 0 0 0 0 0 -1 0 0 ... 0 for (var i = 0; i < matrix.RowCount; i++) { // Insert the first set of -1's if (i > (GridSize - 1)) { matrix[i, i - GridSize] = -1; } // Insert the second set of -1's if (i > 0) { matrix[i, i - 1] = -1; } // Insert the centerline values matrix[i, i] = 4; // Insert the first trailing set of -1's if (i < matrix.RowCount - 1) { matrix[i, i + 1] = -1; } // Insert the second trailing set of -1's if (i < matrix.RowCount - GridSize) { matrix[i, i + GridSize] = -1; } } // Create the y vector var y = DenseVector.Create(matrix.RowCount, i => 1); // Create an iteration monitor which will keep track of iterative convergence var monitor = new Iterator<double>(new IIterationStopCriterium<double>[] { new IterationCountStopCriterium<double>(MaximumIterations), new ResidualStopCriterium(ConvergenceBoundary), new DivergenceStopCriterium(), new FailureStopCriterium() }); var solver = new TFQMR(monitor); // Solve equation Ax = y var x = solver.Solve(matrix, y); // Now compare the results Assert.IsNotNull(x, "#02"); Assert.AreEqual(y.Count, x.Count, "#03"); // Back multiply the vector var z = matrix.Multiply(x); // Check that the solution converged Assert.IsTrue(monitor.HasConverged, "#04"); // Now compare the vectors for (var i = 0; i < y.Count; i++) { Assert.IsTrue(Math.Abs(y[i] - z[i]).IsSmaller(ConvergenceBoundary, 1), "#05-" + i); } }