From: stevenj Date: Thu, 13 Sep 2007 20:06:09 +0000 (-0400) Subject: added first version of MLSL multistart-type algorithm X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=8068ae4d59f9bbbb195a253f40ce46150fb445f5;p=nlopt.git added first version of MLSL multistart-type algorithm darcs-hash:20070913200609-c8de0-b0e9b03737e97fb885b5a7a4305e79f6cd21a18f.gz --- diff --git a/Makefile.am b/Makefile.am index d0949db..e33c24b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,13 +3,14 @@ lib_LTLIBRARIES = libnlopt.la ACLOCAL_AMFLAGS=-I ./m4 -SUBDIRS= util subplex direct cdirect stogo praxis luksan crs api octave . test +SUBDIRS= util subplex direct cdirect stogo praxis luksan crs mlsl api octave . test EXTRA_DIST=COPYRIGHT autogen.sh nlopt.pc.in m4 libnlopt_la_SOURCES = libnlopt_la_LIBADD = subplex/libsubplex.la direct/libdirect.la \ cdirect/libcdirect.la stogo/libstogo.la praxis/libpraxis.la \ -luksan/libluksan.la crs/libcrs.la api/libapi.la util/libutil.la +luksan/libluksan.la crs/libcrs.la mlsl/libmlsl.la api/libapi.la \ +util/libutil.la libnlopt_la_LDFLAGS = -no-undefined -version-info @SHARED_VERSION_INFO@ diff --git a/api/Makefile.am b/api/Makefile.am index 63634e0..4bec3cd 100644 --- a/api/Makefile.am +++ b/api/Makefile.am @@ -1,4 +1,4 @@ -AM_CPPFLAGS = -I$(top_srcdir)/cdirect -I$(top_srcdir)/direct -I$(top_srcdir)/stogo -I$(top_srcdir)/subplex -I$(top_srcdir)/praxis -I$(top_srcdir)/luksan -I$(top_srcdir)/crs -I$(top_srcdir)/util +AM_CPPFLAGS = -I$(top_srcdir)/cdirect -I$(top_srcdir)/direct -I$(top_srcdir)/stogo -I$(top_srcdir)/subplex -I$(top_srcdir)/praxis -I$(top_srcdir)/luksan -I$(top_srcdir)/crs -I$(top_srcdir)/mlsl -I$(top_srcdir)/util include_HEADERS = nlopt.h noinst_LTLIBRARIES = libapi.la diff --git a/api/nlopt.c b/api/nlopt.c index 732a5d8..f605753 100644 --- a/api/nlopt.c +++ b/api/nlopt.c @@ -62,8 +62,10 @@ static const char nlopt_algorithm_names[NLOPT_NUM_ALGORITHMS][256] = { "Preconditioned truncated Newton (local, derivative-based)", "Preconditioned truncated Newton with restarting (local, derivative-based)", "Controlled random search (CRS2) with local mutation (global, no-derivative)", - "Controlled quasi-random search (CRS2) with local mutation (global, no-derivative), using Sobol' LDS", - + "Multi-level single-linkage (MLSL), random (global, no-derivative)", + "Multi-level single-linkage (MLSL), random (global, derivative)", + "Multi-level single-linkage (MLSL), quasi-random (global, no-derivative)", + "Multi-level single-linkage (MLSL), quasi-random (global, derivative)" }; const char *nlopt_algorithm_name(nlopt_algorithm a) @@ -331,6 +333,18 @@ static nlopt_result nlopt_minimize_( case NLOPT_GN_CRS2_LM: return crs_minimize(n, f, f_data, lb, ub, x, minf, &stop, 0); + case NLOPT_GN_MLSL: + case NLOPT_GD_MLSL: + case NLOPT_GN_MLSL_LDS: + case NLOPT_GD_MLSL_LDS: + return mlsl_minimize(n, f, f_data, lb, ub, x, minf, &stop, + (algorithm == NLOPT_GN_MLSL || + algorithm == NLOPT_GN_MLSL_LDS) + ? local_search_alg_nonderiv + : local_search_alg_deriv, + local_search_maxeval, + algorithm >= NLOPT_GN_MLSL_LDS); + default: return NLOPT_INVALID_ARGS; } diff --git a/api/nlopt.h b/api/nlopt.h index 750d308..a6f129b 100644 --- a/api/nlopt.h +++ b/api/nlopt.h @@ -52,6 +52,11 @@ typedef enum { NLOPT_GN_CRS2_LM, + NLOPT_GN_MLSL, + NLOPT_GD_MLSL, + NLOPT_GN_MLSL_LDS, + NLOPT_GD_MLSL_LDS, + NLOPT_NUM_ALGORITHMS /* not an algorithm, just the number of them */ } nlopt_algorithm; diff --git a/api/nlopt_minimize.3 b/api/nlopt_minimize.3 index b208d02..22f795f 100644 --- a/api/nlopt_minimize.3 +++ b/api/nlopt_minimize.3 @@ -283,6 +283,22 @@ other variants of this algorithm: Global (G) derivative-free (N) optimization using controlled random search (CRS2) algorithm of Price, with the "local mutation" (LM) modification suggested by Kaelo and Ali. +.TP +\fBNLOPT_GD_MLSL_LDS\fR, \fBNLOPT_GN_MLSL_LDS\fR +Global (G) derivative-based (D) or derivative-free (N) optimization +using the multi-level single-linkage (MLSL) algorithm with a +low-discrepancy sequence (LDS). This algorithm executes a quasi-random +(LDS) sequence of local searches, with a clustering heuristic to +avoid multiple local searches for the same local minimum. The local +search uses the derivative/nonderivative algorithm set by +.I nlopt_set_local_search_algorithm +(currently defaulting to +.I NLOPT_LD_LBFGS +and +.I NLOPT_LN_SUBPLEX +for derivative/nonderivative searches, respectively). There are also +two other variants, \fBNLOPT_GD_MLSL\fR and \fBNLOPT_GN_MLSL\fR, which use +pseudo-random numbers (instead of an LDS) as in the original MLSL algorithm. .SH STOPPING CRITERIA Multiple stopping criteria for the optimization are supported, as specified by the following arguments to @@ -410,6 +426,10 @@ you want to use deterministic random numbers, you can set the seed by calling: .sp .BI " void nlopt_srand(unsigned long " "seed" ); +.sp +Some of the algorithms also support using low-discrepancy sequences (LDS), +sometimes known as quasi-random numbers. NLopt uses the Sobol LDS, which +is implemented for up to 1111 dimensions. .SH BUGS Currently the NLopt library is in pre-alpha stage. Most algorithms currently do not support all termination conditions: the only diff --git a/configure.ac b/configure.ac index e4ac3d7..ef97129 100644 --- a/configure.ac +++ b/configure.ac @@ -182,6 +182,7 @@ AC_CONFIG_FILES([ praxis/Makefile luksan/Makefile crs/Makefile + mlsl/Makefile test/Makefile ]) diff --git a/mlsl/Makefile.am b/mlsl/Makefile.am new file mode 100644 index 0000000..b019c2c --- /dev/null +++ b/mlsl/Makefile.am @@ -0,0 +1,6 @@ +AM_CPPFLAGS = -I$(top_srcdir)/util -I$(top_srcdir)/api + +noinst_LTLIBRARIES = libmlsl.la +libmlsl_la_SOURCES = mlsl.c mlsl.h + +EXTRA_DIST = README diff --git a/mlsl/README b/mlsl/README new file mode 100644 index 0000000..feeb9cd --- /dev/null +++ b/mlsl/README @@ -0,0 +1,22 @@ +This is my implementation of the "Multi-Level Single-Linkage" (MLSL) +algorithm for global optimization by random local optimizations (a +multistart algorithm with "clustering" to avoid repeated detection of +the same local minimum), modified to optionally use a Sobol' +low-discrepancy sequence (LDS) instead of pseudorandom numbers. See: + + A. H. G. Rinnooy Kan and G. T. Timmer, "Stochastic global optimization + methods," Mathematical Programming, vol. 39, p. 27-78 (1978). + [ actually 2 papers -- part I: clustering methods (p. 27), then + part II: multilevel methods (p. 57) ] + +and also: + + Sergei Kucherenko and Yury Sytsko, "Application of deterministic + low-discrepancy sequences in global optimization," Computational + Optimization and Applications, vol. 30, p. 297-318 (2005). + +It is under the same MIT license as the rest of my code in NLopt (see +../COPYRIGHT). + +Steven G. Johnson +September 2007 diff --git a/mlsl/mlsl.c b/mlsl/mlsl.c new file mode 100644 index 0000000..f1b90a4 --- /dev/null +++ b/mlsl/mlsl.c @@ -0,0 +1,406 @@ +/* Multi-Level Single-Linkage (MLSL) algorithm for + global optimization by random local optimizations (a multistart algorithm + with "clustering" to avoid repeated detection of the same local minimum), + modified to optionally use a Sobol' low-discrepancy sequence (LDS) instead + of pseudorandom numbers. See: + + A. H. G. Rinnooy Kan and G. T. Timmer, "Stochastic global optimization + methods," Mathematical Programming, vol. 39, p. 27-78 (1978). + [ actually 2 papers -- part I: clustering methods (p. 27), then + part II: multilevel methods (p. 57) ] + + and also: + + Sergei Kucherenko and Yury Sytsko, "Application of deterministic + low-discrepancy sequences in global optimization," Computational + Optimization and Applications, vol. 30, p. 297-318 (2005). + + Compared to the above papers, I made a couple other modifications + to the algorithm besides the use of a LDS. + + 1) first, the original algorithm suggests discarding points + within a *fixed* distance of the boundaries or of previous + local minima; I changed this to a distance that decreases with, + iteration, proportional to the same threshold radius used + for clustering. (In the case of the boundaries, I make + the proportionality constant rather small as well.) + + 2) Kan and Timmer suggest using fancy "spiral-search" algorithms + to quickly locate nearest-neighbor points, reducing the + overall time for N sample points from O(N^2) to O(N log N) + However, recent papers seem to show that such schemes (kd trees, + etcetera) become inefficient for high-dimensional spaces (d > 20), + and finding a better approach seems to be an open question. Therefore, + since I am mainly interested in MLSL for high-dimensional problems + (in low dimensions we have DIRECT etc.), I punted on this question + for now. In practice, O(N^2) (which does not count the #points + evaluated in local searches) does not seem too bad if the objective + function is expensive. + +*/ + +#include +#include +#include + +#include "redblack.h" +#include "mlsl.h" + +/* data structure for each random/quasirandom point in the population */ +typedef struct { + double f; /* function value at x */ + int minimized; /* if we have already minimized starting from x */ + double closest_pt_d; /* distance^2 to closest pt with smaller f */ + double closest_lm_d; /* distance^2 to closest lm with smaller f*/ + double x[1]; /* array of length n (K&R struct hack) */ +} pt; + +/* all of the data used by the various mlsl routines...it's + not clear in hindsight that we need to put all of this in a data + structure since most of the work occurs in a single routine, + but it doesn't hurt us */ +typedef struct { + int n; /* # dimensions */ + const double *lb, *ub; + nlopt_stopping *stop; /* stopping criteria */ + nlopt_func f; void *f_data; + + rb_tree pts; /* tree of points (k == pt), sorted by f */ + rb_tree lms; /* tree of local minimizers, sorted by function value + (k = array of length d+1, [0] = f, [1..d] = x) */ + + nlopt_sobol s; /* sobol data for LDS point generation, or NULL + to use pseudo-random numbers */ + + nlopt_algorithm local_alg; /* local search algorithm */ + int local_maxeval; /* max # local iterations (0 if unlimited) */ + + double R_prefactor, dlm, dbound, gamma; /* parameters of MLSL */ + int N; /* number of pts to add per iteration */ +} mlsl_data; + +/* comparison routines to sort the red-black trees by function value */ +static int pt_compare(rb_key p1_, rb_key p2_) +{ + pt *p1 = (pt *) p1_; + pt *p2 = (pt *) p2_; + if (p1->f < p2->f) return -1; + if (p1->f > p2->f) return +1; + return 0; +} +static int lm_compare(double *k1, double *k2) +{ + if (*k1 < *k2) return -1; + if (*k1 > *k2) return +1; + return 0; +} + +/* Euclidean distance |x1 - x2|^2 */ +static double distance2(int n, const double *x1, const double *x2) +{ + int i; + double d = 0.; + for (i = 0; i < n; ++i) { + double dx = x1[i] - x2[i]; + d += dx * dx; + } + return d; +} + +/* find the closest pt to p with a smaller function value; + this function is called when p is first added to our tree */ +static void find_closest_pt(int n, rb_tree *pts, pt *p) +{ + rb_node *node = rb_tree_find_lt(pts, (rb_key) p); + double closest_d = HUGE_VAL; + while (node) { + double d = distance2(n, p->x, ((pt *) node->k)->x); + if (d < closest_d) closest_d = d; + node = rb_tree_pred(node); + } + p->closest_pt_d = closest_d; +} + +/* find the closest local minimizer (lm) to p with a smaller function value; + this function is called when p is first added to our tree */ +static void find_closest_lm(int n, rb_tree *lms, pt *p) +{ + rb_node *node = rb_tree_find_lt(lms, &p->f); + double closest_d = HUGE_VAL; + while (node) { + double d = distance2(n, p->x, node->k+1); + if (d < closest_d) closest_d = d; + node = rb_tree_pred(node); + } + p->closest_lm_d = closest_d; +} + +/* given newpt, which presumably has just been added to our + tree, update all pts with a greater function value in case + newpt is closer to them than their previous closest_pt ... + we can ignore already-minimized points since we never do + local minimization from the same point twice */ +static void pts_update_newpt(int n, rb_tree *pts, pt *newpt) +{ + rb_node *node = rb_tree_find_gt(pts, (rb_key) newpt); + while (node) { + pt *p = (pt *) node->k; + if (!p->minimized) { + double d = distance2(n, newpt->x, p->x); + if (d < p->closest_pt_d) p->closest_pt_d = d; + } + node = rb_tree_succ(node); + } +} + +/* given newlm, which presumably has just been added to our + tree, update all pts with a greater function value in case + newlm is closer to them than their previous closest_lm ... + we can ignore already-minimized points since we never do + local minimization from the same point twice */ +static void pts_update_newlm(int n, rb_tree *pts, double *newlm) +{ + pt tmp_pt; + rb_node *node; + tmp_pt.f = newlm[0]; + node = rb_tree_find_gt(pts, (rb_key) &tmp_pt); + while (node) { + pt *p = (pt *) node->k; + if (!p->minimized) { + double d = distance2(n, newlm+1, p->x); + if (d < p->closest_lm_d) p->closest_lm_d = d; + } + node = rb_tree_succ(node); + } +} + +static int is_potential_minimizer(mlsl_data *mlsl, pt *p, + double dpt_min, + double dlm_min, + double dbound_min) +{ + int i, n = mlsl->n; + const double *lb = mlsl->lb; + const double *ub = mlsl->ub; + const double *x = p->x; + + if (p->minimized) + return 0; + + if (p->closest_pt_d <= dpt_min*dpt_min) + return 0; + + if (p->closest_lm_d <= dlm_min*dlm_min) + return 0; + + for (i = 0; i < n; ++i) + if (x[i] - lb[i] <= dbound_min || ub[i] - x[i] <= dbound_min) + return 0; + + return 1; +} + +#define K2PI (6.2831853071795864769252867665590057683943388) + +/* compute Gamma(1 + n/2)^{1/n} ... this is a constant factor + used in MLSL as part of the minimum-distance cutoff*/ +static double gam(int n) +{ + /* use Stirling's approximation: + Gamma(1 + z) ~ sqrt(2*pi*z) * z^z / exp(z) + ... this is more than accurate enough for our purposes + (error in gam < 15% for d=1, < 4% for d=2, < 2% for d=3, ...) + and avoids overflow problems because we can combine it with + the ^{1/n} exponent */ + double z = n/2; + return sqrt(pow(K2PI * z, 1.0/n) * z) * exp(-0.5); +} + +static pt *alloc_pt(int n) +{ + pt *p = (pt *) malloc(sizeof(pt) + (n-1) * sizeof(double)); + if (p) { + p->minimized = 0; + p->closest_pt_d = HUGE_VAL; + p->closest_lm_d = HUGE_VAL; + } + return p; +} + +/* wrapper around objective function that increments evaluation count */ +static double fcount(int n, const double *x, double *grad, void *p_) +{ + mlsl_data *p = (mlsl_data *) p_; + p->stop->nevals++; + return p->f(n, x, grad, p->f_data); +} + +static void get_minf(mlsl_data *d, double *minf, double *x) +{ + rb_node *node = rb_tree_min(&d->pts); + if (node) { + *minf = ((pt *) node->k)->f; + memcpy(x, ((pt *) node->k)->x, sizeof(double) * d->n); + } + node = rb_tree_min(&d->lms); + if (node && node->k[0] < *minf) { + *minf = node->k[0]; + memcpy(x, node->k + 1, sizeof(double) * d->n); + } +} + +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + +#define MLSL_SIGMA 2. /* MLSL sigma parameter, using value from the papers */ +#define MLSL_GAMMA 0.3 /* MLSL gamma parameter (FIXME: what should it be?) */ + +nlopt_result mlsl_minimize(int n, nlopt_func f, void *f_data, + const double *lb, const double *ub, /* bounds */ + double *x, /* in: initial guess, out: minimizer */ + double *minf, + nlopt_stopping *stop, + nlopt_algorithm local_alg, + int local_maxeval, + int lds) /* random or low-discrepancy seq. (lds) */ +{ + nlopt_result ret = NLOPT_SUCCESS; + mlsl_data d; + int i; + pt *p; + + d.n = n; + d.lb = lb; d.ub = ub; + d.stop = stop; + d.f = f; d.f_data = f_data; + rb_tree_init(&d.pts, pt_compare); + rb_tree_init(&d.lms, lm_compare); + d.s = lds ? nlopt_sobol_create((unsigned) n) : NULL; + d.local_alg = local_alg; d.local_maxeval = local_maxeval; + + d.gamma = MLSL_GAMMA; + d.N = 4; /* FIXME: what is good number of samples per iteration? */ + + d.R_prefactor = sqrt(2./K2PI) * pow(gam(n) * MLSL_SIGMA, 1.0/n); + for (i = 0; i < n; ++i) + d.R_prefactor *= pow(ub[i] - lb[i], 1.0/n); + + /* MLSL also suggests setting some minimum distance from points + to previous local minimiza and to the boundaries; I don't know + how to choose this as a fixed number, so I set it proportional + to R; see also the comments at top. dlm and dbound are the + proportionality constants. */ + d.dlm = 1.0; /* min distance/R to local minima (FIXME: good value?) */ + d.dbound = 1e-6; /* min distance/R to ub/lb boundaries (good value?) */ + + + p = alloc_pt(n); + if (!p) { ret = NLOPT_OUT_OF_MEMORY; goto done; } + + /* FIXME: how many sobol points to skip, if any? */ + nlopt_sobol_skip(d.s, (unsigned) (10*n+1), p->x); + + memcpy(p->x, x, n * sizeof(double)); + p->f = f(n, x, NULL, f_data); + stop->nevals++; + if (!rb_tree_insert(&d.pts, (rb_key) p)) { + free(p); ret = NLOPT_OUT_OF_MEMORY; + } + if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED; + else if (nlopt_stop_time(stop)) ret = NLOPT_MAXEVAL_REACHED; + else if (p->f < stop->minf_max) ret = NLOPT_MINF_MAX_REACHED; + + while (ret == NLOPT_SUCCESS) { + rb_node *node; + double R; + + get_minf(&d, minf, x); + + /* sampling phase: add random/quasi-random points */ + for (i = 0; i < d.N && ret == NLOPT_SUCCESS; ++i) { + p = alloc_pt(n); + if (!p) { ret = NLOPT_OUT_OF_MEMORY; goto done; } + if (d.s) nlopt_sobol_next(d.s, p->x, lb, ub); + else { /* use random points instead of LDS */ + int j; + for (j = 0; j < n; ++j) p->x[j] = nlopt_urand(lb[j],ub[j]); + } + p->f = f(n, p->x, NULL, f_data); + stop->nevals++; + if (!rb_tree_insert(&d.pts, (rb_key) p)) { + free(p); ret = NLOPT_OUT_OF_MEMORY; + } + if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED; + else if (nlopt_stop_time(stop)) ret = NLOPT_MAXEVAL_REACHED; + else if (p->f < stop->minf_max) ret = NLOPT_MINF_MAX_REACHED; + else { + find_closest_pt(n, &d.pts, p); + find_closest_lm(n, &d.lms, p); + pts_update_newpt(n, &d.pts, p); + } + } + + /* distance threshhold parameter R in MLSL */ + R = d.R_prefactor + * pow(log((double) d.pts.N) / d.pts.N, 1.0 / n); + + /* local search phase: do local opt. for promising points */ + node = rb_tree_min(&d.pts); + for (i = (int) (ceil(d.gamma * d.pts.N) + 0.5); + node && i > 0 && ret == NLOPT_SUCCESS; --i) { + p = (pt *) node->k; + if (is_potential_minimizer(&d, p, + R, d.dlm*R, d.dbound*R)) { + nlopt_result lret; + double *lm; + double t = nlopt_seconds(); + + if (nlopt_stop_evals(stop)) { + ret = NLOPT_MAXEVAL_REACHED; break; + } + if (stop->maxtime > 0 && + t - stop->start >= stop->maxtime) { + ret = NLOPT_MAXTIME_REACHED; break; + } + lm = (double *) malloc(sizeof(double) * (n+1)); + if (!lm) { ret = NLOPT_OUT_OF_MEMORY; goto done; } + memcpy(lm+1, p->x, sizeof(double) * n); + lret = nlopt_minimize(local_alg, n, fcount, &d, + lb, ub, lm+1, lm, + stop->minf_max, + stop->ftol_rel, stop->ftol_abs, + stop->xtol_rel, stop->xtol_abs, + local_maxeval > 0 ? + MIN(local_maxeval, + stop->maxeval - stop->nevals) + : stop->maxeval - stop->nevals, + stop->maxtime - (t - stop->start)); + p->minimized = 1; + if (lret < 0) { free(lm); ret = lret; goto done; } + if (!rb_tree_insert(&d.lms, lm)) { + free(lm); ret = NLOPT_OUT_OF_MEMORY; + } + else if (*lm < stop->minf_max) + ret = NLOPT_MINF_MAX_REACHED; + else if (nlopt_stop_evals(stop)) + ret = NLOPT_MAXEVAL_REACHED; + else if (nlopt_stop_time(stop)) + ret = NLOPT_MAXTIME_REACHED; + else + pts_update_newlm(n, &d.pts, lm); + } + + /* TODO: additional stopping criteria based + e.g. on improvement in function values, etc? */ + + node = rb_tree_succ(node); + } + } + + get_minf(&d, minf, x); + + done: + nlopt_sobol_destroy(d.s); + rb_tree_destroy_with_keys(&d.lms); + rb_tree_destroy_with_keys(&d.pts); + return ret; +} diff --git a/mlsl/mlsl.h b/mlsl/mlsl.h new file mode 100644 index 0000000..e748b9c --- /dev/null +++ b/mlsl/mlsl.h @@ -0,0 +1,26 @@ +#ifndef MLSL_H +#define MLSL_H + +#include "nlopt.h" +#include "nlopt-util.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +nlopt_result mlsl_minimize(int n, nlopt_func f, void *f_data, + const double *lb, const double *ub, /* bounds */ + double *x, /* in: initial guess, out: minimizer */ + double *minf, + nlopt_stopping *stop, + nlopt_algorithm local_alg, + int local_maxeval, + int lds); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif + diff --git a/octave/Makefile.am b/octave/Makefile.am index 2fd66bf..18265d1 100644 --- a/octave/Makefile.am +++ b/octave/Makefile.am @@ -1,6 +1,6 @@ AM_CPPFLAGS = -I$(top_srcdir)/api -MFILES = NLOPT_GN_DIRECT.m NLOPT_GN_DIRECT_L.m NLOPT_GN_DIRECT_L_RAND.m NLOPT_GN_DIRECT_NOSCAL.m NLOPT_GN_DIRECT_L_NOSCAL.m NLOPT_GN_DIRECT_L_RAND_NOSCAL.m NLOPT_GN_ORIG_DIRECT.m NLOPT_GN_ORIG_DIRECT_L.m NLOPT_LN_SUBPLEX.m NLOPT_GD_STOGO.m NLOPT_GD_STOGO_RAND.m NLOPT_LD_LBFGS.m NLOPT_LN_PRAXIS.m NLOPT_LD_VAR1.m NLOPT_LD_VAR2.m NLOPT_LD_TNEWTON.m NLOPT_LD_TNEWTON_RESTART.m NLOPT_LD_TNEWTON_PRECOND.m NLOPT_LD_TNEWTON_PRECOND_RESTART.m NLOPT_GN_CRS2_LM.m +MFILES = NLOPT_GN_DIRECT.m NLOPT_GN_DIRECT_L.m NLOPT_GN_DIRECT_L_RAND.m NLOPT_GN_DIRECT_NOSCAL.m NLOPT_GN_DIRECT_L_NOSCAL.m NLOPT_GN_DIRECT_L_RAND_NOSCAL.m NLOPT_GN_ORIG_DIRECT.m NLOPT_GN_ORIG_DIRECT_L.m NLOPT_LN_SUBPLEX.m NLOPT_GD_STOGO.m NLOPT_GD_STOGO_RAND.m NLOPT_LD_LBFGS.m NLOPT_LN_PRAXIS.m NLOPT_LD_VAR1.m NLOPT_LD_VAR2.m NLOPT_LD_TNEWTON.m NLOPT_LD_TNEWTON_RESTART.m NLOPT_LD_TNEWTON_PRECOND.m NLOPT_LD_TNEWTON_PRECOND_RESTART.m NLOPT_GN_CRS2_LM.m NLOPT_GN_MLSL.m NLOPT_GD_MLSL.m NLOPT_GN_MLSL_LDS.m NLOPT_GD_MLSL_LDS.m ####################################################################### octdir = $(OCT_INSTALL_DIR) diff --git a/octave/NLOPT_GD_MLSL.m b/octave/NLOPT_GD_MLSL.m new file mode 100644 index 0000000..9cc25ea --- /dev/null +++ b/octave/NLOPT_GD_MLSL.m @@ -0,0 +1,5 @@ +% NLOPT_GD_MLSL: Multi-level single-linkage (MLSL), random (global, derivative) +% +% See nlopt_minimize for more information. +function val = NLOPT_GD_MLSL + val = 21; diff --git a/octave/NLOPT_GD_MLSL_LDS.m b/octave/NLOPT_GD_MLSL_LDS.m new file mode 100644 index 0000000..73c1ef1 --- /dev/null +++ b/octave/NLOPT_GD_MLSL_LDS.m @@ -0,0 +1,5 @@ +% NLOPT_GD_MLSL_LDS: Multi-level single-linkage (MLSL), quasi-random (global, derivative) +% +% See nlopt_minimize for more information. +function val = NLOPT_GD_MLSL_LDS + val = 23; diff --git a/octave/NLOPT_GN_MLSL.m b/octave/NLOPT_GN_MLSL.m new file mode 100644 index 0000000..4642de0 --- /dev/null +++ b/octave/NLOPT_GN_MLSL.m @@ -0,0 +1,5 @@ +% NLOPT_GN_MLSL: Multi-level single-linkage (MLSL), random (global, no-derivative) +% +% See nlopt_minimize for more information. +function val = NLOPT_GN_MLSL + val = 20; diff --git a/octave/NLOPT_GN_MLSL_LDS.m b/octave/NLOPT_GN_MLSL_LDS.m new file mode 100644 index 0000000..bdde5ba --- /dev/null +++ b/octave/NLOPT_GN_MLSL_LDS.m @@ -0,0 +1,5 @@ +% NLOPT_GN_MLSL_LDS: Multi-level single-linkage (MLSL), quasi-random (global, no-derivative) +% +% See nlopt_minimize for more information. +function val = NLOPT_GN_MLSL_LDS + val = 22; diff --git a/octave/nlopt_minimize.m b/octave/nlopt_minimize.m index 43f6975..931381d 100644 --- a/octave/nlopt_minimize.m +++ b/octave/nlopt_minimize.m @@ -52,7 +52,15 @@ % optimization. Names with _*N_ are derivative-free, while names % with _*D_ are gradient-based algorithms. Algorithms: % -% NLOPT_GN_DIRECT, NLOPT_GN_DIRECT_L, NLOPT_GN_DIRECT_L_RAND, NLOPT_GN_DIRECT_NOSCAL, NLOPT_GN_DIRECT_L_NOSCAL, NLOPT_GN_DIRECT_L_RAND_NOSCAL, NLOPT_GN_ORIG_DIRECT, NLOPT_GN_ORIG_DIRECT_L, NLOPT_LN_SUBPLEX, NLOPT_GD_STOGO, NLOPT_GD_STOGO_RAND, NLOPT_LD_LBFGS, NLOPT_LN_PRAXIS, NLOPT_LD_VAR1, NLOPT_LD_VAR2, NLOPT_LD_TNEWTON, NLOPT_LD_TNEWTON_RESTART, NLOPT_LD_TNEWTON_PRECOND, NLOPT_LD_TNEWTON_PRECOND_RESTART, NLOPT_GN_CRS2_LM +% NLOPT_GN_DIRECT, NLOPT_GN_DIRECT_L, NLOPT_GN_DIRECT_L_RAND, +% NLOPT_GN_DIRECT_NOSCAL, NLOPT_GN_DIRECT_L_NOSCAL, +% NLOPT_GN_DIRECT_L_RAND_NOSCAL, NLOPT_GN_ORIG_DIRECT, +% NLOPT_GN_ORIG_DIRECT_L, NLOPT_LN_SUBPLEX, NLOPT_GD_STOGO, +% NLOPT_GD_STOGO_RAND, NLOPT_LD_LBFGS, NLOPT_LN_PRAXIS, +% NLOPT_LD_VAR1, NLOPT_LD_VAR2, NLOPT_LD_TNEWTON, +% NLOPT_LD_TNEWTON_RESTART, NLOPT_LD_TNEWTON_PRECOND, +% NLOPT_LD_TNEWTON_PRECOND_RESTART, NLOPT_GN_CRS2_LM, NLOPT_GN_MLSL, +% NLOPT_GD_MLSL, NLOPT_GN_MLSL_LDS, NLOPT_GD_MLSL_LDS % % For more information on individual functions, see their individual % help pages (e.g. "help NLOPT_LN_SUBPLEX").