chiark / gitweb /
Merge branch 'master' of https://github.com/stevengj/nlopt
authorSteven G. Johnson <stevenj@alum.mit.edu>
Sat, 11 Apr 2015 13:36:05 +0000 (09:36 -0400)
committerSteven G. Johnson <stevenj@alum.mit.edu>
Sat, 11 Apr 2015 13:36:05 +0000 (09:36 -0400)
CMakeLists.txt
api/general.c
api/optimize.c
bobyqa/bobyqa.c
slsqp/slsqp.c
swig/CMakeLists.txt [new file with mode: 0644]
util/nlopt-util.h

index 9a7ba0cf5e1eee5b92e7faa69c9ad9d6b84e9dc7..1fa13a32799ae31273776e0d163cc33021495de8 100644 (file)
@@ -164,9 +164,6 @@ IF (_VERSION_INFO_LINE)
   SET(_INFO_VERSION "${_INFO_SOVERSION}.${_VERSION_INFO_AGE}.${_VERSION_INFO_REVISION}")\r
   SET_TARGET_PROPERTIES(nlopt PROPERTIES SOVERSION ${_INFO_SOVERSION})\r
   SET_TARGET_PROPERTIES(nlopt PROPERTIES VERSION ${_INFO_VERSION} )\r
-  IF (WIN32)\r
-    SET_TARGET_PROPERTIES(nlopt PROPERTIES SUFFIX -${_INFO_SOVERSION}.dll)\r
-  ENDIF ()\r
 ENDIF ()\r
 \r
 INSTALL ( TARGETS nlopt\r
@@ -175,5 +172,4 @@ INSTALL ( TARGETS nlopt
           ARCHIVE DESTINATION lib${LIB_SUFFIX}\r
         )\r
 \r
-\r
-    \r
+add_subdirectory (swig)\r
index d97fcb5da0d79ec0d20f5facd1dcbdd64bb9591c..dfe20102de0d8d9a2a1d8ddb46bd75948b5fee41 100644 (file)
@@ -34,6 +34,11 @@ int nlopt_isinf(double x) {
 #endif
          ;
 }
+
+int nlopt_isfinite(double x) {
+    return fabs(x) <= DBL_MAX;
+}
+
 /*************************************************************************/
 
 void NLOPT_STDCALL nlopt_version(int *major, int *minor, int *bugfix)
index 49b8d340ae0b2a983dd604fc8f77da90f4e4617a..f6f1236599486a211960f0bd0c681985345932f2 100644 (file)
@@ -641,11 +641,11 @@ static nlopt_result nlopt_optimize_(nlopt_opt opt, double *x, double *minf)
                   if (nlopt_set_default_initial_step(opt, x) != NLOPT_SUCCESS)
                        return NLOPT_OUT_OF_MEMORY;
              }
-             return cobyla_minimize(n, f, f_data, 
-                                    opt->m, opt->fc,
-                                    opt->p, opt->h,
-                                    lb, ub, x, minf, &stop,
-                                    opt->dx);
+             ret = cobyla_minimize(n, f, f_data, 
+                                    opt->m, opt->fc,
+                                    opt->p, opt->h,
+                                    lb, ub, x, minf, &stop,
+                                    opt->dx);
              if (freedx) { free(opt->dx); opt->dx = NULL; }
              return ret;
         }
