Skip to content

Commit

Permalink
Convenience API for derivatives and Jacobians.
Browse files Browse the repository at this point in the history
  • Loading branch information
dextorious committed Nov 8, 2017
1 parent 31e05ab commit f6e7a6b
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 156 deletions.
20 changes: 20 additions & 0 deletions src/derivative_wrappers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,23 @@ mutable struct UDerivativeWrapper{F,tType} <: Function
t::tType
end
(p::UDerivativeWrapper)(u) = p.f(p.t,u)

function derivative!(df::AbstractArray{<:Number}, f, x::Union{Number,AbstractArray{<:Number}}, fx::AbstractArray{<:Number}, integrator::DEIntegrator)
if alg_autodiff(integrator.alg)
ForwardDiff.derivative!(df, f, fx, x)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference!(df, f, x, integrator.alg.diff_type, RealOrComplex, Val{:DiffEqDerivativeWrapper}, fx)
end
nothing
end

function jacobian!(J::AbstractMatrix{<:Number}, f, x::AbstractArray{<:Number}, fx::AbstractArray{<:Number}, integrator::DEIntegrator, jac_config)
if alg_autodiff(integrator.alg)
ForwardDiff.jacobian!(J, f, fx, x, jac_config)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference_jacobian!(J, f, x, integrator.alg.diff_type, RealOrComplex, Val{:JacobianWrapper}, fx)
end
nothing
end
98 changes: 14 additions & 84 deletions src/integrators/rosenbrock_integrators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,7 @@ end
else
tf.vf.sizeu = sizeu
tf.uprev = uprev
if alg_autodiff(integrator.alg)
ForwardDiff.derivative!(dT, tf, vec(du2), t)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference!(dT, tf, t, integrator.alg.diff_type, RealOrComplex, Val{:DiffEqDerivativeWrapper}, vec(du2))
end
derivative!(dT, tf, t, vec(du2), integrator)
end
end

Expand All @@ -53,12 +48,7 @@ end
else
uf.vfr.sizeu = sizeu
uf.t = t
if alg_autodiff(integrator.alg)
ForwardDiff.jacobian!(J, uf, vec(du1), vec(uprev), jac_config)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference_jacobian!(J, uf, vec(uprev), integrator.alg.diff_type, RealOrComplex, Val{:JacobianWrapper}, vec(du1))
end
jacobian!(J, uf, vec(uprev), vec(du1), integrator, jac_config)
end
for j in 1:length(u), i in 1:length(u)
@inbounds W[i,j] = mass_matrix[i,j] - γ*J[i,j]
Expand Down Expand Up @@ -148,12 +138,7 @@ end
else
tf.vf.sizeu = sizeu
tf.uprev = uprev
if alg_autodiff(integrator.alg)
ForwardDiff.derivative!(dT, tf, vec(du2), t)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference!(dT, tf, t, integrator.alg.diff_type, RealOrComplex, Val{:DiffEqDerivativeWrapper}, vec(du2))
end
derivative!(dT, tf, t, vec(du2), integrator)
end
end

Expand All @@ -171,12 +156,7 @@ end
else
uf.vfr.sizeu = sizeu
uf.t = t
if alg_autodiff(integrator.alg)
ForwardDiff.jacobian!(J, uf, vec(du1), vec(uprev), jac_config)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference_jacobian!(J, uf, vec(uprev), integrator.alg.diff_type, RealOrComplex, Val{:JacobianWrapper}, vec(du1))
end
jacobian!(J, uf, vec(uprev), vec(du1), integrator, jac_config)
end
for j in 1:length(u), i in 1:length(u)
@inbounds W[i,j] = mass_matrix[i,j] - γ*J[i,j]
Expand Down Expand Up @@ -457,12 +437,7 @@ end
else
tf.vf.sizeu = sizeu
tf.uprev = uprev
if alg_autodiff(integrator.alg)
ForwardDiff.derivative!(dT, tf, vec(du2), t)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference!(dT, tf, t, integrator.alg.diff_type, RealOrComplex, Val{:DiffEqDerivativeWrapper}, vec(du2))
end
derivative!(dT, tf, t, vec(du2), integrator)
end
end

