2 Downloaded from http://www.netlib.org/opt/subplex.tgz
4 README file for SUBPLEX
7 subplex - subspace-searching simplex method for unconstrained
11 Subplex is a subspace-searching simplex method for the
12 unconstrained optimization of general multivariate functions.
13 Like the Nelder-Mead simplex method it generalizes, the subplex
14 method is well suited for optimizing noisy objective functions.
15 The number of function evaluations required for convergence
16 typically increases only linearly with the problem size, so for
17 most applications the subplex method is much more efficient than
21 To build subplex on UNIX systems, edit the Makefile as necessary
26 This will create a linkable library named subplex.a and a
27 demonstration executable named demo.
30 To run subplex on a simple objective function type:
34 To run subplex on other problems, edit a copy of the sample driver
39 Oak Ridge National Laboratory
40 Mathematical Sciences Section
41 P.O. Box 2008, Bldg. 6012
42 Oak Ridge, TN 37831-6367
46 Email: na.rowan@na-net.ornl.gov
49 T. Rowan, "Functional Stability Analysis of Numerical Algorithms",
50 Ph.D. thesis, Department of Computer Sciences, University of Texas
54 Please send comments, suggestions, or bug reports to
55 na.rowan@na-net.ornl.gov.
65 typedef double doublereal;
72 typedef subplex_func D_fp;
74 #define max(a,b) ((a) > (b) ? (a) : (b))
75 #define min(a,b) ((a) < (b) ? (a) : (b))
76 #define abs(x) fabs(x)
78 /****************************************************************************/
79 /****************************************************************************/
81 /* dasum.f -- translated by f2c (version 19991025).
82 You must link the resulting object file with the libraries:
83 -lf2c -lm (in that order)
86 static doublereal dasum_(integer *n, doublereal *dx, integer *incx)
88 /* System generated locals */
90 doublereal ret_val, d__1, d__2, d__3, d__4, d__5, d__6;
98 /* takes the sum of the absolute values. */
99 /* uses unrolled loops for increment equal to one. */
100 /* jack dongarra, linpack, 3/11/78. */
101 /* modified to correct problem with negative increment, 8/21/90. */
104 /* Parameter adjustments */
117 /* code for increment not equal to 1 */
121 ix = (-(*n) + 1) * *incx + 1;
124 for (i__ = 1; i__ <= i__1; ++i__) {
125 dtemp += (d__1 = dx[ix], abs(d__1));
132 /* code for increment equal to 1 */
143 for (i__ = 1; i__ <= i__1; ++i__) {
144 dtemp += (d__1 = dx[i__], abs(d__1));
153 for (i__ = mp1; i__ <= i__1; i__ += 6) {
154 dtemp = dtemp + (d__1 = dx[i__], abs(d__1)) + (d__2 = dx[i__ + 1],
155 abs(d__2)) + (d__3 = dx[i__ + 2], abs(d__3)) + (d__4 = dx[i__
156 + 3], abs(d__4)) + (d__5 = dx[i__ + 4], abs(d__5)) + (d__6 =
157 dx[i__ + 5], abs(d__6));
165 /* daxpy.f -- translated by f2c (version 19991025).
166 You must link the resulting object file with the libraries:
167 -lf2c -lm (in that order)
170 static int daxpy_(integer *n, doublereal *da, doublereal *dx,
171 integer *incx, doublereal *dy, integer *incy)
173 /* System generated locals */
176 /* Local variables */
177 integer i__, m, ix, iy, mp1;
180 /* constant times a vector plus a vector. */
181 /* uses unrolled loops for increments equal to one. */
182 /* jack dongarra, linpack, 3/11/78. */
185 /* Parameter adjustments */
196 if (*incx == 1 && *incy == 1) {
200 /* code for unequal increments or equal increments */
206 ix = (-(*n) + 1) * *incx + 1;
209 iy = (-(*n) + 1) * *incy + 1;
212 for (i__ = 1; i__ <= i__1; ++i__) {
213 dy[iy] += *da * dx[ix];
220 /* code for both increments equal to 1 */
231 for (i__ = 1; i__ <= i__1; ++i__) {
232 dy[i__] += *da * dx[i__];
241 for (i__ = mp1; i__ <= i__1; i__ += 4) {
242 dy[i__] += *da * dx[i__];
243 dy[i__ + 1] += *da * dx[i__ + 1];
244 dy[i__ + 2] += *da * dx[i__ + 2];
245 dy[i__ + 3] += *da * dx[i__ + 3];
251 /* dcopy.f -- translated by f2c (version 19991025).
252 You must link the resulting object file with the libraries:
253 -lf2c -lm (in that order)
256 static int dcopy_(integer *n, const doublereal *dx, integer *incx,
257 doublereal *dy, integer *incy)
259 /* System generated locals */
262 /* Local variables */
263 integer i__, m, ix, iy, mp1;
266 /* copies a vector, x, to a vector, y. */
267 /* uses unrolled loops for increments equal to one. */
268 /* jack dongarra, linpack, 3/11/78. */
271 /* Parameter adjustments */
279 if (*incx == 1 && *incy == 1) {
283 /* code for unequal increments or equal increments */
289 ix = (-(*n) + 1) * *incx + 1;
292 iy = (-(*n) + 1) * *incy + 1;
295 for (i__ = 1; i__ <= i__1; ++i__) {
303 /* code for both increments equal to 1 */
314 for (i__ = 1; i__ <= i__1; ++i__) {
324 for (i__ = mp1; i__ <= i__1; i__ += 7) {
326 dy[i__ + 1] = dx[i__ + 1];
327 dy[i__ + 2] = dx[i__ + 2];
328 dy[i__ + 3] = dx[i__ + 3];
329 dy[i__ + 4] = dx[i__ + 4];
330 dy[i__ + 5] = dx[i__ + 5];
331 dy[i__ + 6] = dx[i__ + 6];
337 /* dscal.f -- translated by f2c (version 19991025).
338 You must link the resulting object file with the libraries:
339 -lf2c -lm (in that order)
342 static int dscal_(integer *n, doublereal *da, doublereal *dx,
345 /* System generated locals */
348 /* Local variables */
349 integer i__, m, ix, mp1;
352 /* scales a vector by a constant. */
353 /* uses unrolled loops for increment equal to one. */
354 /* jack dongarra, linpack, 3/11/78. */
355 /* modified to correct problem with negative increment, 8/21/90. */
358 /* Parameter adjustments */
369 /* code for increment not equal to 1 */
373 ix = (-(*n) + 1) * *incx + 1;
376 for (i__ = 1; i__ <= i__1; ++i__) {
377 dx[ix] = *da * dx[ix];
383 /* code for increment equal to 1 */
394 for (i__ = 1; i__ <= i__1; ++i__) {
395 dx[i__] = *da * dx[i__];
404 for (i__ = mp1; i__ <= i__1; i__ += 5) {
405 dx[i__] = *da * dx[i__];
406 dx[i__ + 1] = *da * dx[i__ + 1];
407 dx[i__ + 2] = *da * dx[i__ + 2];
408 dx[i__ + 3] = *da * dx[i__ + 3];
409 dx[i__ + 4] = *da * dx[i__ + 4];
415 /* dist.f -- translated by f2c (version 19991025).
416 You must link the resulting object file with the libraries:
417 -lf2c -lm (in that order)
420 static doublereal dist_(integer *n, doublereal *x, doublereal *y)
422 /* System generated locals */
424 doublereal ret_val, d__1;
426 /* Local variables */
428 doublereal scale, absxmy, sum;
432 /* Coded by Tom Rowan */
433 /* Department of Computer Sciences */
434 /* University of Texas at Austin */
436 /* dist calculates the distance between the points x,y. */
440 /* n - number of components */
442 /* x - point in n-space */
444 /* y - point in n-space */
446 /* local variables */
449 /* subroutines and functions */
453 /* ----------------------------------------------------------- */
455 /* Parameter adjustments */
460 absxmy = (d__1 = x[1] - y[1], abs(d__1));
462 sum = absxmy * absxmy;
469 for (i__ = 2; i__ <= i__1; ++i__) {
470 absxmy = (d__1 = x[i__] - y[i__], abs(d__1));
471 if (absxmy <= scale) {
472 /* Computing 2nd power */
473 d__1 = absxmy / scale;
476 /* Computing 2nd power */
477 d__1 = scale / absxmy;
478 sum = sum * (d__1 * d__1) + 1.;
483 ret_val = scale * sqrt(sum);
487 /* calcc.f -- translated by f2c (version 19991025).
488 You must link the resulting object file with the libraries:
489 -lf2c -lm (in that order)
492 /* Table of constant values */
494 static doublereal c_b3 = 0.;
495 static integer c__0 = 0;
496 static integer c__1 = 1;
497 static doublereal c_b7 = 1.;
499 static int calcc_(integer *ns, doublereal *s, integer *ih, integer *
500 inew, logical *updatc, doublereal *c__)
502 /* System generated locals */
503 integer s_dim1, s_offset, i__1;
506 /* Local variables */
509 /* Coded by Tom Rowan */
510 /* Department of Computer Sciences */
511 /* University of Texas at Austin */
513 /* calcc calculates the centroid of the simplex without the */
514 /* vertex with highest function value. */
518 /* ns - subspace dimension */
520 /* s - double precision work space of dimension .ge. */
521 /* ns*(ns+3) used to store simplex */
523 /* ih - index to vertex with highest function value */
525 /* inew - index to new point */
527 /* updatc - logical switch */
528 /* = .true. : update centroid */
529 /* = .false. : calculate centroid from scratch */
531 /* c - centroid of the simplex without vertex with */
532 /* highest function value */
536 /* c - new centroid */
538 /* local variables */
541 /* subroutines and functions */
545 /* ----------------------------------------------------------- */
547 /* Parameter adjustments */
550 s_offset = 1 + s_dim1 * 1;
559 for (i__ = 1; i__ <= i__1; ++i__) {
560 c__[i__] += (s[i__ + *inew * s_dim1] - s[i__ + *ih * s_dim1]) / *
565 dcopy_(ns, &c_b3, &c__0, &c__[1], &c__1);
567 for (j = 1; j <= i__1; ++j) {
569 daxpy_(ns, &c_b7, &s[j * s_dim1 + 1], &c__1, &c__[1], &c__1);
574 dscal_(ns, &d__1, &c__[1], &c__1);
579 /* order.f -- translated by f2c (version 19991025).
580 You must link the resulting object file with the libraries:
581 -lf2c -lm (in that order)
584 static int order_(integer *npts, doublereal *fs, integer *il,
585 integer *is, integer *ih)
587 /* System generated locals */
590 /* Local variables */
595 /* Coded by Tom Rowan */
596 /* Department of Computer Sciences */
597 /* University of Texas at Austin */
599 /* order determines the indices of the vertices with the */
600 /* lowest, second highest, and highest function values. */
604 /* npts - number of points in simplex */
606 /* fs - double precision vector of function values of */
609 /* il - index to vertex with lowest function value */
613 /* il - new index to vertex with lowest function value */
615 /* is - new index to vertex with second highest */
618 /* ih - new index to vertex with highest function value */
620 /* local variables */
623 /* subroutines and functions */
627 /* ----------------------------------------------------------- */
629 /* Parameter adjustments */
635 if (fs[j] >= fs[*il]) {
643 i__1 = il0 + *npts - 2;
644 for (i__ = il0 + 1; i__ <= i__1; ++i__) {
646 if (fs[j] >= fs[*ih]) {
649 } else if (fs[j] > fs[*is]) {
651 } else if (fs[j] < fs[*il]) {
659 /* partx.f -- translated by f2c (version 19991025).
660 You must link the resulting object file with the libraries:
661 -lf2c -lm (in that order)
664 /* Common Block Declarations */
667 doublereal alpha, beta, gamma, delta, psi, omega;
668 integer nsmin, nsmax, irepl, ifxsw;
669 doublereal bonus, fstop;
670 integer nfstop, nfxe;
671 doublereal fxstat[4], ftest;
672 logical minf, initx, newx;
675 #define usubc_1 usubc_
677 static int partx_(integer *n, integer *ip, doublereal *absdx,
678 integer *nsubs, integer *nsvals)
680 /* System generated locals */
683 /* Local variables */
684 static integer i__, nleft, nused;
685 static doublereal as1max, gapmax, asleft, as1, as2;
686 static integer ns1, ns2;
687 static doublereal gap;
691 /* Coded by Tom Rowan */
692 /* Department of Computer Sciences */
693 /* University of Texas at Austin */
695 /* partx partitions the vector x by grouping components of */
696 /* similar magnitude of change. */
700 /* n - number of components (problem dimension) */
702 /* ip - permutation vector */
704 /* absdx - vector of magnitude of change in x */
706 /* nsvals - integer array dimensioned .ge. int(n/nsmin) */
710 /* nsubs - number of subspaces */
712 /* nsvals - integer array of subspace dimensions */
718 /* local variables */
722 /* subroutines and functions */
726 /* ----------------------------------------------------------- */
728 /* Parameter adjustments */
739 for (i__ = 2; i__ <= i__1; ++i__) {
740 asleft += absdx[i__];
747 i__1 = usubc_1.nsmin - 1;
748 for (i__ = 1; i__ <= i__1; ++i__) {
749 as1 += absdx[ip[nused + i__]];
753 i__1 = min(usubc_1.nsmax,nleft);
754 for (ns1 = usubc_1.nsmin; ns1 <= i__1; ++ns1) {
755 as1 += absdx[ip[nused + ns1]];
758 if (ns2 >= ((ns2 - 1) / usubc_1.nsmax + 1) * usubc_1.nsmin) {
760 gap = as1 / ns1 - as2 / ns2;
763 nsvals[*nsubs] = ns1;
768 if (as1 / ns1 > gapmax) {
769 nsvals[*nsubs] = ns1;
775 nused += nsvals[*nsubs];
783 /* sortd.f -- translated by f2c (version 19991025).
784 You must link the resulting object file with the libraries:
785 -lf2c -lm (in that order)
788 static int sortd_(integer *n, doublereal *xkey, integer *ix)
790 /* System generated locals */
793 /* Local variables */
794 integer ixip1, i__, ilast, iswap, ifirst, ixi;
798 /* Coded by Tom Rowan */
799 /* Department of Computer Sciences */
800 /* University of Texas at Austin */
802 /* sortd uses the shakersort method to sort an array of keys */
803 /* in decreasing order. The sort is performed implicitly by */
804 /* modifying a vector of indices. */
806 /* For nearly sorted arrays, sortd requires O(n) comparisons. */
807 /* for completely unsorted arrays, sortd requires O(n**2) */
808 /* comparisons and will be inefficient unless n is small. */
812 /* n - number of components */
814 /* xkey - double precision vector of keys */
816 /* ix - integer vector of indices */
820 /* ix - indices satisfy xkey(ix(i)) .ge. xkey(ix(i+1)) */
821 /* for i = 1,...,n-1 */
823 /* local variables */
826 /* ----------------------------------------------------------- */
828 /* Parameter adjustments */
837 if (ifirst <= ilast) {
839 for (i__ = ifirst; i__ <= i__1; ++i__) {
842 if (xkey[ixi] < xkey[ixip1]) {
851 for (i__ = ilast; i__ >= i__1; --i__) {
854 if (xkey[ixi] < xkey[ixip1]) {
867 /* newpt.f -- translated by f2c (version 19991025).
868 You must link the resulting object file with the libraries:
869 -lf2c -lm (in that order)
872 static int newpt_(integer *ns, doublereal *coef, doublereal *xbase,
873 doublereal *xold, logical *new__, doublereal *xnew, logical *small)
875 /* System generated locals */
878 /* Local variables */
886 /* Coded by Tom Rowan */
887 /* Department of Computer Sciences */
888 /* University of Texas at Austin */
890 /* newpt performs reflections, expansions, contractions, and */
891 /* shrinkages (massive contractions) by computing: */
893 /* xbase + coef * (xbase - xold) */
895 /* The result is stored in xnew if new .eq. .true., */
896 /* in xold otherwise. */
898 /* use : coef .gt. 0 to reflect */
899 /* coef .lt. 0 to expand, contract, or shrink */
903 /* ns - number of components (subspace dimension) */
905 /* coef - one of four simplex method coefficients */
907 /* xbase - double precision ns-vector representing base */
910 /* xold - double precision ns-vector representing old */
913 /* new - logical switch */
914 /* = .true. : store result in xnew */
915 /* = .false. : store result in xold, xnew is not */
920 /* xold - unchanged if new .eq. .true., contains new */
921 /* point otherwise */
923 /* xnew - double precision ns-vector representing new */
924 /* point if new .eq. .true., not referenced */
927 /* small - logical flag */
928 /* = .true. : coincident points */
929 /* = .false. : otherwise */
931 /* local variables */
934 /* subroutines and functions */
938 /* ----------------------------------------------------------- */
940 /* Parameter adjustments */
950 for (i__ = 1; i__ <= i__1; ++i__) {
951 xnew[i__] = xbase[i__] + *coef * (xbase[i__] - xold[i__]);
952 eqbase = eqbase && xnew[i__] == xbase[i__];
953 eqold = eqold && xnew[i__] == xold[i__];
958 for (i__ = 1; i__ <= i__1; ++i__) {
960 xold[i__] = xbase[i__] + *coef * (xbase[i__] - xold[i__]);
961 eqbase = eqbase && xold[i__] == xbase[i__];
962 eqold = eqold && xold[i__] == xoldi;
966 *small = eqbase || eqold;
970 /* start.f -- translated by f2c (version 19991025).
971 You must link the resulting object file with the libraries:
972 -lf2c -lm (in that order)
975 static int start_(integer *n, doublereal *x, doublereal *step,
976 integer *ns, integer *ips, doublereal *s, logical *small)
978 /* System generated locals */
979 integer s_dim1, s_offset, i__1;
981 /* Local variables */
985 /* Coded by Tom Rowan */
986 /* Department of Computer Sciences */
987 /* University of Texas at Austin */
989 /* start creates the initial simplex for simplx minimization. */
993 /* n - problem dimension */
995 /* x - current best point */
997 /* step - stepsizes for corresponding components of x */
999 /* ns - subspace dimension */
1001 /* ips - permutation vector */
1006 /* s - first ns+1 columns contain initial simplex */
1008 /* small - logical flag */
1009 /* = .true. : coincident points */
1010 /* = .false. : otherwise */
1012 /* local variables */
1015 /* subroutines and functions */
1020 /* ----------------------------------------------------------- */
1022 /* Parameter adjustments */
1027 s_offset = 1 + s_dim1 * 1;
1032 for (i__ = 1; i__ <= i__1; ++i__) {
1033 s[i__ + s_dim1] = x[ips[i__]];
1037 for (j = 2; j <= i__1; ++j) {
1038 dcopy_(ns, &s[s_dim1 + 1], &c__1, &s[j * s_dim1 + 1], &c__1);
1039 s[j - 1 + j * s_dim1] = s[j - 1 + s_dim1] + step[ips[j - 1]];
1043 /* check for coincident points */
1046 for (j = 2; j <= i__1; ++j) {
1047 if (s[j - 1 + j * s_dim1] == s[j - 1 + s_dim1]) {
1055 /* coincident points */
1062 /* fstats.f -- translated by f2c (version 19991025).
1063 You must link the resulting object file with the libraries:
1064 -lf2c -lm (in that order)
1067 static int fstats_(doublereal *fx, integer *ifxwt, logical *reset)
1069 /* System generated locals */
1070 doublereal d__1, d__2, d__3;
1072 /* Local variables */
1073 static doublereal fscale;
1075 static doublereal f1sv;
1079 /* Coded by Tom Rowan */
1080 /* Department of Computer Sciences */
1081 /* University of Texas at Austin */
1083 /* fstats modifies the common /usubc/ variables nfxe,fxstat. */
1087 /* fx - most recent evaluation of f at best x */
1089 /* ifxwt - integer weight for fx */
1091 /* reset - logical switch */
1092 /* = .true. : initialize nfxe,fxstat */
1093 /* = .false. : update nfxe,fxstat */
1099 /* local variables */
1103 /* subroutines and functions */
1107 /* ----------------------------------------------------------- */
1110 usubc_1.nfxe = *ifxwt;
1111 usubc_1.fxstat[0] = *fx;
1112 usubc_1.fxstat[1] = *fx;
1113 usubc_1.fxstat[2] = *fx;
1114 usubc_1.fxstat[3] = 0.;
1117 f1sv = usubc_1.fxstat[0];
1118 usubc_1.nfxe += *ifxwt;
1119 usubc_1.fxstat[0] += *ifxwt * (*fx - usubc_1.fxstat[0]) /
1121 usubc_1.fxstat[1] = max(usubc_1.fxstat[1],*fx);
1122 usubc_1.fxstat[2] = min(usubc_1.fxstat[2],*fx);
1124 d__1 = abs(usubc_1.fxstat[1]), d__2 = abs(usubc_1.fxstat[2]), d__1 =
1126 fscale = max(d__1,1.);
1127 /* Computing 2nd power */
1128 d__1 = usubc_1.fxstat[3] / fscale;
1129 /* Computing 2nd power */
1130 d__2 = (usubc_1.fxstat[0] - f1sv) / fscale;
1131 /* Computing 2nd power */
1132 d__3 = (*fx - usubc_1.fxstat[0]) / fscale;
1133 usubc_1.fxstat[3] = fscale * sqrt(((nsv - 1) * (d__1 * d__1) + nsv * (
1134 d__2 * d__2) + *ifxwt * (d__3 * d__3)) / (usubc_1.nfxe - 1));
1139 /* evalf.f -- translated by f2c (version 19991025).
1140 You must link the resulting object file with the libraries:
1141 -lf2c -lm (in that order)
1144 /* Common Block Declarations */
1147 doublereal fbonus, sfstop, sfbest;
1151 #define isubc_1 isubc_
1153 static logical c_true = TRUE_;
1154 static logical c_false = FALSE_;
1156 static int evalf_(D_fp f,void*fdata, integer *ns, integer *ips, doublereal *xs,
1157 integer *n, doublereal *x, doublereal *sfx, integer *nfe)
1159 /* System generated locals */
1162 /* Local variables */
1164 static doublereal fx;
1165 static logical newbst;
1167 /* Coded by Tom Rowan */
1168 /* Department of Computer Sciences */
1169 /* University of Texas at Austin */
1171 /* evalf evaluates the function f at a point defined by x */
1172 /* with ns of its components replaced by those in xs. */
1176 /* f - user supplied function f(n,x) to be optimized */
1178 /* ns - subspace dimension */
1180 /* ips - permutation vector */
1182 /* xs - double precision ns-vector to be mapped to x */
1184 /* n - problem dimension */
1186 /* x - double precision n-vector */
1188 /* nfe - number of function evaluations */
1192 /* sfx - signed value of f evaluated at x */
1194 /* nfe - incremented number of function evaluations */
1202 /* local variables */
1206 /* subroutines and functions */
1209 /* ----------------------------------------------------------- */
1211 /* Parameter adjustments */
1218 for (i__ = 1; i__ <= i__1; ++i__) {
1219 x[ips[i__]] = xs[i__];
1222 usubc_1.newx = isubc_1.new__ || usubc_1.irepl != 2;
1223 fx = (*f)(*n, &x[1], fdata);
1224 if (usubc_1.irepl == 0) {
1230 } else if (isubc_1.new__) {
1233 newbst = fx < usubc_1.ftest;
1236 newbst = fx > usubc_1.ftest;
1238 if (usubc_1.initx || newbst) {
1239 if (usubc_1.irepl == 1) {
1240 fstats_(&fx, &c__1, &c_true);
1243 isubc_1.sfbest = *sfx;
1246 if (usubc_1.irepl == 1) {
1247 fstats_(&fx, &c__1, &c_false);
1248 fx = usubc_1.fxstat[usubc_1.ifxsw - 1];
1250 usubc_1.ftest = fx + isubc_1.fbonus * usubc_1.fxstat[3];
1252 *sfx = usubc_1.ftest;
1253 isubc_1.sfbest = fx;
1255 *sfx = -usubc_1.ftest;
1256 isubc_1.sfbest = -fx;
1263 /* simplx.f -- translated by f2c (version 19991025).
1264 You must link the resulting object file with the libraries:
1265 -lf2c -lm (in that order)
1268 static int simplx_(D_fp f, void *fdata, integer *n, doublereal *step, integer *
1269 ns, integer *ips, nlopt_stopping *stop, logical *cmode, doublereal *x,
1270 doublereal *fx, integer *nfe, doublereal *s, doublereal *fs, integer *
1273 /* System generated locals */
1274 integer s_dim1, s_offset, i__1;
1275 doublereal d__1, d__2;
1277 /* Local variables */
1278 static integer inew;
1279 static integer npts;
1280 static integer i__, j;
1281 static integer icent;
1282 static logical small;
1283 static integer itemp;
1284 static doublereal fc, fe;
1285 static integer ih, il;
1286 static doublereal fr;
1288 static logical updatc;
1289 static doublereal dum, tol;
1293 /* Coded by Tom Rowan */
1294 /* Department of Computer Sciences */
1295 /* University of Texas at Austin */
1297 /* simplx uses the Nelder-Mead simplex method to minimize the */
1298 /* function f on a subspace. */
1302 /* f - function to be minimized, declared external in */
1303 /* calling routine */
1305 /* n - problem dimension */
1307 /* step - stepsizes for corresponding components of x */
1309 /* ns - subspace dimension */
1311 /* ips - permutation vector */
1313 /* maxnfe - maximum number of function evaluations */
1315 /* cmode - logical switch */
1316 /* = .true. : continuation of previous call */
1317 /* = .false. : first call */
1319 /* x - starting guess for minimum */
1321 /* fx - value of f at x */
1323 /* nfe - number of function evaluations */
1325 /* s - double precision work array of dimension .ge. */
1326 /* ns*(ns+3) used to store simplex */
1328 /* fs - double precision work array of dimension .ge. */
1329 /* ns+1 used to store function values of simplex */
1334 /* x - computed minimum */
1336 /* fx - value of f at x */
1338 /* nfe - incremented number of function evaluations */
1340 /* iflag - error flag */
1341 /* = -1 : maxnfe exceeded */
1342 /* = 0 : simplex reduced by factor of psi */
1343 /* = 1 : limit of machine precision */
1344 /* = 2 : reached fstop */
1352 /* local variables */
1356 /* subroutines and functions */
1361 /* ----------------------------------------------------------- */
1363 /* Parameter adjustments */
1368 s_offset = 1 + s_dim1 * 1;
1380 start_(n, &x[1], &step[1], ns, &ips[1], &s[s_offset], &small);
1385 if (usubc_1.irepl > 0) {
1386 isubc_1.new__ = FALSE_;
1387 evalf_((D_fp)f,fdata, ns, &ips[1], &s[s_dim1 + 1], n, &x[1], &fs[1], nfe);
1392 isubc_1.new__ = TRUE_;
1394 for (j = 2; j <= i__1; ++j) {
1395 evalf_((D_fp)f, fdata,ns, &ips[1], &s[j * s_dim1 + 1], n, &x[1], &fs[j],
1401 order_(&npts, &fs[1], &il, &is, &ih);
1402 tol = usubc_1.psi * dist_(ns, &s[ih * s_dim1 + 1], &s[il * s_dim1 + 1]);
1407 calcc_(ns, &s[s_offset], &ih, &inew, &updatc, &s[icent * s_dim1 + 1]);
1413 newpt_(ns, &usubc_1.alpha, &s[icent * s_dim1 + 1], &s[ih * s_dim1 + 1], &
1414 c_true, &s[itemp * s_dim1 + 1], &small);
1418 evalf_((D_fp)f,fdata, ns, &ips[1], &s[itemp * s_dim1 + 1], n, &x[1], &fr, nfe);
1424 d__1 = -usubc_1.gamma;
1425 newpt_(ns, &d__1, &s[icent * s_dim1 + 1], &s[itemp * s_dim1 + 1], &
1426 c_true, &s[ih * s_dim1 + 1], &small);
1430 evalf_((D_fp)f,fdata, ns, &ips[1], &s[ih * s_dim1 + 1], n, &x[1], &fe, nfe);
1435 dcopy_(ns, &s[itemp * s_dim1 + 1], &c__1, &s[ih * s_dim1 + 1], &
1439 } else if (fr < fs[is]) {
1441 /* accept reflected point */
1443 dcopy_(ns, &s[itemp * s_dim1 + 1], &c__1, &s[ih * s_dim1 + 1], &c__1);
1450 d__1 = -usubc_1.beta;
1451 newpt_(ns, &d__1, &s[icent * s_dim1 + 1], &s[ih * s_dim1 + 1], &
1452 c_true, &s[itemp * s_dim1 + 1], &small);
1454 d__1 = -usubc_1.beta;
1455 newpt_(ns, &d__1, &s[icent * s_dim1 + 1], &s[itemp * s_dim1 + 1],
1456 &c_false, &dum, &small);
1461 evalf_((D_fp)f,fdata, ns, &ips[1], &s[itemp * s_dim1 + 1], n, &x[1], &fc,
1465 d__1 = fr, d__2 = fs[ih];
1466 if (fc < min(d__1,d__2)) {
1467 dcopy_(ns, &s[itemp * s_dim1 + 1], &c__1, &s[ih * s_dim1 + 1], &
1472 /* shrink simplex */
1475 for (j = 1; j <= i__1; ++j) {
1477 d__1 = -usubc_1.delta;
1478 newpt_(ns, &d__1, &s[il * s_dim1 + 1], &s[j * s_dim1 + 1],
1479 &c_false, &dum, &small);
1483 evalf_((D_fp)f,fdata, ns, &ips[1], &s[j * s_dim1 + 1], n, &x[1],
1492 order_(&npts, &fs[1], &il, &is, &ih);
1494 /* check termination */
1497 if (usubc_1.irepl == 0) {
1500 *fx = isubc_1.sfbest;
1503 if (*fx < stop->minf_max)
1505 else if (nlopt_stop_evals(stop))
1507 else if (nlopt_stop_time(stop))
1509 else if (dist_(ns, &s[ih * s_dim1 + 1], &s[il * s_dim1 + 1]) <= tol
1515 /* end main loop, return best point */
1518 for (i__ = 1; i__ <= i__1; ++i__) {
1519 x[ips[i__]] = s[i__ + il * s_dim1];
1525 /* subopt.f -- translated by f2c (version 19991025).
1526 You must link the resulting object file with the libraries:
1527 -lf2c -lm (in that order)
1530 static int subopt_(integer *n)
1534 /* Coded by Tom Rowan */
1535 /* Department of Computer Sciences */
1536 /* University of Texas at Austin */
1538 /* subopt sets options for subplx. */
1542 /* n - problem dimension */
1549 /* subroutines and functions */
1553 /* ----------------------------------------------------------- */
1555 /* *********************************************************** */
1556 /* simplex method strategy parameters */
1557 /* *********************************************************** */
1559 /* alpha - reflection coefficient */
1564 /* beta - contraction coefficient */
1565 /* 0 .lt. beta .lt. 1 */
1569 /* gamma - expansion coefficient */
1574 /* delta - shrinkage (massive contraction) coefficient */
1575 /* 0 .lt. delta .lt. 1 */
1579 /* *********************************************************** */
1580 /* subplex method strategy parameters */
1581 /* *********************************************************** */
1583 /* psi - simplex reduction coefficient */
1584 /* 0 .lt. psi .lt. 1 */
1588 /* omega - step reduction coefficient */
1589 /* 0 .lt. omega .lt. 1 */
1593 /* nsmin and nsmax specify a range of subspace dimensions. */
1594 /* In addition to satisfying 1 .le. nsmin .le. nsmax .le. n, */
1595 /* nsmin and nsmax must be chosen so that n can be expressed */
1596 /* as a sum of positive integers where each of these integers */
1597 /* ns(i) satisfies nsmin .le. ns(i) .ge. nsmax. */
1599 /* nsmin*ceil(n/nsmax) .le. n must be true. */
1601 /* nsmin - subspace dimension minimum */
1603 usubc_1.nsmin = min(2,*n);
1605 /* nsmax - subspace dimension maximum */
1607 usubc_1.nsmax = min(5,*n);
1609 /* *********************************************************** */
1610 /* subplex method special cases */
1611 /* *********************************************************** */
1612 /* nelder-mead simplex method with periodic restarts */
1613 /* nsmin = nsmax = n */
1614 /* *********************************************************** */
1615 /* nelder-mead simplex method */
1616 /* nsmin = nsmax = n, psi = small positive */
1617 /* *********************************************************** */
1619 /* irepl, ifxsw, and bonus deal with measurement replication. */
1620 /* Objective functions subject to large amounts of noise can */
1621 /* cause an optimization method to halt at a false optimum. */
1622 /* An expensive solution to this problem is to evaluate f */
1623 /* several times at each point and return the average (or max */
1624 /* or min) of these trials as the function value. subplx */
1625 /* performs measurement replication only at the current best */
1626 /* point. The longer a point is retained as best, the more */
1627 /* accurate its function value becomes. */
1629 /* The common variable nfxe contains the number of function */
1630 /* evaluations at the current best point. fxstat contains the */
1631 /* mean, max, min, and standard deviation of these trials. */
1633 /* irepl - measurement replication switch */
1634 /* irepl = 0, 1, or 2 */
1635 /* = 0 : no measurement replication */
1636 /* = 1 : subplx performs measurement replication */
1637 /* = 2 : user performs measurement replication */
1638 /* (This is useful when optimizing on the mean, */
1639 /* max, or min of trials is insufficient. Common */
1640 /* variable initx is true for first function */
1641 /* evaluation. newx is true for first trial at */
1642 /* this point. The user uses subroutine fstats */
1643 /* within his objective function to maintain */
1644 /* fxstat. By monitoring newx, the user can tell */
1645 /* whether to return the function evaluation */
1646 /* (newx = .true.) or to use the new function */
1647 /* evaluation to refine the function evaluation */
1648 /* of the current best point (newx = .false.). */
1649 /* The common variable ftest gives the function */
1650 /* value that a new point must beat to be */
1651 /* considered the new best point.) */
1655 /* ifxsw - measurement replication optimization switch */
1656 /* ifxsw = 1, 2, or 3 */
1657 /* = 1 : retain mean of trials as best function value */
1658 /* = 2 : retain max */
1659 /* = 3 : retain min */
1663 /* Since the current best point will also be the most */
1664 /* accurately evaluated point whenever irepl .gt. 0, a bonus */
1665 /* should be added to the function value of the best point */
1666 /* so that the best point is not replaced by a new point */
1667 /* that only appears better because of noise. */
1668 /* subplx uses bonus to determine how many multiples of */
1669 /* fxstat(4) should be added as a bonus to the function */
1670 /* evaluation. (The bonus is adjusted automatically by */
1671 /* subplx when ifxsw or minf is changed.) */
1673 /* bonus - measurement replication bonus coefficient */
1674 /* bonus .ge. 0 (normally, bonus = 0 or 1) */
1675 /* = 0 : bonus not used */
1676 /* = 1 : bonus used */
1680 /* nfstop = 0 : f(x) is not tested against fstop */
1681 /* = 1 : if f(x) has reached fstop, subplx returns */
1683 /* = 2 : (only valid when irepl .gt. 0) */
1684 /* if f(x) has reached fstop and */
1685 /* nfxe .gt. nfstop, subplx returns iflag = 2 */
1689 /* fstop - f target value */
1690 /* Its usage is determined by the value of nfstop. */
1692 /* minf - logical switch */
1693 /* = .true. : subplx performs minimization */
1694 /* = .false. : subplx performs maximization */
1696 usubc_1.minf = TRUE_;
1700 /* setstp.f -- translated by f2c (version 19991025).
1701 You must link the resulting object file with the libraries:
1702 -lf2c -lm (in that order)
1705 static double d_sign(doublereal *x, doublereal *y)
1707 return copysign(*x, *y);
1710 static int setstp_(integer *nsubs, integer *n, doublereal *deltax,
1713 /* System generated locals */
1715 doublereal d__1, d__2, d__3;
1717 /* Builtin functions */
1718 /* double d_sign(doublereal *, doublereal *); */
1720 /* Local variables */
1722 static doublereal stpfac;
1726 /* Coded by Tom Rowan */
1727 /* Department of Computer Sciences */
1728 /* University of Texas at Austin */
1730 /* setstp sets the stepsizes for the corresponding components */
1731 /* of the solution vector. */
1735 /* nsubs - number of subspaces */
1737 /* n - number of components (problem dimension) */
1739 /* deltax - vector of change in solution vector */
1741 /* step - stepsizes for corresponding components of */
1742 /* solution vector */
1746 /* step - new stepsizes */
1752 /* local variables */
1756 /* subroutines and functions */
1761 /* ----------------------------------------------------------- */
1765 /* Parameter adjustments */
1773 d__3 = dasum_(n, &deltax[1], &c__1) / dasum_(n, &step[1], &c__1);
1774 d__1 = max(d__3,usubc_1.omega), d__2 = 1. / usubc_1.omega;
1775 stpfac = min(d__1,d__2);
1777 stpfac = usubc_1.psi;
1779 dscal_(n, &stpfac, &step[1], &c__1);
1781 /* reorient simplex */
1784 for (i__ = 1; i__ <= i__1; ++i__) {
1785 if (deltax[i__] != 0.) {
1786 step[i__] = d_sign(&step[i__], &deltax[i__]);
1788 step[i__] = -step[i__];
1795 /* subplx.f -- translated by f2c (version 19991025).
1796 You must link the resulting object file with the libraries:
1797 -lf2c -lm (in that order)
1800 static int subplx_(D_fp f, void *fdata, integer *n,
1801 nlopt_stopping *stop, integer *mode,
1802 const doublereal *scale, doublereal *x, doublereal *fx,
1803 integer *nfe, doublereal *work, integer *iwork,
1806 /* Initialized data */
1808 static doublereal bnsfac[6] /* was [3][2] */ = { -1.,-2.,0.,1.,0.,2. };
1810 /* System generated locals */
1812 doublereal d__1, d__2, d__3, d__4, d__5, d__6;
1814 /* Local variables */
1816 static logical cmode;
1817 static integer istep;
1818 static doublereal xpscl;
1819 static integer nsubs, ipptr;
1820 static integer isptr;
1821 static integer ns, insfnl, ifsptr;
1822 static integer insptr;
1823 static integer istptr;
1824 static doublereal scl, dum;
1826 static doublereal sfx, sfx_old, *x_old;
1830 /* Coded by Tom Rowan */
1831 /* Department of Computer Sciences */
1832 /* University of Texas at Austin */
1834 /* subplx uses the subplex method to solve unconstrained */
1835 /* optimization problems. The method is well suited for */
1836 /* optimizing objective functions that are noisy or are */
1837 /* discontinuous at the solution. */
1839 /* subplx sets default optimization options by calling the */
1840 /* subroutine subopt. The user can override these defaults */
1841 /* by calling subopt prior to calling subplx, changing the */
1842 /* appropriate common variables, and setting the value of */
1843 /* mode as indicated below. */
1845 /* By default, subplx performs minimization. */
1849 /* f - user supplied function f(n,x) to be optimized, */
1850 /* declared external in calling routine */
1852 /* n - problem dimension */
1854 /* tol - relative error tolerance for x (tol .ge. 0.) */
1856 /* maxnfe - maximum number of function evaluations */
1858 /* mode - integer mode switch with binary expansion */
1859 /* (bit 1) (bit 0) : */
1860 /* bit 0 = 0 : first call to subplx */
1861 /* = 1 : continuation of previous call */
1862 /* bit 1 = 0 : use default options */
1863 /* = 1 : user set options */
1865 /* scale - scale and initial stepsizes for corresponding */
1866 /* components of x */
1867 /* (If scale(1) .lt. 0., */
1868 /* abs(scale(1)) is used for all components of x, */
1869 /* and scale(2),...,scale(n) are not referenced.) */
1871 /* x - starting guess for optimum */
1873 /* work - double precision work array of dimension .ge. */
1874 /* 2*n + nsmax*(nsmax+4) + 1 */
1875 /* (nsmax is set in subroutine subopt. */
1876 /* default: nsmax = min(5,n)) */
1878 /* iwork - integer work array of dimension .ge. */
1879 /* n + int(n/nsmin) */
1880 /* (nsmin is set in subroutine subopt. */
1881 /* default: nsmin = min(2,n)) */
1885 /* x - computed optimum */
1887 /* fx - value of f at x */
1889 /* nfe - number of function evaluations */
1891 /* iflag - error flag */
1892 /* = -2 : invalid input */
1893 /* = -1 : maxnfe exceeded */
1894 /* = 0 : tol satisfied */
1895 /* = 1 : limit of machine precision */
1896 /* = 2 : fstop reached (fstop usage is determined */
1897 /* by values of options minf, nfstop, and */
1898 /* irepl. default: f(x) not tested against */
1900 /* iflag should not be reset between calls to */
1909 /* local variables */
1913 /* subroutines and functions */
1920 /* Parameter adjustments */
1929 /* ----------------------------------------------------------- */
1931 if (*mode % 2 == 0) {
1933 /* first call, check input */
1938 if (scale[1] >= 0.) {
1940 for (i__ = 1; i__ <= i__1; ++i__) {
1941 xpscl = x[i__] + scale[i__];
1942 if (xpscl == x[i__]) {
1948 scl = abs(scale[1]);
1950 for (i__ = 1; i__ <= i__1; ++i__) {
1951 xpscl = x[i__] + scl;
1952 if (xpscl == x[i__]) {
1958 if (*mode / 2 % 2 == 0) {
1961 if (usubc_1.alpha <= 0.) {
1964 if (usubc_1.beta <= 0. || usubc_1.beta >= 1.) {
1967 if (usubc_1.gamma <= 1.) {
1970 if (usubc_1.delta <= 0. || usubc_1.delta >= 1.) {
1973 if (usubc_1.psi <= 0. || usubc_1.psi >= 1.) {
1976 if (usubc_1.omega <= 0. || usubc_1.omega >= 1.) {
1979 if (usubc_1.nsmin < 1 || usubc_1.nsmax < usubc_1.nsmin || *n <
1983 if (*n < ((*n - 1) / usubc_1.nsmax + 1) * usubc_1.nsmin) {
1986 if (usubc_1.irepl < 0 || usubc_1.irepl > 2) {
1989 if (usubc_1.ifxsw < 1 || usubc_1.ifxsw > 3) {
1992 if (usubc_1.bonus < 0.) {
1995 if (usubc_1.nfstop < 0) {
2000 /* initialization */
2003 isptr = istptr + *n;
2004 ifsptr = isptr + usubc_1.nsmax * (usubc_1.nsmax + 3);
2006 if (scale[1] > 0.) {
2007 dcopy_(n, &scale[1], &c__1, &work[1], &c__1);
2008 dcopy_(n, &scale[1], &c__1, &work[istptr], &c__1);
2010 dcopy_(n, &scl, &c__0, &work[1], &c__1);
2011 dcopy_(n, &scl, &c__0, &work[istptr], &c__1);
2014 for (i__ = 1; i__ <= i__1; ++i__) {
2020 if (usubc_1.irepl == 0) {
2021 isubc_1.fbonus = 0.;
2022 } else if (usubc_1.minf) {
2023 isubc_1.fbonus = bnsfac[usubc_1.ifxsw - 1] * usubc_1.bonus;
2025 isubc_1.fbonus = bnsfac[usubc_1.ifxsw + 2] * usubc_1.bonus;
2027 if (usubc_1.nfstop == 0) {
2028 isubc_1.sfstop = 0.;
2029 } else if (usubc_1.minf) {
2030 isubc_1.sfstop = usubc_1.fstop;
2032 isubc_1.sfstop = -usubc_1.fstop;
2036 isubc_1.new__ = TRUE_;
2037 usubc_1.initx = TRUE_;
2038 evalf_((D_fp)f, fdata, &c__0, &iwork[1], &dum, n, &x[1], &sfx, nfe);
2040 usubc_1.initx = FALSE_;
2043 /* continuation of previous call */
2047 isubc_1.sfstop = usubc_1.fstop;
2049 isubc_1.sfstop = -usubc_1.fstop;
2053 } else if (*iflag == -1) {
2056 } else if (*iflag == 0) {
2068 for (i__ = 1; i__ <= i__1; ++i__) {
2069 work[i__] = (d__1 = work[i__], abs(d__1));
2072 sortd_(n, &work[1], &iwork[1]);
2073 partx_(n, &iwork[1], &work[1], &nsubs, &iwork[insptr]);
2074 dcopy_(n, &x[1], &c__1, &work[1], &c__1);
2076 insfnl = insptr + nsubs - 1;
2081 memcpy(&x_old[1], &x[1], sizeof(doublereal) * *n);
2085 simplx_((D_fp)f, fdata, n, &work[istptr], &ns, &iwork[ipptr], stop, &cmode, &x[1], &sfx, nfe, &work[isptr], &work[ifsptr], iflag);
2096 /* end simplex loop */
2099 for (i__ = 1; i__ <= i__1; ++i__) {
2100 work[i__] = x[i__] - work[i__];
2104 /* check termination */
2106 if (nlopt_stop_ftol(stop, sfx, sfx_old)) {
2110 if (nlopt_stop_x(stop, &x[1], &x_old[1])) {
2118 for (i__ = 1; i__ <= i__1; ++i__) {
2120 d__4 = (d__2 = work[i__], abs(d__2)), d__5 = (d__1 = work[istep], abs(
2121 d__1)) * usubc_1.psi;
2123 d__6 = (d__3 = x[i__], abs(d__3));
2124 if (max(d__4,d__5) / max(d__6,1.) > stop->xtol_rel) {
2125 setstp_(&nsubs, n, &work[1], &work[istptr]);
2132 /* end subplex loop */
2150 /****************************************************************************/
2151 /****************************************************************************/
2153 /* front-end for subplex routines */
2155 /* Wrapper around f2c'ed subplx_ routine, for multidimensinal
2156 unconstrained optimization:
2160 f: function f(n,x,fdata) to be optimized
2161 n: problem dimension
2162 minf: (output) value of f at minimum
2163 x[n]: (input) starting guess position, (output) computed minimum
2164 fdata: data pointer passed to f
2167 tol: relative error tolerance for x
2168 maxnfe: maximum number of function evaluations
2169 minf_max, use_minf_max: if use_minf_max, stop when f <= minf_max
2171 new args: nlopt_stopping *stop (stopping criteria)
2173 scale[n]: (input) scale & initial stepsizes for components of x
2174 (if *scale < 0, |*scale| is used for all components)
2177 = -2 : invalid input
2178 = -10 : maxtime exceeded
2179 = -1 : maxevals exceeded
2181 = 1 : limit of machine precision
2182 = 2 : fstop reached (fstop usage is determined by values of
2183 options minf, nfstop, and irepl. default: f(x) not
2184 tested against fstop)
2186 = -200 : out of memory
2188 int nlopt_subplex(subplex_func f, double *minf, double *x, int n, void *fdata,
2189 nlopt_stopping *stop,
2190 const double *scale)
2192 int mode = 0, *iwork, nsmax, nsmin, errflag, nfe;
2197 work = (double*) malloc(sizeof(double) * (3*n + nsmax*(nsmax+4) + 1));
2200 iwork = (int*) malloc(sizeof(int) * (n + n/nsmin + 1));
2206 subplx_(f,fdata, &n,
2210 work, iwork, &errflag);