BBOWDA - Black Box Optimization With Data Analysis
==================================================

INTRODUCTION
------------

BBOWDA is an algorithm and a reference implementation to solve optimization
problems where:
* both the objective function and the constraints may be black box functions,
* we do not have any gradient or Hessian information for those black box
  functions,
* the functions are assumed to be expensive to compute, thus the number of
  function evaluations shall be kept as small as possible,
using methods from data analysis:
* covariance models,
* Gaussian mixture models (GMMs) and the Expectation-Maximization (EM) iteration
  and
* ratio-reject (outlier rejection algorithm by Tax and Duin).

The algorithm is a so-called incomplete global optimizer, i.e. it attempts to
find a global solution for the optimization problem, but is unable to guarantee
globality. In fact, it cannot even guarantee always finding a local optimum, due
to the lack of gradients and any sort of global information. Despite this lack
of guarantees, the algorithm performs well in practice.

BBOWDA is a surrogate model method, hence it depends on third-party solvers for
Non-Linear (optimization) Programs (NLPs) and Linear (optimization) Programs
(LPs). For NLPs, BBOWDA currently supports any of:
* NLopt SLSQP (MIT and 3-clause BSD licenses),
* Ipopt from COIN-OR (Eclipse Public License version 2.0),
* DONLP2 (donlp2_intv_dyn) by Prof. Peter Spellucci (free for research only),
* DONLP3 (reentrant C++ version of DONLP2, see above, from COCONUT).
Note that DONLP2 is NOT reentrant. Use another solver if you require BBOWDA to
be reentrant. All other currently supported solvers (including DONLP3) are
reentrant.
For LPs, BBOWDA currently requires lp_solve (GNU LGPL version 2.1 or later).

The implementation is licensed under the GNU General Public License, version 3
or later, with special exceptions allowing to link with the third-party
optimizers used. See licenses.txt for details.

HOW TO COMPILE
--------------

BBOWDA is a standard CMake program, hence it can be built with something like:
cmake . && make
You may want to build in a build directory instead, or use parallel make, etc.
See the documentation of CMake for details.

(Note that using "make install" or similar is NOT recommended at this time.)

The following CMake options are supported (use -D to set them):

// Build libbbowdapp as a shared library.
BBOWDAPP_SHARED:BOOL=ON

// Build libbbowda as a shared library.
BBOWDA_SHARED:BOOL=ON

// Choose the type of build, options are: None Debug Release RelWithDebInfo
// MinSizeRel ...
CMAKE_BUILD_TYPE:STRING=Release

// Install path prefix, prepended onto install directories.
CMAKE_INSTALL_PREFIX:PATH=/usr/local

// The path to the donlp3-dist directory.
DONLP3_DIR:PATH=../donlp3-dist

// Select a gradient-based NLP solver for the surrogate and density problems,
// options are: NLopt Ipopt donlp2 donlp3.
NLP_SOLVER:STRING=NLopt

// The directory containing a CMake configuration file for NLopt.
NLopt_DIR:PATH=/usr/lib64/cmake/nlopt

// Full path to pdfdoclet-1.0.3-all.jar file.
PDFDOCLET_JAR:FILEPATH=~/.local/share/java/pdfdoclet-1.0.3-all.jar

// Full path to tools.jar file.
TOOLS_JAR:FILEPATH=/usr/lib/jvm/java-1.8.0/lib/tools.jar

// Enable the C++ binding (bbowdapp).
WITH_CXX:BOOL=ON

// Enable Doxygen documentation.
WITH_DOXYGEN:BOOL=ON

// Enable Doxygen PDF documentation.
WITH_DOXYGEN_PDF:BOOL=OFF

// Build the SWIG Java binding for bbowdapp.
WITH_JAVA:BOOL=ON

// Enable Javadoc documentation for the Java binding.
WITH_JAVA_JAVADOC:BOOL=ON

// Enable Javadoc PDF documentation for the Java binding.
WITH_JAVA_JAVADOC_PDF:BOOL=OFF

// Build the SWIG Python 3 binding for bbowdapp.
WITH_PYTHON:BOOL=ON

// Enable Sphinx documentation for the Python binding.
WITH_PYTHON_SPHINX:BOOL=ON

// Enable Sphinx PDF documentation for the Python binding.
WITH_PYTHON_SPHINX_PDF:BOOL=OFF

If you are missing a required dependency, CMake will complain.

When building with DONLP2, the files from donlp2_intv_dyn are expected to be
extracted to the nlp_donlp2/donlp2_intv_dyn directory. They will then be
compiled as part of BBOWDA.

Building with DONLP3 requires the static library libdonlp3.a, which can be built
as follows:
1. Obtain/extract the donlp3-dist directory from the COCONUT project.
2. Patch it with the patches under nlp_donlp3/patches:
   patch -p1 <$BBOWDA_DIR/nlp_donlp3/patches/donlp3-dist-standalone.patch
   patch -p1 <$BBOWDA_DIR/nlp_donlp3/patches/donlp3-dist-donlp2-backport.patch
   patch -p1 <$BBOWDA_DIR/nlp_donlp3/patches/donlp3-dist-fPIC.patch
   patch -p1 <$BBOWDA_DIR/nlp_donlp3/patches/donlp3-dist-hidden-visibility.patch
3. Build it with Makefile.Cppversion
   make -f Makefile.Cppversion
Then you have to point CMake to it and to the header files by setting DONLP3_DIR
to the donlp3-dist directory.

All other dependencies are expected to be installed somewhere where CMake finds
them.

HOW TO USE
----------

* From C:

  BBOWDA provides a procedural C interface in the library libbbowda. The
  example.c file provides an example of how to use the library (minimizing a
  simple Rosenbrock function). Either edit the example or write your own main
  program calling the bbowda function like example.c does. Then link your main
  program to libbbowda.

* From C++:

  BBOWDA provides an object-oriented C++ interface in the library libbbowdapp.
  The example.cc file provides an example of how to use the library (minimizing
  a simple Rosenbrock function). Either edit the example or write your own main
  program subclassing Bbowda::OptimizationProblem and calling its solve method
  like example.cc does. Then link your main program to libbbowdapp.

* From Java:

  BBOWDA provides a Java binding to the object-oriented C++ interface, using the
  SWIG binding generator, in the files bbowda.jar and libbbowdajni. The Java
  package is called com.dagopt.bbowda. The example.java file provides an example
  of how to use the library (minimizing a simple Rosenbrock function). Either
  edit the example or write your own main program subclassing
  com.dagopt.bbowda.OptimizationProblem and calling its solve method like
  example.java does. Then compile and run your main program with bbowda.jar in
  the class path and libbbowdajni in the LD_LIBRARY_PATH.

* From Python:

  BBOWDA provides a Python binding to the object-oriented C++ interface, using
  the SWIG binding generator, in the Python package bbowda. The example.py file
  provides an example of how to use the library (minimizing a simple Rosenbrock
  function). Either edit the example or write your own main program subclassing
  bbowda.OptimizationProblem and calling its solve method like example.py does.
  Then run your main program with the
  build/bbowdapp/swig:build/bbowdapp/swig/python directories in the PYTHONPATH.

* If the problem is only available as an external binary:

  There is currently no builtin support for file-based communication interfaces.
  So, use one of the above bindings and handle the file-based communication with
  the external binary yourself in your favorite programming language.