Expand All @@ -481,12 +456,7 @@ end
else
uf.vfr.sizeu = sizeu
uf.t = t
if alg_autodiff(integrator.alg)
ForwardDiff.jacobian!(J, uf, vec(du1), vec(uprev), jac_config)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference_jacobian!(J, uf, vec(uprev), integrator.alg.diff_type, RealOrComplex, Val{:JacobianWrapper}, vec(du1))
end
jacobian!(J, uf, vec(uprev), vec(du1), integrator, jac_config)
end
for j in 1:length(u), i in 1:length(u)
@inbounds W[i,j] = mass_matrix[i,j]/dtgamma - J[i,j]
Expand Down Expand Up @@ -667,12 +637,7 @@ end
else
tf.vf.sizeu = sizeu
tf.uprev = uprev
if alg_autodiff(integrator.alg)
ForwardDiff.derivative!(dT, tf, vec(du2), t)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference!(dT, tf, t, integrator.alg.diff_type, RealOrComplex, Val{:DiffEqDerivativeWrapper}, vec(du2))
end
derivative!(dT, tf, t, vec(du2), integrator)
end
end

Expand All @@ -690,12 +655,7 @@ end
else
uf.vfr.sizeu = sizeu
uf.t = t
if alg_autodiff(integrator.alg)
ForwardDiff.jacobian!(J, uf, vec(du1), vec(uprev), jac_config)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference_jacobian!(J, uf, vec(uprev), integrator.alg.diff_type, RealOrComplex, Val{:JacobianWrapper}, vec(du1))
end
jacobian!(J, uf, vec(uprev), vec(du1), integrator, jac_config)
end
for j in 1:length(u), i in 1:length(u)
@inbounds W[i,j] = mass_matrix[i,j]/dtgamma - J[i,j]
Expand Down Expand Up @@ -901,12 +861,7 @@ end
else
tf.vf.sizeu = sizeu
tf.uprev = uprev
if alg_autodiff(integrator.alg)
ForwardDiff.derivative!(dT, tf, vec(du2), t)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference!(dT, tf, t, integrator.alg.diff_type, RealOrComplex, Val{:DiffEqDerivativeWrapper}, vec(du2))
end
derivative!(dT, tf, t, vec(du2), integrator)
end
end

Expand All @@ -925,12 +880,7 @@ end
else
uf.vfr.sizeu = sizeu
uf.t = t
if alg_autodiff(integrator.alg)
ForwardDiff.jacobian!(J, uf, vec(du1), vec(uprev), jac_config)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference_jacobian!(J, uf, vec(uprev), integrator.alg.diff_type, RealOrComplex, Val{:JacobianWrapper}, vec(du1))
end
jacobian!(J, uf, vec(uprev), vec(du1), integrator, jac_config)
end
for j in 1:length(u), i in 1:length(u)
@inbounds W[i,j] = mass_matrix[i,j]/dtgamma - J[i,j]
Expand Down Expand Up @@ -1159,12 +1109,7 @@ end
else
tf.vf.sizeu = sizeu
tf.uprev = uprev
if alg_autodiff(integrator.alg)
ForwardDiff.derivative!(dT, tf, vec(du2), t)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference!(dT, tf, t, integrator.alg.diff_type, RealOrComplex, Val{:DiffEqDerivativeWrapper}, vec(du2))
end
derivative!(dT, tf, t, vec(du2), integrator)
end
end

Expand All @@ -1185,12 +1130,7 @@ end
else
uf.vfr.sizeu = sizeu
uf.t = t
if alg_autodiff(integrator.alg)
ForwardDiff.jacobian!(J, uf, vec(du1), vec(uprev), jac_config)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference_jacobian!(J, uf, vec(uprev), integrator.alg.diff_type, RealOrComplex, Val{:JacobianWrapper}, vec(du1))
end
jacobian!(J, uf, vec(uprev), vec(du1), integrator, jac_config)
end
for j in 1:length(u), i in 1:length(u)
@inbounds W[i,j] = mass_matrix[i,j]/dtgamma - J[i,j]
Expand Down Expand Up @@ -1546,12 +1486,7 @@ end
else
tf.vf.sizeu = sizeu
tf.uprev = uprev
if alg_autodiff(integrator.alg)
ForwardDiff.derivative!(dT, tf, vec(du2), t)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference!(dT, tf, t, integrator.alg.diff_type, RealOrComplex, Val{:DiffEqDerivativeWrapper}, vec(du2))
end
derivative!(dT, tf, t, vec(du2), integrator)
end
end

