O
2scl reimplements the Open Optimization Library (OOL) available at
http://ool.sourceforge.net. The associated classes allow constrained minimization when the constraint can be expressed as a hyper-cubic constraint on all of the independent variables. The routines have been rewritten and reformatted for C++ in order to facilitate the use of member functions and user-defined vector types as arguments. The base class is mmin_constr and there are two different constrained minimzation algorithms implemented in
o2scl::mmin_constr_pgrad,
o2scl::mmin_constr_spg. (The
o2scl::mmin_constr_gencan minimizer is not yet finished). The O
2scl implementation should be essentially identical to the most recently released version of OOL.
The constrained minimization classes operate in a similar way to the other multi-dimensional minimization classes (which are derived from o2scl::mmin_base). The constraints are specified with the function
mmin_constr::set_constraints(size_t nc, vec_t &lower,
vec_t &upper);
and the minimization can be performed by calling either o2scl::mmin_base::mmin() or o2scl::mmin_base::mmin_de() (if the gradient is provided by the user). The method in o2scl::mmin_constr_gencan requires a Hessian vector product and the user can specify this product for the minimization by using o2scl::mmin_constr::mmin_hess(). The Hessian product function can be specified as an object of type o2scl::ool_hfunct11 in a similar way to the other function objects in O2scl .
There are five error codes defined in o2scl::mmin_constr which are specific to the classes derived from OOL.
The class o2scl::anneal_gsl can handle some kinds of constraints by ignoring proposed steps which cause the user-specified function to return a non-zero value.
Also, a simple way of implementing constraints is to add a function to the original which increases the value outside of the allowed region. This can be done with the functions constraint() and o2scl::lower_bound(). There are two analogous functions, o2scl::cont_constraint() and o2scl::cont_lower_bound(), which continuous and differentiable versions. Where possible, it is better to use the constrained minimization routines described above.
Constrained minimization example
This example minimizes the function
which is undefined for
and
. The function is also minimized by o2scl::mmin_simp2, which goes outside the allowed region where the function is undefined.
#include <boost/numeric/ublas/vector.hpp>
#include <gsl/gsl_math.h>
#include <gsl/gsl_blas.h>
#include <o2scl/test_mgr.h>
#include <o2scl/mmin_constr_spg.h>
#include <o2scl/mmin_simp2.h>
using namespace std;
using namespace o2scl;
double func(size_t nv, const ubvector &x) {
if (x[0]<0.0 || x[1]<0.0 || x[0]>100.0 || x[1]>100.0) {
cout << "Outside constraint region." << endl;
}
double ret=(log(x[0])*x[0]*x[0]+1.0)*(sqrt(x[1])*(x[1]-1.0)+1.0);
return ret;
}
int dfunc(size_t nv, ubvector &x, ubvector &g) {
g[0]=(x[0]+2.0*x[0]*log(x[0]))*(sqrt(x[1])*(x[1]-1.0)+1.0);
g[1]=(log(x[0])*x[0]*x[0]+1.0)*(sqrt(x[1])+(x[1]-1.0)/2.0/sqrt(x[1]));
return 0;
}
int main(void) {
cout.setf(ios::scientific);
static const size_t nv=2;
ubvector c1(nv), c2(nv), x(nv);
double fmin;
cout << "Simple minimizer: " << endl;
for(size_t i=0;i<nv;i++) {
x[i]=10.0;
}
gm1.
mmin(nv,x,fmin,mff11);
cout << endl;
cout << "Constrained minimizer: " << endl;
for(size_t i=0;i<nv;i++) {
x[i]=10.0;
}
for(size_t i=0;i<nv;i++) {
c1[i]=1.0e-9;
c2[i]=100.0;
}
cout << x[0] << " " << x[1] << " " << fmin << endl;
return 0;
}