From d9b49544a6c6854ec2c649776f46445aa37320fa Mon Sep 17 00:00:00 2001 From: stevenj Date: Mon, 1 Sep 2008 02:36:05 -0400 Subject: [PATCH] check bounds in testopt, fix bug in NEWUOA_BOUNDS that allowed it to go outside of the bounds in one case darcs-hash:20080901063605-c8de0-466debf023ac975267a65a9f125ada08c771fb49.gz --- newuoa/newuoa.c | 6 ++++++ test/testopt.cpp | 25 ++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/newuoa/newuoa.c b/newuoa/newuoa.c index 883f30f..8842c3c 100644 --- a/newuoa/newuoa.c +++ b/newuoa/newuoa.c @@ -1744,6 +1744,12 @@ L50: /* L60: */ x[j] = xpt[nf + j * xpt_dim1] + xbase[j]; } + if (lb && ub) { /* SGJ, 2008: make sure we are within bounds */ + for (j = 1; j <= i__1; ++j) { + if (x[j] < lb[j-1]) x[j] = lb[j-1]; + else if (x[j] > ub[j-1]) x[j] = ub[j-1]; + } + } goto L310; L70: fval[nf] = f; diff --git a/test/testopt.cpp b/test/testopt.cpp index 71ac50a..66a74d8 100644 --- a/test/testopt.cpp +++ b/test/testopt.cpp @@ -39,6 +39,24 @@ static void listfuncs(FILE *f) fprintf(f, " %2d: %s (%d dims)\n", i, testfuncs[i].name, testfuncs[i].n); } +typedef struct { + const double *lb, *ub; + nlopt_func f; + void *f_data; +} bounds_wrap_data; + +static double bounds_wrap_func(int n, const double *x, double *grad, void *d_) +{ + bounds_wrap_data *d = (bounds_wrap_data *) d_; + int i; + for (i = 0; i < n; ++i) + if (x[i] < d->lb[i] || x[i] > d->ub[i]) + break; + if (i < n) + fprintf(stderr, "WARNING: bounds violated by x[%d] = %g\n", i, x[i]); + return d->f(n, x, grad, d->f_data); +} + static int test_function(int ifunc) { testfunc func; @@ -48,6 +66,7 @@ static int test_function(int ifunc) double start = nlopt_seconds(); int total_count = 0; double total_err = 0, max_err = 0; + bounds_wrap_data bw; if (ifunc < 0 || ifunc >= NTESTFUNCS) { fprintf(stderr, "testopt: invalid function %d\n", ifunc); @@ -61,6 +80,10 @@ static int test_function(int ifunc) lb = x + func.n * 3; ub = lb + func.n; xtabs = x + func.n * 2; + bw.lb = lb; + bw.ub = ub; + bw.f = func.f; + bw.f_data = func.f_data; for (i = 0; i < func.n; ++i) xtabs[i] = xtol_abs; minf_max = minf_max_delta > (-HUGE_VAL) ? minf_max_delta + func.minf : (-HUGE_VAL); @@ -129,7 +152,7 @@ static int test_function(int ifunc) } ret = nlopt_minimize(algorithm, - func.n, func.f, func.f_data, + func.n, bounds_wrap_func, &bw, lb, ub, x, &minf, minf_max, ftol_rel, ftol_abs, xtol_rel, xtabs, -- 2.30.2