Expand All @@ -1572,12 +1507,7 @@ end
else
uf.vfr.sizeu = sizeu
uf.t = t
if alg_autodiff(integrator.alg)
ForwardDiff.jacobian!(J, uf, vec(du1), vec(uprev), jac_config)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference_jacobian!(J, uf, vec(uprev), integrator.alg.diff_type, RealOrComplex, Val{:JacobianWrapper}, vec(du1))
end
jacobian!(J, uf, vec(uprev), vec(du1), integrator, jac_config)
end
for j in 1:length(u), i in 1:length(u)
@inbounds W[i,j] = mass_matrix[i,j]/dtgamma - J[i,j]
Expand Down
84 changes: 12 additions & 72 deletions src/integrators/sdirk_integrators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,7 @@ end
f(Val{:jac},t,uprev,J)
else
uf.t = t
if alg_autodiff(integrator.alg)
ForwardDiff.jacobian!(J,uf,vec(du1),vec(uprev),jac_config)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference_jacobian!(J, uf, vec(uprev), integrator.alg.diff_type, RealOrComplex, Val{:JacobianWrapper}, vec(du1))
end
jacobian!(J, uf, vec(uprev), vec(du1), integrator, jac_config)
end
end
# skip calculation of W if step is repeated
Expand Down Expand Up @@ -362,12 +357,7 @@ end
f(Val{:jac},t,uprev,J)
else
uf.t = t
if alg_autodiff(integrator.alg)
ForwardDiff.jacobian!(J,uf,vec(du1),vec(uprev),jac_config)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference_jacobian!(J, uf, vec(uprev), integrator.alg.diff_type, RealOrComplex, Val{:JacobianWrapper}, vec(du1))
end
jacobian!(J, uf, vec(uprev), vec(du1), integrator, jac_config)
end
end
# skip calculation of W if step is repeated
Expand Down Expand Up @@ -910,12 +900,7 @@ end
f(Val{:jac},t,uprev,J)
else
uf.t = t
if alg_autodiff(integrator.alg)
ForwardDiff.jacobian!(J,uf,vec(du1),vec(uprev),jac_config)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference_jacobian!(J, uf, vec(uprev), integrator.alg.diff_type, RealOrComplex, Val{:JacobianWrapper}, vec(du1))
end
jacobian!(J, uf, vec(uprev), vec(du1), integrator, jac_config)
end
end
# skip calculation of W if step is repeated
Expand Down Expand Up @@ -1234,12 +1219,7 @@ end
f(Val{:jac},t,uprev,J)
else
uf.t = t
if alg_autodiff(integrator.alg)
ForwardDiff.jacobian!(J,uf,vec(du1),vec(uprev),jac_config)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference_jacobian!(J, uf, vec(uprev), integrator.alg.diff_type, RealOrComplex, Val{:JacobianWrapper}, vec(du1))
end
jacobian!(J, uf, vec(uprev), vec(du1), integrator, jac_config)
end
end
# skip calculation of W if step is repeated
Expand Down Expand Up @@ -1558,12 +1538,7 @@ end
f(Val{:jac},t,uprev,J)
else
uf.t = t
if alg_autodiff(integrator.alg)
ForwardDiff.jacobian!(J,uf,vec(du1),vec(uprev),jac_config)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference_jacobian!(J, uf, vec(uprev), integrator.alg.diff_type, RealOrComplex, Val{:JacobianWrapper}, vec(du1))
end
jacobian!(J, uf, vec(uprev), vec(du1), integrator, jac_config)
end
end
# skip calculation of W if step is repeated
Expand Down Expand Up @@ -1909,12 +1884,7 @@ end
f(Val{:jac},t,uprev,J)
else
uf.t = t
if alg_autodiff(integrator.alg)
ForwardDiff.jacobian!(J,uf,vec(du1),vec(uprev),jac_config)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference_jacobian!(J, uf, vec(uprev), integrator.alg.diff_type, RealOrComplex, Val{:JacobianWrapper}, vec(du1))
end
jacobian!(J, uf, vec(uprev), vec(du1), integrator, jac_config)
end
end
# skip calculation of W if step is repeated
Expand Down Expand Up @@ -2423,12 +2393,7 @@ end
f(Val{:jac},t,uprev,J)
else
uf.t = t
if alg_autodiff(integrator.alg)
ForwardDiff.jacobian!(J,uf,vec(du1),vec(uprev),jac_config)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference_jacobian!(J, uf, vec(uprev), integrator.alg.diff_type, RealOrComplex, Val{:JacobianWrapper}, vec(du1))
end
jacobian!(J, uf, vec(uprev), vec(du1), integrator, jac_config)
end
end
# skip calculation of W if step is repeated
Expand Down Expand Up @@ -3032,12 +2997,7 @@ end
f(Val{:jac},t,uprev,J)
else
uf.t = t
if alg_autodiff(integrator.alg)
ForwardDiff.jacobian!(J,uf,vec(du1),vec(uprev),jac_config)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference_jacobian!(J, uf, vec(uprev), integrator.alg.diff_type, RealOrComplex, Val{:JacobianWrapper}, vec(du1))
end
jacobian!(J, uf, vec(uprev), vec(du1), integrator, jac_config)
end
end
# skip calculation of W if step is repeated
Expand Down Expand Up @@ -3608,12 +3568,7 @@ end
f(Val{:jac},t,uprev,J)
else
uf.t = t
if alg_autodiff(integrator.alg)
ForwardDiff.jacobian!(J,uf,vec(du1),vec(uprev),jac_config)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference_jacobian!(J, uf, vec(uprev), integrator.alg.diff_type, RealOrComplex, Val{:JacobianWrapper}, vec(du1))
end
jacobian!(J, uf, vec(uprev), vec(du1), integrator, jac_config)
end
end
# skip calculation of W if step is repeated
Expand Down Expand Up @@ -4166,12 +4121,7 @@ end
f(Val{:jac},t,uprev,J)
else
uf.t = t
if alg_autodiff(integrator.alg)
ForwardDiff.jacobian!(J,uf,vec(du1),vec(uprev),jac_config)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference_jacobian!(J, uf, vec(uprev), integrator.alg.diff_type, RealOrComplex, Val{:JacobianWrapper}, vec(du1))
end
jacobian!(J, uf, vec(uprev), vec(du1), integrator, jac_config)
end
end
# skip calculation of W if step is repeated
Expand Down Expand Up @@ -4822,12 +4772,7 @@ end
f(Val{:jac},t,uprev,J)
else
uf.t = t
if alg_autodiff(integrator.alg)
ForwardDiff.jacobian!(J,uf,vec(du1),vec(uprev),jac_config)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference_jacobian!(J, uf, vec(uprev), integrator.alg.diff_type, RealOrComplex, Val{:JacobianWrapper}, vec(du1))
end
jacobian!(J, uf, vec(uprev), vec(du1), integrator, jac_config)
end
end
# skip calculation of W if step is repeated
Expand Down Expand Up @@ -5576,12 +5521,7 @@ end
f(Val{:jac},t,uprev,J)
else
uf.t = t
if alg_autodiff(integrator.alg)
ForwardDiff.jacobian!(J,uf,vec(du1),vec(uprev),jac_config)
else
RealOrComplex = eltype(integrator.u) <: Complex ? Val{:Complex} : Val{:Real}
DiffEqDiffTools.finite_difference_jacobian!(J, uf, vec(uprev), integrator.alg.diff_type, RealOrComplex, Val{:JacobianWrapper}, vec(du1))
end
jacobian!(J, uf, vec(uprev), vec(du1), integrator, jac_config)
end
end
# skip calculation of W if step is repeated
Expand Down

0 comments on commit f6e7a6b

Please sign in to comment.