/// <summary> /// The main method that uses the Ilutp preconditioner. /// </summary> public void UseSolver() { // Create a sparse matrix. For now the size will be 10 x 10 elements Matrix matrix = CreateMatrix(10); // Create the right hand side vector. The size is the same as the matrix // and all values will be 2.0. Vector rightHandSideVector = new DenseVector(10, 2.0); // Create the Ilutp preconditioner Ilutp preconditioner = new Ilutp(); // Set the drop tolerance. All entries with absolute values smaller than this value will be // removed from the preconditioner matrices. preconditioner.DropTolerance = 1e-5; // Set the relative fill level. This indicates how much additional fill we allow. In this case // about 200% preconditioner.FillLevel = 200; // Set the pivot tolerance. This indicates when pivoting is used. In this case we pivot if // the largest off-diagonal entry is twice as big as the diagonal entry. preconditioner.PivotTolerance = 0.5; // Create the actual preconditioner preconditioner.Initialize(matrix); // Now that all is set we can solve the matrix equation. Vector solutionVector = preconditioner.Approximate(rightHandSideVector); // Another way to get the values is by using the overloaded solve method // In this case the solution vector needs to be of the correct size. preconditioner.Approximate(rightHandSideVector, solutionVector); }
/// <summary> /// Create preconditioner (internal) /// </summary> /// <returns>Ilutp instance.</returns> private Ilutp InternalCreatePreconditioner() { var result = new Ilutp { DropTolerance = _dropTolerance, FillLevel = _fillLevel, PivotTolerance = _pivotTolerance }; return result; }
public void CompareWithOriginalDenseMatrixWithoutPivoting() { var sparseMatrix = new SparseMatrix(3); sparseMatrix[0, 0] = -1; sparseMatrix[0, 1] = 5; sparseMatrix[0, 2] = 6; sparseMatrix[1, 0] = 3; sparseMatrix[1, 1] = -6; sparseMatrix[1, 2] = 1; sparseMatrix[2, 0] = 6; sparseMatrix[2, 1] = 8; sparseMatrix[2, 2] = 9; var ilu = new Ilutp { PivotTolerance = 0.0, DropTolerance = 0, FillLevel = 10 }; ilu.Initialize(sparseMatrix); var l = GetLowerTriangle(ilu); // Assert l is lower triagonal for (var i = 0; i < l.RowCount; i++) { for (var j = i + 1; j < l.RowCount; j++) { Assert.IsTrue(0.0.AlmostEqual(l[i, j].Magnitude, -Epsilon.Magnitude()), "#01-" + i + "-" + j); } } var u = GetUpperTriangle(ilu); // Assert u is upper triagonal for (var i = 0; i < u.RowCount; i++) { for (var j = 0; j < i; j++) { Assert.IsTrue(0.0.AlmostEqual(u[i, j].Magnitude, -Epsilon.Magnitude()), "#02-" + i + "-" + j); } } var original = l.Multiply(u); for (var i = 0; i < sparseMatrix.RowCount; i++) { for (var j = 0; j < sparseMatrix.ColumnCount; j++) { Assert.IsTrue(sparseMatrix[i, j].Real.AlmostEqual(original[i, j].Real, -Epsilon.Magnitude()), "#03-" + i + "-" + j); Assert.IsTrue(sparseMatrix[i, j].Imaginary.AlmostEqual(original[i, j].Imaginary, -Epsilon.Magnitude()), "#04-" + i + "-" + j); } } }
/// <summary> /// Invoke method from Ilutp class. /// </summary> /// <typeparam name="T">Type of the return value.</typeparam> /// <param name="ilutp">Ilutp instance.</param> /// <param name="methodName">Method name.</param> /// <returns>Result of the method invocation.</returns> private static T GetMethod<T>(Ilutp ilutp, string methodName) { var type = ilutp.GetType(); var methodInfo = type.GetMethod( methodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, null, CallingConventions.Standard, new Type[0], null); var obj = methodInfo.Invoke(ilutp, null); return (T)obj; }
public void SolveWithPivoting() { const int Size = 10; var newMatrix = CreateReverseUnitMatrix(Size); var vector = CreateStandardBcVector(Size); var preconditioner = new Ilutp { PivotTolerance = 1.0, DropTolerance = 0, FillLevel = 10 }; preconditioner.Initialize(newMatrix); Vector result = new DenseVector(vector.Count); preconditioner.Approximate(vector, result); CheckResult(preconditioner, newMatrix, vector, result); }
public void CompareWithOriginalDenseMatrixWithPivoting() { var sparseMatrix = new SparseMatrix(3); sparseMatrix[0, 0] = -1; sparseMatrix[0, 1] = 5; sparseMatrix[0, 2] = 6; sparseMatrix[1, 0] = 3; sparseMatrix[1, 1] = -6; sparseMatrix[1, 2] = 1; sparseMatrix[2, 0] = 6; sparseMatrix[2, 1] = 8; sparseMatrix[2, 2] = 9; var ilu = new Ilutp { PivotTolerance = 1.0, DropTolerance = 0, FillLevel = 10 }; ilu.Initialize(sparseMatrix); var l = GetLowerTriangle(ilu); var u = GetUpperTriangle(ilu); var pivots = GetPivots(ilu); var p = new SparseMatrix(l.RowCount); for (var i = 0; i < p.RowCount; i++) { p[i, pivots[i]] = 1.0; } var temp = l.Multiply(u); var original = temp.Multiply(p); for (var i = 0; i < sparseMatrix.RowCount; i++) { for (var j = 0; j < sparseMatrix.ColumnCount; j++) { Assert.IsTrue(sparseMatrix[i, j].Real.AlmostEqual(original[i, j].Real, -Epsilon.Magnitude()), "#01-" + i + "-" + j); Assert.IsTrue(sparseMatrix[i, j].Imaginary.AlmostEqual(original[i, j].Imaginary, -Epsilon.Magnitude()), "#02-" + i + "-" + j); } } }
/// <summary> /// Get upper triangle. /// </summary> /// <param name="ilutp">Ilutp instance.</param> /// <returns>Upper triangle.</returns> private static SparseMatrix GetUpperTriangle(Ilutp ilutp) { return GetMethod<SparseMatrix>(ilutp, "UpperTriangle"); }
/// <summary> /// Get pivots. /// </summary> /// <param name="ilutp">Ilutp instance.</param> /// <returns>Pivots array.</returns> private static int[] GetPivots(Ilutp ilutp) { return GetMethod<int[]>(ilutp, "Pivots"); }
/// <summary> /// Get lower triangle. /// </summary> /// <param name="ilutp">Ilutp instance.</param> /// <returns>Lower triangle.</returns> private static SparseMatrix GetLowerTriangle(Ilutp ilutp) { return(GetMethod <SparseMatrix>(ilutp, "LowerTriangle")); }