提交 13e0f277 编写于 作者: S stevenj

add C++ style API

darcs-hash:20100405044954-c8de0-9c3737452317f7a0619d9acff42fd48a847ef894.gz
上级 f8909135
AM_CPPFLAGS = -I$(top_srcdir)/cdirect -I$(top_srcdir)/direct -I$(top_srcdir)/stogo -I$(top_srcdir)/praxis -I$(top_srcdir)/lbfgs -I$(top_srcdir)/luksan -I$(top_srcdir)/crs -I$(top_srcdir)/mlsl -I$(top_srcdir)/mma -I$(top_srcdir)/cobyla -I$(top_srcdir)/newuoa -I$(top_srcdir)/neldermead -I$(top_srcdir)/auglag -I$(top_srcdir)/bobyqa -I$(top_srcdir)/isres -I$(top_srcdir)/util
include_HEADERS = nlopt.h nlopt.f
include_HEADERS = nlopt.h nlopt.f nlopt.hpp
noinst_LTLIBRARIES = libapi.la
dist_man_MANS = nlopt_minimize.3 nlopt_minimize_constrained.3
libapi_la_SOURCES = general.c options.c optimize.c deprecated.c \
nlopt-internal.h nlopt.h f77api.c f77funcs.h
BUILT_SOURCES = nlopt.f
BUILT_SOURCES = nlopt.f nlopt.hpp
EXTRA_DIST = nlopt-in.hpp
if MAINTAINER_MODE
# convert constants to F77 parameter statements
# convert constants to F77 parameter statements & C++
nlopt.f: nlopt.h
rm -f $@
(i=0; egrep 'NLOPT_[LG][DN]' $(srcdir)/nlopt.h | tr -d ' =0,' | while read n; do echo " integer $$n"; echo " parameter ($$n=$$i)"; i=`expr $$i + 1`; done; tail -n +`grep -n enum $(srcdir)/nlopt.h |cut -d: -f1 |tail -n 1` $(srcdir)/nlopt.h | grep NLOPT | grep -v NLOPT_EXTERN | cut -d, -f1 | tr -d ' ' | perl -pe 's/([A-Za-z0-9_]+)=([-+0-9]+)/ integer \1\n parameter (\1=\2)/') > $@
nlopt.hpp: nlopt.h nlopt-in.hpp
rm -f $@
(n=`grep -n GEN_ENUMS_HERE nlopt-in.hpp | cut -d: -f1`; head -n $$n $(srcdir)/nlopt-in.hpp; echo " enum algorithm {"; egrep 'NLOPT_[LG][DN]|NLOPT_NUM_ALGORITHMS' $(srcdir)/nlopt.h | sed 's/NLOPT_//g'; echo " };"; echo " enum result {"; egrep 'NLOPT_[A-Z_]* =' $(srcdir)/nlopt.h | egrep -v 'NLOPT_[LG][DN]' | sed 's/NLOPT_//g'; echo " };"; tail -n +$$n $(srcdir)/nlopt-in.hpp) > $@
endif
/* Copyright (c) 2007-2009 Massachusetts Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
// C++ style wrapper around NLopt API
// nlopt.hpp is AUTOMATICALLY GENERATED from nlopt-in.hpp - edit the latter!
#include <nlopt.h>
#include <vector>
#include <stdexcept>
#include <new>
// convenience overloading for below (not in nlopt:: since has nlopt_ prefix)
inline nlopt_result nlopt_get_initial_step(const nlopt_opt opt, double *dx) {
return nlopt_get_initial_step(opt, (const double *) NULL, dx);
}
namespace nlopt {
//////////////////////////////////////////////////////////////////////
// nlopt::* namespace versions of the C enumerated types
// AUTOMATICALLY GENERATED, DO NOT EDIT
// GEN_ENUMS_HERE
//////////////////////////////////////////////////////////////////////
// virtual base class for objective function and constraints:
class func {
public:
// should return function value, and set grad to gradient
// (x and grad are length n)
virtual double operator()(int n, const double *x, double *grad) = 0;
// should return function value (x is length n)
virtual double operator()(int n, const double *x) = 0;
};
// (Note: it is inefficient to use std::vector<double> for the arguments,
// since that would require a copy to be made of NLopt's double* data.)
//////////////////////////////////////////////////////////////////////
class opt {
private:
nlopt_opt o;
void mythrow(nlopt_result ret) const {
switch (ret) {
case NLOPT_FAILURE: throw std::runtime_error("nlopt failure");
case NLOPT_OUT_OF_MEMORY: throw std::bad_alloc();
case NLOPT_INVALID_ARGS: throw std::invalid_argument("nlopt");
case NLOPT_ROUNDOFF_LIMITED: throw std::runtime_error("nlopt roundoff");
default: break;
}
}
// nlopt_func wrapper around C++ "functional"
static double myfunc(int n, const double *x, double *grad, void *f_) {
func *f = reinterpret_cast<func*>(f_);
return grad ? (*f)(n, x, grad) : (*f)(n, x);
}
public:
// Constructors etc.
opt() : o(NULL) {}
opt(nlopt_algorithm a, int n) : o(nlopt_create(a, n)) {
if (!o) throw std::bad_alloc();
}
opt(algorithm a, int n) : o(nlopt_create(nlopt_algorithm(a), n)) {
if (!o) throw std::bad_alloc();
}
opt(const nlopt_opt o0) : o(nlopt_copy(o0)) {
if (o0 && !o) throw std::bad_alloc();
}
~opt() { nlopt_destroy(o); }
opt(const opt& from) : o(nlopt_copy(from.o)) {
if (from.o && !o) throw std::bad_alloc();
}
opt& operator=(opt const& f) {
if (this == &f) return *this; // self-assignment
nlopt_destroy(o);
o = nlopt_copy(f.o);
if (f.o && !o) throw std::bad_alloc();
return *this;
}
// Do the optimization:
result optimize(double *x, double &opt_f) {
nlopt_result ret = nlopt_optimize(o, x, &opt_f);
mythrow(ret);
return result(ret);
}
result optimize(std::vector<double> &x, double &opt_f) {
return optimize(x.empty() ? NULL : &x[0], opt_f);
}
// accessors:
algorithm get_algorithm() const {
if (!o) throw std::invalid_argument("uninitialized nlopt::opt");
return algorithm(nlopt_get_algorithm(o));
}
int get_dimension() const {
if (!o) throw std::invalid_argument("uninitialized nlopt::opt");
return nlopt_get_dimension(o);
}
// Set the objective function
void set_min_objective(nlopt_func f, void *f_data) {
nlopt_result ret = nlopt_set_min_objective(o, f, f_data);
mythrow(ret);
}
void set_min_objective(func *f) {
set_min_objective(myfunc, f);
}
// Nonlinear constraints:
void remove_inequality_constraints(void) {
nlopt_result ret = nlopt_remove_inequality_constraints(o);
mythrow(ret);
}
void add_inequality_constraint(nlopt_func f, void *f_data, double tol=0) {
nlopt_result ret = nlopt_add_inequality_constraint(o, f, f_data, tol);
mythrow(ret);
}
void add_inequality_constraint(func *f, double tol=0) {
add_inequality_constraint(myfunc, f, tol);
}
void remove_equality_constraints(void) {
nlopt_result ret = nlopt_remove_equality_constraints(o);
mythrow(ret);
}
void add_equality_constraint(nlopt_func f, void *f_data, double tol=0) {
nlopt_result ret = nlopt_add_equality_constraint(o, f, f_data, tol);
mythrow(ret);
}
void add_equality_constraint(func *f, double tol=0) {
add_equality_constraint(myfunc, f, tol);
}
#define NLOPT_GETSET_VEC(name) \
void get_##name(double *v) const { \
nlopt_result ret = nlopt_get_##name(o, v); \
mythrow(ret); \
} \
void set_##name(const double *v) { \
nlopt_result ret = nlopt_set_##name(o, v); \
mythrow(ret); \
} \
void set_##name(double val) { \
nlopt_result ret = nlopt_set_##name##1(o, val); \
mythrow(ret); \
} \
void get_##name(std::vector<double> &v) const { \
if (o && unsigned(nlopt_get_dimension(o)) != v.size()) \
throw std::invalid_argument("dimension mismatch"); \
get_##name(v.empty() ? NULL : &v[0]); \
} \
std::vector<double> get_##name(void) const { \
if (!o) throw std::invalid_argument("uninitialized nlopt::opt"); \
std::vector<double> v(unsigned(nlopt_get_dimension(o))); \
get_##name(v); \
return v; \
} \
void set_##name(const std::vector<double> &v) { \
if (o && unsigned(nlopt_get_dimension(o)) != v.size()) \
throw std::invalid_argument("dimension mismatch"); \
set_##name(v.empty() ? NULL : &v[0]); \
}
NLOPT_GETSET_VEC(lower_bounds)
NLOPT_GETSET_VEC(upper_bounds)
// stopping criteria:
#define NLOPT_GETSET(T, name) \
T get_##name() const { \
if (!o) throw std::invalid_argument("uninitialized nlopt::opt"); \
return nlopt_get_##name(o); \
} \
void set_##name(T name) { \
nlopt_result ret = nlopt_set_##name(o, name); \
mythrow(ret); \
}
NLOPT_GETSET(double, stopval)
NLOPT_GETSET(double, ftol_rel)
NLOPT_GETSET(double, ftol_abs)
NLOPT_GETSET(double, xtol_rel)
NLOPT_GETSET_VEC(xtol_abs)
NLOPT_GETSET(int, maxeval)
NLOPT_GETSET(double, maxtime)
// algorithm-specific parameters:
void set_local_optimizer(const nlopt_opt lo) {
nlopt_result ret = nlopt_set_local_optimizer(o, lo);
mythrow(ret);
}
void set_local_optimizer(const opt &lo) {
set_local_optimizer(lo.o);
}
NLOPT_GETSET(int, population)
NLOPT_GETSET_VEC(initial_step)
void set_default_initial_step(const double *x) {
nlopt_result ret = nlopt_set_default_initial_step(o, x);
mythrow(ret);
}
void set_default_initial_step(const std::vector<double> &x) {
set_default_initial_step(x.empty() ? NULL : &x[0]);
}
void get_initial_step(const double *x, double *dx) const {
nlopt_result ret = nlopt_get_initial_step(o, x, dx);
mythrow(ret);
}
void get_initial_step(const std::vector<double> &x, std::vector<double> &dx) const {
if (o && (unsigned(nlopt_get_dimension(o)) != x.size()
|| unsigned(nlopt_get_dimension(o)) != dx.size()))
throw std::invalid_argument("dimension mismatch");
get_initial_step(x.empty() ? NULL : &x[0],
dx.empty() ? NULL : &dx[0]);
}
std::vector<double> get_initial_step(const std::vector<double> &x) const {
if (!o) throw std::invalid_argument("uninitialized nlopt::opt");
std::vector<double> v(unsigned(nlopt_get_dimension(o)));
get_initial_step(x, v);
return v;
}
};
//////////////////////////////////////////////////////////////////////
} // namespace nlopt
......@@ -182,11 +182,13 @@ NLOPT_EXTERN int nlopt_get_dimension(const nlopt_opt opt);
NLOPT_EXTERN nlopt_result nlopt_set_lower_bounds(nlopt_opt opt,
const double *lb);
NLOPT_EXTERN nlopt_result nlopt_set_lower_bounds1(nlopt_opt opt, double lb);
NLOPT_EXTERN void nlopt_get_lower_bounds(const nlopt_opt opt, double *lb);
NLOPT_EXTERN nlopt_result nlopt_get_lower_bounds(const nlopt_opt opt,
double *lb);
NLOPT_EXTERN nlopt_result nlopt_set_upper_bounds(nlopt_opt opt,
const double *ub);
NLOPT_EXTERN nlopt_result nlopt_set_upper_bounds1(nlopt_opt opt, double ub);
NLOPT_EXTERN void nlopt_get_upper_bounds(const nlopt_opt opt, double *ub);
NLOPT_EXTERN nlopt_result nlopt_get_upper_bounds(const nlopt_opt opt,
double *ub);
NLOPT_EXTERN nlopt_result nlopt_remove_inequality_constraints(nlopt_opt opt);
NLOPT_EXTERN nlopt_result nlopt_add_inequality_constraint(nlopt_opt opt,
......@@ -214,7 +216,8 @@ NLOPT_EXTERN nlopt_result nlopt_set_xtol_rel(nlopt_opt opt, double tol);
NLOPT_EXTERN double nlopt_get_xtol_rel(const nlopt_opt opt);
NLOPT_EXTERN nlopt_result nlopt_set_xtol_abs1(nlopt_opt opt, double tol);
NLOPT_EXTERN nlopt_result nlopt_set_xtol_abs(nlopt_opt opt, const double *tol);
NLOPT_EXTERN void nlopt_get_xtol_abs(const nlopt_opt opt, double *tol);
NLOPT_EXTERN nlopt_result nlopt_get_xtol_abs(const nlopt_opt opt,
double *tol);
NLOPT_EXTERN nlopt_result nlopt_set_maxeval(nlopt_opt opt, int maxeval);
NLOPT_EXTERN int nlopt_get_maxeval(nlopt_opt opt);
......
......@@ -169,7 +169,7 @@ nlopt_result nlopt_set_min_objective(nlopt_opt opt, nlopt_func f, void *f_data)
nlopt_result nlopt_set_lower_bounds(nlopt_opt opt, const double *lb)
{
if (opt) {
if (opt && (opt->n == 0 || lb)) {
memcpy(opt->lb, lb, sizeof(double) * U(opt->n));
return NLOPT_SUCCESS;
}
......@@ -187,9 +187,18 @@ nlopt_result nlopt_set_lower_bounds1(nlopt_opt opt, double lb)
return NLOPT_INVALID_ARGS;
}
nlopt_result nlopt_get_lower_bounds(nlopt_opt opt, double *lb)
{
if (opt && (opt->n == 0 || lb)) {
memcpy(lb, opt->lb, sizeof(double) * U(opt->n));
return NLOPT_SUCCESS;
}
return NLOPT_INVALID_ARGS;
}
nlopt_result nlopt_set_upper_bounds(nlopt_opt opt, const double *ub)
{
if (opt) {
if (opt && (opt->n == 0 || ub)) {
memcpy(opt->ub, ub, sizeof(double) * U(opt->n));
return NLOPT_SUCCESS;
}
......@@ -207,6 +216,15 @@ nlopt_result nlopt_set_upper_bounds1(nlopt_opt opt, double ub)
return NLOPT_INVALID_ARGS;
}
nlopt_result nlopt_get_upper_bounds(nlopt_opt opt, double *ub)
{
if (opt && (opt->n == 0 || ub)) {
memcpy(ub, opt->ub, sizeof(double) * U(opt->n));
return NLOPT_SUCCESS;
}
return NLOPT_INVALID_ARGS;
}
/*************************************************************************/
#define AUGLAG_ALG(a) ((a) == NLOPT_LN_AUGLAG || \
......@@ -333,9 +351,10 @@ nlopt_result nlopt_set_xtol_abs1(nlopt_opt opt, const double xtol_abs)
return NLOPT_INVALID_ARGS;
}
void nlopt_get_xtol_abs(const nlopt_opt opt, double *xtol_abs)
nlopt_result nlopt_get_xtol_abs(const nlopt_opt opt, double *xtol_abs)
{
memcpy(xtol_abs, opt->xtol_abs, opt->n & sizeof(double));
return NLOPT_SUCCESS;
}
GETSET(maxeval, int, maxeval)
......@@ -397,15 +416,17 @@ nlopt_result nlopt_set_initial_step(nlopt_opt opt, const double *dx)
return NLOPT_SUCCESS;
}
nlopt_result nlopt_get_initial_step(nlopt_opt opt, const double *x, double *dx)
nlopt_result nlopt_get_initial_step(const nlopt_opt opt, const double *x,
double *dx)
{
if (!opt) return NLOPT_INVALID_ARGS;
if (!opt->n) return NLOPT_SUCCESS;
if (!opt->dx) {
nlopt_result ret = nlopt_set_default_initial_step(opt, x);
nlopt_opt o = (nlopt_opt) opt; /* discard const temporarily */
nlopt_result ret = nlopt_set_default_initial_step(o, x);
if (ret != NLOPT_SUCCESS) return ret;
memcpy(dx, opt->dx, sizeof(double) * U(opt->n));
free(opt->dx); opt->dx = NULL; /* don't save, since x-dependent */
memcpy(dx, o->dx, sizeof(double) * U(opt->n));
free(o->dx); o->dx = NULL; /* don't save, since x-dependent */
}
else
memcpy(dx, opt->dx, sizeof(double) * U(opt->n));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册