From f76e29781e28e7015e29744b71d77865d79ff4be Mon Sep 17 00:00:00 2001 From: "U-EA\\ECL23226" Date: Mon, 22 Jul 2019 15:46:55 -0400 Subject: [PATCH 1/2] add a guide for compiling in Windows --- doc/docs/NLopt_on_Windows.md | 25 +++- doc/docs/flymd.md | 47 ++++++++ src/octave/nlopt_optimize_usage.h | 192 ++++++++++++++++++++++++++++++ 3 files changed, 259 insertions(+), 5 deletions(-) create mode 100644 doc/docs/flymd.md create mode 100644 src/octave/nlopt_optimize_usage.h diff --git a/doc/docs/NLopt_on_Windows.md b/doc/docs/NLopt_on_Windows.md index 364e7f17..bd5f93a6 100644 --- a/doc/docs/NLopt_on_Windows.md +++ b/doc/docs/NLopt_on_Windows.md @@ -20,13 +20,28 @@ Unofficial Python binaries for Windows are available from Christoph Gohike: ### NLopt with MinGW -If you want to compile NLopt on Windows with [MinGW](http://www.mingw.org/), be sure to install the MinGW version of `cmake` (e.g. with `pacman -S mingw-w64-x86_64-cmake`) and then build via `cmake -G"MSYS Makefiles" . && make` in order to ensure that `cmake` produces the correct type of makefile. +If you want to compile NLopt on Windows: + +1. Install [MSYS2](https://www.msys2.org/). +2. Run the following command: + pacman -S --needed base-devel mingw-w64-i686-toolchain mingw-w64-x86_64-toolchain \ + git subversion mercurial \ + mingw-w64-i686-cmake mingw-w64-x86_64-cmake --disable-download-timeout +3. Download the NLopt using git + git clone https://github.com/stevengj/nlopt.git +4. Create a build folder inside the project. +5. From build folder run the following command: + cmake -G"MSYS Makefiles" .. +6. Then run `make` ### Octave plugin To build the NLopt plugin for [GNU Octave](https://en.wikipedia.org/wiki/GNU_Octave) (a free Matlab clone, which uses the [same NLopt interface as in Matlab](NLopt_Matlab_Reference.md)), you will need the following additional steps. (See [Octave for Windows](https://wiki.octave.org/Octave_for_Microsoft_Windows) on the Octave web page to download Octave.) -1. First, download the `.dll` and import library (`.dll.a`) from above. -2. Download [`nlopt_optimize-oct.cc`](https://github.com/stevengj/nlopt/raw/master/src/octave/nlopt_optimize-oct.cc) and put it in the same directory as the `.dll` and `.dll.a` files. -3. Compile the Octave plugin (`.oct` file) with `mkoctfile -lnlopt --output nlopt_optimize.oct nlopt_optimize-oct.cc` (`mkoctfile` is a program included with Octave). -4. Finally, move `libnlopt.dll` to the *octave*``bin` directory (the location of `octave.exe`) so that Octave can find it. +1. Copy `libnlopt.dll` from `build` to `C:\Octave\Octave-X.X.X.X\mingw64\bin` +2. Copy `nlopt.f`, `nlopt.h`, and `nlopt.hpp` from `build\src\api` to `C:\Octave\Octave-X.X.X.X\mingw64\include` +3. Create a folder named "nlopt" inside `C:\Octave\Octave-X.X.X.X\mingw64\lib\cmake` +4. Copy `NLoptConfig.cmake`, `NLoptConfigVersion.cmake`, `NLoptLibraryDepends.cmake`, and `NLoptLibraryDepends-release.cmake` from `build` and `build\CMakeFiles\Export\lib\cmake\nlopt`, respectively, to `C:\Octave\Octave-X.X.X.X\mingw64\lib\cmake` +5. Copy `nlopt.pc` from `build` to `C:\Octave\Octave-X.X.X.X\mingw64\lib\pkgconfig` +6. Copy `libnlopt.dll.a` from `build` to `C:\Octave\Octave-X.X.X.X\mingw64\lib` +7. Compile the Octave plugin (`.oct` file) with `mkoctfile -lnlopt --output nlopt_optimize.oct nlopt_optimize-oct.cc` (`mkoctfile` is a program included with Octave). diff --git a/doc/docs/flymd.md b/doc/docs/flymd.md new file mode 100644 index 00000000..23c36755 --- /dev/null +++ b/doc/docs/flymd.md @@ -0,0 +1,47 @@ +--- +# NLopt on Windows +--- + +NLopt on Windows +---------------- + +NLopt works fine on Microsoft Windows computers, and you can compile it directly using the included [CMake](https://en.wikipedia.org/wiki/CMake) build scripts. + +To simplify installation, there are also precompiled 32-bit and 64-bit Windows [DLLs](https://en.wikipedia.org/wiki/Dynamic-link_library) (along with binaries for many other systems) at [NLoptBuilder/releases](https://github.com/stevengj/NLoptBuilder/releases). In particular, the Windows builds are + +- [NLopt.v2.6.1.i686-w64-mingw32.tar.gz](https://github.com/stevengj/NLoptBuilder/releases/download/v2.6.1/NLopt.v2.6.1.i686-w64-mingw32.tar.gz) (32-bit) +- [NLopt.v2.6.1.x86_64-w64-mingw32.tar.gz](https://github.com/stevengj/NLoptBuilder/releases/download/v2.6.1/NLopt.v2.6.1.x86_64-w64-mingw32.tar.gz) (64-bit) + +These `.tar.gz` files unpack (with a variety of Windows software, e.g. 7-zip) into a folder with a `bin` subdirectory that contains `libnlopt.dll`. To link with this in your compiler, you will typically also want the [import library](https://stackoverflow.com/questions/3573475/how-does-the-import-library-work-details) for the DLL, which can be found in the `lib` subdirectory and is called `libnlopt.dll.a` (this can be used similarly to the `.lib` files you may be used to). + +Unofficial Python binaries for Windows are available from Christoph Gohike: + +- [Python binaries for 64-bit Windows](http://www.lfd.uci.edu/~gohlke/pythonlibs/#nlopt) + +### NLopt with MinGW + +If you want to compile NLopt on Windows: + +1. Install [MSYS2](https://www.msys2.org/). +2. Run the following command: + pacman -S --needed base-devel mingw-w64-i686-toolchain mingw-w64-x86_64-toolchain \ + git subversion mercurial \ + mingw-w64-i686-cmake mingw-w64-x86_64-cmake --disable-download-timeout +3. Download the NLopt using git + git clone https://github.com/stevengj/nlopt.git +4. Create a build folder inside the project. +5. From build folder run the following command: + cmake -G"MSYS Makefiles" .. +6. Then run `make` + +### Octave plugin + +To build the NLopt plugin for [GNU Octave](https://en.wikipedia.org/wiki/GNU_Octave) (a free Matlab clone, which uses the [same NLopt interface as in Matlab](NLopt_Matlab_Reference.md)), you will need the following additional steps. (See [Octave for Windows](https://wiki.octave.org/Octave_for_Microsoft_Windows) on the Octave web page to download Octave.) + +1. Copy `libnlopt.dll` from `build` to `C:\Octave\Octave-X.X.X.X\mingw64\bin` +2. Copy `nlopt.f`, `nlopt.h`, and `nlopt.hpp` from `build\src\api` to `C:\Octave\Octave-X.X.X.X\mingw64\include` +3. Create a folder named "nlopt" inside `C:\Octave\Octave-X.X.X.X\mingw64\lib\cmake` +4. Copy `NLoptConfig.cmake`, `NLoptConfigVersion.cmake`, `NLoptLibraryDepends.cmake`, and `NLoptLibraryDepends-release.cmake` from `build` and `build\CMakeFiles\Export\lib\cmake\nlopt`, respectively, to `C:\Octave\Octave-X.X.X.X\mingw64\lib\cmake` +5. Copy `nlopt.pc` from `build` to `C:\Octave\Octave-X.X.X.X\mingw64\lib\pkgconfig` +6. Copy `libnlopt.dll.a` from `build` to `C:\Octave\Octave-X.X.X.X\mingw64\lib` +7. Compile the Octave plugin (`.oct` file) with `mkoctfile -lnlopt --output nlopt_optimize.oct nlopt_optimize-oct.cc` (`mkoctfile` is a program included with Octave).fLyMd-mAkEr diff --git a/src/octave/nlopt_optimize_usage.h b/src/octave/nlopt_optimize_usage.h new file mode 100644 index 00000000..8449e793 --- /dev/null +++ b/src/octave/nlopt_optimize_usage.h @@ -0,0 +1,192 @@ +#define NLOPT_OPTIMIZE_USAGE \ +"Usage: [xopt, fopt, retcode] = nlopt_optimize(opt, xinit)\n" \ +"\n" \ +"Optimizes (minimizes or maximizes) a nonlinear function under\n" \ +"nonlinear constraints from the starting guess xinit, where the\n" \ +"objective, constraints, stopping criteria, and other options are \n" \ +"specified in the structure opt described below. A variety of local\n" \ +"and global optimization algorithms can be used, as specified by the \n" \ +"opt.algorithm parameter described below. Returns the optimum\n" \ +"function value fopt, the location xopt of the optimum, and a\n" \ +"return code retcode described below (> 0 on success).\n" \ +"\n" \ +"The dimension (n) of the problem, i.e. the number of design variables,\n" \ +"is specified implicitly via the length of xinit.\n" \ +"\n" \ +"This function is a front-end for the external routine nlopt_optimize\n" \ +"in the free NLopt nonlinear-optimization library, which is a wrapper\n" \ +"around a number of free/open-source optimization subroutines. More\n" \ +"details can be found on the NLopt web page (ab-initio.mit.edu/nlopt)\n" \ +"and also under 'man nlopt_minimize' on Unix.\n" \ +"\n" \ +"OBJECTIVE FUNCTION:\n" \ +"\n" \ +"The objective function f is specified via opt.min_objective or\n" \ +"opt.max_objective for minimization or maximization, respectively.\n" \ +"opt.min/max_objective should be a handle (@) to a function of the form:\n" \ +"\n" \ +" [val, gradient] = f(x)\n" \ +"\n" \ +"where x is a row vector, val is the function value f(x), and gradient\n" \ +"is a row vector giving the gradient of the function with respect to x.\n" \ +"The gradient is only used for gradient-based optimization algorithms;\n" \ +"some of the algorithms (below) are derivative-free and only require\n" \ +"f to return val (its value).\n" \ +"\n" \ +"BOUND CONSTRAINTS:\n" \ +"\n" \ +"Lower and/or upper bounds for the design variables x are specified\n" \ +"via opt.lower_bounds and/or opt.upper_bounds, respectively: these\n" \ +"are vectors (of the same length as xinit, above) giving the bounds\n" \ +"in each component. An unbounded component may be specified by a\n" \ +"lower/upper bound of -inf/+inf, respectively. If opt.lower_bounds\n" \ +"and/or opt.upper_bounds are not specified, the default bounds are\n" \ +"-inf/+inf (i.e. unbounded), respectively.\n" \ +"\n" \ +"NONLINEAR CONSTRAINTS:\n" \ +"\n" \ +"Several of the algorithms in NLopt (MMA, COBYLA, and ORIG_DIRECT) also\n" \ +"support arbitrary nonlinear inequality constraints, and some also allow\n" \ +"nonlinear equality constraints (ISRES and AUGLAG). For these \n" \ +"algorithms, you can specify as many nonlinear constraints as you wish.\n" \ +"(The default is no nonlinear constraints.)\n" \ +"\n" \ +"Inequality constraints of the form fc{i}(x) <= 0 are specified via opt.fc,\n" \ +"which is a cell array of function handles (@) of the same form as\n" \ +"the objective function above (i.e., returning the value and optionally\n" \ +"the gradient of the constraint function fc{i}, where the gradient is\n" \ +"only needed for gradient-based algorithms).\n" \ +"\n" \ +"Equality constraints of the form h{i}(x) = 0 are specified via opt.h,\n" \ +"which is a cell array of function handles (@) of the same form as\n" \ +"the objective function above (i.e., returning the value and optionally\n" \ +"the gradient of the constraint function h{i}, where the gradient is\n" \ +"only needed for gradient-based algorithms).\n" \ +"\n" \ +"For both inequality and equality constraints, you can supply a\n" \ +"\"tolerance\" for each constraint: this tolerance is used for convergence\n" \ +"tests only, and a point x is considered feasible for purposes of\n" \ +"convergence if the constraint is violated by the given tolerance.\n" \ +"The tolerances are specified via opt.fc_tol and opt.h_tol, respectively,\n" \ +"which must be vectors of the same length as opt.fc and opt.h, so\n" \ +"that opt.fc_tol(i) is the tolerance for opt.fc{i} and opt.h_tol(i)\n" \ +"is the tolerance for opt.h{i}. These tolerances default to zero; a\n" \ +"small nonzero tolerance is recommended, however, especially for h_tol.\n" \ +"\n" \ +"ALGORITHMS\n" \ +"\n" \ +"The optimization algorithm must be specified via opt.algorithm.\n" \ +"\n" \ +"The algorithm should be one of the following constants (name and\n" \ +"interpretation are the same as for the C language interface). Names\n" \ +"with _G*_ are global optimization, and names with _L*_ are local\n" \ +"optimization. Names with _*N_ are derivative-free, while names\n" \ +"with _*D_ are gradient-based algorithms. Algorithms:\n" \ +"\n" \ +"NLOPT_GD_MLSL_LDS, NLOPT_GD_MLSL, NLOPT_GD_STOGO, NLOPT_GD_STOGO_RAND, \n" \ +"NLOPT_GN_CRS2_LM, NLOPT_GN_DIRECT_L, NLOPT_GN_DIRECT_L_NOSCAL, \n" \ +"NLOPT_GN_DIRECT_L_RAND, NLOPT_GN_DIRECT_L_RAND_NOSCAL, NLOPT_GN_DIRECT, \n" \ +"NLOPT_GN_DIRECT_NOSCAL, NLOPT_GN_ISRES, NLOPT_GN_MLSL_LDS, NLOPT_GN_MLSL, \n" \ +"NLOPT_GN_ORIG_DIRECT_L, NLOPT_GN_ORIG_DIRECT, NLOPT_LD_AUGLAG_EQ, \n" \ +"NLOPT_LD_AUGLAG, NLOPT_LD_LBFGS, NLOPT_LD_LBFGS_NOCEDAL, NLOPT_LD_MMA, \n" \ +"NLOPT_LD_TNEWTON, NLOPT_LD_TNEWTON_PRECOND, \n" \ +"NLOPT_LD_TNEWTON_PRECOND_RESTART, NLOPT_LD_TNEWTON_RESTART, \n" \ +"NLOPT_LD_VAR1, NLOPT_LD_VAR2, NLOPT_LN_AUGLAG_EQ, NLOPT_LN_AUGLAG, \n" \ +"NLOPT_LN_BOBYQA, NLOPT_LN_COBYLA, NLOPT_LN_NELDERMEAD, \n" \ +"NLOPT_LN_NEWUOA_BOUND, NLOPT_LN_NEWUOA, NLOPT_LN_PRAXIS, NLOPT_LN_SBPLX\n" \ +"\n" \ +"For more information on individual algorithms, see their individual\n" \ +"help pages (e.g. \"help NLOPT_LN_SBPLX\").\n" \ +"\n" \ +"STOPPING CRITERIA:\n" \ +"\n" \ +"Multiple stopping criteria can be specified by setting one or more of\n" \ +"the following fields of opt. The optimization halts whenever any\n" \ +"one of the given criteria is satisfied.\n" \ +"\n" \ +"opt.stopval: Stop when an objective value of at least stopval is found.\n" \ +" That is, stop minimizing when a value <= stopval is found, or stop\n" \ +" maximizing when a value >= stopval is found.\n" \ +"\n" \ +"opt.ftol_rel: Relative tolerance on function value, to stop when\n" \ +" an optimization step (or an estimate of the optimum) changes\n" \ +" the function value by less than opt.ftol_rel multiplied by\n" \ +" the absolute value of the function.\n" \ +"\n" \ +"opt.ftol_abs: Absolute tolerance on function value, to stop when\n" \ +" an optimization step (or an estimate of the optimum) changes\n" \ +" the function value by less than opt.ftol_abs.\n" \ +"\n" \ +"opt.xtol_rel: Relative tolerance on function value, to stop when\n" \ +" an optimization step (or an estimate of the optimum) changes\n" \ +" every component of x by less than opt.xtol_rel multiplied by\n" \ +" the absolute value of that component of x.\n" \ +"\n" \ +"opt.xtol_abs: Absolute tolerance on function value, to stop when\n" \ +" an optimization step (or an estimate of the optimum) changes\n" \ +" every component of x by less than that component of opt.xtol_abs\n" \ +" -- should be a vector of same length as x.\n" \ +"\n" \ +"opt.maxeval: Maximum number of function evaluations.\n" \ +"\n" \ +"opt.maxtime: Maximum runtime (in seconds) for the optimization.\n" \ +"\n" \ +"RETURN CODE:\n" \ +"\n" \ +"The retcode result is positive upon successful completion, and\n" \ +"negative for an error. The specific values are:\n" \ +"\n" \ +"generic success code: +1\n" \ +" stopval reached: +2\n" \ +" ftol reached: +3\n" \ +" xtol reached: +4\n" \ +" maxeval reached: +5\n" \ +" maxtime reached: +6\n" \ +"generic failure code: -1\n" \ +" invalid arguments: -2\n" \ +" out of memory: -3\n" \ +" roundoff-limited: -4\n" \ +"\n" \ +"LOCAL OPTIMIZER:\n" \ +"\n" \ +"Some of the algorithms, especially MLSL and AUGLAG, use a different\n" \ +"optimization algorithm as a subroutine, typically for local optimization.\n" \ +"By default, they use MMA or COBYLA for gradient-based or derivative-free\n" \ +"searching, respectively. However, you can change this by specifying\n" \ +"opt.local_optimizer: this is a structure with the same types of fields as opt\n" \ +"(stopping criteria, algorithm, etcetera). The objective function\n" \ +"and nonlinear constraint parameters of opt.local_optimizer are ignored.\n" \ +"\n" \ +"INITIAL STEP SIZE:\n" \ +"\n" \ +"For derivative-free local-optimization algorithms, the optimizer must\n" \ +"somehow decide on some initial step size to perturb x by when it begins\n" \ +"the optimization. This step size should be big enough that the value\n" \ +"of the objective changes significantly, but not too big if you want to\n" \ +"find the local optimum nearest to x. By default, NLopt chooses this\n" \ +"initial step size heuristically from the bounds, tolerances, and other\n" \ +"information, but this may not always be the best choice.\n" \ +"\n" \ +"You can modify the initial step by setting opt.initial_step, which\n" \ +"is a vector of the same length as x containing the (nonzero) initial\n" \ +"step size for each component of x.\n" \ +"\n" \ +"STOCHASTIC POPULATION:\n" \ +"\n" \ +"Several of the stochastic search algorithms (e.g., CRS, MLSL, and\n" \ +"ISRES) start by generating some initial \"population\" of random points\n" \ +"x. By default, this initial population size is chosen heuristically in\n" \ +"some algorithm-specific way, but the initial population can by changed\n" \ +"by setting opt.population to the desired initial population size.\n" \ +"\n" \ +"VERBOSE OUTPUT:\n" \ +"\n" \ +"If opt.verbose is set to a nonzero value, then nlopt_optimize\n" \ +"will print out verbose output; for example, it will print the\n" \ +"value of the objective function after each evaluation.\n" \ +"\n" \ +"MORE INFORMATION:\n" \ +"\n" \ +"For more documentation, such as a detailed description of all the\n" \ +"algorithms, see the NLopt home page: http://ab-initio.mit.edu/nlopt\n" \ + From 8a552ac43797f70e67ff04b0bd4992497eda026c Mon Sep 17 00:00:00 2001 From: "U-EA\\ECL23226" Date: Tue, 23 Jul 2019 12:18:45 -0400 Subject: [PATCH 2/2] edit based on the comments --- doc/docs/NLopt_on_Windows.md | 23 +++++++++-------------- test/t_octave.m | 12 +++++++----- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/doc/docs/NLopt_on_Windows.md b/doc/docs/NLopt_on_Windows.md index bd5f93a6..227debca 100644 --- a/doc/docs/NLopt_on_Windows.md +++ b/doc/docs/NLopt_on_Windows.md @@ -24,24 +24,19 @@ If you want to compile NLopt on Windows: 1. Install [MSYS2](https://www.msys2.org/). 2. Run the following command: - pacman -S --needed base-devel mingw-w64-i686-toolchain mingw-w64-x86_64-toolchain \ - git subversion mercurial \ - mingw-w64-i686-cmake mingw-w64-x86_64-cmake --disable-download-timeout -3. Download the NLopt using git - git clone https://github.com/stevengj/nlopt.git + `pacman -S --needed base-devel mingw-w64-i686-toolchain mingw-w64-x86_64-toolchain \ + mingw-w64-i686-cmake mingw-w64-x86_64-cmake --disable-download-timeout` +3. Download the NLopt using git. + `git clone https://github.com/stevengj/nlopt.git` 4. Create a build folder inside the project. 5. From build folder run the following command: - cmake -G"MSYS Makefiles" .. -6. Then run `make` + `cmake -G"MSYS Makefiles" ..` +6. Then run `make`. ### Octave plugin To build the NLopt plugin for [GNU Octave](https://en.wikipedia.org/wiki/GNU_Octave) (a free Matlab clone, which uses the [same NLopt interface as in Matlab](NLopt_Matlab_Reference.md)), you will need the following additional steps. (See [Octave for Windows](https://wiki.octave.org/Octave_for_Microsoft_Windows) on the Octave web page to download Octave.) -1. Copy `libnlopt.dll` from `build` to `C:\Octave\Octave-X.X.X.X\mingw64\bin` -2. Copy `nlopt.f`, `nlopt.h`, and `nlopt.hpp` from `build\src\api` to `C:\Octave\Octave-X.X.X.X\mingw64\include` -3. Create a folder named "nlopt" inside `C:\Octave\Octave-X.X.X.X\mingw64\lib\cmake` -4. Copy `NLoptConfig.cmake`, `NLoptConfigVersion.cmake`, `NLoptLibraryDepends.cmake`, and `NLoptLibraryDepends-release.cmake` from `build` and `build\CMakeFiles\Export\lib\cmake\nlopt`, respectively, to `C:\Octave\Octave-X.X.X.X\mingw64\lib\cmake` -5. Copy `nlopt.pc` from `build` to `C:\Octave\Octave-X.X.X.X\mingw64\lib\pkgconfig` -6. Copy `libnlopt.dll.a` from `build` to `C:\Octave\Octave-X.X.X.X\mingw64\lib` -7. Compile the Octave plugin (`.oct` file) with `mkoctfile -lnlopt --output nlopt_optimize.oct nlopt_optimize-oct.cc` (`mkoctfile` is a program included with Octave). +1. Copy `libnlopt.dll` from `build` to `C:\Octave\Octave-X.X.X.X\mingw64\bin`. +2. Copy `libnlopt.dll.a` from `build` to `C:\Octave\Octave-X.X.X.X\mingw64\lib`. +3. Change the current folder to 'src\octave' and compile the Octave plugin (`.oct` file) with `mkoctfile -I"build/src/api" -lnlopt --output nlopt_optimize nlopt_optimize-oct.cc` (`mkoctfile` is a program included with Octave). \ No newline at end of file diff --git a/test/t_octave.m b/test/t_octave.m index f9d863b8..7f4c3014 100644 --- a/test/t_octave.m +++ b/test/t_octave.m @@ -1,4 +1,5 @@ - +clear all +clc arg_list = argv (); for i = 1:nargin loadpath = arg_list{i}; @@ -21,11 +22,12 @@ endfunction -opt.algorithm = NLOPT_LD_MMA -% opt.algorithm = NLOPT_LN_COBYLA +%opt.algorithm = NLOPT_LD_MMA +opt.algorithm = NLOPT_LN_SBPLX ; opt.lower_bounds = [-inf, 0] +opt.upper_bounds = [10, inf] opt.min_objective = @myfunc -opt.fc = { (@(x) myconstraint(x,2,0)), (@(x) myconstraint(x,-1,1)) } -opt.fc_tol = [1e-8, 1e-8]; +%opt.fc = { (@(x) myconstraint(x,2,0)), (@(x) myconstraint(x,-1,1)) } +%opt.fc_tol = [1e-8, 1e-8]; opt.xtol_rel = 1e-4 [xopt, fmin, retcode] = nlopt_optimize(opt, [1.234 5.678])