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.9471843107498e-310,6.94722925301707e-310,6.9471843107506e-310,6.94722925301707e-310), Dual{Nothing}(6.9471843107514e-310,6.94722925301707e-310,6.94723362236764e-310,6.94722925301707e-310), Dual{Nothing}(6.947233622589e-310,6.94722925301707e-310,6.94723362256685e-310,6.94722925301707e-310)], ForwardDiff.Dual{Nothing, Float64, 3}[Dual{Nothing}(6.9471843107498e-310,6.94722925301707e-310,6.9471843107506e-310,6.94722925301707e-310), Dual{Nothing}(6.9471843107514e-310,6.94722925301707e-310,6.94723362236764e-310,6.94722925301707e-310), Dual{Nothing}(6.947233622589e-310,6.94722925301707e-310,6.94723362256685e-310,6.94722925301707e-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}(6.94722610794537e-310,6.94723363243867e-310,6.94722545148074e-310,6.9472253419697e-310), Dual{Nothing}(6.9472336327264e-310,6.94723363274855e-310,6.9472336327707e-310,6.9472336327928e-310), Dual{Nothing}(6.94723363281495e-310,6.9472336328371e-310,6.9472336328592e-310,6.94723363288136e-310)], ForwardDiff.Dual{Nothing, Float64, 3}[Dual{Nothing}(0.0,0.0,0.0,0.0), Dual{Nothing}(0.0,0.0,0.0,0.0), Dual{Nothing}(0.0,0.0,0.0,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.493302
This 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