Skip to content

Vector-valued inequality constraints not working as expected #256

@nklb

Description

@nklb

I struggle making vector-valued constraints work. Here is a modification of the example in the README using vector-valued constraints as explained in the later part of the README.

using NLopt
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 my_constraint_fn(x::Vector, grad::Vector, a, b)
    if length(grad) > 0
        grad[1] = 3 * a * (a * x[1] + b)^2
        grad[2] = -1
    end
    return (a * x[1] + b)^3 - x[2]
end

function constraints(result::Vector{Float64}, x::Vector{Float64},
                     grad::Matrix{Float64})
    g1 = [0., 0.]
    g2 = [0., 0.]
    f1 = my_constraint_fn(x, g1, 2, 0)
    f2 = my_constraint_fn(x, g2, -1, 1)
    if length(grad) > 0
        grad = vcat(transpose(g1), transpose(g2))
    end
    result[1] = f1
    result[2] = f2
    #@show result
    return nothing
end

        
opt = NLopt.Opt(:LD_MMA, 2)
NLopt.lower_bounds!(opt, [-Inf, 0.0])
NLopt.xtol_rel!(opt, 1e-6)
NLopt.min_objective!(opt, my_objective_fn)
# NLopt.inequality_constraint!(opt, (x, g) -> my_constraint_fn(x, g, 2, 0), 1e-8)
# NLopt.inequality_constraint!(opt, (x, g) -> my_constraint_fn(x, g, -1, 1), 1e-8)
NLopt.inequality_constraint!(opt, constraints, 1e-8 * ones(2))
min_f, min_x, ret = NLopt.optimize(opt, [1.234, 5.678])
num_evals = NLopt.numevals(opt)
println(
    """
    objective value       : $min_f
    solution              : $min_x
    solution status       : $ret
    # function evaluation : $num_evals
    """
)

Running this gives me

objective value       : 2.382855429941145
solution              : [1.234, 5.678]
solution status       : XTOL_REACHED
# function evaluation : 2

while this is expected (and the result of using two separate constraints):

objective value       : 0.5443310477213124
solution              : [0.3333333342139688, 0.29629628951338166]
solution status       : XTOL_REACHED
# function evaluation : 18

If I output the constraints running the code I can also see that the first entry is positive. Am I doing something wrong here? I use Julia version 1.11.5.

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