23 #ifndef SELDON_COMPUTATION_OPTIMIZATION_NLOPT_HXX
24 #define SELDON_COMPUTATION_OPTIMIZATION_NLOPT_HXX
44 void mythrow(nlopt_result ret)
const
50 case NLOPT_OUT_OF_MEMORY:
52 "Nlopt failed to allocate the"
53 " requested storage space.");
54 case NLOPT_INVALID_ARGS:
56 case NLOPT_ROUNDOFF_LIMITED:
58 case NLOPT_FORCED_STOP:
73 nlopt_munge munge_destroy, munge_copy;
77 static void *free_myfunc_data(
void *p)
79 myfunc_data *d = (myfunc_data *) p;
82 if (d->f_data && d->munge_destroy)
83 d->munge_destroy(d->f_data);
90 static void *dup_myfunc_data(
void *p)
92 myfunc_data *d = (myfunc_data *) p;
96 if (d->f_data && d->munge_copy) {
97 f_data = d->munge_copy(d->f_data);
103 myfunc_data *dnew =
new myfunc_data;
107 dnew->f_data = f_data;
116 static double myfunc(
unsigned n,
const double *x,
double *grad,
119 myfunc_data *d =
reinterpret_cast<myfunc_data*
>(d_);
120 return d->f(n, x, grad, d->f_data);
124 static void mymfunc(
unsigned m,
double *result,
125 unsigned n,
const double *x,
126 double *grad,
void *d_)
128 myfunc_data *d =
reinterpret_cast<myfunc_data*
>(d_);
129 d->mf(m, result, n, x, grad, d->f_data);
137 static double myvfunc(
unsigned n,
const double *x,
double *grad,
140 myfunc_data *d =
reinterpret_cast<myfunc_data*
>(d_);
143 memcpy(xv.GetData(), x, n *
sizeof(
double));
145 double val=d->vf(xv, grad ? d->o->gradtmp : d->o->gradtmp0,
150 memcpy(grad, gradv.GetData(), n *
sizeof(
double));
158 if (xtmp.GetSize() !=
int(nlopt_get_dimension(o)))
168 nlopt_result forced_stop_reason;
173 SeldonOpt() : o(NULL), xtmp(0), gradtmp(0), gradtmp0(0),
174 last_result(nlopt::FAILURE), last_optf(HUGE_VAL),
175 forced_stop_reason(NLOPT_FORCED_STOP)
187 o(nlopt_create(nlopt_algorithm(a), n)),
188 xtmp(0), gradtmp(0), gradtmp0(0),
189 last_result(nlopt::FAILURE), last_optf(HUGE_VAL),
190 forced_stop_reason(NLOPT_FORCED_STOP)
194 "Nlopt failed to allocate the"
195 " requested storage space.");
196 nlopt_set_munge(o, free_myfunc_data, dup_myfunc_data);
202 xtmp(f.xtmp), gradtmp(f.gradtmp),
204 last_result(f.last_result),
205 last_optf(f.last_optf),
206 forced_stop_reason(f.forced_stop_reason)
210 "Nlopt failed to allocate the"
211 " requested storage space.");
223 "Nlopt failed to allocate the"
224 " requested storage space.");
227 last_result = f.last_result;
228 last_optf = f.last_optf;
229 forced_stop_reason = f.forced_stop_reason;
236 if (o &&
int(nlopt_get_dimension(o)) != x.GetSize())
238 "Seldon::Vector<double>& x,"
239 " double& opt_f)",
"Dimension mismatch.");
240 forced_stop_reason = NLOPT_FORCED_STOP;
242 nlopt_optimize(o, x.GetSize() == 0 ? NULL : x.GetData(),
244 last_result = result(ret);
246 if (ret == NLOPT_FORCED_STOP)
247 mythrow(forced_stop_reason);
256 last_result = optimize(x, last_optf);
261 result last_optimize_result()
const
267 double last_optimum_value()
const
273 algorithm get_algorithm()
const
277 "Uninitialized nlopt::SeldonOpt.");
278 return algorithm(nlopt_get_algorithm(o));
282 const char *get_algorithm_name()
const
286 "Uninitialized nlopt::SeldonOpt.");
287 return nlopt_algorithm_name(nlopt_get_algorithm(o));
291 unsigned get_dimension()
const
295 "Uninitialized nlopt::SeldonOpt.");
296 return nlopt_get_dimension(o);
300 void set_min_objective(func f,
void *f_data)
302 myfunc_data *d =
new myfunc_data;
305 "void *f_data)",
"Nlopt failed to allocate the"
306 " requested storage space.");
312 d->munge_destroy = d->munge_copy = NULL;
313 mythrow(nlopt_set_min_objective(o, myfunc, d));
317 void set_min_objective(svfunc vf,
void *f_data) {
318 myfunc_data *d =
new myfunc_data;
321 "void *f_data)",
"Nlopt failed to allocate the"
322 " requested storage space.");
328 d->munge_destroy = d->munge_copy = NULL;
329 mythrow(nlopt_set_min_objective(o, myvfunc, d));
334 void set_max_objective(func f,
void *f_data) {
335 myfunc_data *d =
new myfunc_data;
338 "void *f_data)",
"Nlopt failed to allocate the"
339 " requested storage space.");
345 d->munge_destroy = d->munge_copy = NULL;
346 mythrow(nlopt_set_max_objective(o, myfunc, d));
350 void set_max_objective(svfunc vf,
void *f_data)
352 myfunc_data *d =
new myfunc_data;
355 "void *f_data)",
"Nlopt failed to allocate the"
356 " requested storage space.");
362 d->munge_destroy = d->munge_copy = NULL;
363 mythrow(nlopt_set_max_objective(o, myvfunc, d));
368 void set_min_objective(func f,
void *f_data,
369 nlopt_munge md, nlopt_munge mc)
371 myfunc_data *d =
new myfunc_data;
374 "void *f_data)",
"Nlopt failed to allocate the"
375 " requested storage space.");
381 d->munge_destroy = md;
383 mythrow(nlopt_set_min_objective(o, myfunc, d));
387 void set_max_objective(func f,
void *f_data,
388 nlopt_munge md, nlopt_munge mc)
390 myfunc_data *d =
new myfunc_data;
393 "void *f_data)",
"Nlopt failed to allocate the"
394 " requested storage space.");
400 d->munge_destroy = md;
402 mythrow(nlopt_set_max_objective(o, myfunc, d));
406 void remove_inequality_constraints()
408 nlopt_result ret = nlopt_remove_inequality_constraints(o);
413 void add_inequality_constraint(func f,
void *f_data,
double tol = 0)
415 myfunc_data *d =
new myfunc_data;
418 "void *f_data, double tol = 0)",
419 "Nlopt failed to allocate the"
420 " requested storage space.");
426 d->munge_destroy = d->munge_copy = NULL;
427 mythrow(nlopt_add_inequality_constraint(o, myfunc, d, tol));
431 void add_inequality_constraint(svfunc vf,
void *f_data,
434 myfunc_data *d =
new myfunc_data;
437 "void *f_data, double tol = 0)",
438 "Nlopt failed to allocate the"
439 " requested storage space.");
445 d->munge_destroy = d->munge_copy = NULL;
446 mythrow(nlopt_add_inequality_constraint(o, myvfunc, d, tol));
451 void add_inequality_mconstraint(mfunc mf,
void *f_data,
454 myfunc_data *d =
new myfunc_data;
457 " void *f_data, double tol = 0)",
458 "Nlopt failed to allocate the"
459 " requested storage space.");
465 d->munge_destroy = d->munge_copy = NULL;
466 mythrow(nlopt_add_inequality_mconstraint(o, tol.GetSize(),
469 ? NULL : tol.GetData()));
473 void remove_equality_constraints()
475 nlopt_result ret = nlopt_remove_equality_constraints(o);
480 void add_equality_constraint(func f,
void *f_data,
double tol = 0)
482 myfunc_data *d =
new myfunc_data;
485 "void *f_data, double tol = 0)",
486 "Nlopt failed to allocate the"
487 " requested storage space.");
493 d->munge_destroy = d->munge_copy = NULL;
494 nlopt_add_equality_constraint(o, myfunc, d, tol);
495 mythrow(nlopt_add_equality_constraint(o, myfunc, d, tol));
499 void add_equality_constraint(svfunc vf,
void *f_data,
double tol = 0)
501 myfunc_data *d =
new myfunc_data;
504 "void *f_data, double tol = 0)",
505 "Nlopt failed to allocate the"
506 " requested storage space.");
512 d->munge_destroy = d->munge_copy = NULL;
513 mythrow(nlopt_add_equality_constraint(o, myvfunc, d, tol));
518 void add_equality_mconstraint(mfunc mf,
void *f_data,
521 myfunc_data *d =
new myfunc_data;
524 "void *f_data, double tol = 0)",
525 "Nlopt failed to allocate the"
526 " requested storage space.");
532 d->munge_destroy = d->munge_copy = NULL;
533 mythrow(nlopt_add_equality_mconstraint(o, tol.GetSize(),
536 NULL : tol.GetData()));
541 void add_inequality_constraint(func f,
void *f_data,
542 nlopt_munge md, nlopt_munge mc,
545 myfunc_data *d =
new myfunc_data;
548 "void *f_data, double tol = 0)",
549 "Nlopt failed to allocate the"
550 " requested storage space.");
556 d->munge_destroy = md;
558 mythrow(nlopt_add_inequality_constraint(o, myfunc, d, tol));
562 void add_equality_constraint(func f,
void *f_data,
563 nlopt_munge md, nlopt_munge mc,
566 myfunc_data *d =
new myfunc_data;
569 "void *f_data, double tol = 0)",
570 "Nlopt failed to allocate the"
571 " requested storage space.");
577 d->munge_destroy = md;
579 mythrow(nlopt_add_equality_constraint(o, myfunc, d, tol));
583 void add_inequality_mconstraint(mfunc mf,
void *f_data,
584 nlopt_munge md, nlopt_munge mc,
587 myfunc_data *d =
new myfunc_data;
590 " void *f_data, double tol = 0)",
591 "Nlopt failed to allocate the"
592 " requested storage space.");
598 d->munge_destroy = md; d->munge_copy = mc;
599 mythrow(nlopt_add_inequality_mconstraint(o, tol.GetSize(),
602 ? NULL : tol.GetData()));
606 void add_equality_mconstraint(mfunc mf,
void *f_data,
607 nlopt_munge md, nlopt_munge mc,
610 myfunc_data *d =
new myfunc_data;
614 "nlopt_munge md, nlopt_munge mc,"
615 "const Seldon::Vector<double> &tol)",
616 "Nlopt failed to allocate the"
617 " requested storage space.");
623 d->munge_destroy = md;
625 mythrow(nlopt_add_equality_mconstraint(o, tol.GetSize(), mymfunc,
626 d, tol.GetSize() == 0
632 #define SELDON_NLOPT_GETSET_VEC(name) \
633 void set_##name(double val) { \
634 mythrow(nlopt_set_##name##1(o, val)); \
636 void get_##name(Seldon::Vector<double> &v) const { \
637 if (o && int(nlopt_get_dimension(o)) != v.GetSize()) \
638 throw Seldon::WrongArgument("SeldonOpt::get_" #name "(Vector&)" \
640 "Nlopt invalid argument."); \
641 mythrow(nlopt_get_##name(o, v.GetSize() == 0 ? NULL : \
644 Seldon::Vector<double> get_##name() const { \
646 Seldon::Error("SeldonOpt::get_" #name "() const", \
647 "Uninitialized nlopt::SeldonOpt."); \
648 Seldon::Vector<double> v(nlopt_get_dimension(o)); \
652 void set_##name(const Seldon::Vector<double> &v) { \
653 if (o && int(nlopt_get_dimension(o)) != v.GetSize()) \
654 throw Seldon::WrongArgument("SeldonOpt::get_" #name "(Vector&)" \
656 "Nlopt invalid argument."); \
657 mythrow(nlopt_set_##name(o, v.GetSize() == 0 ? \
658 NULL : v.GetData())); \
661 SELDON_NLOPT_GETSET_VEC(lower_bounds)
662 SELDON_NLOPT_GETSET_VEC(upper_bounds)
665 #define SELDON_NLOPT_GETSET(T, name) \
666 T get_##name() const { \
668 Seldon::Error("SeldonOpt::get_" #name "() const", \
669 "Uninitialized nlopt::SeldonOpt."); \
670 return nlopt_get_##name(o); \
672 void set_##name(T name) { \
673 mythrow(nlopt_set_##name(o, name)); \
677 SELDON_NLOPT_GETSET(
double, stopval)
678 SELDON_NLOPT_GETSET(
double, ftol_rel)
679 SELDON_NLOPT_GETSET(
double, ftol_abs)
680 SELDON_NLOPT_GETSET(
double, xtol_rel)
681 SELDON_NLOPT_GETSET_VEC(xtol_abs)
682 SELDON_NLOPT_GETSET(
int, maxeval)
683 SELDON_NLOPT_GETSET(
double, maxtime)
685 SELDON_NLOPT_GETSET(
int, force_stop)
694 void set_local_optimizer(
const SeldonOpt &lo)
696 nlopt_result ret = nlopt_set_local_optimizer(o, lo.o);
701 SELDON_NLOPT_GETSET(
unsigned, population)
702 SELDON_NLOPT_GETSET_VEC(initial_step)
708 = nlopt_set_default_initial_step(o, x.GetSize() == 0 ?
717 if (o && (
int(nlopt_get_dimension(o)) != x.GetSize()
718 ||
int(nlopt_get_dimension(o)) != dx.GetSize()))
720 "Vector<double>& x, double& dx)",
721 "Dimension mismatch.");
722 nlopt_result ret = nlopt_get_initial_step(o, x.GetSize() == 0 ?
725 NULL : dx.GetData());
735 "(const Seldon::Vector<double>& x)",
736 "Uninitialized nlopt::SeldonOpt.");
738 get_initial_step(x, v);
744 #undef SELDON_NLOPT_GETSET
745 #undef SELDON_NLOPT_GETSET_VEC