Skip to content

LD_MMA unexpected solution for simple problem #270

@OskarBergmann

Description

@OskarBergmann

The following code is supposed to minimise sqrt(x[2]) s.t. x[1]>2, x[2]>a, initial guess [1.234, 5.678]. (There are infinitely many solutions).

With a = 8, a correct solution is found - FTOL_REACHED
With a = 6, the solution is wrong (x[2]opt = 6.07, when it should be 6) - MAXEVAL_REACHED
With a = 5, the solution is wrong (x[2]opt = 5.678, when it should be 5) - FTOL_REACHED

Note: when I exchange LD_MMA with LD_SLSQP, the correct solution is always found

using NLopt
import ForwardDiff

function autodiff(f::Function)
    function nlopt_fn(x::Vector, grad::Vector)
        if length(grad) > 0 # modify grad in place if it is passed
           ForwardDiff.gradient!(grad, f, x)
        end
        return f(x) # return f(x) in all cases
    end
end # return the function nlopt_fn

function my_objective_fn(x::Vector, grad::Vector)
           if length(grad) > 0
               grad[1] = 0
               grad[2] = 0.5 / sqrt(x[2])
           end
           return sqrt(x[2])
end

function con1(x::Vector)
    return 2-x[1]
end

function con2(x::Vector,a)
    return a-x[2]
end


opt = NLopt.Opt(:LD_MMA, 2)
NLopt.lower_bounds!(opt, [-Inf, 0.5])
NLopt.xtol_rel!(opt, 1e-8)
NLopt.ftol_abs!(opt, 1e-8)
NLopt.min_objective!(opt, my_objective_fn)
NLopt.maxeval!(opt, 500)

NLopt.inequality_constraint!(opt, autodiff(con1), 1e-8)
NLopt.inequality_constraint!(opt, autodiff(con2), 1e-8)

NLopt.inequality_constraint!(opt, autodiff(con1), 1e-8)
a = 5.5
NLopt.inequality_constraint!(opt, autodiff(x -> con2(x,a)), 1e-8)

min_f, min_x, ret = NLopt.optimize(opt, [1.234, 5.678])

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions