+/* Copyright (c) 2007-2014 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "nlopt.h"
#include "cdirect.h"
#include "redblack.h"
-#include "config.h"
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define ALLOC_RECT(rect, L) if (!(rect = (double*) malloc(sizeof(double)*(L)))) return NLOPT_OUT_OF_MEMORY
-static double *fv_qsort = 0;
-static int sort_fv_compare(const void *a_, const void *b_)
+static int sort_fv_compare(void *fv_, const void *a_, const void *b_)
{
+ const double *fv = (const double *) fv_;
int a = *((const int *) a_), b = *((const int *) b_);
- double fa = MIN(fv_qsort[2*a], fv_qsort[2*a+1]);
- double fb = MIN(fv_qsort[2*b], fv_qsort[2*b+1]);
+ double fa = MIN(fv[2*a], fv[2*a+1]);
+ double fb = MIN(fv[2*b], fv[2*b+1]);
if (fa < fb)
return -1;
else if (fa > fb)
{
int i;
for (i = 0; i < n; ++i) isort[i] = i;
- fv_qsort = fv; /* not re-entrant, sigh... */
- qsort(isort, (unsigned) n, sizeof(int), sort_fv_compare);
- fv_qsort = 0;
+ nlopt_qsort_r(isort, (unsigned) n, sizeof(int), fv, sort_fv_compare);
}
static double function_eval(const double *x, params *p) {
p->stop->nevals++;
return f;
}
-#define FUNCTION_EVAL(fv,x,p,freeonerr) fv = function_eval(x, p); if (p->minf < p->stop->minf_max) { free(freeonerr); return NLOPT_MINF_MAX_REACHED; } else if (nlopt_stop_evals((p)->stop)) { free(freeonerr); return NLOPT_MAXEVAL_REACHED; } else if (nlopt_stop_time((p)->stop)) { free(freeonerr); return NLOPT_MAXTIME_REACHED; }
+#define FUNCTION_EVAL(fv,x,p,freeonerr) fv = function_eval(x, p); if (nlopt_stop_forced((p)->stop)) { free(freeonerr); return NLOPT_FORCED_STOP; } else if (p->minf < p->stop->minf_max) { free(freeonerr); return NLOPT_MINF_MAX_REACHED; } else if (nlopt_stop_evals((p)->stop)) { free(freeonerr); return NLOPT_MAXEVAL_REACHED; } else if (nlopt_stop_time((p)->stop)) { free(freeonerr); return NLOPT_MAXTIME_REACHED; }
#define THIRD (0.3333333333333333333333)
static nlopt_result divide_rect(double *rdiv, params *p)
{
int i;
- const const int n = p->n;
+ const int n = p->n;
const int L = p->L;
double *c = rdiv + 3; /* center of rect to divide */
double *w = c + n; /* widths of rect to divide */
do { /* include any duplicate points at (xmax,ymaxmin) */
hull[nhull++] = nmax->k;
nmax = rb_tree_succ(nmax);
- } while (nmax && nmax->k[0] == xmax && n->k[1] == ymaxmin);
+ } while (nmax && nmax->k[0] == xmax && nmax->k[1] == ymaxmin);
else
hull[nhull++] = nmax->k;
int im, ip;
/* find unequal points before (im) and after (ip) to get slope */
- for (im = i-1; im >= 0 && hull[im][0] == hull[i][0]; --im);
- for (ip = i+1; ip < nhull && hull[ip][0] == hull[i][0]; ++ip);
+ for (im = i-1; im >= 0 && hull[im][0] == hull[i][0]; --im) ;
+ for (ip = i+1; ip < nhull && hull[ip][0] == hull[i][0]; ++ip) ;
if (im >= 0)
K1 = (hull[i][1] - hull[im][1]) / (hull[i][0] - hull[im][0]);
if (ip < nhull)
- K1 = (hull[i][1] - hull[ip][1]) / (hull[i][0] - hull[ip][0]);
+ K2 = (hull[i][1] - hull[ip][1]) / (hull[i][0] - hull[ip][0]);
K = MAX(K1, K2);
if (hull[i][1] - K * hull[i][0]
<= p->minf - magic_eps * fabs(p->minf) || ip == nhull) {
coordinates to a unit hypercube ... we do this simply by
wrapping cdirect() around cdirect_unscaled(). */
-double cdirect_uf(int n, const double *xu, double *grad, void *d_)
+double cdirect_uf(unsigned n, const double *xu, double *grad, void *d_)
{
cdirect_uf_data *d = (cdirect_uf_data *) d_;
double f;
- int i;
+ unsigned i;
for (i = 0; i < n; ++i)
d->x[i] = d->lb[i] + xu[i] * (d->ub[i] - d->lb[i]);
f = d->f(n, d->x, grad, d->f_data);