Skip to content

Support generic (double-sided) inequality constraints #540

Open
@charelstoncrabb

Description

The current interface requires (according to the documentation):

a nonlinear inequality constraint of the form $f_c(x) \leq 0$

A very common pattern in constrained optimization is the more general setup of $l_c \leq f_c(x) \leq u_c$. Providing this type of interface seems much more aligned with what a user actually wants to do, and would take a lot of burden off the user to specialize implementations for each type of (upper/lower) constraint.

If I have an existing constraint function $f_c$ (as a part of some external shared runtime e.g.), this requirement significantly complicates wiring into nlopt.

It seems like the logic could be wrapped in an interface something like:

nlopt::opt::add_inequality_constraint(nlopt::func fc, void* userdata, double lc, double uc, double tol)

Somewhat related to why it makes it an unnecessary pain for the user is the lack of support for lambdas (though a separate issue itself).

If lambdas were supported, this would be much simpler, e.g.

opt.add_inequality_constraint(
    [&](unsigned n, const double*x, double*grad, void* data){
        return fc(n,x,grad,data) - ub;
    },
    1.e-8
)
opt.add_inequality_constraint(
    [&](unsigned n, const double*x, double*grad, void* data){
        double ans = lb - fc(n,x,grad,data);
        if (grad) for (unsigned i = 0; i < n; i++) grad[i]*=-1.;
        return ans;
    },
    1.e-8
)

Either the overloaded add_inequality_constraint method above, or overloaded methods

nlopt::opt::add_<objective/constraint/etc> ( std::function<double(unsigned, const double*, double*, void*)> nlopt_fun, ... );

would be fantastic 😁

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions