Hello,
I am trying to use Ipopt in JuMP to solve a minimization problem with automatic differentiation.
I am aware that I need to specify the types of the inputs as Real
rather than Float64
but it’s not clear to me to what extent I must do so because I still get this error message:
MethodError: no method matching InvF(::Dict{String,Any}, ::Array{ForwardDiff.Dual{ForwardDiff.Tag{JuMP.var"#110#112"{typeof(objfunc)},Float64},Float64,3},3}, ::Array{ForwardDiff.Dual{ForwardDiff.Tag{JuMP.var"#110#112"{typeof(objfunc)},Float64},Float64,3},2}, ::Array{ForwardDiff.Dual{ForwardDiff.Tag{JuMP.var"#110#112"{typeof(objfunc)},Float64},Float64,3},3}, ::Array{ForwardDiff.Dual{ForwardDiff.Tag{JuMP.var"#110#112"{typeof(objfunc)},Float64},Float64,3},2}, ::Array{ForwardDiff.Dual{ForwardDiff.Tag{JuMP.var"#110#112"{typeof(objfunc)},Float64},Float64,3},3}, ::Array{ForwardDiff.Dual{ForwardDiff.Tag{JuMP.var"#110#112"{typeof(objfunc)},Float64},Float64,3},1})
I hope that the lines below suffice for this, if not I am happy to provide more details:
The minimization problem
function objfunc(x1::Real,x2::Real,x3::Real)
return sum(SSresid(mod_pars,x1,x2,x3).^2);
end
model = Model(with_optimizer(Ipopt.Optimizer, max_iter=100, print_level=0));
#adding variables
@variable(model, 0.8 <= x1 <= 1.2);
@variable(model, 95 <= x2 <= 100);
@variable(model, 1e-6 <= x3 <= 0.01);
#register function
register(model, :objfunc, 3, objfunc, autodiff=true);
@NLobjective(model, Min, objfunc(x1,x2,x3));
@time xsol_jump = JuMP.optimize!(model);
The functions called and the types specified:
function SSresid(mp::Dict,L::Real,K::Real,τE::Real)
#Step 1: solve HH problem
CUpol, CEpol, Us, Es, AUpol, AEpol = HHblock(mp,L,K,τE,false);
println(typeof(CUpol))
#Step 2: stationary distribution
DistE, DistU = InvF(mp,CEpol,CUpol,AEpol,AUpol,Es,Us);
#Step 3: clearing markets
res = MCblock(mp,DistE,DistU,CEpol,CUpol,L,K,τE);
return abs.(res);
end
function InvF(mp::Dict,CEpol::Array{Real}, CUpol::Array{Real},
AEpol::Array{Real}, AUpol::Array{Real}, Es::Array{Real},
Us::Array{Real}, tol=1e-6,maxiter=10000)
#initializing distributions (to have everyone with no assets)
DistE0 = zeros(Real,N,M,T); DistE0[1,1,1] = 0.92;
DistU0 = zeros(Real,N); DistU0[1] = 1-0.92;
DistE1 = copy(DistE0); DistU1 = copy(DistU0);
#iterating until convergence
itnum = 0; dist = Inf;
while dist>tol && itnum<maxiter
DistE1, DistU1 = updateDist(mp,DistE0, DistU0, CEpol, CUpol, AEpol, AUpol, Es, Us);
dist = max(maximum(abs.(DistE1.-DistE0)),maximum(abs.(DistU1.-DistU0)));
DistE0 = copy(DistE1);
DistU0 = copy(DistU1);
itnum +=1;
end
if itnum==1000
@warn "Reached maximum number of iterations, iteration did not converge"
end
return DistE1, DistU1;
end