I'm trying to use NLopt library for an optimization problem in c++. The docs indicate the input function to be optimized should look like this:
double myfunc(const std::vector<double> &x, std::vector<double> &grad, void *my_func_data);
I don't understand how to use the void *my_func_data argument, which accepts additional data necessary for the function to be optimized.
The docs show the example to create your function to be optimized here:
int count = 0;
double myfunc(int n, const double *x, double *grad, void *my_func_data)
{
++count;
if (grad) {
grad[0] = 0.0;
grad[1] = 0.5 / sqrt(x[1]);
}
return sqrt(x[1]);
}
However, they do not use the void *my_func_data argument.
I want to use this argument, because I have additional data I'll need to pass in. My function looks like this:
double myfunc(const std::vector<double> &x, std::vector<double> &grad, void *my_func_data)
{
if (!grad.empty()) {
grad[0] = 0.0;
grad[1] = 0.5 / sqrt(x[1]);
}
my_func_data;
double xM = 1.;
double yM = 1.;
double xF = 1.;
double yF = 1.;
double theta = 2.;
double tx = 1.4;
double ty = 0.4;
return sqrt(
pow(abs(xF - (cos(theta)*xM) - (sin(theta)*yM) + tx), 2) + \
pow(abs(yF - (sin(theta)*xM) + (cos(theta)*yM) + ty), 2)
);
}
However, I want these variables:
double xM = 1.;
double yM = 1.;
double xF = 1.;
double yF = 1.;
to be passed into the function using the my_func_data argument, but I don't understand how to format a void input argument. Please advise.
Docs: https://nlopt.readthedocs.io/en/latest/NLopt_Tutorial/#example-in-c
xM, yM are x,y coordinates stored in a vector of Point2f. xF, yF are also x,y coordinates stored in a vector of Point2f.
EDIT
Now my code is this:
struct ExtraData
{
double xM = 1.;
double yM = 1.;
double xF = 1.;
double yF = 1.;
};
double myfunc(const std::vector<double> &x, std::vector<double> &grad, void *my_func_data);
double myfunc(const std::vector<double> &x, std::vector<double> &grad, void *my_func_data)
{
if (!grad.empty()) {
grad[0] = 0.0;
grad[1] = 0.5 / sqrt(x[1]);
}
ExtraData* extraData = static_cast<ExtraData*>(my_func_data);
double xM = extraData -> xM;
double yM = extraData -> yM;
double xF = extraData -> xF;
double yF = extraData -> yF;
// double xM = 1.;
// double yM = 1.;
// double xF = 1.;
// double yF = 1.;
double theta = 2.;
double tx = 1.4;
double ty = 0.4;
return sqrt(
pow(abs(xF - (cos(theta)*xM) - (sin(theta)*yM) + tx), 2) + \
pow(abs(yF - (sin(theta)*xM) + (cos(theta)*yM) + ty), 2)
);
}
int main()
{
nlopt::opt opt(nlopt::LD_SLSQP, 2);
std::vector<double> lb(2);
lb[0] = -HUGE_VAL; //HUGE_VAL is a C++ constant
lb[1] = 0;
opt.set_lower_bounds(lb);
opt.set_min_objective(myfunc, NULL);
double data[4] = {2,0,-1,1}; //use one dimensional array
std::vector<double> tol_constraint(2);
tol_constraint[0] = 1e-8;
tol_constraint[1] = 1e-8;
opt.add_inequality_mconstraint(multi_constraint, data, tol_constraint);
opt.set_xtol_rel(1e-4);
std::vector<double> x(2);
x[0] = 1.234;
x[1] = 5.678;
double minf;
nlopt::result result = opt.optimize(x, minf);
std::cout << "The result is" << std::endl;
std::cout << result << std::endl;
std::cout << "Minimal function value " << minf << std::endl;
}
Which compiles, but when I run it, I get:
Segmentation fault: 11