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.