Automates adjoints. Forward and reverse mode algorithmic differentiation around implicit functions (not propagating AD through), as well as custom rules to allow for mixed-mode AD or calling external (non-AD compatible) functions within an AD chain.
I have a very similar function that gets me matrices and vectors from an external geometry module (here using Python and returns a sample output) for which I plan to finite difference when needed in the AD chain.
I have a very similar function that gets me matrices and vectors from an external geometry module (here using Python and returns a sample output) for which I plan to finite difference when needed in the AD chain.
`using PyCall py""" def demopython(r,p): return [r,r^3-4*r^2,r^2/2] """
demojulia(r,p) = [r,r^3-4*r^2,r^2/2]
function trysolve(r) p = () meshdata = provide_rule(py"demopython",r,p;mode="ffd") return meshdata end
r = 1.0 J1 = ForwardDiff.derivative(trysolve,r) print(J1)`
When run, this gives the stacktrace below
`ERROR: MethodError: no method matching Float64(::ForwardDiff.Dual{ForwardDiff.Tag{typeof(trysolve), Float64}, Float64, 1})
Closest candidates are: (::Type{T})(::Real, ::RoundingMode) where T<:AbstractFloat @ Base rounding.jl:207 (::Type{T})(::T) where T<:Number @ Core boot.jl:792 Float64(::IrrationalConstants.Log4π) @ IrrationalConstants ~/.julia/packages/IrrationalConstants/vp5v4/src/macro.jl:112 ...
Stacktrace: [1] convert(::Type{Float64}, x::ForwardDiff.Dual{ForwardDiff.Tag{typeof(trysolve), Float64}, Float64, 1}) @ Base ./number.jl:7 [2] cconvert(T::Type, x::ForwardDiff.Dual{ForwardDiff.Tag{typeof(trysolve), Float64}, Float64, 1}) @ Base ./essentials.jl:543 [3] macro expansion @ ~/.julia/packages/PyCall/1gn3u/src/exception.jl:108 [inlined] [4] PyObject(r::ForwardDiff.Dual{ForwardDiff.Tag{typeof(trysolve), Float64}, Float64, 1}) @ PyCall ~/.julia/packages/PyCall/1gn3u/src/conversions.jl:23 [5] _pycall!(ret::PyObject, o::PyObject, args::Tuple{ForwardDiff.Dual{…}, Tuple{}}, nargs::Int64, kw::Ptr{Nothing}) @ PyCall ~/.julia/packages/PyCall/1gn3u/src/pyfncall.jl:24 [6] _pycall! @ ~/.julia/packages/PyCall/1gn3u/src/pyfncall.jl:11 [inlined] [7] PyObject @ ~/.julia/packages/PyCall/1gn3u/src/pyfncall.jl:86 [inlined] [8] _provide_rule @ ~/.julia/packages/ImplicitAD/bF0uI/src/external.jl:21 [inlined] [9] #provide_rule#80 @ ~/.julia/packages/ImplicitAD/bF0uI/src/external.jl:19 [inlined] [10] trysolve(r::ForwardDiff.Dual{ForwardDiff.Tag{typeof(trysolve), Float64}, Float64, 1}) @ Main ~/Desktop/BEM.jl/rankineAD.jl:66 [11] derivative(f::typeof(trysolve), x::Float64) @ ForwardDiff ~/.julia/packages/ForwardDiff/PcZ48/src/derivative.jl:14 [12] top-level scope @ ~/Desktop/BEM.jl/rankineAD.jl:72`