Hi there,
I wrote the following log-likelihood function for which I want to try out ForwardDiff.jl
to compute the Jacobian. I have it also by hand but just wanted to try it out and check the differences. However I run into an error that I do not understand how to fix:
using ForwardDiff
struct Observation
y::Float64
x1::Float64
x2::Float64
end
# this function will generate the logit data for Q4
function simulate_logit_data(; n_obs = 300000)
# define the DGP
X1 = 1.0:0.01:10.0
X2 = 18:0.01:65.0
α = -1.0
θ_1 = 0.5
θ_2 = 0.02
# pre-allocate the container for the data
data = Array{Observation}(undef, n_obs)
for i in eachindex(data)
x1 = rand(X1)
x2 = rand(X2)
u = rand()
y = (α + θ_1*x2 + θ_2*x2 + log(u/(1-u)) > 0) ? 1.0 : 0.0
data[i] = Observation(y, x1, x2)
end
return data
end
function Xθ(θ, obs; f = fieldnames(Observation))
result::Float64 = θ[1]
for i in 2:length(f)
result += θ[i]*getfield(obs, f[i])
end
return result
end
# this function will compute the log-likelihood given a parameter space point
function LL(θ, data)
ll::Float64 = 0.0
for i in eachindex(data)
ll += -log(1+exp(Xθ(θ, data[i]))) + getfield(data[i], :y)*Xθ(θ, data[i])
end
return ll
end
function main()
data = simulate_logit_data()
ForwardDiff.gradient(θ -> LL(θ, data), rand(3))
end
main()
Where the error message reads:
ERROR: LoadError: MethodError: no method matching Float64(::ForwardDiff.Dual{ForwardDiff.Tag{var"#121#122"{Vector{Observation}}, Float64}, Float64, 3})
The type `Float64` exists, but no method is defined for this combination of argument types when trying to construct it.
Closest candidates are:
(::Type{T})(::Real, ::RoundingMode) where T<:AbstractFloat
@ Base rounding.jl:265
(::Type{T})(::T) where T<:Number
@ Core boot.jl:900
Float64(::IrrationalConstants.Logten)
@ IrrationalConstants ~/.julia/packages/IrrationalConstants/vp5v4/src/macro.jl:112
...
Stacktrace:
[1] convert(::Type{Float64}, x::ForwardDiff.Dual{ForwardDiff.Tag{var"#121#122"{Vector{Observation}}, Float64}, Float64, 3})
@ Base ./number.jl:7
[2] Xθ(θ::Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#121#122"{…}, Float64}, Float64, 3}}, obs::Observation; f::Tuple{Symbol, Symbol, Symbol})
@ Main ~/Documents/Psets/StructuralEconometrics/Pset4/Code/test.jl:30
[3] Xθ(θ::Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#121#122"{Vector{Observation}}, Float64}, Float64, 3}}, obs::Observation)
@ Main ~/Documents/Psets/StructuralEconometrics/Pset4/Code/test.jl:29
[4] LL
@ ~/Documents/Psets/StructuralEconometrics/Pset4/Code/test.jl:41 [inlined]
[5] #121
@ ~/Documents/Psets/StructuralEconometrics/Pset4/Code/test.jl:48 [inlined]
[6] vector_mode_dual_eval!
@ ~/.julia/packages/ForwardDiff/UBbGT/src/apiutils.jl:24 [inlined]
[7] vector_mode_gradient
@ ~/.julia/packages/ForwardDiff/UBbGT/src/gradient.jl:91 [inlined]
[8] gradient(f::var"#121#122"{…}, x::Vector{…}, cfg::ForwardDiff.GradientConfig{…}, ::Val{…})
@ ForwardDiff ~/.julia/packages/ForwardDiff/UBbGT/src/gradient.jl:20
[9] gradient(f::var"#121#122"{Vector{…}}, x::Vector{Float64}, cfg::ForwardDiff.GradientConfig{ForwardDiff.Tag{…}, Float64, 3, Vector{…}})
@ ForwardDiff ~/.julia/packages/ForwardDiff/UBbGT/src/gradient.jl:17
[10] gradient(f::var"#121#122"{Vector{Observation}}, x::Vector{Float64})
@ ForwardDiff ~/.julia/packages/ForwardDiff/UBbGT/src/gradient.jl:17
[11] main()
@ Main ~/Documents/Psets/StructuralEconometrics/Pset4/Code/test.jl:48
[12] top-level scope
@ ~/Documents/Psets/StructuralEconometrics/Pset4/Code/test.jl:51
[13] include(fname::String)
@ Main ./sysimg.jl:38
[14] top-level scope
@ REPL[73]:1
in expression starting at /Users/miguelborrero/Documents/Psets/StructuralEconometrics/Pset4/Code/test.jl:51
Some type information was truncated. Use `show(err)` to see complete types.
Thanks in advance!