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.
64 typedef double doublereal;
71 typedef subplex_func D_fp;
73 #define max(a,b) ((a) > (b) ? (a) : (b))
74 #define min(a,b) ((a) < (b) ? (a) : (b))
75 #define abs(x) fabs(x)
77 /****************************************************************************/
78 /****************************************************************************/
80 /* dasum.f -- translated by f2c (version 19991025).
81 You must link the resulting object file with the libraries:
82 -lf2c -lm (in that order)
85 static doublereal dasum_(integer *n, doublereal *dx, integer *incx)
87 /* System generated locals */
89 doublereal ret_val, d__1, d__2, d__3, d__4, d__5, d__6;
97 /* takes the sum of the absolute values. */
98 /* uses unrolled loops for increment equal to one. */
99 /* jack dongarra, linpack, 3/11/78. */
100 /* modified to correct problem with negative increment, 8/21/90. */
103 /* Parameter adjustments */
116 /* code for increment not equal to 1 */
120 ix = (-(*n) + 1) * *incx + 1;
123 for (i__ = 1; i__ <= i__1; ++i__) {
124 dtemp += (d__1 = dx[ix], abs(d__1));
131 /* code for increment equal to 1 */
142 for (i__ = 1; i__ <= i__1; ++i__) {
143 dtemp += (d__1 = dx[i__], abs(d__1));
152 for (i__ = mp1; i__ <= i__1; i__ += 6) {
153 dtemp = dtemp + (d__1 = dx[i__], abs(d__1)) + (d__2 = dx[i__ + 1],
154 abs(d__2)) + (d__3 = dx[i__ + 2], abs(d__3)) + (d__4 = dx[i__
155 + 3], abs(d__4)) + (d__5 = dx[i__ + 4], abs(d__5)) + (d__6 =
156 dx[i__ + 5], abs(d__6));
164 /* daxpy.f -- translated by f2c (version 19991025).
165 You must link the resulting object file with the libraries:
166 -lf2c -lm (in that order)
169 static int daxpy_(integer *n, doublereal *da, doublereal *dx,
170 integer *incx, doublereal *dy, integer *incy)
172 /* System generated locals */
175 /* Local variables */
176 integer i__, m, ix, iy, mp1;
179 /* constant times a vector plus a vector. */
180 /* uses unrolled loops for increments equal to one. */
181 /* jack dongarra, linpack, 3/11/78. */
184 /* Parameter adjustments */
195 if (*incx == 1 && *incy == 1) {
199 /* code for unequal increments or equal increments */
205 ix = (-(*n) + 1) * *incx + 1;
208 iy = (-(*n) + 1) * *incy + 1;
211 for (i__ = 1; i__ <= i__1; ++i__) {
212 dy[iy] += *da * dx[ix];
219 /* code for both increments equal to 1 */
230 for (i__ = 1; i__ <= i__1; ++i__) {
231 dy[i__] += *da * dx[i__];
240 for (i__ = mp1; i__ <= i__1; i__ += 4) {
241 dy[i__] += *da * dx[i__];
242 dy[i__ + 1] += *da * dx[i__ + 1];
243 dy[i__ + 2] += *da * dx[i__ + 2];
244 dy[i__ + 3] += *da * dx[i__ + 3];
250 /* dcopy.f -- translated by f2c (version 19991025).
251 You must link the resulting object file with the libraries:
252 -lf2c -lm (in that order)
255 static int dcopy_(integer *n, doublereal *dx, integer *incx,
256 doublereal *dy, integer *incy)
258 /* System generated locals */
261 /* Local variables */
262 integer i__, m, ix, iy, mp1;
265 /* copies a vector, x, to a vector, y. */
266 /* uses unrolled loops for increments equal to one. */
267 /* jack dongarra, linpack, 3/11/78. */
270 /* Parameter adjustments */
278 if (*incx == 1 && *incy == 1) {
282 /* code for unequal increments or equal increments */
288 ix = (-(*n) + 1) * *incx + 1;
291 iy = (-(*n) + 1) * *incy + 1;
294 for (i__ = 1; i__ <= i__1; ++i__) {
302 /* code for both increments equal to 1 */
313 for (i__ = 1; i__ <= i__1; ++i__) {
323 for (i__ = mp1; i__ <= i__1; i__ += 7) {
325 dy[i__ + 1] = dx[i__ + 1];
326 dy[i__ + 2] = dx[i__ + 2];
327 dy[i__ + 3] = dx[i__ + 3];
328 dy[i__ + 4] = dx[i__ + 4];
329 dy[i__ + 5] = dx[i__ + 5];
330 dy[i__ + 6] = dx[i__ + 6];
336 /* dscal.f -- translated by f2c (version 19991025).
337 You must link the resulting object file with the libraries:
338 -lf2c -lm (in that order)
341 static int dscal_(integer *n, doublereal *da, doublereal *dx,
344 /* System generated locals */
347 /* Local variables */
348 integer i__, m, ix, mp1;
351 /* scales a vector by a constant. */
352 /* uses unrolled loops for increment equal to one. */
353 /* jack dongarra, linpack, 3/11/78. */
354 /* modified to correct problem with negative increment, 8/21/90. */
357 /* Parameter adjustments */
368 /* code for increment not equal to 1 */
372 ix = (-(*n) + 1) * *incx + 1;
375 for (i__ = 1; i__ <= i__1; ++i__) {
376 dx[ix] = *da * dx[ix];
382 /* code for increment equal to 1 */
393 for (i__ = 1; i__ <= i__1; ++i__) {
394 dx[i__] = *da * dx[i__];
403 for (i__ = mp1; i__ <= i__1; i__ += 5) {
404 dx[i__] = *da * dx[i__];
405 dx[i__ + 1] = *da * dx[i__ + 1];
406 dx[i__ + 2] = *da * dx[i__ + 2];
407 dx[i__ + 3] = *da * dx[i__ + 3];
408 dx[i__ + 4] = *da * dx[i__ + 4];
414 /* dist.f -- translated by f2c (version 19991025).
415 You must link the resulting object file with the libraries:
416 -lf2c -lm (in that order)
419 static doublereal dist_(integer *n, doublereal *x, doublereal *y)
421 /* System generated locals */
423 doublereal ret_val, d__1;
425 /* Builtin functions */
426 double sqrt(doublereal);
428 /* Local variables */
430 doublereal scale, absxmy, sum;
434 /* Coded by Tom Rowan */
435 /* Department of Computer Sciences */
436 /* University of Texas at Austin */
438 /* dist calculates the distance between the points x,y. */
442 /* n - number of components */
444 /* x - point in n-space */
446 /* y - point in n-space */
448 /* local variables */
451 /* subroutines and functions */
455 /* ----------------------------------------------------------- */
457 /* Parameter adjustments */
462 absxmy = (d__1 = x[1] - y[1], abs(d__1));
464 sum = absxmy * absxmy;
471 for (i__ = 2; i__ <= i__1; ++i__) {
472 absxmy = (d__1 = x[i__] - y[i__], abs(d__1));
473 if (absxmy <= scale) {
474 /* Computing 2nd power */
475 d__1 = absxmy / scale;
478 /* Computing 2nd power */
479 d__1 = scale / absxmy;
480 sum = sum * (d__1 * d__1) + 1.;
485 ret_val = scale * sqrt(sum);
489 /* calcc.f -- translated by f2c (version 19991025).
490 You must link the resulting object file with the libraries:
491 -lf2c -lm (in that order)
494 /* Table of constant values */
496 static doublereal c_b3 = 0.;
497 static integer c__0 = 0;
498 static integer c__1 = 1;
499 static doublereal c_b7 = 1.;
501 static int calcc_(integer *ns, doublereal *s, integer *ih, integer *
502 inew, logical *updatc, doublereal *c__)
504 /* System generated locals */
505 integer s_dim1, s_offset, i__1;
508 /* Local variables */
511 /* Coded by Tom Rowan */
512 /* Department of Computer Sciences */
513 /* University of Texas at Austin */
515 /* calcc calculates the centroid of the simplex without the */
516 /* vertex with highest function value. */
520 /* ns - subspace dimension */
522 /* s - double precision work space of dimension .ge. */
523 /* ns*(ns+3) used to store simplex */
525 /* ih - index to vertex with highest function value */
527 /* inew - index to new point */
529 /* updatc - logical switch */
530 /* = .true. : update centroid */
531 /* = .false. : calculate centroid from scratch */
533 /* c - centroid of the simplex without vertex with */
534 /* highest function value */
538 /* c - new centroid */
540 /* local variables */
543 /* subroutines and functions */
547 /* ----------------------------------------------------------- */
549 /* Parameter adjustments */
552 s_offset = 1 + s_dim1 * 1;
561 for (i__ = 1; i__ <= i__1; ++i__) {
562 c__[i__] += (s[i__ + *inew * s_dim1] - s[i__ + *ih * s_dim1]) / *
567 dcopy_(ns, &c_b3, &c__0, &c__[1], &c__1);
569 for (j = 1; j <= i__1; ++j) {
571 daxpy_(ns, &c_b7, &s[j * s_dim1 + 1], &c__1, &c__[1], &c__1);
576 dscal_(ns, &d__1, &c__[1], &c__1);
581 /* order.f -- translated by f2c (version 19991025).
582 You must link the resulting object file with the libraries:
583 -lf2c -lm (in that order)
586 static int order_(integer *npts, doublereal *fs, integer *il,
587 integer *is, integer *ih)
589 /* System generated locals */
592 /* Local variables */
597 /* Coded by Tom Rowan */
598 /* Department of Computer Sciences */
599 /* University of Texas at Austin */
601 /* order determines the indices of the vertices with the */
602 /* lowest, second highest, and highest function values. */
606 /* npts - number of points in simplex */
608 /* fs - double precision vector of function values of */
611 /* il - index to vertex with lowest function value */
615 /* il - new index to vertex with lowest function value */
617 /* is - new index to vertex with second highest */
620 /* ih - new index to vertex with highest function value */
622 /* local variables */
625 /* subroutines and functions */
629 /* ----------------------------------------------------------- */
631 /* Parameter adjustments */
637 if (fs[j] >= fs[*il]) {
645 i__1 = il0 + *npts - 2;
646 for (i__ = il0 + 1; i__ <= i__1; ++i__) {
648 if (fs[j] >= fs[*ih]) {
651 } else if (fs[j] > fs[*is]) {
653 } else if (fs[j] < fs[*il]) {
661 /* partx.f -- translated by f2c (version 19991025).
662 You must link the resulting object file with the libraries:
663 -lf2c -lm (in that order)
666 /* Common Block Declarations */
669 doublereal alpha, beta, gamma, delta, psi, omega;
670 integer nsmin, nsmax, irepl, ifxsw;
671 doublereal bonus, fstop;
672 integer nfstop, nfxe;
673 doublereal fxstat[4], ftest;
674 logical minf, initx, newx;
677 #define usubc_1 usubc_
679 static int partx_(integer *n, integer *ip, doublereal *absdx,
680 integer *nsubs, integer *nsvals)
682 /* System generated locals */
685 /* Local variables */
686 static integer i__, nleft, nused;
687 static doublereal as1max, gapmax, asleft, as1, as2;
688 static integer ns1, ns2;
689 static doublereal gap;
693 /* Coded by Tom Rowan */
694 /* Department of Computer Sciences */
695 /* University of Texas at Austin */
697 /* partx partitions the vector x by grouping components of */
698 /* similar magnitude of change. */
702 /* n - number of components (problem dimension) */
704 /* ip - permutation vector */
706 /* absdx - vector of magnitude of change in x */
708 /* nsvals - integer array dimensioned .ge. int(n/nsmin) */
712 /* nsubs - number of subspaces */
714 /* nsvals - integer array of subspace dimensions */
720 /* local variables */
724 /* subroutines and functions */
728 /* ----------------------------------------------------------- */
730 /* Parameter adjustments */
741 for (i__ = 2; i__ <= i__1; ++i__) {
742 asleft += absdx[i__];
749 i__1 = usubc_1.nsmin - 1;
750 for (i__ = 1; i__ <= i__1; ++i__) {
751 as1 += absdx[ip[nused + i__]];
755 i__1 = min(usubc_1.nsmax,nleft);
756 for (ns1 = usubc_1.nsmin; ns1 <= i__1; ++ns1) {
757 as1 += absdx[ip[nused + ns1]];
760 if (ns2 >= ((ns2 - 1) / usubc_1.nsmax + 1) * usubc_1.nsmin) {
762 gap = as1 / ns1 - as2 / ns2;
765 nsvals[*nsubs] = ns1;
770 if (as1 / ns1 > gapmax) {
771 nsvals[*nsubs] = ns1;
777 nused += nsvals[*nsubs];
785 /* sortd.f -- translated by f2c (version 19991025).
786 You must link the resulting object file with the libraries:
787 -lf2c -lm (in that order)
790 static int sortd_(integer *n, doublereal *xkey, integer *ix)
792 /* System generated locals */
795 /* Local variables */
796 integer ixip1, i__, ilast, iswap, ifirst, ixi;
800 /* Coded by Tom Rowan */
801 /* Department of Computer Sciences */
802 /* University of Texas at Austin */
804 /* sortd uses the shakersort method to sort an array of keys */
805 /* in decreasing order. The sort is performed implicitly by */
806 /* modifying a vector of indices. */
808 /* For nearly sorted arrays, sortd requires O(n) comparisons. */
809 /* for completely unsorted arrays, sortd requires O(n**2) */
810 /* comparisons and will be inefficient unless n is small. */
814 /* n - number of components */
816 /* xkey - double precision vector of keys */
818 /* ix - integer vector of indices */
822 /* ix - indices satisfy xkey(ix(i)) .ge. xkey(ix(i+1)) */
823 /* for i = 1,...,n-1 */
825 /* local variables */
828 /* ----------------------------------------------------------- */
830 /* Parameter adjustments */
839 if (ifirst <= ilast) {
841 for (i__ = ifirst; i__ <= i__1; ++i__) {
844 if (xkey[ixi] < xkey[ixip1]) {
853 for (i__ = ilast; i__ >= i__1; --i__) {
856 if (xkey[ixi] < xkey[ixip1]) {
869 /* newpt.f -- translated by f2c (version 19991025).
870 You must link the resulting object file with the libraries:
871 -lf2c -lm (in that order)
874 static int newpt_(integer *ns, doublereal *coef, doublereal *xbase,
875 doublereal *xold, logical *new__, doublereal *xnew, logical *small)
877 /* System generated locals */
880 /* Local variables */
888 /* Coded by Tom Rowan */
889 /* Department of Computer Sciences */
890 /* University of Texas at Austin */
892 /* newpt performs reflections, expansions, contractions, and */
893 /* shrinkages (massive contractions) by computing: */
895 /* xbase + coef * (xbase - xold) */
897 /* The result is stored in xnew if new .eq. .true., */
898 /* in xold otherwise. */
900 /* use : coef .gt. 0 to reflect */
901 /* coef .lt. 0 to expand, contract, or shrink */
905 /* ns - number of components (subspace dimension) */
907 /* coef - one of four simplex method coefficients */
909 /* xbase - double precision ns-vector representing base */
912 /* xold - double precision ns-vector representing old */
915 /* new - logical switch */
916 /* = .true. : store result in xnew */
917 /* = .false. : store result in xold, xnew is not */
922 /* xold - unchanged if new .eq. .true., contains new */
923 /* point otherwise */
925 /* xnew - double precision ns-vector representing new */
926 /* point if new .eq. .true., not referenced */
929 /* small - logical flag */
930 /* = .true. : coincident points */
931 /* = .false. : otherwise */
933 /* local variables */
936 /* subroutines and functions */
940 /* ----------------------------------------------------------- */
942 /* Parameter adjustments */
952 for (i__ = 1; i__ <= i__1; ++i__) {
953 xnew[i__] = xbase[i__] + *coef * (xbase[i__] - xold[i__]);
954 eqbase = eqbase && xnew[i__] == xbase[i__];
955 eqold = eqold && xnew[i__] == xold[i__];
960 for (i__ = 1; i__ <= i__1; ++i__) {
962 xold[i__] = xbase[i__] + *coef * (xbase[i__] - xold[i__]);
963 eqbase = eqbase && xold[i__] == xbase[i__];
964 eqold = eqold && xold[i__] == xoldi;
968 *small = eqbase || eqold;
972 /* start.f -- translated by f2c (version 19991025).
973 You must link the resulting object file with the libraries:
974 -lf2c -lm (in that order)
977 static int start_(integer *n, doublereal *x, doublereal *step,
978 integer *ns, integer *ips, doublereal *s, logical *small)
980 /* System generated locals */
981 integer s_dim1, s_offset, i__1;
983 /* Local variables */
987 /* Coded by Tom Rowan */
988 /* Department of Computer Sciences */
989 /* University of Texas at Austin */
991 /* start creates the initial simplex for simplx minimization. */
995 /* n - problem dimension */
997 /* x - current best point */
999 /* step - stepsizes for corresponding components of x */
1001 /* ns - subspace dimension */
1003 /* ips - permutation vector */
1008 /* s - first ns+1 columns contain initial simplex */
1010 /* small - logical flag */
1011 /* = .true. : coincident points */
1012 /* = .false. : otherwise */
1014 /* local variables */
1017 /* subroutines and functions */
1022 /* ----------------------------------------------------------- */
1024 /* Parameter adjustments */
1029 s_offset = 1 + s_dim1 * 1;
1034 for (i__ = 1; i__ <= i__1; ++i__) {
1035 s[i__ + s_dim1] = x[ips[i__]];
1039 for (j = 2; j <= i__1; ++j) {
1040 dcopy_(ns, &s[s_dim1 + 1], &c__1, &s[j * s_dim1 + 1], &c__1);
1041 s[j - 1 + j * s_dim1] = s[j - 1 + s_dim1] + step[ips[j - 1]];
1045 /* check for coincident points */
1048 for (j = 2; j <= i__1; ++j) {
1049 if (s[j - 1 + j * s_dim1] == s[j - 1 + s_dim1]) {
1057 /* coincident points */
1064 /* fstats.f -- translated by f2c (version 19991025).
1065 You must link the resulting object file with the libraries:
1066 -lf2c -lm (in that order)
1069 static int fstats_(doublereal *fx, integer *ifxwt, logical *reset)
1071 /* System generated locals */
1072 doublereal d__1, d__2, d__3;
1074 /* Builtin functions */
1075 double sqrt(doublereal);
1077 /* Local variables */
1078 static doublereal fscale;
1080 static doublereal f1sv;
1084 /* Coded by Tom Rowan */
1085 /* Department of Computer Sciences */
1086 /* University of Texas at Austin */
1088 /* fstats modifies the common /usubc/ variables nfxe,fxstat. */
1092 /* fx - most recent evaluation of f at best x */
1094 /* ifxwt - integer weight for fx */
1096 /* reset - logical switch */
1097 /* = .true. : initialize nfxe,fxstat */
1098 /* = .false. : update nfxe,fxstat */
1104 /* local variables */
1108 /* subroutines and functions */
1112 /* ----------------------------------------------------------- */
1115 usubc_1.nfxe = *ifxwt;
1116 usubc_1.fxstat[0] = *fx;
1117 usubc_1.fxstat[1] = *fx;
1118 usubc_1.fxstat[2] = *fx;
1119 usubc_1.fxstat[3] = 0.;
1122 f1sv = usubc_1.fxstat[0];
1123 usubc_1.nfxe += *ifxwt;
1124 usubc_1.fxstat[0] += *ifxwt * (*fx - usubc_1.fxstat[0]) /
1126 usubc_1.fxstat[1] = max(usubc_1.fxstat[1],*fx);
1127 usubc_1.fxstat[2] = min(usubc_1.fxstat[2],*fx);
1129 d__1 = abs(usubc_1.fxstat[1]), d__2 = abs(usubc_1.fxstat[2]), d__1 =
1131 fscale = max(d__1,1.);
1132 /* Computing 2nd power */
1133 d__1 = usubc_1.fxstat[3] / fscale;
1134 /* Computing 2nd power */
1135 d__2 = (usubc_1.fxstat[0] - f1sv) / fscale;
1136 /* Computing 2nd power */
1137 d__3 = (*fx - usubc_1.fxstat[0]) / fscale;
1138 usubc_1.fxstat[3] = fscale * sqrt(((nsv - 1) * (d__1 * d__1) + nsv * (
1139 d__2 * d__2) + *ifxwt * (d__3 * d__3)) / (usubc_1.nfxe - 1));
1144 /* evalf.f -- translated by f2c (version 19991025).
1145 You must link the resulting object file with the libraries:
1146 -lf2c -lm (in that order)
1149 /* Common Block Declarations */
1152 doublereal fbonus, sfstop, sfbest;
1156 #define isubc_1 isubc_
1158 static logical c_true = TRUE_;
1159 static logical c_false = FALSE_;
1161 static int evalf_(D_fp f,void*fdata, integer *ns, integer *ips, doublereal *xs,
1162 integer *n, doublereal *x, doublereal *sfx, integer *nfe)
1164 /* System generated locals */
1167 /* Local variables */
1169 static doublereal fx;
1170 static logical newbst;
1172 /* Coded by Tom Rowan */
1173 /* Department of Computer Sciences */
1174 /* University of Texas at Austin */
1176 /* evalf evaluates the function f at a point defined by x */
1177 /* with ns of its components replaced by those in xs. */
1181 /* f - user supplied function f(n,x) to be optimized */
1183 /* ns - subspace dimension */
1185 /* ips - permutation vector */
1187 /* xs - double precision ns-vector to be mapped to x */
1189 /* n - problem dimension */
1191 /* x - double precision n-vector */
1193 /* nfe - number of function evaluations */
1197 /* sfx - signed value of f evaluated at x */
1199 /* nfe - incremented number of function evaluations */
1207 /* local variables */
1211 /* subroutines and functions */
1214 /* ----------------------------------------------------------- */
1216 /* Parameter adjustments */
1223 for (i__ = 1; i__ <= i__1; ++i__) {
1224 x[ips[i__]] = xs[i__];
1227 usubc_1.newx = isubc_1.new__ || usubc_1.irepl != 2;
1228 fx = (*f)(*n, &x[1], fdata);
1229 if (usubc_1.irepl == 0) {
1235 } else if (isubc_1.new__) {
1238 newbst = fx < usubc_1.ftest;
1241 newbst = fx > usubc_1.ftest;
1243 if (usubc_1.initx || newbst) {
1244 if (usubc_1.irepl == 1) {
1245 fstats_(&fx, &c__1, &c_true);
1248 isubc_1.sfbest = *sfx;
1251 if (usubc_1.irepl == 1) {
1252 fstats_(&fx, &c__1, &c_false);
1253 fx = usubc_1.fxstat[usubc_1.ifxsw - 1];
1255 usubc_1.ftest = fx + isubc_1.fbonus * usubc_1.fxstat[3];
1257 *sfx = usubc_1.ftest;
1258 isubc_1.sfbest = fx;
1260 *sfx = -usubc_1.ftest;
1261 isubc_1.sfbest = -fx;
1268 /* simplx.f -- translated by f2c (version 19991025).
1269 You must link the resulting object file with the libraries:
1270 -lf2c -lm (in that order)
1273 static int simplx_(D_fp f, void *fdata, integer *n, doublereal *step, integer *
1274 ns, integer *ips, integer *maxnfe, logical *cmode, doublereal *x,
1275 doublereal *fx, integer *nfe, doublereal *s, doublereal *fs, integer *
1278 /* System generated locals */
1279 integer s_dim1, s_offset, i__1;
1280 doublereal d__1, d__2;
1282 /* Local variables */
1283 static integer inew;
1284 static integer npts;
1285 static integer i__, j;
1286 static integer icent;
1287 static logical small;
1288 static integer itemp;
1289 static doublereal fc, fe;
1290 static integer ih, il;
1291 static doublereal fr;
1293 static logical updatc;
1294 static doublereal dum, tol;
1298 /* Coded by Tom Rowan */
1299 /* Department of Computer Sciences */
1300 /* University of Texas at Austin */
1302 /* simplx uses the Nelder-Mead simplex method to minimize the */
1303 /* function f on a subspace. */
1307 /* f - function to be minimized, declared external in */
1308 /* calling routine */
1310 /* n - problem dimension */
1312 /* step - stepsizes for corresponding components of x */
1314 /* ns - subspace dimension */
1316 /* ips - permutation vector */
1318 /* maxnfe - maximum number of function evaluations */
1320 /* cmode - logical switch */
1321 /* = .true. : continuation of previous call */
1322 /* = .false. : first call */
1324 /* x - starting guess for minimum */
1326 /* fx - value of f at x */
1328 /* nfe - number of function evaluations */
1330 /* s - double precision work array of dimension .ge. */
1331 /* ns*(ns+3) used to store simplex */
1333 /* fs - double precision work array of dimension .ge. */
1334 /* ns+1 used to store function values of simplex */
1339 /* x - computed minimum */
1341 /* fx - value of f at x */
1343 /* nfe - incremented number of function evaluations */
1345 /* iflag - error flag */
1346 /* = -1 : maxnfe exceeded */
1347 /* = 0 : simplex reduced by factor of psi */
1348 /* = 1 : limit of machine precision */
1349 /* = 2 : reached fstop */
1357 /* local variables */
1361 /* subroutines and functions */
1366 /* ----------------------------------------------------------- */
1368 /* Parameter adjustments */
1373 s_offset = 1 + s_dim1 * 1;
1385 start_(n, &x[1], &step[1], ns, &ips[1], &s[s_offset], &small);
1390 if (usubc_1.irepl > 0) {
1391 isubc_1.new__ = FALSE_;
1392 evalf_((D_fp)f,fdata, ns, &ips[1], &s[s_dim1 + 1], n, &x[1], &fs[1], nfe);
1396 isubc_1.new__ = TRUE_;
1398 for (j = 2; j <= i__1; ++j) {
1399 evalf_((D_fp)f, fdata,ns, &ips[1], &s[j * s_dim1 + 1], n, &x[1], &fs[j],
1404 order_(&npts, &fs[1], &il, &is, &ih);
1405 tol = usubc_1.psi * dist_(ns, &s[ih * s_dim1 + 1], &s[il * s_dim1 + 1]);
1410 calcc_(ns, &s[s_offset], &ih, &inew, &updatc, &s[icent * s_dim1 + 1]);
1416 newpt_(ns, &usubc_1.alpha, &s[icent * s_dim1 + 1], &s[ih * s_dim1 + 1], &
1417 c_true, &s[itemp * s_dim1 + 1], &small);
1421 evalf_((D_fp)f,fdata, ns, &ips[1], &s[itemp * s_dim1 + 1], n, &x[1], &fr, nfe);
1426 d__1 = -usubc_1.gamma;
1427 newpt_(ns, &d__1, &s[icent * s_dim1 + 1], &s[itemp * s_dim1 + 1], &
1428 c_true, &s[ih * s_dim1 + 1], &small);
1432 evalf_((D_fp)f,fdata, ns, &ips[1], &s[ih * s_dim1 + 1], n, &x[1], &fe, nfe);
1436 dcopy_(ns, &s[itemp * s_dim1 + 1], &c__1, &s[ih * s_dim1 + 1], &
1440 } else if (fr < fs[is]) {
1442 /* accept reflected point */
1444 dcopy_(ns, &s[itemp * s_dim1 + 1], &c__1, &s[ih * s_dim1 + 1], &c__1);
1451 d__1 = -usubc_1.beta;
1452 newpt_(ns, &d__1, &s[icent * s_dim1 + 1], &s[ih * s_dim1 + 1], &
1453 c_true, &s[itemp * s_dim1 + 1], &small);
1455 d__1 = -usubc_1.beta;
1456 newpt_(ns, &d__1, &s[icent * s_dim1 + 1], &s[itemp * s_dim1 + 1],
1457 &c_false, &dum, &small);
1462 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],
1491 order_(&npts, &fs[1], &il, &is, &ih);
1493 /* check termination */
1496 if (usubc_1.irepl == 0) {
1499 *fx = isubc_1.sfbest;
1502 if (usubc_1.nfstop > 0 && *fx <= isubc_1.sfstop && usubc_1.nfxe >=
1505 } else if (*nfe >= *maxnfe) {
1507 } else if (dist_(ns, &s[ih * s_dim1 + 1], &s[il * s_dim1 + 1]) <= tol ||
1514 /* end main loop, return best point */
1517 for (i__ = 1; i__ <= i__1; ++i__) {
1518 x[ips[i__]] = s[i__ + il * s_dim1];
1524 /* subopt.f -- translated by f2c (version 19991025).
1525 You must link the resulting object file with the libraries:
1526 -lf2c -lm (in that order)
1529 static int subopt_(integer *n)
1533 /* Coded by Tom Rowan */
1534 /* Department of Computer Sciences */
1535 /* University of Texas at Austin */
1537 /* subopt sets options for subplx. */
1541 /* n - problem dimension */
1548 /* subroutines and functions */
1552 /* ----------------------------------------------------------- */
1554 /* *********************************************************** */
1555 /* simplex method strategy parameters */
1556 /* *********************************************************** */
1558 /* alpha - reflection coefficient */
1563 /* beta - contraction coefficient */
1564 /* 0 .lt. beta .lt. 1 */
1568 /* gamma - expansion coefficient */
1573 /* delta - shrinkage (massive contraction) coefficient */
1574 /* 0 .lt. delta .lt. 1 */
1578 /* *********************************************************** */
1579 /* subplex method strategy parameters */
1580 /* *********************************************************** */
1582 /* psi - simplex reduction coefficient */
1583 /* 0 .lt. psi .lt. 1 */
1587 /* omega - step reduction coefficient */
1588 /* 0 .lt. omega .lt. 1 */
1592 /* nsmin and nsmax specify a range of subspace dimensions. */
1593 /* In addition to satisfying 1 .le. nsmin .le. nsmax .le. n, */
1594 /* nsmin and nsmax must be chosen so that n can be expressed */
1595 /* as a sum of positive integers where each of these integers */
1596 /* ns(i) satisfies nsmin .le. ns(i) .ge. nsmax. */
1598 /* nsmin*ceil(n/nsmax) .le. n must be true. */
1600 /* nsmin - subspace dimension minimum */
1602 usubc_1.nsmin = min(2,*n);
1604 /* nsmax - subspace dimension maximum */
1606 usubc_1.nsmax = min(5,*n);
1608 /* *********************************************************** */
1609 /* subplex method special cases */
1610 /* *********************************************************** */
1611 /* nelder-mead simplex method with periodic restarts */
1612 /* nsmin = nsmax = n */
1613 /* *********************************************************** */
1614 /* nelder-mead simplex method */
1615 /* nsmin = nsmax = n, psi = small positive */
1616 /* *********************************************************** */
1618 /* irepl, ifxsw, and bonus deal with measurement replication. */
1619 /* Objective functions subject to large amounts of noise can */
1620 /* cause an optimization method to halt at a false optimum. */
1621 /* An expensive solution to this problem is to evaluate f */
1622 /* several times at each point and return the average (or max */
1623 /* or min) of these trials as the function value. subplx */
1624 /* performs measurement replication only at the current best */
1625 /* point. The longer a point is retained as best, the more */
1626 /* accurate its function value becomes. */
1628 /* The common variable nfxe contains the number of function */
1629 /* evaluations at the current best point. fxstat contains the */
1630 /* mean, max, min, and standard deviation of these trials. */
1632 /* irepl - measurement replication switch */
1633 /* irepl = 0, 1, or 2 */
1634 /* = 0 : no measurement replication */
1635 /* = 1 : subplx performs measurement replication */
1636 /* = 2 : user performs measurement replication */
1637 /* (This is useful when optimizing on the mean, */
1638 /* max, or min of trials is insufficient. Common */
1639 /* variable initx is true for first function */
1640 /* evaluation. newx is true for first trial at */
1641 /* this point. The user uses subroutine fstats */
1642 /* within his objective function to maintain */
1643 /* fxstat. By monitoring newx, the user can tell */
1644 /* whether to return the function evaluation */
1645 /* (newx = .true.) or to use the new function */
1646 /* evaluation to refine the function evaluation */
1647 /* of the current best point (newx = .false.). */
1648 /* The common variable ftest gives the function */
1649 /* value that a new point must beat to be */
1650 /* considered the new best point.) */
1654 /* ifxsw - measurement replication optimization switch */
1655 /* ifxsw = 1, 2, or 3 */
1656 /* = 1 : retain mean of trials as best function value */
1657 /* = 2 : retain max */
1658 /* = 3 : retain min */
1662 /* Since the current best point will also be the most */
1663 /* accurately evaluated point whenever irepl .gt. 0, a bonus */
1664 /* should be added to the function value of the best point */
1665 /* so that the best point is not replaced by a new point */
1666 /* that only appears better because of noise. */
1667 /* subplx uses bonus to determine how many multiples of */
1668 /* fxstat(4) should be added as a bonus to the function */
1669 /* evaluation. (The bonus is adjusted automatically by */
1670 /* subplx when ifxsw or minf is changed.) */
1672 /* bonus - measurement replication bonus coefficient */
1673 /* bonus .ge. 0 (normally, bonus = 0 or 1) */
1674 /* = 0 : bonus not used */
1675 /* = 1 : bonus used */
1679 /* nfstop = 0 : f(x) is not tested against fstop */
1680 /* = 1 : if f(x) has reached fstop, subplx returns */
1682 /* = 2 : (only valid when irepl .gt. 0) */
1683 /* if f(x) has reached fstop and */
1684 /* nfxe .gt. nfstop, subplx returns iflag = 2 */
1688 /* fstop - f target value */
1689 /* Its usage is determined by the value of nfstop. */
1691 /* minf - logical switch */
1692 /* = .true. : subplx performs minimization */
1693 /* = .false. : subplx performs maximization */
1695 usubc_1.minf = TRUE_;
1699 /* setstp.f -- translated by f2c (version 19991025).
1700 You must link the resulting object file with the libraries:
1701 -lf2c -lm (in that order)
1704 static double d_sign(doublereal *x, doublereal *y)
1706 return copysign(*x, *y);
1709 static int setstp_(integer *nsubs, integer *n, doublereal *deltax,
1712 /* System generated locals */
1714 doublereal d__1, d__2, d__3;
1716 /* Builtin functions */
1717 /* double d_sign(doublereal *, doublereal *); */
1719 /* Local variables */
1721 static doublereal stpfac;
1725 /* Coded by Tom Rowan */
1726 /* Department of Computer Sciences */
1727 /* University of Texas at Austin */
1729 /* setstp sets the stepsizes for the corresponding components */
1730 /* of the solution vector. */
1734 /* nsubs - number of subspaces */
1736 /* n - number of components (problem dimension) */
1738 /* deltax - vector of change in solution vector */
1740 /* step - stepsizes for corresponding components of */
1741 /* solution vector */
1745 /* step - new stepsizes */
1751 /* local variables */
1755 /* subroutines and functions */
1760 /* ----------------------------------------------------------- */
1764 /* Parameter adjustments */
1772 d__3 = dasum_(n, &deltax[1], &c__1) / dasum_(n, &step[1], &c__1);
1773 d__1 = max(d__3,usubc_1.omega), d__2 = 1. / usubc_1.omega;
1774 stpfac = min(d__1,d__2);
1776 stpfac = usubc_1.psi;
1778 dscal_(n, &stpfac, &step[1], &c__1);
1780 /* reorient simplex */
1783 for (i__ = 1; i__ <= i__1; ++i__) {
1784 if (deltax[i__] != 0.) {
1785 step[i__] = d_sign(&step[i__], &deltax[i__]);
1787 step[i__] = -step[i__];
1794 /* subplx.f -- translated by f2c (version 19991025).
1795 You must link the resulting object file with the libraries:
1796 -lf2c -lm (in that order)
1799 static int subplx_(D_fp f, void *fdata, integer *n, doublereal *tol, integer *
1800 maxnfe, integer *mode, doublereal *scale, doublereal *x, doublereal *
1801 fx, integer *nfe, doublereal *work, integer *iwork, integer *iflag)
1803 /* Initialized data */
1805 static doublereal bnsfac[6] /* was [3][2] */ = { -1.,-2.,0.,1.,0.,2. };
1807 /* System generated locals */
1809 doublereal d__1, d__2, d__3, d__4, d__5, d__6;
1811 /* Local variables */
1813 static logical cmode;
1814 static integer istep;
1815 static doublereal xpscl;
1816 static integer nsubs, ipptr;
1817 static integer isptr;
1818 static integer ns, insfnl, ifsptr;
1819 static integer insptr;
1820 static integer istptr;
1821 static doublereal scl, dum;
1823 static doublereal sfx;
1827 /* Coded by Tom Rowan */
1828 /* Department of Computer Sciences */
1829 /* University of Texas at Austin */
1831 /* subplx uses the subplex method to solve unconstrained */
1832 /* optimization problems. The method is well suited for */
1833 /* optimizing objective functions that are noisy or are */
1834 /* discontinuous at the solution. */
1836 /* subplx sets default optimization options by calling the */
1837 /* subroutine subopt. The user can override these defaults */
1838 /* by calling subopt prior to calling subplx, changing the */
1839 /* appropriate common variables, and setting the value of */
1840 /* mode as indicated below. */
1842 /* By default, subplx performs minimization. */
1846 /* f - user supplied function f(n,x) to be optimized, */
1847 /* declared external in calling routine */
1849 /* n - problem dimension */
1851 /* tol - relative error tolerance for x (tol .ge. 0.) */
1853 /* maxnfe - maximum number of function evaluations */
1855 /* mode - integer mode switch with binary expansion */
1856 /* (bit 1) (bit 0) : */
1857 /* bit 0 = 0 : first call to subplx */
1858 /* = 1 : continuation of previous call */
1859 /* bit 1 = 0 : use default options */
1860 /* = 1 : user set options */
1862 /* scale - scale and initial stepsizes for corresponding */
1863 /* components of x */
1864 /* (If scale(1) .lt. 0., */
1865 /* abs(scale(1)) is used for all components of x, */
1866 /* and scale(2),...,scale(n) are not referenced.) */
1868 /* x - starting guess for optimum */
1870 /* work - double precision work array of dimension .ge. */
1871 /* 2*n + nsmax*(nsmax+4) + 1 */
1872 /* (nsmax is set in subroutine subopt. */
1873 /* default: nsmax = min(5,n)) */
1875 /* iwork - integer work array of dimension .ge. */
1876 /* n + int(n/nsmin) */
1877 /* (nsmin is set in subroutine subopt. */
1878 /* default: nsmin = min(2,n)) */
1882 /* x - computed optimum */
1884 /* fx - value of f at x */
1886 /* nfe - number of function evaluations */
1888 /* iflag - error flag */
1889 /* = -2 : invalid input */
1890 /* = -1 : maxnfe exceeded */
1891 /* = 0 : tol satisfied */
1892 /* = 1 : limit of machine precision */
1893 /* = 2 : fstop reached (fstop usage is determined */
1894 /* by values of options minf, nfstop, and */
1895 /* irepl. default: f(x) not tested against */
1897 /* iflag should not be reset between calls to */
1906 /* local variables */
1910 /* subroutines and functions */
1917 /* Parameter adjustments */
1924 /* ----------------------------------------------------------- */
1926 if (*mode % 2 == 0) {
1928 /* first call, check input */
1939 if (scale[1] >= 0.) {
1941 for (i__ = 1; i__ <= i__1; ++i__) {
1942 xpscl = x[i__] + scale[i__];
1943 if (xpscl == x[i__]) {
1949 scl = abs(scale[1]);
1951 for (i__ = 1; i__ <= i__1; ++i__) {
1952 xpscl = x[i__] + scl;
1953 if (xpscl == x[i__]) {
1959 if (*mode / 2 % 2 == 0) {
1962 if (usubc_1.alpha <= 0.) {
1965 if (usubc_1.beta <= 0. || usubc_1.beta >= 1.) {
1968 if (usubc_1.gamma <= 1.) {
1971 if (usubc_1.delta <= 0. || usubc_1.delta >= 1.) {
1974 if (usubc_1.psi <= 0. || usubc_1.psi >= 1.) {
1977 if (usubc_1.omega <= 0. || usubc_1.omega >= 1.) {
1980 if (usubc_1.nsmin < 1 || usubc_1.nsmax < usubc_1.nsmin || *n <
1984 if (*n < ((*n - 1) / usubc_1.nsmax + 1) * usubc_1.nsmin) {
1987 if (usubc_1.irepl < 0 || usubc_1.irepl > 2) {
1990 if (usubc_1.ifxsw < 1 || usubc_1.ifxsw > 3) {
1993 if (usubc_1.bonus < 0.) {
1996 if (usubc_1.nfstop < 0) {
2001 /* initialization */
2004 isptr = istptr + *n;
2005 ifsptr = isptr + usubc_1.nsmax * (usubc_1.nsmax + 3);
2007 if (scale[1] > 0.) {
2008 dcopy_(n, &scale[1], &c__1, &work[1], &c__1);
2009 dcopy_(n, &scale[1], &c__1, &work[istptr], &c__1);
2011 dcopy_(n, &scl, &c__0, &work[1], &c__1);
2012 dcopy_(n, &scl, &c__0, &work[istptr], &c__1);
2015 for (i__ = 1; i__ <= i__1; ++i__) {
2021 if (usubc_1.irepl == 0) {
2022 isubc_1.fbonus = 0.;
2023 } else if (usubc_1.minf) {
2024 isubc_1.fbonus = bnsfac[usubc_1.ifxsw - 1] * usubc_1.bonus;
2026 isubc_1.fbonus = bnsfac[usubc_1.ifxsw + 2] * usubc_1.bonus;
2028 if (usubc_1.nfstop == 0) {
2029 isubc_1.sfstop = 0.;
2030 } else if (usubc_1.minf) {
2031 isubc_1.sfstop = usubc_1.fstop;
2033 isubc_1.sfstop = -usubc_1.fstop;
2037 isubc_1.new__ = TRUE_;
2038 usubc_1.initx = TRUE_;
2039 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;
2084 simplx_((D_fp)f, fdata, n, &work[istptr], &ns, &iwork[ipptr], maxnfe, &cmode, &x[
2085 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 */
2109 for (i__ = 1; i__ <= i__1; ++i__) {
2111 d__4 = (d__2 = work[i__], abs(d__2)), d__5 = (d__1 = work[istep], abs(
2112 d__1)) * usubc_1.psi;
2114 d__6 = (d__3 = x[i__], abs(d__3));
2115 if (max(d__4,d__5) / max(d__6,1.) > *tol) {
2116 setstp_(&nsubs, n, &work[1], &work[istptr]);
2123 /* end subplex loop */
2141 /****************************************************************************/
2142 /****************************************************************************/
2144 /* front-end for subplex routines */
2146 /* Wrapper around f2c'ed subplx_ routine, for multidimensinal
2147 unconstrained optimization:
2151 f: function f(n,x,fdata) to be optimized
2152 n: problem dimension
2153 fmin: (output) value of f at minimum
2154 x[n]: (input) starting guess position, (output) computed minimum
2155 fdata: data pointer passed to f
2156 tol: relative error tolerance for x
2157 maxnfe: maximum number of function evaluations
2158 fmin_max, use_fmin_max: if use_fmin_max, stop when f <= fmin_max
2159 scale[n]: (input) scale & initial stepsizes for components of x
2160 (if *scale < 0, |*scale| is used for all components)
2163 = -2 : invalid input
2164 = -1 : maxnfe exceeded
2166 = 1 : limit of machine precision
2167 = 2 : fstop reached (fstop usage is determined by values of
2168 options minf, nfstop, and irepl. default: f(x) not
2169 tested against fstop)
2171 int subplex(subplex_func f, double *fmin, double *x, int n, void *fdata,
2172 double tol, int maxnfe,
2173 double fmin_max, int use_fmin_max,
2174 const double *scale)
2176 int mode = 0, *iwork, nsmax, nsmin, errflag, nfe;
2181 work = (double*) malloc(sizeof(double) * (2*n + nsmax*(nsmax+4) + 1));
2182 iwork = (int*) malloc(sizeof(int) * (n + n/nsmin + 1));
2183 if (!work || !iwork) {
2184 fprintf(stderr, "subplex: error, out of memory!\n");
2188 if (use_fmin_max) { /* stop when fmin_max is reached */
2191 usubc_1.fstop = fmin_max;
2195 subplx_(f,fdata, &n,
2196 &tol, &maxnfe, &mode,
2199 work, iwork, &errflag);