1 /* C-style API for DIRECT functions.  SGJ (August 2007). */
2 
3 #include "direct-internal.h"
4 
5 /* Perform global minimization using (Gablonsky implementation of) DIRECT
6    algorithm.   Arguments:
7 
8    f, f_data: the objective function and any user data
9        -- the objective function f(n, x, undefined_flag, data) takes 4 args:
10               int n: the dimension, same as dimension arg. to direct_optimize
11               const double *x: array x[n] of point to evaluate
12 	      int *undefined_flag: set to 1 on return if x violates constraints
13 	                           or don't touch otherwise
14               void *data: same as f_data passed to direct_optimize
15           return value = value of f(x)
16 
17    dimension: the number of minimization variable dimensions
18    lower_bounds, upper_bounds: arrays of length dimension of variable bounds
19 
20    x: an array of length dimension, set to optimum variables upon return
21    minf: on return, set to minimum f value
22 
23    magic_eps, magic_eps_abs: Jones' "magic" epsilon parameter, and
24                              also an absolute version of the same
25 			     (not multipled by minf).  Jones suggests
26 			     setting this to 1e-4, but 0 also works...
27 
28    max_feval, max_iter: maximum number of function evaluations & DIRECT iters
29    volume_reltol: relative tolerance on hypercube volume (0 if none)
30    sigma_reltol: relative tolerance on hypercube "measure" (??) (0 if none)
31 
32    fglobal: the global minimum of f, if known ahead of time
33        -- this is mainly for benchmarking, in most cases it
34           is not known and you should pass DIRECT_UNKNOWN_FGLOBAL
35    fglobal_reltol: relative tolerance on how close we should find fglobal
36        -- ignored if fglobal is DIRECT_UNKNOWN_FGLOBAL
37 
38    logfile: an output file to write diagnostic info to (NULL for no I/O)
39 
40    algorithm: whether to use the original DIRECT algorithm (DIRECT_ORIGINAL)
41               or Gablonsky's "improved" version (DIRECT_GABLONSKY)
42 */
direct_optimize(direct_objective_func f,void * f_data,int dimension,const double * lower_bounds,const double * upper_bounds,double * x,double * minf,int max_feval,int max_iter,double start,double maxtime,double magic_eps,double magic_eps_abs,double volume_reltol,double sigma_reltol,int * force_stop,double fglobal,double fglobal_reltol,FILE * logfile,direct_algorithm algorithm)43 direct_return_code direct_optimize(
44      direct_objective_func f, void *f_data,
45      int dimension,
46      const double *lower_bounds, const double *upper_bounds,
47 
48      double *x, double *minf,
49 
50      int max_feval, int max_iter,
51      double start, double maxtime,
52      double magic_eps, double magic_eps_abs,
53      double volume_reltol, double sigma_reltol,
54      int *force_stop,
55 
56      double fglobal,
57      double fglobal_reltol,
58 
59      FILE *logfile,
60      direct_algorithm algorithm)
61 {
62      integer algmethod = algorithm == DIRECT_GABLONSKY;
63      integer ierror;
64      doublereal *l, *u;
65      int i;
66 
67      /* convert to percentages: */
68      volume_reltol *= 100;
69      sigma_reltol *= 100;
70      fglobal_reltol *= 100;
71 
72      /* make sure these are ignored if <= 0 */
73      if (volume_reltol <= 0) volume_reltol = -1;
74      if (sigma_reltol <= 0) sigma_reltol = -1;
75 
76      if (fglobal == DIRECT_UNKNOWN_FGLOBAL)
77 	  fglobal_reltol = DIRECT_UNKNOWN_FGLOBAL_RELTOL;
78 
79      if (dimension < 1) return DIRECT_INVALID_ARGS;
80 
81      l = (doublereal *) malloc(sizeof(doublereal) * dimension * 2);
82      if (!l) return DIRECT_OUT_OF_MEMORY;
83      u = l + dimension;
84      for (i = 0; i < dimension; ++i) {
85 	  l[i] = lower_bounds[i];
86 	  u[i] = upper_bounds[i];
87      }
88 
89      direct_direct_(f, x, &dimension, &magic_eps, magic_eps_abs,
90 		    &max_feval, &max_iter,
91 		    start, maxtime, force_stop,
92 		    minf,
93 		    l, u,
94 		    &algmethod,
95 		    &ierror,
96 		    logfile,
97 		    &fglobal, &fglobal_reltol,
98 		    &volume_reltol, &sigma_reltol,
99 		    f_data);
100 
101      free(l);
102 
103      return (direct_return_code) ierror;
104 }
105