Generic interface
Krylov.jl provides a generic interface for solving linear systems using (block) Krylov methods. The interface is designed to be common for all methods and contains three routines krylov_workspace
, krylov_solve
and krylov_solve!
. They allow to build Krylov workspaces and call both in-place and out-of-place variants of the solvers with a unified API.
Krylov.krylov_workspace
— Functionworkspace = krylov_workspace(Val(method), args...; kwargs...)
Generic function that dispatches to the appropriate workspace constructor for each subtype of KrylovWorkspace
and BlockKrylovWorkspace
. The first argument Val(method)
, where method
is a symbol (such as :cg
, :gmres
or :block_minres
), specifies the (block) Krylov method for which a workspace is desired. The returned workspace can later be used by krylov_solve!
to execute the (block) Krylov method in-place.
Krylov.krylov_solve
— Functionkrylov_solve(Val(method), args...; kwargs...)
Generic function that dispatches to the appropriate out-of-place (block) Krylov method specified by symbol method
(such as :cg
, :gmres
or :block_minres
).
Krylov.krylov_solve!
— Functionkrylov_solve!(workspace, args...; kwargs...)
Generic function that dispatches to the appropriate in-place (block) Krylov method based on the type of workspace
. The argument workspace
must be a subtype of KrylovWorkspace
or BlockKrylovWorkspace
(such as CgWorkspace
, GmresWorkspace
or BlockMinresWorkspace
).
The section on workspace accessors describes how to retrieve the solution, statistics, and other results from a workspace after calling krylov_solve!
.
Examples
using Krylov, SparseArrays, LinearAlgebra
# Define a symmetric positive definite matrix A and a right-hand side vector b
n = 1000
A = sprandn(n, n, 0.005)
A = A * A' + I
b = randn(n)
# Out-of-place interface
for method in (:cg, :cr, :car)
x, stats = krylov_solve(Val(method), A, b)
r = b - A * x
println("Residual norm for $(method): ", norm(r))
end
Residual norm for cg: 3.406895148541806e-7
Residual norm for cr: 3.720577865400298e-7
Residual norm for car: 4.3843116777622553e-7
using Krylov, SparseArrays, LinearAlgebra
# Define a square nonsymmetric matrix A and a right-hand side vector b
n = 100
A = sprand(n, n, 0.05) + I
b = rand(n)
# In-place interface
for method in (:bicgstab, :gmres, :qmr)
# Create a workspace for the Krylov method
workspace = krylov_workspace(Val(method), A, b)
# Solve the system in-place
krylov_solve!(workspace, A, b)
# Get the statistics
stats = Krylov.statistics(workspace)
# Retrieve the solution
x = Krylov.solution(workspace)
# Check if the solver converged
solved = Krylov.issolved(workspace)
println("Convergence of $method: ", solved)
# Display the number of iterations
niter = Krylov.iteration_count(workspace)
println("Number of iterations for $method: ", niter)
# Display the elapsed timer
timer = Krylov.elapsed_time(workspace)
println("Elapsed time for $method: ", timer, " seconds")
# Display the number of operator-vector products with A and A'
nAprod = Krylov.Aprod_count(workspace)
nAtprod = Krylov.Atprod_count(workspace)
println("Number of operator-vector products with A and A' for $method: ", (nAprod, nAtprod))
println()
end
Convergence of bicgstab: true
Number of iterations for bicgstab: 194
Elapsed time for bicgstab: 0.000255769 seconds
Number of operator-vector products with A and A' for bicgstab: (388, 0)
Convergence of gmres: true
Number of iterations for gmres: 85
Elapsed time for gmres: 0.000277671 seconds
Number of operator-vector products with A and A' for gmres: (85, 0)
Convergence of qmr: true
Number of iterations for qmr: 128
Elapsed time for qmr: 0.000179046 seconds
Number of operator-vector products with A and A' for qmr: (128, 128)