Jacobians
The supertype Jacobian comprises different ways of taking Jacobians:
We first start by showing JacobianAutodiff:
# the input and output dimensions of this function are the same
F(y::AbstractArray, x::AbstractArray, params) = y .= tanh.(x)
dim = 3
x = rand(dim)
jac = JacobianAutodiff{eltype(x)}(F, dim)JacobianAutodiff{Float64, typeof(Main.F), ForwardDiff.JacobianConfig{Nothing, Float64, 3, Tuple{Vector{ForwardDiff.Dual{Nothing, Float64, 3}}, Vector{ForwardDiff.Dual{Nothing, Float64, 3}}}}, Vector{Float64}}(Main.F, ForwardDiff.JacobianConfig{Nothing, Float64, 3, Tuple{Vector{ForwardDiff.Dual{Nothing, Float64, 3}}, Vector{ForwardDiff.Dual{Nothing, Float64, 3}}}}((Partials(1.0, 0.0, 0.0), Partials(0.0, 1.0, 0.0), Partials(0.0, 0.0, 1.0)), (ForwardDiff.Dual{Nothing, Float64, 3}[Dual{Nothing}(6.92132057644657e-310,6.9213602316723e-310,6.9213602312067e-310,6.9213602316723e-310), Dual{Nothing}(6.92132057644736e-310,6.9213602316723e-310,6.9213205767043e-310,6.92132057670507e-310), Dual{Nothing}(6.9213602316723e-310,6.92132108440455e-310,6.9213602316723e-310,6.9213602316723e-310)], ForwardDiff.Dual{Nothing, Float64, 3}[Dual{Nothing}(5.0e-324,1.0e-323,6.92131278973405e-310,6.92131278973563e-310), Dual{Nothing}(1.5e-323,1.5e-323,6.9213127897372e-310,6.92131278974037e-310), Dual{Nothing}(2.0e-323,2.5e-323,6.92131278974196e-310,6.92131278974354e-310)])), [0.0, 0.0, 0.0])Instead of calling JacobianAutodiff(f, x) we can equivalently do:
jac = Jacobian{eltype(x)}(F, dim; mode = :autodiff)JacobianAutodiff{Float64, typeof(Main.F), ForwardDiff.JacobianConfig{Nothing, Float64, 3, Tuple{Vector{ForwardDiff.Dual{Nothing, Float64, 3}}, Vector{ForwardDiff.Dual{Nothing, Float64, 3}}}}, Vector{Float64}}(Main.F, ForwardDiff.JacobianConfig{Nothing, Float64, 3, Tuple{Vector{ForwardDiff.Dual{Nothing, Float64, 3}}, Vector{ForwardDiff.Dual{Nothing, Float64, 3}}}}((Partials(1.0, 0.0, 0.0), Partials(0.0, 1.0, 0.0), Partials(0.0, 0.0, 1.0)), (ForwardDiff.Dual{Nothing, Float64, 3}[Dual{Nothing}(5.0e-324,3.0e-323,6.92131207712064e-310,6.9213120771222e-310), Dual{Nothing}(3.5e-323,3.5e-323,6.9213120771238e-310,6.9213120771254e-310), Dual{Nothing}(4.0e-323,4.4e-323,6.92131207712696e-310,6.92131207712855e-310)], ForwardDiff.Dual{Nothing, Float64, 3}[Dual{Nothing}(6.92131206485516e-310,6.92135107531414e-310,6.9213602316723e-310,6.92131139495195e-310), Dual{Nothing}(1.9086e-319,1.9423e-319,7.748597204865894e-304,7.746817145885187e-304), Dual{Nothing}(1.132330905991725e-308,6.9213559845836e-310,2.803920358997454e-309,0.0)])), [0.0, 0.0, 0.0])When calling an instance of Jacobian we can use the function [compute_jacobian!]:
params = nothing
j = zeros(dim, dim)
compute_jacobian!(j, x, jac, params)3×3 Matrix{Float64}:
0.770907 0.0 0.0
0.0 0.721643 0.0
0.0 0.0 0.493302This is equivalent to calling:
jac(j, x, params)3×3 Matrix{Float64}:
0.770907 0.0 0.0
0.0 0.721643 0.0
0.0 0.0 0.493302