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 number doublereal;
65
typedef boolean logical;
70
typedef subplex_func D_fp;
72
#define max(a,b) ((a) > (b) ? (a) : (b))
73
#define min(a,b) ((a) < (b) ? (a) : (b))
74
#define abs(x) fabs(x)
76
/****************************************************************************/
77
/****************************************************************************/
79
/* dasum.f -- translated by f2c (version 19991025).
80
You must link the resulting object file with the libraries:
81
-lf2c -lm (in that order)
84
static doublereal dasum_(integer *n, doublereal *dx, integer *incx)
86
/* System generated locals */
88
doublereal ret_val, d__1, d__2, d__3, d__4, d__5, d__6;
96
/* takes the sum of the absolute values. */
97
/* uses unrolled loops for increment equal to one. */
98
/* jack dongarra, linpack, 3/11/78. */
99
/* modified to correct problem with negative increment, 8/21/90. */
102
/* Parameter adjustments */
115
/* code for increment not equal to 1 */
119
ix = (-(*n) + 1) * *incx + 1;
122
for (i__ = 1; i__ <= i__1; ++i__) {
123
dtemp += (d__1 = dx[ix], abs(d__1));
130
/* code for increment equal to 1 */
141
for (i__ = 1; i__ <= i__1; ++i__) {
142
dtemp += (d__1 = dx[i__], abs(d__1));
151
for (i__ = mp1; i__ <= i__1; i__ += 6) {
152
dtemp = dtemp + (d__1 = dx[i__], abs(d__1)) + (d__2 = dx[i__ + 1],
153
abs(d__2)) + (d__3 = dx[i__ + 2], abs(d__3)) + (d__4 = dx[i__
154
+ 3], abs(d__4)) + (d__5 = dx[i__ + 4], abs(d__5)) + (d__6 =
155
dx[i__ + 5], abs(d__6));
163
/* daxpy.f -- translated by f2c (version 19991025).
164
You must link the resulting object file with the libraries:
165
-lf2c -lm (in that order)
168
static int daxpy_(integer *n, doublereal *da, doublereal *dx,
169
integer *incx, doublereal *dy, integer *incy)
171
/* System generated locals */
174
/* Local variables */
175
integer i__, m, ix, iy, mp1;
178
/* constant times a vector plus a vector. */
179
/* uses unrolled loops for increments equal to one. */
180
/* jack dongarra, linpack, 3/11/78. */
183
/* Parameter adjustments */
194
if (*incx == 1 && *incy == 1) {
198
/* code for unequal increments or equal increments */
204
ix = (-(*n) + 1) * *incx + 1;
207
iy = (-(*n) + 1) * *incy + 1;
210
for (i__ = 1; i__ <= i__1; ++i__) {
211
dy[iy] += *da * dx[ix];
218
/* code for both increments equal to 1 */
229
for (i__ = 1; i__ <= i__1; ++i__) {
230
dy[i__] += *da * dx[i__];
239
for (i__ = mp1; i__ <= i__1; i__ += 4) {
240
dy[i__] += *da * dx[i__];
241
dy[i__ + 1] += *da * dx[i__ + 1];
242
dy[i__ + 2] += *da * dx[i__ + 2];
243
dy[i__ + 3] += *da * dx[i__ + 3];
249
/* dcopy.f -- translated by f2c (version 19991025).
250
You must link the resulting object file with the libraries:
251
-lf2c -lm (in that order)
254
static int dcopy_(integer *n, doublereal *dx, integer *incx,
255
doublereal *dy, integer *incy)
257
/* System generated locals */
260
/* Local variables */
261
integer i__, m, ix, iy, mp1;
264
/* copies a vector, x, to a vector, y. */
265
/* uses unrolled loops for increments equal to one. */
266
/* jack dongarra, linpack, 3/11/78. */
269
/* Parameter adjustments */
277
if (*incx == 1 && *incy == 1) {
281
/* code for unequal increments or equal increments */
287
ix = (-(*n) + 1) * *incx + 1;
290
iy = (-(*n) + 1) * *incy + 1;
293
for (i__ = 1; i__ <= i__1; ++i__) {
301
/* code for both increments equal to 1 */
312
for (i__ = 1; i__ <= i__1; ++i__) {
322
for (i__ = mp1; i__ <= i__1; i__ += 7) {
324
dy[i__ + 1] = dx[i__ + 1];
325
dy[i__ + 2] = dx[i__ + 2];
326
dy[i__ + 3] = dx[i__ + 3];
327
dy[i__ + 4] = dx[i__ + 4];
328
dy[i__ + 5] = dx[i__ + 5];
329
dy[i__ + 6] = dx[i__ + 6];
335
/* dscal.f -- translated by f2c (version 19991025).
336
You must link the resulting object file with the libraries:
337
-lf2c -lm (in that order)
340
static int dscal_(integer *n, doublereal *da, doublereal *dx,
343
/* System generated locals */
346
/* Local variables */
347
integer i__, m, ix, mp1;
350
/* scales a vector by a constant. */
351
/* uses unrolled loops for increment equal to one. */
352
/* jack dongarra, linpack, 3/11/78. */
353
/* modified to correct problem with negative increment, 8/21/90. */
356
/* Parameter adjustments */
367
/* code for increment not equal to 1 */
371
ix = (-(*n) + 1) * *incx + 1;
374
for (i__ = 1; i__ <= i__1; ++i__) {
375
dx[ix] = *da * dx[ix];
381
/* code for increment equal to 1 */
392
for (i__ = 1; i__ <= i__1; ++i__) {
393
dx[i__] = *da * dx[i__];
402
for (i__ = mp1; i__ <= i__1; i__ += 5) {
403
dx[i__] = *da * dx[i__];
404
dx[i__ + 1] = *da * dx[i__ + 1];
405
dx[i__ + 2] = *da * dx[i__ + 2];
406
dx[i__ + 3] = *da * dx[i__ + 3];
407
dx[i__ + 4] = *da * dx[i__ + 4];
413
/* dist.f -- translated by f2c (version 19991025).
414
You must link the resulting object file with the libraries:
415
-lf2c -lm (in that order)
418
static doublereal dist_(integer *n, doublereal *x, doublereal *y)
420
/* System generated locals */
422
doublereal ret_val, d__1;
424
/* Builtin functions */
425
double sqrt(doublereal);
427
/* Local variables */
429
doublereal scale, absxmy, sum;
433
/* Coded by Tom Rowan */
434
/* Department of Computer Sciences */
435
/* University of Texas at Austin */
437
/* dist calculates the distance between the points x,y. */
441
/* n - number of components */
443
/* x - point in n-space */
445
/* y - point in n-space */
447
/* local variables */
450
/* subroutines and functions */
454
/* ----------------------------------------------------------- */
456
/* Parameter adjustments */
461
absxmy = (d__1 = x[1] - y[1], abs(d__1));
463
sum = absxmy * absxmy;
470
for (i__ = 2; i__ <= i__1; ++i__) {
471
absxmy = (d__1 = x[i__] - y[i__], abs(d__1));
472
if (absxmy <= scale) {
473
/* Computing 2nd power */
474
d__1 = absxmy / scale;
477
/* Computing 2nd power */
478
d__1 = scale / absxmy;
479
sum = sum * (d__1 * d__1) + 1.;
484
ret_val = scale * sqrt(sum);
488
/* calcc.f -- translated by f2c (version 19991025).
489
You must link the resulting object file with the libraries:
490
-lf2c -lm (in that order)
493
/* Table of constant values */
495
static doublereal c_b3 = 0.;
496
static integer c__0 = 0;
497
static integer c__1 = 1;
498
static doublereal c_b7 = 1.;
500
static int calcc_(integer *ns, doublereal *s, integer *ih, integer *
501
inew, logical *updatc, doublereal *c__)
503
/* System generated locals */
504
integer s_dim1, s_offset, i__1;
507
/* Local variables */
510
/* Coded by Tom Rowan */
511
/* Department of Computer Sciences */
512
/* University of Texas at Austin */
514
/* calcc calculates the centroid of the simplex without the */
515
/* vertex with highest function value. */
519
/* ns - subspace dimension */
521
/* s - double precision work space of dimension .ge. */
522
/* ns*(ns+3) used to store simplex */
524
/* ih - index to vertex with highest function value */
526
/* inew - index to new point */
528
/* updatc - logical switch */
529
/* = .true. : update centroid */
530
/* = .false. : calculate centroid from scratch */
532
/* c - centroid of the simplex without vertex with */
533
/* highest function value */
537
/* c - new centroid */
539
/* local variables */
542
/* subroutines and functions */
546
/* ----------------------------------------------------------- */
548
/* Parameter adjustments */
551
s_offset = 1 + s_dim1 * 1;
560
for (i__ = 1; i__ <= i__1; ++i__) {
561
c__[i__] += (s[i__ + *inew * s_dim1] - s[i__ + *ih * s_dim1]) / *
566
dcopy_(ns, &c_b3, &c__0, &c__[1], &c__1);
568
for (j = 1; j <= i__1; ++j) {
570
daxpy_(ns, &c_b7, &s[j * s_dim1 + 1], &c__1, &c__[1], &c__1);
575
dscal_(ns, &d__1, &c__[1], &c__1);
580
/* order.f -- translated by f2c (version 19991025).
581
You must link the resulting object file with the libraries:
582
-lf2c -lm (in that order)
585
static int order_(integer *npts, doublereal *fs, integer *il,
586
integer *is, integer *ih)
588
/* System generated locals */
591
/* Local variables */
596
/* Coded by Tom Rowan */
597
/* Department of Computer Sciences */
598
/* University of Texas at Austin */
600
/* order determines the indices of the vertices with the */
601
/* lowest, second highest, and highest function values. */
605
/* npts - number of points in simplex */
607
/* fs - double precision vector of function values of */
610
/* il - index to vertex with lowest function value */
614
/* il - new index to vertex with lowest function value */
616
/* is - new index to vertex with second highest */
619
/* ih - new index to vertex with highest function value */
621
/* local variables */
624
/* subroutines and functions */
628
/* ----------------------------------------------------------- */
630
/* Parameter adjustments */
636
if (fs[j] >= fs[*il]) {
644
i__1 = il0 + *npts - 2;
645
for (i__ = il0 + 1; i__ <= i__1; ++i__) {
647
if (fs[j] >= fs[*ih]) {
650
} else if (fs[j] > fs[*is]) {
652
} else if (fs[j] < fs[*il]) {
660
/* partx.f -- translated by f2c (version 19991025).
661
You must link the resulting object file with the libraries:
662
-lf2c -lm (in that order)
665
/* Common Block Declarations */
668
doublereal alpha, beta, gamma, delta, psi, omega;
669
integer nsmin, nsmax, irepl, ifxsw;
670
doublereal bonus, fstop;
671
integer nfstop, nfxe;
672
doublereal fxstat[4], ftest;
673
logical minf, initx, newx;
676
#define usubc_1 usubc_
678
static int partx_(integer *n, integer *ip, doublereal *absdx,
679
integer *nsubs, integer *nsvals)
681
/* System generated locals */
684
/* Local variables */
685
static integer i__, nleft, nused;
686
static doublereal as1max, gapmax, asleft, as1, as2;
687
static integer ns1, ns2;
688
static doublereal gap;
692
/* Coded by Tom Rowan */
693
/* Department of Computer Sciences */
694
/* University of Texas at Austin */
696
/* partx partitions the vector x by grouping components of */
697
/* similar magnitude of change. */
701
/* n - number of components (problem dimension) */
703
/* ip - permutation vector */
705
/* absdx - vector of magnitude of change in x */
707
/* nsvals - integer array dimensioned .ge. int(n/nsmin) */
711
/* nsubs - number of subspaces */
713
/* nsvals - integer array of subspace dimensions */
719
/* local variables */
723
/* subroutines and functions */
727
/* ----------------------------------------------------------- */
729
/* Parameter adjustments */
740
for (i__ = 2; i__ <= i__1; ++i__) {
741
asleft += absdx[i__];
748
i__1 = usubc_1.nsmin - 1;
749
for (i__ = 1; i__ <= i__1; ++i__) {
750
as1 += absdx[ip[nused + i__]];
754
i__1 = min(usubc_1.nsmax,nleft);
755
for (ns1 = usubc_1.nsmin; ns1 <= i__1; ++ns1) {
756
as1 += absdx[ip[nused + ns1]];
759
if (ns2 >= ((ns2 - 1) / usubc_1.nsmax + 1) * usubc_1.nsmin) {
761
gap = as1 / ns1 - as2 / ns2;
764
nsvals[*nsubs] = ns1;
769
if (as1 / ns1 > gapmax) {
770
nsvals[*nsubs] = ns1;
776
nused += nsvals[*nsubs];
784
/* sortd.f -- translated by f2c (version 19991025).
785
You must link the resulting object file with the libraries:
786
-lf2c -lm (in that order)
789
static int sortd_(integer *n, doublereal *xkey, integer *ix)
791
/* System generated locals */
794
/* Local variables */
795
integer ixip1, i__, ilast, iswap, ifirst, ixi;
799
/* Coded by Tom Rowan */
800
/* Department of Computer Sciences */
801
/* University of Texas at Austin */
803
/* sortd uses the shakersort method to sort an array of keys */
804
/* in decreasing order. The sort is performed implicitly by */
805
/* modifying a vector of indices. */
807
/* For nearly sorted arrays, sortd requires O(n) comparisons. */
808
/* for completely unsorted arrays, sortd requires O(n**2) */
809
/* comparisons and will be inefficient unless n is small. */
813
/* n - number of components */
815
/* xkey - double precision vector of keys */
817
/* ix - integer vector of indices */
821
/* ix - indices satisfy xkey(ix(i)) .ge. xkey(ix(i+1)) */
822
/* for i = 1,...,n-1 */
824
/* local variables */
827
/* ----------------------------------------------------------- */
829
/* Parameter adjustments */
838
if (ifirst <= ilast) {
840
for (i__ = ifirst; i__ <= i__1; ++i__) {
843
if (xkey[ixi] < xkey[ixip1]) {
852
for (i__ = ilast; i__ >= i__1; --i__) {
855
if (xkey[ixi] < xkey[ixip1]) {
868
/* newpt.f -- translated by f2c (version 19991025).
869
You must link the resulting object file with the libraries:
870
-lf2c -lm (in that order)
873
static int newpt_(integer *ns, doublereal *coef, doublereal *xbase,
874
doublereal *xold, logical *new__, doublereal *xnew, logical *small)
876
/* System generated locals */
879
/* Local variables */
887
/* Coded by Tom Rowan */
888
/* Department of Computer Sciences */
889
/* University of Texas at Austin */
891
/* newpt performs reflections, expansions, contractions, and */
892
/* shrinkages (massive contractions) by computing: */
894
/* xbase + coef * (xbase - xold) */
896
/* The result is stored in xnew if new .eq. .true., */
897
/* in xold otherwise. */
899
/* use : coef .gt. 0 to reflect */
900
/* coef .lt. 0 to expand, contract, or shrink */
904
/* ns - number of components (subspace dimension) */
906
/* coef - one of four simplex method coefficients */
908
/* xbase - double precision ns-vector representing base */
911
/* xold - double precision ns-vector representing old */
914
/* new - logical switch */
915
/* = .true. : store result in xnew */
916
/* = .false. : store result in xold, xnew is not */
921
/* xold - unchanged if new .eq. .true., contains new */
922
/* point otherwise */
924
/* xnew - double precision ns-vector representing new */
925
/* point if new .eq. .true., not referenced */
928
/* small - logical flag */
929
/* = .true. : coincident points */
930
/* = .false. : otherwise */
932
/* local variables */
935
/* subroutines and functions */
939
/* ----------------------------------------------------------- */
941
/* Parameter adjustments */
951
for (i__ = 1; i__ <= i__1; ++i__) {
952
xnew[i__] = xbase[i__] + *coef * (xbase[i__] - xold[i__]);
953
eqbase = eqbase && xnew[i__] == xbase[i__];
954
eqold = eqold && xnew[i__] == xold[i__];
959
for (i__ = 1; i__ <= i__1; ++i__) {
961
xold[i__] = xbase[i__] + *coef * (xbase[i__] - xold[i__]);
962
eqbase = eqbase && xold[i__] == xbase[i__];
963
eqold = eqold && xold[i__] == xoldi;
967
*small = eqbase || eqold;
971
/* start.f -- translated by f2c (version 19991025).
972
You must link the resulting object file with the libraries:
973
-lf2c -lm (in that order)
976
static int start_(integer *n, doublereal *x, doublereal *step,
977
integer *ns, integer *ips, doublereal *s, logical *small)
979
/* System generated locals */
980
integer s_dim1, s_offset, i__1;
982
/* Local variables */
986
/* Coded by Tom Rowan */
987
/* Department of Computer Sciences */
988
/* University of Texas at Austin */
990
/* start creates the initial simplex for simplx minimization. */
994
/* n - problem dimension */
996
/* x - current best point */
998
/* step - stepsizes for corresponding components of x */
1000
/* ns - subspace dimension */
1002
/* ips - permutation vector */
1007
/* s - first ns+1 columns contain initial simplex */
1009
/* small - logical flag */
1010
/* = .true. : coincident points */
1011
/* = .false. : otherwise */
1013
/* local variables */
1016
/* subroutines and functions */
1021
/* ----------------------------------------------------------- */
1023
/* Parameter adjustments */
1028
s_offset = 1 + s_dim1 * 1;
1033
for (i__ = 1; i__ <= i__1; ++i__) {
1034
s[i__ + s_dim1] = x[ips[i__]];
1038
for (j = 2; j <= i__1; ++j) {
1039
dcopy_(ns, &s[s_dim1 + 1], &c__1, &s[j * s_dim1 + 1], &c__1);
1040
s[j - 1 + j * s_dim1] = s[j - 1 + s_dim1] + step[ips[j - 1]];
1044
/* check for coincident points */
1047
for (j = 2; j <= i__1; ++j) {
1048
if (s[j - 1 + j * s_dim1] == s[j - 1 + s_dim1]) {
1056
/* coincident points */
1063
/* fstats.f -- translated by f2c (version 19991025).
1064
You must link the resulting object file with the libraries:
1065
-lf2c -lm (in that order)
1068
static int fstats_(doublereal *fx, integer *ifxwt, logical *reset)
1070
/* System generated locals */
1071
doublereal d__1, d__2, d__3;
1073
/* Builtin functions */
1074
double sqrt(doublereal);
1076
/* Local variables */
1077
static doublereal fscale;
1079
static doublereal f1sv;
1083
/* Coded by Tom Rowan */
1084
/* Department of Computer Sciences */
1085
/* University of Texas at Austin */
1087
/* fstats modifies the common /usubc/ variables nfxe,fxstat. */
1091
/* fx - most recent evaluation of f at best x */
1093
/* ifxwt - integer weight for fx */
1095
/* reset - logical switch */
1096
/* = .true. : initialize nfxe,fxstat */
1097
/* = .false. : update nfxe,fxstat */
1103
/* local variables */
1107
/* subroutines and functions */
1111
/* ----------------------------------------------------------- */
1114
usubc_1.nfxe = *ifxwt;
1115
usubc_1.fxstat[0] = *fx;
1116
usubc_1.fxstat[1] = *fx;
1117
usubc_1.fxstat[2] = *fx;
1118
usubc_1.fxstat[3] = 0.;
1121
f1sv = usubc_1.fxstat[0];
1122
usubc_1.nfxe += *ifxwt;
1123
usubc_1.fxstat[0] += *ifxwt * (*fx - usubc_1.fxstat[0]) /
1125
usubc_1.fxstat[1] = max(usubc_1.fxstat[1],*fx);
1126
usubc_1.fxstat[2] = min(usubc_1.fxstat[2],*fx);
1128
d__1 = abs(usubc_1.fxstat[1]), d__2 = abs(usubc_1.fxstat[2]), d__1 =
1130
fscale = max(d__1,1.);
1131
/* Computing 2nd power */
1132
d__1 = usubc_1.fxstat[3] / fscale;
1133
/* Computing 2nd power */
1134
d__2 = (usubc_1.fxstat[0] - f1sv) / fscale;
1135
/* Computing 2nd power */
1136
d__3 = (*fx - usubc_1.fxstat[0]) / fscale;
1137
usubc_1.fxstat[3] = fscale * sqrt(((nsv - 1) * (d__1 * d__1) + nsv * (
1138
d__2 * d__2) + *ifxwt * (d__3 * d__3)) / (usubc_1.nfxe - 1));
1143
/* evalf.f -- translated by f2c (version 19991025).
1144
You must link the resulting object file with the libraries:
1145
-lf2c -lm (in that order)
1148
/* Common Block Declarations */
1151
doublereal fbonus, sfstop, sfbest;
1155
#define isubc_1 isubc_
1157
static logical c_true = TRUE_;
1158
static logical c_false = FALSE_;
1160
static int evalf_(D_fp f,void*fdata, integer *ns, integer *ips, doublereal *xs,
1161
integer *n, doublereal *x, doublereal *sfx, integer *nfe)
1163
/* System generated locals */
1166
/* Local variables */
1168
static doublereal fx;
1169
static logical newbst;
1171
/* Coded by Tom Rowan */
1172
/* Department of Computer Sciences */
1173
/* University of Texas at Austin */
1175
/* evalf evaluates the function f at a point defined by x */
1176
/* with ns of its components replaced by those in xs. */
1180
/* f - user supplied function f(n,x) to be optimized */
1182
/* ns - subspace dimension */
1184
/* ips - permutation vector */
1186
/* xs - double precision ns-vector to be mapped to x */
1188
/* n - problem dimension */
1190
/* x - double precision n-vector */
1192
/* nfe - number of function evaluations */
1196
/* sfx - signed value of f evaluated at x */
1198
/* nfe - incremented number of function evaluations */
1206
/* local variables */
1210
/* subroutines and functions */
1213
/* ----------------------------------------------------------- */
1215
/* Parameter adjustments */
1222
for (i__ = 1; i__ <= i__1; ++i__) {
1223
x[ips[i__]] = xs[i__];
1226
usubc_1.newx = isubc_1.new__ || usubc_1.irepl != 2;
1227
fx = (*f)(*n, &x[1], fdata);
1228
if (usubc_1.irepl == 0) {
1234
} else if (isubc_1.new__) {
1237
newbst = fx < usubc_1.ftest;
1240
newbst = fx > usubc_1.ftest;
1242
if (usubc_1.initx || newbst) {
1243
if (usubc_1.irepl == 1) {
1244
fstats_(&fx, &c__1, &c_true);
1247
isubc_1.sfbest = *sfx;
1250
if (usubc_1.irepl == 1) {
1251
fstats_(&fx, &c__1, &c_false);
1252
fx = usubc_1.fxstat[usubc_1.ifxsw - 1];
1254
usubc_1.ftest = fx + isubc_1.fbonus * usubc_1.fxstat[3];
1256
*sfx = usubc_1.ftest;
1257
isubc_1.sfbest = fx;
1259
*sfx = -usubc_1.ftest;
1260
isubc_1.sfbest = -fx;
1267
/* simplx.f -- translated by f2c (version 19991025).
1268
You must link the resulting object file with the libraries:
1269
-lf2c -lm (in that order)
1272
static int simplx_(D_fp f, void *fdata, integer *n, doublereal *step, integer *
1273
ns, integer *ips, integer *maxnfe, logical *cmode, doublereal *x,
1274
doublereal *fx, integer *nfe, doublereal *s, doublereal *fs, integer *
1277
/* System generated locals */
1278
integer s_dim1, s_offset, i__1;
1279
doublereal d__1, d__2;
1281
/* Local variables */
1282
static integer inew;
1283
static integer npts;
1284
static integer i__, j;
1285
static integer icent;
1286
static logical small;
1287
static integer itemp;
1288
static doublereal fc, fe;
1289
static integer ih, il;
1290
static doublereal fr;
1292
static logical updatc;
1293
static doublereal dum, tol;
1297
/* Coded by Tom Rowan */
1298
/* Department of Computer Sciences */
1299
/* University of Texas at Austin */
1301
/* simplx uses the Nelder-Mead simplex method to minimize the */
1302
/* function f on a subspace. */
1306
/* f - function to be minimized, declared external in */
1307
/* calling routine */
1309
/* n - problem dimension */
1311
/* step - stepsizes for corresponding components of x */
1313
/* ns - subspace dimension */
1315
/* ips - permutation vector */
1317
/* maxnfe - maximum number of function evaluations */
1319
/* cmode - logical switch */
1320
/* = .true. : continuation of previous call */
1321
/* = .false. : first call */
1323
/* x - starting guess for minimum */
1325
/* fx - value of f at x */
1327
/* nfe - number of function evaluations */
1329
/* s - double precision work array of dimension .ge. */
1330
/* ns*(ns+3) used to store simplex */
1332
/* fs - double precision work array of dimension .ge. */
1333
/* ns+1 used to store function values of simplex */
1338
/* x - computed minimum */
1340
/* fx - value of f at x */
1342
/* nfe - incremented number of function evaluations */
1344
/* iflag - error flag */
1345
/* = -1 : maxnfe exceeded */
1346
/* = 0 : simplex reduced by factor of psi */
1347
/* = 1 : limit of machine precision */
1348
/* = 2 : reached fstop */
1356
/* local variables */
1360
/* subroutines and functions */
1365
/* ----------------------------------------------------------- */
1367
/* Parameter adjustments */
1372
s_offset = 1 + s_dim1 * 1;
1384
start_(n, &x[1], &step[1], ns, &ips[1], &s[s_offset], &small);
1389
if (usubc_1.irepl > 0) {
1390
isubc_1.new__ = FALSE_;
1391
evalf_((D_fp)f,fdata, ns, &ips[1], &s[s_dim1 + 1], n, &x[1], &fs[1], nfe);
1395
isubc_1.new__ = TRUE_;
1397
for (j = 2; j <= i__1; ++j) {
1398
evalf_((D_fp)f, fdata,ns, &ips[1], &s[j * s_dim1 + 1], n, &x[1], &fs[j],
1403
order_(&npts, &fs[1], &il, &is, &ih);
1404
tol = usubc_1.psi * dist_(ns, &s[ih * s_dim1 + 1], &s[il * s_dim1 + 1]);
1409
calcc_(ns, &s[s_offset], &ih, &inew, &updatc, &s[icent * s_dim1 + 1]);
1415
newpt_(ns, &usubc_1.alpha, &s[icent * s_dim1 + 1], &s[ih * s_dim1 + 1], &
1416
c_true, &s[itemp * s_dim1 + 1], &small);
1420
evalf_((D_fp)f,fdata, ns, &ips[1], &s[itemp * s_dim1 + 1], n, &x[1], &fr, nfe);
1425
d__1 = -usubc_1.gamma;
1426
newpt_(ns, &d__1, &s[icent * s_dim1 + 1], &s[itemp * s_dim1 + 1], &
1427
c_true, &s[ih * s_dim1 + 1], &small);
1431
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,
1464
d__1 = fr, d__2 = fs[ih];
1465
if (fc < min(d__1,d__2)) {
1466
dcopy_(ns, &s[itemp * s_dim1 + 1], &c__1, &s[ih * s_dim1 + 1], &
1471
/* shrink simplex */
1474
for (j = 1; j <= i__1; ++j) {
1476
d__1 = -usubc_1.delta;
1477
newpt_(ns, &d__1, &s[il * s_dim1 + 1], &s[j * s_dim1 + 1],
1478
&c_false, &dum, &small);
1482
evalf_((D_fp)f,fdata, ns, &ips[1], &s[j * s_dim1 + 1], n, &x[1],
1490
order_(&npts, &fs[1], &il, &is, &ih);
1492
/* check termination */
1495
if (usubc_1.irepl == 0) {
1498
*fx = isubc_1.sfbest;
1501
if (usubc_1.nfstop > 0 && *fx <= isubc_1.sfstop && usubc_1.nfxe >=
1504
} else if (*nfe >= *maxnfe) {
1506
} else if (dist_(ns, &s[ih * s_dim1 + 1], &s[il * s_dim1 + 1]) <= tol ||
1513
/* end main loop, return best point */
1516
for (i__ = 1; i__ <= i__1; ++i__) {
1517
x[ips[i__]] = s[i__ + il * s_dim1];
1523
/* subopt.f -- translated by f2c (version 19991025).
1524
You must link the resulting object file with the libraries:
1525
-lf2c -lm (in that order)
1528
static int subopt_(integer *n)
1532
/* Coded by Tom Rowan */
1533
/* Department of Computer Sciences */
1534
/* University of Texas at Austin */
1536
/* subopt sets options for subplx. */
1540
/* n - problem dimension */
1547
/* subroutines and functions */
1551
/* ----------------------------------------------------------- */
1553
/* *********************************************************** */
1554
/* simplex method strategy parameters */
1555
/* *********************************************************** */
1557
/* alpha - reflection coefficient */
1562
/* beta - contraction coefficient */
1563
/* 0 .lt. beta .lt. 1 */
1567
/* gamma - expansion coefficient */
1572
/* delta - shrinkage (massive contraction) coefficient */
1573
/* 0 .lt. delta .lt. 1 */
1577
/* *********************************************************** */
1578
/* subplex method strategy parameters */
1579
/* *********************************************************** */
1581
/* psi - simplex reduction coefficient */
1582
/* 0 .lt. psi .lt. 1 */
1586
/* omega - step reduction coefficient */
1587
/* 0 .lt. omega .lt. 1 */
1591
/* nsmin and nsmax specify a range of subspace dimensions. */
1592
/* In addition to satisfying 1 .le. nsmin .le. nsmax .le. n, */
1593
/* nsmin and nsmax must be chosen so that n can be expressed */
1594
/* as a sum of positive integers where each of these integers */
1595
/* ns(i) satisfies nsmin .le. ns(i) .ge. nsmax. */
1597
/* nsmin*ceil(n/nsmax) .le. n must be true. */
1599
/* nsmin - subspace dimension minimum */
1601
usubc_1.nsmin = min(2,*n);
1603
/* nsmax - subspace dimension maximum */
1605
usubc_1.nsmax = min(5,*n);
1607
/* *********************************************************** */
1608
/* subplex method special cases */
1609
/* *********************************************************** */
1610
/* nelder-mead simplex method with periodic restarts */
1611
/* nsmin = nsmax = n */
1612
/* *********************************************************** */
1613
/* nelder-mead simplex method */
1614
/* nsmin = nsmax = n, psi = small positive */
1615
/* *********************************************************** */
1617
/* irepl, ifxsw, and bonus deal with measurement replication. */
1618
/* Objective functions subject to large amounts of noise can */
1619
/* cause an optimization method to halt at a false optimum. */
1620
/* An expensive solution to this problem is to evaluate f */
1621
/* several times at each point and return the average (or max */
1622
/* or min) of these trials as the function value. subplx */
1623
/* performs measurement replication only at the current best */
1624
/* point. The longer a point is retained as best, the more */
1625
/* accurate its function value becomes. */
1627
/* The common variable nfxe contains the number of function */
1628
/* evaluations at the current best point. fxstat contains the */
1629
/* mean, max, min, and standard deviation of these trials. */
1631
/* irepl - measurement replication switch */
1632
/* irepl = 0, 1, or 2 */
1633
/* = 0 : no measurement replication */
1634
/* = 1 : subplx performs measurement replication */
1635
/* = 2 : user performs measurement replication */
1636
/* (This is useful when optimizing on the mean, */
1637
/* max, or min of trials is insufficient. Common */
1638
/* variable initx is true for first function */
1639
/* evaluation. newx is true for first trial at */
1640
/* this point. The user uses subroutine fstats */
1641
/* within his objective function to maintain */
1642
/* fxstat. By monitoring newx, the user can tell */
1643
/* whether to return the function evaluation */
1644
/* (newx = .true.) or to use the new function */
1645
/* evaluation to refine the function evaluation */
1646
/* of the current best point (newx = .false.). */
1647
/* The common variable ftest gives the function */
1648
/* value that a new point must beat to be */
1649
/* considered the new best point.) */
1653
/* ifxsw - measurement replication optimization switch */
1654
/* ifxsw = 1, 2, or 3 */
1655
/* = 1 : retain mean of trials as best function value */
1656
/* = 2 : retain max */
1657
/* = 3 : retain min */
1661
/* Since the current best point will also be the most */
1662
/* accurately evaluated point whenever irepl .gt. 0, a bonus */
1663
/* should be added to the function value of the best point */
1664
/* so that the best point is not replaced by a new point */
1665
/* that only appears better because of noise. */
1666
/* subplx uses bonus to determine how many multiples of */
1667
/* fxstat(4) should be added as a bonus to the function */
1668
/* evaluation. (The bonus is adjusted automatically by */
1669
/* subplx when ifxsw or minf is changed.) */
1671
/* bonus - measurement replication bonus coefficient */
1672
/* bonus .ge. 0 (normally, bonus = 0 or 1) */
1673
/* = 0 : bonus not used */
1674
/* = 1 : bonus used */
1678
/* nfstop = 0 : f(x) is not tested against fstop */
1679
/* = 1 : if f(x) has reached fstop, subplx returns */
1681
/* = 2 : (only valid when irepl .gt. 0) */
1682
/* if f(x) has reached fstop and */
1683
/* nfxe .gt. nfstop, subplx returns iflag = 2 */
1687
/* fstop - f target value */
1688
/* Its usage is determined by the value of nfstop. */
1690
/* minf - logical switch */
1691
/* = .true. : subplx performs minimization */
1692
/* = .false. : subplx performs maximization */
1694
usubc_1.minf = TRUE_;
1698
/* setstp.f -- translated by f2c (version 19991025).
1699
You must link the resulting object file with the libraries:
1700
-lf2c -lm (in that order)
1703
static double d_sign(doublereal *x, doublereal *y)
1705
return copysign(*x, *y);
1708
static int setstp_(integer *nsubs, integer *n, doublereal *deltax,
1711
/* System generated locals */
1713
doublereal d__1, d__2, d__3;
1715
/* Builtin functions */
1716
/* double d_sign(doublereal *, doublereal *); */
1718
/* Local variables */
1720
static doublereal stpfac;
1724
/* Coded by Tom Rowan */
1725
/* Department of Computer Sciences */
1726
/* University of Texas at Austin */
1728
/* setstp sets the stepsizes for the corresponding components */
1729
/* of the solution vector. */
1733
/* nsubs - number of subspaces */
1735
/* n - number of components (problem dimension) */
1737
/* deltax - vector of change in solution vector */
1739
/* step - stepsizes for corresponding components of */
1740
/* solution vector */
1744
/* step - new stepsizes */
1750
/* local variables */
1754
/* subroutines and functions */
1759
/* ----------------------------------------------------------- */
1763
/* Parameter adjustments */
1771
d__3 = dasum_(n, &deltax[1], &c__1) / dasum_(n, &step[1], &c__1);
1772
d__1 = max(d__3,usubc_1.omega), d__2 = 1. / usubc_1.omega;
1773
stpfac = min(d__1,d__2);
1775
stpfac = usubc_1.psi;
1777
dscal_(n, &stpfac, &step[1], &c__1);
1779
/* reorient simplex */
1782
for (i__ = 1; i__ <= i__1; ++i__) {
1783
if (deltax[i__] != 0.) {
1784
step[i__] = d_sign(&step[i__], &deltax[i__]);
1786
step[i__] = -step[i__];
1793
/* subplx.f -- translated by f2c (version 19991025).
1794
You must link the resulting object file with the libraries:
1795
-lf2c -lm (in that order)
1798
static int subplx_(D_fp f, void *fdata, integer *n, doublereal *tol, integer *
1799
maxnfe, integer *mode, doublereal *scale, doublereal *x, doublereal *
1800
fx, integer *nfe, doublereal *work, integer *iwork, integer *iflag)
1802
/* Initialized data */
1804
static doublereal bnsfac[6] /* was [3][2] */ = { -1.,-2.,0.,1.,0.,2. };
1806
/* System generated locals */
1808
doublereal d__1, d__2, d__3, d__4, d__5, d__6;
1810
/* Local variables */
1812
static logical cmode;
1813
static integer istep;
1814
static doublereal xpscl;
1815
static integer nsubs, ipptr;
1816
static integer isptr;
1817
static integer ns, insfnl, ifsptr;
1818
static integer insptr;
1819
static integer istptr;
1820
static doublereal scl, dum;
1822
static doublereal sfx;
1826
/* Coded by Tom Rowan */
1827
/* Department of Computer Sciences */
1828
/* University of Texas at Austin */
1830
/* subplx uses the subplex method to solve unconstrained */
1831
/* optimization problems. The method is well suited for */
1832
/* optimizing objective functions that are noisy or are */
1833
/* discontinuous at the solution. */
1835
/* subplx sets default optimization options by calling the */
1836
/* subroutine subopt. The user can override these defaults */
1837
/* by calling subopt prior to calling subplx, changing the */
1838
/* appropriate common variables, and setting the value of */
1839
/* mode as indicated below. */
1841
/* By default, subplx performs minimization. */
1845
/* f - user supplied function f(n,x) to be optimized, */
1846
/* declared external in calling routine */
1848
/* n - problem dimension */
1850
/* tol - relative error tolerance for x (tol .ge. 0.) */
1852
/* maxnfe - maximum number of function evaluations */
1854
/* mode - integer mode switch with binary expansion */
1855
/* (bit 1) (bit 0) : */
1856
/* bit 0 = 0 : first call to subplx */
1857
/* = 1 : continuation of previous call */
1858
/* bit 1 = 0 : use default options */
1859
/* = 1 : user set options */
1861
/* scale - scale and initial stepsizes for corresponding */
1862
/* components of x */
1863
/* (If scale(1) .lt. 0., */
1864
/* abs(scale(1)) is used for all components of x, */
1865
/* and scale(2),...,scale(n) are not referenced.) */
1867
/* x - starting guess for optimum */
1869
/* work - double precision work array of dimension .ge. */
1870
/* 2*n + nsmax*(nsmax+4) + 1 */
1871
/* (nsmax is set in subroutine subopt. */
1872
/* default: nsmax = min(5,n)) */
1874
/* iwork - integer work array of dimension .ge. */
1875
/* n + int(n/nsmin) */
1876
/* (nsmin is set in subroutine subopt. */
1877
/* default: nsmin = min(2,n)) */
1881
/* x - computed optimum */
1883
/* fx - value of f at x */
1885
/* nfe - number of function evaluations */
1887
/* iflag - error flag */
1888
/* = -2 : invalid input */
1889
/* = -1 : maxnfe exceeded */
1890
/* = 0 : tol satisfied */
1891
/* = 1 : limit of machine precision */
1892
/* = 2 : fstop reached (fstop usage is determined */
1893
/* by values of options minf, nfstop, and */
1894
/* irepl. default: f(x) not tested against */
1896
/* iflag should not be reset between calls to */
1905
/* local variables */
1909
/* subroutines and functions */
1916
/* Parameter adjustments */
1923
/* ----------------------------------------------------------- */
1925
if (*mode % 2 == 0) {
1927
/* 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);
2039
usubc_1.initx = FALSE_;
2042
/* continuation of previous call */
2046
isubc_1.sfstop = usubc_1.fstop;
2048
isubc_1.sfstop = -usubc_1.fstop;
2052
} else if (*iflag == -1) {
2055
} else if (*iflag == 0) {
2067
for (i__ = 1; i__ <= i__1; ++i__) {
2068
work[i__] = (d__1 = work[i__], abs(d__1));
2071
sortd_(n, &work[1], &iwork[1]);
2072
partx_(n, &iwork[1], &work[1], &nsubs, &iwork[insptr]);
2073
dcopy_(n, &x[1], &c__1, &work[1], &c__1);
2075
insfnl = insptr + nsubs - 1;
2083
simplx_((D_fp)f, fdata, n, &work[istptr], &ns, &iwork[ipptr], maxnfe, &cmode, &x[
2084
1], &sfx, nfe, &work[isptr], &work[ifsptr], iflag);
2095
/* end simplex loop */
2098
for (i__ = 1; i__ <= i__1; ++i__) {
2099
work[i__] = x[i__] - work[i__];
2103
/* check termination */
2108
for (i__ = 1; i__ <= i__1; ++i__) {
2110
d__4 = (d__2 = work[i__], abs(d__2)), d__5 = (d__1 = work[istep], abs(
2111
d__1)) * usubc_1.psi;
2113
d__6 = (d__3 = x[i__], abs(d__3));
2114
if (max(d__4,d__5) / max(d__6,1.) > *tol) {
2115
setstp_(&nsubs, n, &work[1], &work[istptr]);
2122
/* end subplex loop */
2140
/****************************************************************************/
2141
/****************************************************************************/
2143
/* front-end for subplex routines */
2145
/* Wrapper around f2c'ed subplx_ routine, for multidimensinal
2146
unconstrained optimization:
2150
f: function f(n,x,fdata) to be optimized
2151
n: problem dimension
2152
x[n]: (input) starting guess position, (output) computed minimum
2153
fdata: data pointer passed to f
2154
tol: relative error tolerance for x
2155
maxnfe: maximum number of function evaluations
2156
scale[n]: (input) scale & initial stepsizes for components of x
2157
(if *scale < 0, |*scale| is used for all components)
2158
nfe: (output) number of function evaluations
2160
= -2 : invalid input
2161
= -1 : maxnfe exceeded
2163
= 1 : limit of machine precision
2164
= 2 : fstop reached (fstop usage is determined by values of
2165
options minf, nfstop, and irepl. default: f(x) not
2166
tested against fstop)
2168
Return value: value of f at minimum.
2170
number subplex(subplex_func f, number *x, integer n, void *fdata,
2171
number tol, integer maxnfe,
2172
number fmin, boolean use_fmin,
2174
integer *nfe, integer *errflag)
2176
integer mode = 0, *iwork, nsmax, nsmin;
2181
work = (number*) malloc(sizeof(number) * (2*n + nsmax*(nsmax+4) + 1));
2182
iwork = (integer*) malloc(sizeof(integer) * (n + n/nsmin + 1));
2183
if (!work || !iwork) {
2184
fprintf(stderr, "subplex: error, out of memory!\n");
2188
if (use_fmin) { /* stop when fmin is reached */
2191
usubc_1.fstop = fmin;
2195
subplx_(f,fdata, &n,
2196
&tol, &maxnfe, &mode,
2199
work, iwork, errflag);
2207
number f_scm_wrapper(integer n, number *x, void *f_scm_p)
2209
SCM *f_scm = (SCM *) f_scm_p;
2210
return gh_scm2double(gh_call1(*f_scm, make_number_list(n, x)));
2213
/* Scheme-callable wrapper for subplex() function, above. */
2214
SCM subplex_scm(SCM f_scm, SCM x_scm,
2215
SCM tol_scm, SCM maxnfe_scm,
2216
SCM fmin_scm, SCM use_fmin_scm,
2219
number *x, tol, *scale, fx, fmin;
2220
integer i, n, maxnfe, nfe, errflag, scale_len;
2224
n = list_length(x_scm);
2225
tol = fabs(gh_scm2double(tol_scm));
2226
maxnfe = gh_scm2int(maxnfe_scm);
2227
fmin = gh_scm2double(fmin_scm);
2228
use_fmin = gh_scm2bool(use_fmin_scm);
2230
scale_len = list_length(scale_scm);
2231
if (scale_len != 1 && scale_len != n) {
2232
fprintf(stderr, "subplex: invalid scale argument length %d\n",
2234
return SCM_UNDEFINED;
2237
x = (number*) malloc(sizeof(number) * n);
2238
scale = (number*) malloc(sizeof(number) * scale_len);
2240
fprintf(stderr, "subplex: error, out of memory!\n");
2244
for (i = 0; i < n; ++i)
2245
x[i] = number_list_ref(x_scm, i);
2246
for (i = 0; i < scale_len; ++i)
2247
scale[i] = fabs(number_list_ref(scale_scm, i));
2248
if (scale_len == 1 && scale_len != n)
2251
fx = subplex(f_scm_wrapper, x, n, &f_scm,
2259
fprintf(stderr, "subplex error: invalid inputs\n");
2260
return SCM_UNDEFINED;
2262
fprintf(stderr, "subplex warning: max # iterations exceeded\n");
2265
fprintf(stderr, "subplex warning: machine precision reached\n");
2268
fprintf(stderr, "subplex warning: fstop reached\n");
2272
retval = gh_cons(make_number_list(n, x), gh_double2scm(fx));