Hi there,
I define my custom parametric types as follows:
struct Parameters{T}
"""
inmutable type to pack the parameters estimated.
"""
ϕ::T
λ::T
γ₁::T
end
struct MarketPostEstimation{T}
"""
inmutable type to pack the data from each market after estimation.
"""
s::T
p::T
x::T
z::T
ξ::T
ω::T
end
parameters = Parameters(rand(3)...)
market_1 = MarketPostEstimation(rand(6)...)
Then I define the following functions:
function s_func(p, market; β₀ = 1.5, β₁ = 0.5, α = -0.5)
"""
function to compute theoretical market shares
inputs:
1) p -> price_vector
2) x -> product characteristic
3) ξ -> unobserved demand shock
outputs:
1) market share vector
"""
δ = β₀ + β₁ * market.x + market.ξ
temp = map(pₖ -> exp(δ + α * pₖ), p)
denominator = 1 + sum(temp)
return temp ./ denominator
end
function solve_price_eq_duopoly(τ, market, parameters; α = - 0.5)
"""
solve for the equilibrium prices for a given (τ₁, τ₂) by first solving for the "markup" and then computing the prices.
inputs:
1) τ tuple
2) market
3) parameter instance
outputs:
1) optimal (p₁, p₂)
"""
initial_guess = 0.0
Δ = find_zero(Δ -> 1 + α * (Δ - parameters.λ)*(1 - sum(s_func((τ[1] + Δ, τ[2] + Δ), market))), initial_guess)
return τ .+ Δ
end
p_1_star(τ₁, τ₂, market, parameters) = solve_price_eq_duopoly((τ₁, τ₂), market, parameters)[1]
p_2_star(τ₁, τ₂, market, parameters) = solve_price_eq_duopoly((τ₁, τ₂), market, parameters)[2]
and my objective is to be able to use ForwardDiff.derivative
on those functions like:
ForwardDiff.derivative(x -> p_1_star(x, 3.4, market_1, parameters), 4.5)
but I get the following error:
ERROR: MethodError: no method matching Float64(::ForwardDiff.Dual{ForwardDiff.Tag{var"#67#68", Float64}, Float64, 1})
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"#67#68", Float64}, Float64, 1})
@ Base ./number.jl:7
[2] update_state
@ ~/.julia/packages/Roots/E1WQf/src/DerivativeFree/secant.jl:38 [inlined]
[3] update_state
@ ~/.julia/packages/Roots/E1WQf/src/DerivativeFree/secant.jl:29 [inlined]
[4] solve!(𝐙::Roots.ZeroProblemIterator{Secant, AlefeldPotraShi, Roots.Callable_Function{…}, Roots.UnivariateZeroState{…}, Roots.UnivariateZeroOptions{…}, Roots.NullTracks}; verbose::Bool)
@ Roots ~/.julia/packages/Roots/E1WQf/src/hybrid.jl:54
[5] solve!
@ ~/.julia/packages/Roots/E1WQf/src/hybrid.jl:30 [inlined]
[6] solve(𝑭𝑿::ZeroProblem{var"#12#13"{Float64, Tuple{…}, MarketPostEstimation{…}, Parameters{…}}, Float64}, M::Order0, p::Nothing; verbose::Bool, kwargs::@Kwargs{tracks::Roots.NullTracks})
@ Roots ~/.julia/packages/Roots/E1WQf/src/find_zero.jl:492
[7] find_zero(f::Function, x0::Float64, M::Order0, p′::Nothing; p::Nothing, verbose::Bool, tracks::Roots.NullTracks, kwargs::@Kwargs{})
@ Roots ~/.julia/packages/Roots/E1WQf/src/find_zero.jl:220
[8] find_zero (repeats 2 times)
@ ~/.julia/packages/Roots/E1WQf/src/find_zero.jl:210 [inlined]
[9] find_zero
@ ~/.julia/packages/Roots/E1WQf/src/find_zero.jl:243 [inlined]
[10] solve_price_eq_duopoly(τ::Tuple{ForwardDiff.Dual{ForwardDiff.Tag{var"#67#68", Float64}, Float64, 1}, Float64}, market::MarketPostEstimation{Float64}, parameters::Parameters{Float64}; α::Float64)
@ Main ./REPL[13]:12
[11] solve_price_eq_duopoly
@ ./REPL[13]:1 [inlined]
[12] p_1_star(τ₁::ForwardDiff.Dual{ForwardDiff.Tag{var"#67#68", Float64}, Float64, 1}, τ₂::Float64, market::MarketPostEstimation{Float64}, parameters::Parameters{Float64})
@ Main ./REPL[57]:1
[13] (::var"#67#68")(x::ForwardDiff.Dual{ForwardDiff.Tag{var"#67#68", Float64}, Float64, 1})
@ Main ./REPL[99]:1
[14] derivative(f::var"#67#68", x::Float64)
@ ForwardDiff ~/.julia/packages/ForwardDiff/UBbGT/src/derivative.jl:14
[15] top-level scope
@ REPL[99]:1
Some type information was truncated. Use `show(err)` to see complete types.
It seems like my function checks out the requirements in the documentation but maybe I’m missing something?
Thanks a lot!
Miguel.