New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update ExpRK to use calc_J!
and new DiffEqOperators
#438
Conversation
The fields used by `jacobian!` are now only referenced in the branch where they are actually used, so they can be absent from the cache.
Codecov Report
@@ Coverage Diff @@
## master #438 +/- ##
==========================================
+ Coverage 94.77% 94.77% +<.01%
==========================================
Files 72 72
Lines 8214 8215 +1
==========================================
+ Hits 7785 7786 +1
Misses 429 429
Continue to review full report at Codecov.
|
I have rewritten the test script for Krylov ExpRK to use The construction of
I think this should be a good interface to the end user (for regular |
calc_J!
and new DiffEqOperatorscalc_J!
and new DiffEqOperators
An additional note on the test script: I have added |
Why don't they?
So there are two ways to do it: specify the |
The caching method require the linear operator to be constant and as a result should only be used in conjunction with a
While what can be done for the first option can always be done using the second one, I think keeping the first one has its advantage. It is more lightweight for simple problems, especially out-of-place ones (we only need |
Oh yeah :).
Yes, though I am not entirely convinced supporting both methods for Jacobians is useful. But in the end, we need the second to do things matrix-free, but I agree it's overkill for dense Jacobians. Maybe we will have a better way to merge it in the future, but for now let's just keep it. |
LGTM. I would like to see a test with a sparse matrix and a test with a matrix-free operator though. |
Here is a simple test script. Note that using OrdinaryDiffEq, DiffEqOperators, LinearAlgebra, Test, SparseArrays, Random
N = 10
# Sparse Jacobian
srand(0); u0 = normalize(randn(N))
dd = -2 * ones(N); du = ones(N-1)
A = spdiagm(-1 => du, 0 => dd, 1 => du)
f = (u,p,t) -> A*u
fun = ODEFunction(f;
jac=(u,p,t) -> A,
analytic=(u,p,t) -> exp(t*Matrix(A)) * u)
prob = ODEProblem(fun, u0, (0.0,1.0))
sol = solve(prob, LawsonEuler(krylov=true, m=N); dt=0.1)
err = norm(sol(1.0) - fun.analytic(u0,nothing,1.0))
println("Error for sparse jacobian: $err")
# Matrix-free Jacobian
# Need to implement the missing interface for DerivativeOperator first
Base.convert(::Type{AbstractArray}, L::DerivativeOperator) = sparse(L)
L = DerivativeOperator{Float64}(2,2,1.0,N,:Dirichlet0,:Dirichlet0)
fun = ODEFunction(L;
jac_prototype=L,
analytic=(u,p,t) -> exp(t*full(L)) * u)
prob = ODEProblem(fun, u0, (0.0,1.0))
sol = solve(prob, LawsonEuler(krylov=true, m=N); dt=0.1)
err = norm(sol(1.0) - fun.analytic(u0,nothing,1.0))
println("Error for matrix-free jacobian: $err") The output is (minus the depwarns from
By the way, about the Travis build error: I think this is probably due to the Travis build still using DiffEqBase before today's hotfix? The stack trace seems a bit cryptic, but anyway the convergence test runs fine on my machine. |
Add these two tests.
Just merged. |
The main goal of this PR is to update the ExpRK integrators to use the
calc_J!
instead of directly callingf.jac
. This would allow general sparse and/or lazy types to be used as the jacobian, as indicated here #416.A secondary goal is to apply the newest changes to DiffEqOperators to the ExpRK integrators. This goes hand in hand with the primary goal as both are related to lazy operator support. One thing in particular I'd like to do is to drop DiffEqOperators in the requirement list, which should make the separation of functionality clearer. This is made possible due to the various new interfaces introduced in the DiffEqOperators update, in particular
convert(Number, a)
andconvert(AbstractArray, A)
.