index 8fc454b67442ef885242e8efda5b230f4ab93eb0..9945b607583eb4b7d716636e30957a3f834bf065 100644 (file)
@@ -3101,6 +3101,7 @@ nlopt_result bobyqa(int n, int npt, double *x,
     nlopt_rescale(U(n), s, x, x); --x;
 
     xs = (double *) malloc(sizeof(double) * (U(n)));
+    if (!xs) { ret = NLOPT_OUT_OF_MEMORY; goto done; }
 
     sxl = nlopt_new_rescaled(U(n), s, xl);
     if (!sxl) { ret = NLOPT_OUT_OF_MEMORY; goto done; }
index 1be33a3ade7d75716467eca355646fca4e867117..7a341d60785ff49f362407a31f9c8befe627fe99 100644 (file)
@@ -2044,12 +2044,16 @@ L190:
     *mode = line == 1 ? -2 : 1;
     goto L330;
 L200:
-    if (h1 <= h3 / ten || line > 10) {
-       goto L240;
+    if (nlopt_isfinite(h1)) {
+           if (h1 <= h3 / ten || line > 10) {
+                   goto L240;
+           }
+           /* Computing MAX */
+           d__1 = h3 / (two * (h3 - h1));
+           alpha = MAX2(d__1,alfmin);
+    } else {
+           alpha = MAX2(alpha*.5,alfmin);
     }
-/* Computing MAX */
-    d__1 = h3 / (two * (h3 - h1));
-    alpha = MAX2(d__1,alfmin);
     goto L190;
 /*   EXACT LINESEARCH */
 L210:
@@ -2453,6 +2457,7 @@ nlopt_result nlopt_slsqp(unsigned n, nlopt_func f, void *f_data,
      int feasible, feasible_cur;
      double infeasibility = HUGE_VAL, infeasibility_cur = HUGE_VAL;
      unsigned max_cdim;
+     int want_grad = 1;
      
      max_cdim = MAX2(nlopt_max_constraint_dim(m, fc),
                    nlopt_max_constraint_dim(p, h));
@@ -2490,121 +2495,103 @@ nlopt_result nlopt_slsqp(unsigned n, nlopt_func f, void *f_data,
                &state);
 
          switch (mode) {
-             case -1:  /* objective & gradient evaluation */
-                  if (prev_mode == -2) break; /* just evaluated this point */
-             case -2:
-                  eval_f_and_grad:
-                  feasible_cur = 1; infeasibility_cur = 0;
-                  fcur = f(n, xcur, grad, f_data);
-                  stop->nevals++;
-                  if (nlopt_stop_forced(stop)) { 
-                       fcur = HUGE_VAL; ret = NLOPT_FORCED_STOP; goto done; }
-                  ii = 0;
-                  for (i = 0; i < p; ++i) {
-                       unsigned j, k;
-                       nlopt_eval_constraint(c+ii, cgradtmp, h+i, n, xcur);
-                       if (nlopt_stop_forced(stop)) { 
-                            ret = NLOPT_FORCED_STOP; goto done; }
-                       for (k = 0; k < h[i].m; ++k, ++ii) {
-                            infeasibility_cur = 
-                                 MAX2(infeasibility_cur, fabs(c[ii]));
-                            feasible_cur = 
-                                 feasible_cur && fabs(c[ii]) <= h[i].tol[k];
-                            for (j = 0; j < n; ++ j)
+         case -1:  /* objective & gradient evaluation */
+             if (prev_mode == -2 && !want_grad) break; /* just evaluated this point */
+         case -2:
+             eval_f_and_grad:
+             want_grad = 1;
+         case 1:{ /* don't need grad unless we don't have it yet */
+             double *newgrad = 0;
+             double *newcgrad = 0;
+             if (want_grad) {
+                 newgrad = grad;
+                 newcgrad = cgradtmp;
+             }
+             feasible_cur = 1; infeasibility_cur = 0;
+             fcur = f(n, xcur, newgrad, f_data);
+             stop->nevals++;
+             if (nlopt_stop_forced(stop)) {
+                 fcur = HUGE_VAL; ret = NLOPT_FORCED_STOP; goto done; }
+             if (nlopt_isfinite(fcur)) {
+                 want_grad = 0;
+                 ii = 0;
+                 for (i = 0; i < p; ++i) {
+                     unsigned j, k;
+                     nlopt_eval_constraint(c+ii, newcgrad, h+i, n, xcur);
+                     if (nlopt_stop_forced(stop)) {
+                         ret = NLOPT_FORCED_STOP; goto done; }
+                     for (k = 0; k < h[i].m; ++k, ++ii) {
+                         infeasibility_cur =
+                             MAX2(infeasibility_cur, fabs(c[ii]));
+                         feasible_cur =
+                             feasible_cur && fabs(c[ii]) <= h[i].tol[k];
+                         if (newcgrad) {
+                             for (j = 0; j < n; ++ j)
                                  cgrad[j*U(mpi1) + ii] = cgradtmp[k*n + j];
-                       }
-                  }
-                  for (i = 0; i < m; ++i) {
-                       unsigned j, k;
-                       nlopt_eval_constraint(c+ii, cgradtmp, fc+i, n, xcur);
-                       if (nlopt_stop_forced(stop)) { 
-                            ret = NLOPT_FORCED_STOP; goto done; }
-                       for (k = 0; k < fc[i].m; ++k, ++ii) {
-                            infeasibility_cur = 
-                                 MAX2(infeasibility_cur, c[ii]);
-                            feasible_cur = 
-                                 feasible_cur && c[ii] <= fc[i].tol[k];
-                            for (j = 0; j < n; ++ j)
+                         }
+                     }
+                 }
+                 for (i = 0; i < m; ++i) {
+                     unsigned j, k;
+                     nlopt_eval_constraint(c+ii, newcgrad, fc+i, n, xcur);
+                     if (nlopt_stop_forced(stop)) {
+                         ret = NLOPT_FORCED_STOP; goto done; }
+                     for (k = 0; k < fc[i].m; ++k, ++ii) {
+                         infeasibility_cur =
+                             MAX2(infeasibility_cur, c[ii]);
+                         feasible_cur =
+                             feasible_cur && c[ii] <= fc[i].tol[k];
+                         if (newcgrad) {
+                             for (j = 0; j < n; ++ j)
                                  cgrad[j*U(mpi1) + ii] = -cgradtmp[k*n + j];
-                            c[ii] = -c[ii]; /* slsqp sign convention */
-                       }
-                  }
-                  break;
+                         }
+                         c[ii] = -c[ii]; /* slsqp sign convention */
+                     }
+                 }
+             }
+             break;}
              case 0: /* required accuracy for solution obtained */
-                  goto done;
-             case 1: /* objective evaluation only (no gradient) */
-                  feasible_cur = 1; infeasibility_cur = 0;
-                  fcur = f(n, xcur, NULL, f_data);
-                  stop->nevals++;
-                  if (nlopt_stop_forced(stop)) { 
-                       fcur = HUGE_VAL; ret = NLOPT_FORCED_STOP; goto done; }
-                  ii = 0;
-                  for (i = 0; i < p; ++i) {
-                       unsigned k;
-                       nlopt_eval_constraint(c+ii, NULL, h+i, n, xcur);
-                       if (nlopt_stop_forced(stop)) { 
-                            ret = NLOPT_FORCED_STOP; goto done; }
-                       for (k = 0; k < h[i].m; ++k, ++ii) {
-                            infeasibility_cur = 
-                                 MAX2(infeasibility_cur, fabs(c[ii]));
-                            feasible_cur = 
-                                 feasible_cur && fabs(c[ii]) <= h[i].tol[k];
-                       }
-                  }
-                  for (i = 0; i < m; ++i) {
-                       unsigned k;
-                       nlopt_eval_constraint(c+ii, NULL, fc+i, n, xcur);
-                       if (nlopt_stop_forced(stop)) { 
-                            ret = NLOPT_FORCED_STOP; goto done; }
-                       for (k = 0; k < fc[i].m; ++k, ++ii) {
-                            infeasibility_cur = 
-                                 MAX2(infeasibility_cur, c[ii]);
-                            feasible_cur = 
-                                 feasible_cur && c[ii] <= fc[i].tol[k];
-                            c[ii] = -c[ii]; /* slsqp sign convention */
-                       }
-                  }
-                  break;
+                 goto done;
              case 8: /* positive directional derivative for linesearch */
-                  /* relaxed convergence check for a feasible_cur point,
-                     as in the SLSQP code (except xtol as well as ftol) */
-                  ret = NLOPT_ROUNDOFF_LIMITED; /* usually why deriv>0 */
-                  if (feasible_cur) {
-                       double save_ftol_rel = stop->ftol_rel;
-                       double save_xtol_rel = stop->xtol_rel;
-                       double save_ftol_abs = stop->ftol_abs;
-                       stop->ftol_rel *= 10;
-                       stop->ftol_abs *= 10;
-                       stop->xtol_rel *= 10;
-                       if (nlopt_stop_ftol(stop, fcur, state.f0))
-                            ret = NLOPT_FTOL_REACHED;
-                       else if (nlopt_stop_x(stop, xcur, state.x0))
-                            ret = NLOPT_XTOL_REACHED;
-                       stop->ftol_rel = save_ftol_rel;
-                       stop->ftol_abs = save_ftol_abs;
-                       stop->xtol_rel = save_xtol_rel;
-                  }
-                  goto done;
+                 /* relaxed convergence check for a feasible_cur point,
+                    as in the SLSQP code (except xtol as well as ftol) */
+                 ret = NLOPT_ROUNDOFF_LIMITED; /* usually why deriv>0 */
+                 if (feasible_cur) {
+                     double save_ftol_rel = stop->ftol_rel;
+                     double save_xtol_rel = stop->xtol_rel;
+                     double save_ftol_abs = stop->ftol_abs;
+                     stop->ftol_rel *= 10;
+                     stop->ftol_abs *= 10;
+                     stop->xtol_rel *= 10;
+                     if (nlopt_stop_ftol(stop, fcur, state.f0))
+                         ret = NLOPT_FTOL_REACHED;
+                     else if (nlopt_stop_x(stop, xcur, state.x0))
+                         ret = NLOPT_XTOL_REACHED;
+                     stop->ftol_rel = save_ftol_rel;
+                     stop->ftol_abs = save_ftol_abs;
+                     stop->xtol_rel = save_xtol_rel;
+                 }
+                 goto done;
              case 5: /* singular matrix E in LSQ subproblem */
              case 6: /* singular matrix C in LSQ subproblem */
              case 7: /* rank-deficient equality constraint subproblem HFTI */
-                  ret = NLOPT_ROUNDOFF_LIMITED;
-                  goto done;
+                 ret = NLOPT_ROUNDOFF_LIMITED;
+                 goto done;
              case 4: /* inequality constraints incompatible */
              case 3: /* more than 3*n iterations in LSQ subproblem */
              case 9: /* more than iter iterations in SQP */
-                  ret = NLOPT_FAILURE;
-                  goto done;
+                 ret = NLOPT_FAILURE;
+                 goto done;
              case 2: /* number of equality constraints > n */
              default: /* >= 10: working space w or jw too small */
-                  ret = NLOPT_INVALID_ARGS;
-                  goto done;
+                 ret = NLOPT_INVALID_ARGS;
+                 goto done;
          }
          prev_mode = mode;
 
          /* update best point so far */
-         if ((fcur < *minf && (feasible_cur || !feasible))
-             || (!feasible && infeasibility_cur < infeasibility)) {
+         if (nlopt_isfinite(fcur) && ((fcur < *minf && (feasible_cur || !feasible))
+                                      || (!feasible && infeasibility_cur < infeasibility))) {
               *minf = fcur;
               feasible = feasible_cur;
               infeasibility = infeasibility_cur;
diff --git a/swig/CMakeLists.txt b/swig/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d2fa84d
--- /dev/null
@@ -0,0 +1,44 @@
+option (BUILD_PYTHON "build python bindings" ON)
+
+find_package (PythonInterp)
+find_package (PythonLibs)
+
+if (NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/nlopt-python.cpp)
+  find_package (SWIG)
+endif ()
+
+if (BUILD_PYTHON AND PYTHONINTERP_FOUND AND PYTHONLIBS_FOUND AND (SWIG_FOUND OR (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/nlopt-python.cpp)) AND BUILD_SHARED_LIBS)
+
+  include_directories (${CMAKE_SOURCE_DIR}/api)
+  include_directories (${PYTHON_INCLUDE_DIRS})
+
+  if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/nlopt-python.cpp)
+    set (SWIG_MODULE_nlopt_REAL_NAME _nlopt)
+    add_library (${SWIG_MODULE_nlopt_REAL_NAME} MODULE nlopt-python.cpp)
+    target_link_libraries(${SWIG_MODULE_nlopt_REAL_NAME} nlopt)
+    target_link_libraries(${SWIG_MODULE_nlopt_REAL_NAME} ${PYTHON_LIBRARIES})
+    set_target_properties (${SWIG_MODULE_nlopt_REAL_NAME} PROPERTIES PREFIX "")
+    if (NOT CMAKE_SOURCE_DIR MATCHES CMAKE_BINARY_DIR)
+      execute_process (COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/nlopt.py ${CMAKE_CURRENT_BINARY_DIR}/nlopt.py)
+    endif ()
+  else ()
+    include (UseSWIG)
+    set_source_files_properties (nlopt.i PROPERTIES CPLUSPLUS ON)
+    set (SWIG_MODULE_nlopt_EXTRA_DEPS nlopt-python.i numpy.i ${CMAKE_SOURCE_DIR}/api/nlopt.hpp)
+
+    swig_add_module (nlopt python nlopt.i)
+    swig_link_libraries (nlopt nlopt)
+    swig_link_libraries (nlopt ${PYTHON_LIBRARIES})
+  endif ()
+  execute_process ( COMMAND ${PYTHON_EXECUTABLE} -c "from distutils import sysconfig; print(sysconfig.get_python_lib(plat_specific=True, prefix='${CMAKE_INSTALL_PREFIX}'))"
+                    OUTPUT_VARIABLE _ABS_PYTHON_MODULE_PATH
+                    OUTPUT_STRIP_TRAILING_WHITESPACE )
+
+  get_filename_component (_ABS_PYTHON_MODULE_PATH ${_ABS_PYTHON_MODULE_PATH} ABSOLUTE)
+  file (RELATIVE_PATH _REL_PYTHON_MODULE_PATH ${CMAKE_INSTALL_PREFIX} ${_ABS_PYTHON_MODULE_PATH})
+
+  set (PYTHON_MODULE_PATH ${_REL_PYTHON_MODULE_PATH})
+
+  install ( FILES ${CMAKE_CURRENT_BINARY_DIR}/nlopt.py DESTINATION ${PYTHON_MODULE_PATH} )
+  install ( TARGETS ${SWIG_MODULE_nlopt_REAL_NAME} LIBRARY DESTINATION ${PYTHON_MODULE_PATH} )
+endif ()
index f460c2d0e2d6badca9ee86597956946de0e01af7..d20a8b1674e9c13249ade741e97bf6c7dfc81c97 100644 (file)
@@ -46,6 +46,7 @@ extern "C"
 #endif /* __cplusplus */
 
 int nlopt_isinf(double x);
+int nlopt_isfinite(double x);
 
 /* re-entrant qsort */
 extern void nlopt_qsort_r(void *base_, size_t nmemb, size_t size, void *thunk,