I’m trying to get gradient of function that calls another one.
using ForwardDiff, BenchmarkTools
const f_l, f_r = 0.0,0.0;
function J(f::AbstractArray, α::AbstractArray, mesh::AbstractArray)
J = 0.0;
N = length(f);
for i = 2:N - 1
J += ( (f[i+1] - f[i])/mesh[i] - α[i] )^2 ;
end
norm = x -> sobolev_1_1_norm(x,mesh);
J += norm(f);
return J
end
function sobolev_1_1_norm(f::AbstractArray,mesh::AbstractArray)
out = 0.0;
N = length(f);
for i = 1:N-1
out += f[i] + ((f[i+1] - f[i])/mesh[i])^2;
end
out += f[end] + ((f[end ] - f[end - 1])/mesh[end])^2;
end
∇J(z,α,mesh) = ForwardDiff.gradient( x -> J(x, α, mesh), α, mesh);
size = 50;
α = rand(-pi:0.01:pi, size);
mesh = fill(0.2, size);
f = rand(size);
@btime J(f,α,mesh)
@btime ∇J(f,α,mesh)
results in
julia> @btime J(f,α,mesh)
556.403 ns (1 allocation: 16 bytes)
678.466801231054
julia> @btime ∇J(f,α,mesh)
ERROR: MethodError: no method matching gradient(::getfield(Main, Symbol("##15#16")){Array{Float64,1},Array{Float64,1}}, ::Array{Float64,1}, ::Array{Float64,1})
Closest candidates are:
gradient(::Any, ::AbstractArray) at /Users/user/.julia/packages/ForwardDiff/hnKaN/src/gradient.jl:15
gradient(::Any, ::AbstractArray, ::ForwardDiff.GradientConfig{T,V,N,D} where D where N where V) where T at /Users/user/.julia/packages/ForwardDiff/hnKaN/src/gradient.jl:15
gradient(::Any, ::AbstractArray, ::ForwardDiff.GradientConfig{T,V,N,D} where D where N where V, ::Val{CHK}) where {T, CHK} at /Users/user/.julia/packages/ForwardDiff/hnKaN/src/gradient.jl:15
...
Stacktrace:
[1] ∇J(::Array{Float64,1}, ::Array{Float64,1}, ::Array{Float64,1}) at ./REPL[26]:1
[2] ##core#404() at /Users/user/.julia/packages/BenchmarkTools/dtwnm/src/execution.jl:293
[3] ##sample#405(::BenchmarkTools.Parameters) at /Users/user/.julia/packages/BenchmarkTools/dtwnm/src/execution.jl:299
[4] #_run#18(::Bool, ::String, ::Base.Iterators.Pairs{Symbol,Integer,NTuple{4,Symbol},NamedTuple{(:samples, :evals, :gctrial, :gcsample),Tuple{Int64,Int64,Bool,Bool}}}, ::Function, ::BenchmarkTools.Benchmark{Symbol("##benchmark#403")}, ::BenchmarkTools.Parameters) at /Users/user/.julia/packages/BenchmarkTools/dtwnm/src/execution.jl:327
[5] (::getfield(Base, Symbol("#inner#2")){Base.Iterators.Pairs{Symbol,Integer,NTuple{5,Symbol},NamedTuple{(:verbose, :samples, :evals, :gctrial, :gcsample),Tuple{Bool,Int64,Int64,Bool,Bool}}},typeof(BenchmarkTools._run),Tuple{BenchmarkTools.Benchmark{Symbol("##benchmark#403")},BenchmarkTools.Parameters}})() at ./none:0
[6] #invokelatest#1 at ./essentials.jl:690 [inlined]
[7] #invokelatest at ./none:0 [inlined]
[8] #run_result#16 at /Users/user/.julia/packages/BenchmarkTools/dtwnm/src/execution.jl:32 [inlined]
[9] #run_result at ./none:0 [inlined]
[10] #run#18(::Base.Iterators.Pairs{Symbol,Integer,NTuple{5,Symbol},NamedTuple{(:verbose, :samples, :evals, :gctrial, :gcsample),Tuple{Bool,Int64,Int64,Bool,Bool}}}, ::Function, ::BenchmarkTools.Benchmark{Symbol("##benchmark#403")}, ::BenchmarkTools.Parameters) at /Users/user/.julia/packages/BenchmarkTools/dtwnm/src/execution.jl:46
[11] #run at ./none:0 [inlined] (repeats 2 times)
[12] #warmup#21 at /Users/user/.julia/packages/BenchmarkTools/dtwnm/src/execution.jl:79 [inlined]
[13] warmup(::BenchmarkTools.Benchmark{Symbol("##benchmark#403")}) at /Users/user/.julia/packages/BenchmarkTools/dtwnm/src/execution.jl:79
[14] top-level scope at /Users/user/.julia/packages/BenchmarkTools/dtwnm/src/execution.jl:387
What I’m missing?