Hello,
With much of your help, I am finally able to write a functioning code file. However, I was not able to find enough resources online for tuning the performance of Ipopt in JuMP.
Now I would like to seek your advice on how to achieve the following goals (or to find resources for achieving these goals):
- optimize my code for better performance
- incorporate codes that speed up the optimization process
- obtain multiple solutions if possible
- export optimal solution(s) to .csv file.
Below is my MWE (@odow I gave it a try!!):
using CSV, DataFrames, StatsBase
using JuMP, Ipopt, Random
# read data
const df = DataFrame(owner = ["b","n","s"],
b_ln_prod = [0.5,0.25,0.1],
s_ln_prod=[0.1,0.25,0.5],
b_delta =[1,2,3],
s_delta=[3,2,1]);
const delta_idx = [1;2;3];
# data dimensions
const n = nrow(df);
const n_delta = length(delta_idx);
const n_parameter = n_delta + 5;
function mle()
# set model parameters
Random.seed!(1234)
model = Model(Ipopt.Optimizer)
#set_optimizer_attribute(model, "max_cpu_time", 60.0)
set_optimizer_attribute(model, "print_level", 0)
set_optimizer_attribute(model, "max_iter", 100)
set_optimizer_attribute(model, "tol", 1e-4)
set_time_limit_sec(model, 60.0)
# add variables
@variables(model, begin
0<=ρ<=1, (start=0.5, base_name = "rho")
0<=α<=1, (start=0.6, base_name = "alpha")
0<=fB<=10, (start = 0.0, base_name = "fB")
0<=fS<=10, (start = 0.0, base_name = "fS")
0<=fO<=10, (start = 0.0, base_name = "fO")
0<=δ[i=1:n_delta]<=1, (start=0.5, base_name = "delta$i")
end)
# constraint
@constraint(model, con, α - ρ >= 0.001)
# objective
function likelihood(ρ::T, α::T, fB::T, fS::T, fO::T, δ::T...) where {T}
sum = zero(T);
for i = 1:n
k = df.owner[i];
θb = df.b_ln_prod[i];
θs = df.s_ln_prod[i];
b_idx = df.b_delta[i];
s_idx = df.s_delta[i];
δb = δ[b_idx];
δs = δ[s_idx];
βB = 0.5 + 0.5*δb^α;
βS = 0.5 - 0.5*δs^α;
βO = 0.5;
ψB = α^(α/(1-α))*((1-α*βB)*(βB*θb)^(ρ/(1-ρ))+(1-α*(1-βB))*((1-βB)*θs)^(ρ/(1-ρ)))/((βB*θb)^(ρ/(1-ρ))+((1-βB)*θs)^(ρ/(1-ρ)))^((ρ-α)/(ρ*(1-α)));
ψS = α^(α/(1-α))*((1-α*βS)*(βS*θb)^(ρ/(1-ρ))+(1-α*(1-βS))*((1-βS)*θs)^(ρ/(1-ρ)))/((βS*θb)^(ρ/(1-ρ))+((1-βS)*θs)^(ρ/(1-ρ)))^((ρ-α)/(ρ*(1-α)));
ψO = α^(α/(1-α))*((1-α*βO)*(βO*θb)^(ρ/(1-ρ))+(1-α*(1-βO))*((1-βO)*θs)^(ρ/(1-ρ)))/((βO*θb)^(ρ/(1-ρ))+((1-βO)*θs)^(ρ/(1-ρ)))^((ρ-α)/(ρ*(1-α)));
temp = ((k=="b" ? 1 : 0)*(exp(ψB-fB))/(exp(ψB-fB)+exp(ψS-fS)+exp(ψO-fO))
+(k=="s" ? 1 : 0)*(exp(ψS-fS))/(exp(ψB-fB)+exp(ψS-fS)+exp(ψO-fO))
+(k=="n" ? 1 : 0)*(exp(ψO-fO))/(exp(ψB-fB)+exp(ψS-fS)+exp(ψO-fO)))
sum = sum + log(temp)
end
return -sum
end
register(model, :likelihood, n_parameter, likelihood; autodiff = true)
@NLobjective(model, Min, likelihood(ρ,α,fB,fS,fO,δ...))
# optimization
JuMP.optimize!(model)
# display results
if termination_status(model) == MOI.OPTIMAL
println("Solution is optimal")
elseif termination_status(model) == MOI.TIME_LIMIT && has_values(model)
println("Solution is suboptimal due to a time limit, but a primal solution is available")
else
error("The model was not solved correctly.")
end
println(" objective value = ", objective_value(model))
end