Gradients

The supertype Gradient comprises different ways of taking gradients:

We first start by showing GradientAutodiff:

f(x::AbstractArray) = sum(x .^ 2)
x = rand(3)
grad = GradientAutodiff(f, x)
GradientAutodiff{Float64, typeof(Main.f), ForwardDiff.GradientConfig{ForwardDiff.Tag{typeof(Main.f), Float64}, Float64, 3, Vector{ForwardDiff.Dual{ForwardDiff.Tag{typeof(Main.f), Float64}, Float64, 3}}}}(Main.f, ForwardDiff.GradientConfig{ForwardDiff.Tag{typeof(Main.f), Float64}, Float64, 3, Vector{ForwardDiff.Dual{ForwardDiff.Tag{typeof(Main.f), Float64}, 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{ForwardDiff.Tag{typeof(Main.f), Float64}, Float64, 3}[Dual{ForwardDiff.Tag{typeof(Main.f), Float64}}(5.0e-324,5.0e-324,6.9013601936944e-310,6.90136019369754e-310), Dual{ForwardDiff.Tag{typeof(Main.f), Float64}}(1.0e-323,1.0e-323,6.9013601936991e-310,6.9013601937023e-310), Dual{ForwardDiff.Tag{typeof(Main.f), Float64}}(1.5e-323,1.5e-323,6.90136019370387e-310,6.90136019370703e-310)]))

Every struct derived from Gradient (including GradientAutodiff) has an associated functor:

grad(x)
3-element Vector{Float64}:
 1.042427591070766
 1.1736135149066969
 1.7817573961855622