From fc8fabc2ad30a0f50d03b6f84eaefbf8c7997019 Mon Sep 17 00:00:00 2001 From: stevenj Date: Thu, 18 Nov 2010 18:42:23 -0500 Subject: [PATCH] add get/set subspace dimension for low-storage quasi-Newton methods darcs-hash:20101118234223-c8de0-d7c2ef4736197f0a7e56a568a5987b3a7b5cea7e.gz --- api/f77funcs_.h | 1 + api/nlopt-in.hpp | 1 + api/nlopt-internal.h | 1 + api/nlopt.h | 3 +++ api/optimize.c | 11 +++++++---- api/options.c | 2 ++ luksan/luksan.h | 5 ++++- luksan/plip.c | 10 ++++++---- luksan/plis.c | 12 +++++++----- luksan/pnet.c | 10 ++++++---- octave/nlopt_optimize-mex.c | 1 + octave/nlopt_optimize-oct.cc | 1 + swig/nlopt-exceptions.i | 3 ++- 13 files changed, 42 insertions(+), 19 deletions(-) diff --git a/api/f77funcs_.h b/api/f77funcs_.h index 8641535..9a2dd94 100644 --- a/api/f77funcs_.h +++ b/api/f77funcs_.h @@ -157,6 +157,7 @@ void F77_(nlo_force_stop,NLO_FORCE_STOP)(int *ret, nlopt_opt *opt) { F77_SET(local_optimizer, LOCAL_OPTIMIZER, nlopt_opt) F77_GETSET(population, POPULATION, unsigned) +F77_GETSET(subspace_dim, SUBSPACE_DIM, unsigned) F77_SETA(default_initial_step, DEFAULT_INITIAL_STEP, double) F77_SETA(initial_step, INITIAL_STEP, double) diff --git a/api/nlopt-in.hpp b/api/nlopt-in.hpp index 22251a2..09215fd 100644 --- a/api/nlopt-in.hpp +++ b/api/nlopt-in.hpp @@ -476,6 +476,7 @@ namespace nlopt { } NLOPT_GETSET(unsigned, population) + NLOPT_GETSET(unsigned, subspace_dim) NLOPT_GETSET_VEC(initial_step) void set_default_initial_step(const std::vector &x) { diff --git a/api/nlopt-internal.h b/api/nlopt-internal.h index 7de7c55..388d4e5 100644 --- a/api/nlopt-internal.h +++ b/api/nlopt-internal.h @@ -69,6 +69,7 @@ struct nlopt_opt_s { nlopt_opt local_opt; /* local optimizer */ unsigned stochastic_population; /* population size for stochastic algs */ double *dx; /* initial step sizes (length n) for nonderivative algs */ + unsigned subspace_dim; /* max subspace dimension (0 for default) */ double *work; /* algorithm-specific workspace during optimization */ }; diff --git a/api/nlopt.h b/api/nlopt.h index 2e5fc4b..5f09f2a 100644 --- a/api/nlopt.h +++ b/api/nlopt.h @@ -268,6 +268,9 @@ NLOPT_EXTERN(nlopt_result) nlopt_set_local_optimizer(nlopt_opt opt, NLOPT_EXTERN(nlopt_result) nlopt_set_population(nlopt_opt opt, unsigned pop); NLOPT_EXTERN(unsigned) nlopt_get_population(const nlopt_opt opt); +NLOPT_EXTERN(nlopt_result) nlopt_set_subspace_dim(nlopt_opt opt, unsigned dim); +NLOPT_EXTERN(unsigned) nlopt_get_subspace_dim(const nlopt_opt opt); + NLOPT_EXTERN(nlopt_result) nlopt_set_default_initial_step(nlopt_opt opt, const double *x); NLOPT_EXTERN(nlopt_result) nlopt_set_initial_step(nlopt_opt opt, diff --git a/api/optimize.c b/api/optimize.c index 25e0852..8c8612c 100644 --- a/api/optimize.c +++ b/api/optimize.c @@ -349,18 +349,21 @@ static nlopt_result nlopt_optimize_(nlopt_opt opt, double *x, double *minf) #endif case NLOPT_LD_LBFGS: - return luksan_plis(ni, f, f_data, lb, ub, x, minf, &stop); + return luksan_plis(ni, f, f_data, lb, ub, x, minf, + &stop, opt->subspace_dim); case NLOPT_LD_VAR1: case NLOPT_LD_VAR2: - return luksan_plip(ni, f, f_data, lb, ub, x, minf, &stop, - algorithm == NLOPT_LD_VAR1 ? 1 : 2); + return luksan_plip(ni, f, f_data, lb, ub, x, minf, + &stop, opt->subspace_dim, + algorithm == NLOPT_LD_VAR1 ? 1 : 2); case NLOPT_LD_TNEWTON: case NLOPT_LD_TNEWTON_RESTART: case NLOPT_LD_TNEWTON_PRECOND: case NLOPT_LD_TNEWTON_PRECOND_RESTART: - return luksan_pnet(ni, f, f_data, lb, ub, x, minf, &stop, + return luksan_pnet(ni, f, f_data, lb, ub, x, minf, + &stop, opt->subspace_dim, 1 + (algorithm - NLOPT_LD_TNEWTON) % 2, 1 + (algorithm - NLOPT_LD_TNEWTON) / 2); diff --git a/api/options.c b/api/options.c index 3749b7b..19df40d 100644 --- a/api/options.c +++ b/api/options.c @@ -88,6 +88,7 @@ nlopt_opt NLOPT_STDCALL nlopt_create(nlopt_algorithm algorithm, unsigned n) opt->local_opt = NULL; opt->stochastic_population = 0; + opt->subspace_dim = 0; opt->dx = NULL; opt->work = NULL; @@ -588,6 +589,7 @@ NLOPT_STDCALL nlopt_set_local_optimizer(nlopt_opt opt, /*************************************************************************/ GETSET(population, unsigned, stochastic_population) +GETSET(subspace_dim, unsigned, subspace_dim) /*************************************************************************/ diff --git a/luksan/luksan.h b/luksan/luksan.h index 9e37557..66b9281 100644 --- a/luksan/luksan.h +++ b/luksan/luksan.h @@ -13,13 +13,15 @@ nlopt_result luksan_plis(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_stopping *stop, + int mf); nlopt_result luksan_plip(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, + int mf, int method); nlopt_result luksan_pnet(int n, nlopt_func f, void *f_data, @@ -27,6 +29,7 @@ nlopt_result luksan_pnet(int n, nlopt_func f, void *f_data, double *x, /* in: initial guess, out: minimizer */ double *minf, nlopt_stopping *stop, + int mf, int mos1, int mos2); /***************************** internal routines *************************/ diff --git a/luksan/plip.c b/luksan/plip.c index 7d4e599..2527dde 100644 --- a/luksan/plip.c +++ b/luksan/plip.c @@ -427,6 +427,7 @@ nlopt_result luksan_plip(int n, nlopt_func f, void *f_data, double *x, /* in: initial guess, out: minimizer */ double *minf, nlopt_stopping *stop, + int mf, /* subspace dimension (0 for default) */ int method) /* 1 or 2, see below */ { int i, *ix, nb = 1; @@ -439,7 +440,6 @@ nlopt_result luksan_plip(int n, nlopt_func f, void *f_data, int mfv = stop->maxeval; stat_common stat; int iterm; - int mf; ix = (int*) malloc(sizeof(int) * n); if (!ix) return NLOPT_OUT_OF_MEMORY; @@ -451,9 +451,11 @@ nlopt_result luksan_plip(int n, nlopt_func f, void *f_data, and we'll assume that the main limiting factor is the memory. We'll assume that at least MEMAVAIL memory, or 4*n memory, whichever is bigger, is available. */ - mf = MAX2(MEMAVAIL/n, 4); - if (stop->maxeval && stop->maxeval <= mf) - mf = MAX2(stop->maxeval - 5, 1); /* mf > maxeval seems not good */ + if (mf <= 0) { + mf = MAX2(MEMAVAIL/n, 4); + if (stop->maxeval && stop->maxeval <= mf) + mf = MAX2(stop->maxeval - 5, 1); /* mf > maxeval seems not good */ + } retry_alloc: work = (double*) malloc(sizeof(double) * (n * 7 + MAX2(n,n*mf) + diff --git a/luksan/plis.c b/luksan/plis.c index 03552f0..e3bcde3 100644 --- a/luksan/plis.c +++ b/luksan/plis.c @@ -422,7 +422,8 @@ nlopt_result luksan_plis(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_stopping *stop, + int mf) /* subspace dimension, 0 for default */ { int i, *ix, nb = 1; double *work, *xl, *xu, *xo, *gf, *s, *go, *uo, *vo; @@ -434,7 +435,6 @@ nlopt_result luksan_plis(int n, nlopt_func f, void *f_data, int mfv = stop->maxeval; stat_common stat; int iterm; - int mf; ix = (int*) malloc(sizeof(int) * n); if (!ix) return NLOPT_OUT_OF_MEMORY; @@ -446,9 +446,11 @@ nlopt_result luksan_plis(int n, nlopt_func f, void *f_data, and we'll assume that the main limiting factor is the memory. We'll assume that at least MEMAVAIL memory, or 4*n memory, whichever is bigger, is available. */ - mf = MAX2(MEMAVAIL/n, 4); - if (stop->maxeval && stop->maxeval <= mf) - mf = MAX2(stop->maxeval - 5, 1); /* mf > maxeval seems not good */ + if (mf <= 0) { + mf = MAX2(MEMAVAIL/n, 4); + if (stop->maxeval && stop->maxeval <= mf) + mf = MAX2(stop->maxeval - 5, 1); /* mf > maxeval seems not good */ + } retry_alloc: work = (double*) malloc(sizeof(double) * (n * 4 + MAX2(n,n*mf)*2 + diff --git a/luksan/pnet.c b/luksan/pnet.c index ac009c7..d8d7ac8 100644 --- a/luksan/pnet.c +++ b/luksan/pnet.c @@ -569,6 +569,7 @@ nlopt_result luksan_pnet(int n, nlopt_func f, void *f_data, double *x, /* in: initial guess, out: minimizer */ double *minf, nlopt_stopping *stop, + int mf, /* subspace dimension (0 for default) */ int mos1, int mos2) /* 1 or 2 */ { int i, *ix, nb = 1; @@ -582,7 +583,6 @@ nlopt_result luksan_pnet(int n, nlopt_func f, void *f_data, int mfv = stop->maxeval; stat_common stat; int iterm; - int mf; ix = (int*) malloc(sizeof(int) * n); if (!ix) return NLOPT_OUT_OF_MEMORY; @@ -594,9 +594,11 @@ nlopt_result luksan_pnet(int n, nlopt_func f, void *f_data, and we'll assume that the main limiting factor is the memory. We'll assume that at least MEMAVAIL memory, or 4*n memory, whichever is bigger, is available. */ - mf = MAX2(MEMAVAIL/n, 4); - if (stop->maxeval && stop->maxeval <= mf) - mf = MAX2(stop->maxeval - 5, 1); /* mf > maxeval seems not good */ + if (mf <= 0) { + mf = MAX2(MEMAVAIL/n, 4); + if (stop->maxeval && stop->maxeval <= mf) + mf = MAX2(stop->maxeval - 5, 1); /* mf > maxeval seems not good */ + } retry_alloc: work = (double*) malloc(sizeof(double) * (n * 9 + MAX2(n,n*mf)*2 + diff --git a/octave/nlopt_optimize-mex.c b/octave/nlopt_optimize-mex.c index 56ca0d9..40af901 100644 --- a/octave/nlopt_optimize-mex.c +++ b/octave/nlopt_optimize-mex.c @@ -151,6 +151,7 @@ nlopt_opt make_opt(const mxArray *opts, unsigned n) nlopt_set_maxtime(opt, struct_val_default(opts, "maxtime", 0.0)); nlopt_set_population(opt, struct_val_default(opts, "population", 0)); + nlopt_set_subspace_dim(opt, struct_val_default(opts, "subspace_dim", 0)); if (struct_arrval(opts, "initial_step", n, NULL)) nlopt_set_initial_step(opt, diff --git a/octave/nlopt_optimize-oct.cc b/octave/nlopt_optimize-oct.cc index f5b1dd6..9e11c49 100644 --- a/octave/nlopt_optimize-oct.cc +++ b/octave/nlopt_optimize-oct.cc @@ -177,6 +177,7 @@ nlopt_opt make_opt(Octave_map &opts, int n) nlopt_set_maxtime(opt, struct_val_default(opts, "maxtime", 0.0)); nlopt_set_population(opt, struct_val_default(opts, "population", 0)); + nlopt_set_subspace_dim(opt, struct_val_default(opts, "subspace_dim", 0)); if (opts.contains("initial_step")) { Matrix zeros(1, n, 0.0); diff --git a/swig/nlopt-exceptions.i b/swig/nlopt-exceptions.i index 0eb1942..6dac57a 100644 --- a/swig/nlopt-exceptions.i +++ b/swig/nlopt-exceptions.i @@ -61,7 +61,8 @@ GETSET_EXCEPT(force_stop, int) %catches(std::bad_alloc,std::invalid_argument) nlopt::opt::set_local_optimizer(const opt &lo); -GETSET_EXCEPT(local_population, unsigned) +GETSET_EXCEPT(population, unsigned) +GETSET_EXCEPT(subspace_dim, unsigned) GETSETVEC_EXCEPT(initial_step) %catches(std::bad_alloc,std::invalid_argument) nlopt::opt::set_default_initial_step(const std::vector &x); -- 2.30.2