I have a MINLP that involves error cdf and pdf of normal distribution in the objective function. I used erf from SpecialFunctions it is not supported. I also tried approximations of erf, even that does not work. I used Knitro (using AmplNLWriter) for my experiments, and it does not support erf. Any suggestions on which solver or another formulation for the model will be helpful.
The code with errors is as follows:
begin
model = Model(() -> AmplNLWriter.Optimizer("/home/simran/ampl_linux-intel64/mglob"))
# model = Model(Ipopt.Optimizer)
# register(model, :er, 1, er, autodiff=true)
@variable(model, n[1:n_types, 1:n_slots].>=0,integer=true)
@variable(model, α[1:n_slots].≥ 0)
@expression(model, mu, μ'*n[:,1])
@expression(model, A1, 1/√(2π)*(α[1]*exp(-(120-mu).^2/(2*α[1]^2))) )
@NLexpression(model, A2, (mu-120)*(1-(0.5(1+er((120-mu)/α[1])))))
# @NLexpression(model, A2, 0.5*(mu-120)*err( (mu-120)/2/α[1] ) )
# @NLexpression(model, A2, (mu - 120) * (1 - 0.5 * (1 + erf((120 - mu) / α[1]))))
@NLobjective(model, Min, A1 + A2)
@constraint(model, sum(n, dims=2) .≤ n_pats)
@constraint(model, μ'*n[:,1] + c*α[1] ≥ 120)
@constraint(model, σ'.^2*n[:,1] .- α[1]^2 .≤ 0)
optimize!(model)
@show value.(n)
@show value.(A1)
@show value.(A2)
end
The er function is:
function er(x)
sign_x = x >= 0 ? 1 : -1
abs_x = abs(x)
# constants
a1 = 0.254829592
a2 = -0.284496736
a3 = 1.421413741
a4 = -1.453152027
a5 = 1.061405429
p = 0.3275911
# A&S formula 7.1.26
t = 1.0 / (1.0 + p * abs_x)
y = 1.0 - (((((a5 * t + a4) * t + a3) * t + a2) * t + a1) * t) * exp(-abs_x * abs_x)
return sign_x * y # erf(-x) = -erf(x)
end
MathOptInterface.UnsupportedNonlinearOperator: The nonlinear operator :er is not supported by the model. and erf results in same error.