c++c++17nonlinear-optimizationnlopt

NLOpt vector-valued inequality constraint function signature in C++


I'm working on implementing a nonlinear optimization problem using the NLOpt library, and I'm having some trouble defining a vector-valued inequality constraint using the C++ interface.

The NLOpt docs seem to indicate that they support defining cost functions and both equality and inequality constraint functions that accept std::vector<double>& arguments, as opposed to pointers to arrays (double*). See the myvfunc() and myvconstraint() signatures in the "Example in C++" section of the following link.

So far, I've had success writing both my cost function and my equality constraint with the following function signatures:

double cost_fcn(const std::vector<double>& x, std::vector<double>& grad, void* data);
double eq_constraint(const std::vector<double>& x, std::vector<double>& grad, void* data);

The NLOpt docs also describe support for vector-valued equality and inequality constraints. But the function signatures (shown below) that they provide are in the C format (using array pointers).

void ineq_constraint(
   unsigned m, double *result, unsigned n, const double* x, double* grad, void* f_data);

where m is the dimension of the constraint vector and n is the dimension of the parameter space.

It's not clear from the docs that the C++-style function signature is supported for vector-valued constraints, but I've tried to implement the following and it's not working:

void ineq_constraint(
   std::vector<double>& result, const std::vector<double>& x, std::vector<double>& grad, void* data);

At this point, I'll switch to trying to use the C-style function signature, but it would be nice to get a definitive answer as to whether or not NLOpt currently supports the C++ style function signature for vector-valued constraints.


Solution

  • After taking a closer look at the NLOpt C header (nlopt.h), there are 2 valid function signature types that NLOpt defines: nlopt_func and nlopt_mfunc.

    typedef double (*nlopt_func) (unsigned n,
                                  const double *x,
                                  double *gradient, /* NULL if not needed */
                                  void *func_data);
    
    typedef void (*nlopt_mfunc) (unsigned m,
                                 double *result,
                                 unsigned n,
                                 const double *x,
                                 double *gradient, /* NULL if not needed */
                                 void *func_data);
    

    The NLOpt C++ header (nlopt.hpp) adds a third valid function signature type (vfunc) and provides aliases (func and mfunc) for the above two types.

    typedef nlopt_func func;   // nlopt::func synoynm
    typedef nlopt_mfunc mfunc; // nlopt::mfunc synoynm
    
    typedef double (*vfunc)(const std::vector<double> &x,
                            std::vector<double> &grad,
                            void *data);
    

    opt::set_min_objective and the scalar-valued constraint functions ( opt::add_equality_constraint and opt::add_inequality_constraint) are overloaded for both the func and vfunc types, i.e. both C and C++-style objective and scalar-valued constraint functions are supported.

    But when it comes to vector-valued constraint functions, the vfunc (C++-style) function type is not supported. Only the mfunc type is currently supported (nlopt.hpp:434).

    It might make a nice addition to NLOpt to add support for the C++-style function signature (vfunc) for vector-valued constraint functions.