lbfgsb 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,287 @@
1
+ /**
2
+ * L-BFGS-B is released under the “New BSD License” (aka “Modified BSD License”
3
+ * or “3-clause license”)
4
+ * Please read attached file License.txt
5
+ */
6
+ #include "blas.h"
7
+
8
+ double dnrm2_(long *n, double *x, long *incx)
9
+ {
10
+ long i__1, i__2;
11
+ double ret_val, d__1, d__2, d__3;
12
+ static long i__;
13
+ static double scale;
14
+
15
+ --x;
16
+
17
+ ret_val = 0.;
18
+ scale = 0.;
19
+ i__1 = *n;
20
+ i__2 = *incx;
21
+ for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
22
+ d__2 = scale, d__3 = (d__1 = x[i__], fabs(d__1));
23
+ scale = d__2 >= d__3 ? d__2 : d__3;
24
+ }
25
+ if (scale == 0.) {
26
+ return ret_val;
27
+ }
28
+ i__2 = *n;
29
+ i__1 = *incx;
30
+ for (i__ = 1; i__1 < 0 ? i__ >= i__2 : i__ <= i__2; i__ += i__1) {
31
+ d__1 = x[i__] / scale;
32
+ ret_val += d__1 * d__1;
33
+ }
34
+ ret_val = scale * sqrt(ret_val);
35
+ return ret_val;
36
+ }
37
+
38
+ int daxpy_(long *n, double *da, double *dx, long *incx, double *dy, long *incy)
39
+ {
40
+ long i__1;
41
+ static long i__, m, ix, iy, mp1;
42
+
43
+ --dy;
44
+ --dx;
45
+
46
+ /* constant times a vector plus a vector. */
47
+ /* uses unrolled loops for increments equal to one. */
48
+ /* jack dongarra, linpack, 3/11/78. */
49
+ if (*n <= 0) {
50
+ return 0;
51
+ }
52
+ if (*da == 0.) {
53
+ return 0;
54
+ }
55
+ if (*incx == 1 && *incy == 1) {
56
+ goto L20;
57
+ }
58
+
59
+ /* code for unequal increments or equal increments */
60
+ /* not equal to 1 */
61
+ ix = 1;
62
+ iy = 1;
63
+ if (*incx < 0) {
64
+ ix = (-(*n) + 1) * *incx + 1;
65
+ }
66
+ if (*incy < 0) {
67
+ iy = (-(*n) + 1) * *incy + 1;
68
+ }
69
+ i__1 = *n;
70
+ for (i__ = 1; i__ <= i__1; ++i__) {
71
+ dy[iy] += *da * dx[ix];
72
+ ix += *incx;
73
+ iy += *incy;
74
+ }
75
+ return 0;
76
+
77
+ /* code for both increments equal to 1 */
78
+ /* clean-up loop */
79
+ L20:
80
+ m = *n % 4;
81
+ if (m == 0) {
82
+ goto L40;
83
+ }
84
+ i__1 = m;
85
+ for (i__ = 1; i__ <= i__1; ++i__) {
86
+ dy[i__] += *da * dx[i__];
87
+ }
88
+ if (*n < 4) {
89
+ return 0;
90
+ }
91
+ L40:
92
+ mp1 = m + 1;
93
+ i__1 = *n;
94
+ for (i__ = mp1; i__ <= i__1; i__ += 4) {
95
+ dy[i__] += *da * dx[i__];
96
+ dy[i__ + 1] += *da * dx[i__ + 1];
97
+ dy[i__ + 2] += *da * dx[i__ + 2];
98
+ dy[i__ + 3] += *da * dx[i__ + 3];
99
+ }
100
+ return 0;
101
+ }
102
+
103
+ int dcopy_(long *n, double *dx, long *incx, double *dy, long *incy)
104
+ {
105
+ long i__1;
106
+ static long i__, m, ix, iy, mp1;
107
+
108
+ --dy;
109
+ --dx;
110
+
111
+ /* copies a vector, x, to a vector, y. */
112
+ /* uses unrolled loops for increments equal to one. */
113
+ /* jack dongarra, linpack, 3/11/78. */
114
+ if (*n <= 0) {
115
+ return 0;
116
+ }
117
+ if (*incx == 1 && *incy == 1) {
118
+ goto L20;
119
+ }
120
+
121
+ /* code for unequal increments or equal increments */
122
+ /* not equal to 1 */
123
+ ix = 1;
124
+ iy = 1;
125
+ if (*incx < 0) {
126
+ ix = (-(*n) + 1) * *incx + 1;
127
+ }
128
+ if (*incy < 0) {
129
+ iy = (-(*n) + 1) * *incy + 1;
130
+ }
131
+ i__1 = *n;
132
+ for (i__ = 1; i__ <= i__1; ++i__) {
133
+ dy[iy] = dx[ix];
134
+ ix += *incx;
135
+ iy += *incy;
136
+ }
137
+ return 0;
138
+
139
+ /* code for both increments equal to 1 */
140
+ /* clean-up loop */
141
+ L20:
142
+ m = *n % 7;
143
+ if (m == 0) {
144
+ goto L40;
145
+ }
146
+ i__1 = m;
147
+ for (i__ = 1; i__ <= i__1; ++i__) {
148
+ dy[i__] = dx[i__];
149
+ }
150
+ if (*n < 7) {
151
+ return 0;
152
+ }
153
+ L40:
154
+ mp1 = m + 1;
155
+ i__1 = *n;
156
+ for (i__ = mp1; i__ <= i__1; i__ += 7) {
157
+ dy[i__] = dx[i__];
158
+ dy[i__ + 1] = dx[i__ + 1];
159
+ dy[i__ + 2] = dx[i__ + 2];
160
+ dy[i__ + 3] = dx[i__ + 3];
161
+ dy[i__ + 4] = dx[i__ + 4];
162
+ dy[i__ + 5] = dx[i__ + 5];
163
+ dy[i__ + 6] = dx[i__ + 6];
164
+ }
165
+ return 0;
166
+ }
167
+
168
+ double ddot_(long *n, double *dx, long *incx, double *dy, long *incy)
169
+ {
170
+ long i__1;
171
+ double ret_val;
172
+ static long i__, m, ix, iy, mp1;
173
+ static double dtemp;
174
+
175
+ --dy;
176
+ --dx;
177
+
178
+ /* forms the dot product of two vectors. */
179
+ /* uses unrolled loops for increments equal to one. */
180
+ /* jack dongarra, linpack, 3/11/78. */
181
+ ret_val = 0.;
182
+ dtemp = 0.;
183
+ if (*n <= 0) {
184
+ return ret_val;
185
+ }
186
+ if (*incx == 1 && *incy == 1) {
187
+ goto L20;
188
+ }
189
+
190
+ /* code for unequal increments or equal increments */
191
+ /* not equal to 1 */
192
+ ix = 1;
193
+ iy = 1;
194
+ if (*incx < 0) {
195
+ ix = (-(*n) + 1) * *incx + 1;
196
+ }
197
+ if (*incy < 0) {
198
+ iy = (-(*n) + 1) * *incy + 1;
199
+ }
200
+ i__1 = *n;
201
+ for (i__ = 1; i__ <= i__1; ++i__) {
202
+ dtemp += dx[ix] * dy[iy];
203
+ ix += *incx;
204
+ iy += *incy;
205
+ }
206
+ ret_val = dtemp;
207
+ return ret_val;
208
+
209
+ /* code for both increments equal to 1 */
210
+ /* clean-up loop */
211
+ L20:
212
+ m = *n % 5;
213
+ if (m == 0) {
214
+ goto L40;
215
+ }
216
+ i__1 = m;
217
+ for (i__ = 1; i__ <= i__1; ++i__) {
218
+ dtemp += dx[i__] * dy[i__];
219
+ }
220
+ if (*n < 5) {
221
+ goto L60;
222
+ }
223
+ L40:
224
+ mp1 = m + 1;
225
+ i__1 = *n;
226
+ for (i__ = mp1; i__ <= i__1; i__ += 5) {
227
+ dtemp = dtemp + dx[i__] * dy[i__] + dx[i__ + 1] * dy[i__ + 1]
228
+ + dx[i__ + 2] * dy[i__ + 2] + dx[i__ + 3] * dy[i__ + 3] + dx[i__ + 4] * dy[i__ + 4];
229
+ }
230
+ L60:
231
+ ret_val = dtemp;
232
+ return ret_val;
233
+ }
234
+
235
+ int dscal_(long *n, double *da, double *dx, long *incx)
236
+ {
237
+ long i__1, i__2;
238
+ static long i__, m, mp1, nincx;
239
+
240
+ --dx;
241
+
242
+ /* scales a vector by a constant. */
243
+ /* uses unrolled loops for increment equal to one. */
244
+ /* jack dongarra, linpack, 3/11/78. */
245
+ /* modified 3/93 to return if incx .le. 0. */
246
+ if (*n <= 0 || *incx <= 0) {
247
+ return 0;
248
+ }
249
+ if (*incx == 1) {
250
+ goto L20;
251
+ }
252
+
253
+ /* code for increment not equal to 1 */
254
+ nincx = *n * *incx;
255
+ i__1 = nincx;
256
+ i__2 = *incx;
257
+ for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
258
+ dx[i__] = *da * dx[i__];
259
+ }
260
+ return 0;
261
+
262
+ /* code for increment equal to 1 */
263
+ /* clean-up loop */
264
+ L20:
265
+ m = *n % 5;
266
+ if (m == 0) {
267
+ goto L40;
268
+ }
269
+ i__2 = m;
270
+ for (i__ = 1; i__ <= i__2; ++i__) {
271
+ dx[i__] = *da * dx[i__];
272
+ }
273
+ if (*n < 5) {
274
+ return 0;
275
+ }
276
+ L40:
277
+ mp1 = m + 1;
278
+ i__2 = *n;
279
+ for (i__ = mp1; i__ <= i__2; i__ += 5) {
280
+ dx[i__] = *da * dx[i__];
281
+ dx[i__ + 1] = *da * dx[i__ + 1];
282
+ dx[i__ + 2] = *da * dx[i__ + 2];
283
+ dx[i__ + 3] = *da * dx[i__ + 3];
284
+ dx[i__ + 4] = *da * dx[i__ + 4];
285
+ }
286
+ return 0;
287
+ }
@@ -0,0 +1,12 @@
1
+ #ifndef LBFGSB_RB_BLAS_H_
2
+ #define LBFGSB_RB_BLAS_H_
3
+
4
+ #include <math.h>
5
+
6
+ extern double dnrm2_(long *n, double *x, long *incx);
7
+ extern int daxpy_(long *n, double *da, double *dx, long *incx, double *dy, long *incy);
8
+ extern int dcopy_(long *n, double *dx, long *incx, double *dy, long *incy);
9
+ extern double ddot_(long *n, double *dx, long *incx, double *dy, long *incy);
10
+ extern int dscal_(long *n, double *da, double *dx, long *incx);
11
+
12
+ #endif /* LBFGSB_RB_BLAS_H_ */
@@ -0,0 +1,4096 @@
1
+ /**
2
+ * L-BFGS-B is released under the “New BSD License” (aka “Modified BSD License”
3
+ * or “3-clause license”)
4
+ * Please read attached file License.txt
5
+ *
6
+ * =========== L-BFGS-B (version 3.0. April 25, 2011 ===================
7
+ *
8
+ * This is a modified version of L-BFGS-B. Minor changes in the updated
9
+ * code appear preceded by a line comment as follows
10
+ *
11
+ * jlm-jn
12
+ *
13
+ * Major changes are described in the accompanying paper:
14
+ *
15
+ * Jorge Nocedal and Jose Luis Morales, Remark on "Algorithm 778:
16
+ * L-BFGS-B: Fortran Subroutines for Large-Scale Bound Constrained
17
+ * Optimization" (2011). To appear in ACM Transactions on
18
+ * Mathematical Software,
19
+ *
20
+ * The paper describes an improvement and a correction to Algorithm 778.
21
+ * It is shown that the performance of the algorithm can be improved
22
+ * significantly by making a relatively simple modication to the subspace
23
+ * minimization phase. The correction concerns an error caused by the use
24
+ * of routine dpmeps to estimate machine precision.
25
+ *
26
+ * The total work space **wa** required by the new version is
27
+ *
28
+ * 2*m*n + 11m*m + 5*n + 8*m
29
+ *
30
+ * the old version required
31
+ *
32
+ * 2*m*n + 12m*m + 4*n + 12*m
33
+ *
34
+ *
35
+ * J. Nocedal Department of Electrical Engineering and
36
+ * Computer Science.
37
+ * Northwestern University. Evanston, IL. USA
38
+ *
39
+ *
40
+ * J.L Morales Departamento de Matematicas,
41
+ * Instituto Tecnologico Autonomo de Mexico
42
+ * Mexico D.F. Mexico.
43
+ *
44
+ * March 2011
45
+ */
46
+
47
+ #include "blas.h"
48
+ #include "linpack.h"
49
+ #include "lbfgsb.h"
50
+
51
+ static double c_b9 = 0.;
52
+ static long c__1 = 1;
53
+ static long c__11 = 11;
54
+ static double c_b280 = .001;
55
+ static double c_b281 = .9;
56
+ static double c_b282 = .1;
57
+
58
+ /**
59
+ * Subroutine setulb
60
+ *
61
+ * This subroutine partitions the working arrays wa and iwa, and
62
+ * then uses the limited memory BFGS method to solve the bound
63
+ * constrained optimization problem by calling mainlb.
64
+ * (The direct method will be used in the subspace minimization.)
65
+ *
66
+ * n is an long variable.
67
+ * On entry n is the dimension of the problem.
68
+ * On exit n is unchanged.
69
+ *
70
+ * m is an long variable.
71
+ * On entry m is the maximum number of variable metric corrections
72
+ * used to define the limited memory matrix.
73
+ * On exit m is unchanged.
74
+ *
75
+ * x is a double precision array of dimension n.
76
+ * On entry x is an approximation to the solution.
77
+ * On exit x is the current approximation.
78
+ *
79
+ * l is a double precision array of dimension n.
80
+ * On entry l is the lower bound on x.
81
+ * On exit l is unchanged.
82
+ *
83
+ * u is a double precision array of dimension n.
84
+ * On entry u is the upper bound on x.
85
+ * On exit u is unchanged.
86
+ *
87
+ * nbd is an long array of dimension n.
88
+ * On entry nbd represents the type of bounds imposed on the
89
+ * variables, and must be specified as follows:
90
+ * nbd(i)=0 if x(i) is unbounded,
91
+ * 1 if x(i) has only a lower bound,
92
+ * 2 if x(i) has both lower and upper bounds, and
93
+ * 3 if x(i) has only an upper bound.
94
+ * On exit nbd is unchanged.
95
+ *
96
+ * f is a double precision variable.
97
+ * On first entry f is unspecified.
98
+ * On final exit f is the value of the function at x.
99
+ *
100
+ * g is a double precision array of dimension n.
101
+ * On first entry g is unspecified.
102
+ * On final exit g is the value of the gradient at x.
103
+ *
104
+ * factr is a double precision variable.
105
+ * On entry factr >= 0 is specified by the user. The iteration
106
+ * will stop when
107
+ *
108
+ * (f^k - f^{k+1})/max{|f^k|,|f^{k+1}|,1} <= factr*epsmch
109
+ *
110
+ * where epsmch is the machine precision, which is automatically
111
+ * generated by the code. Typical values for factr: 1.d+12 for
112
+ * low accuracy; 1.d+7 for moderate accuracy; 1.d+1 for extremely
113
+ * high accuracy.
114
+ *
115
+ * On exit factr is unchanged.
116
+ *
117
+ * pgtol is a double precision variable.
118
+ * On entry pgtol >= 0 is specified by the user. The iteration
119
+ * will stop when
120
+ *
121
+ * max{|proj g_i | i = 1, ..., n} <= pgtol
122
+ *
123
+ * where pg_i is the ith component of the projected gradient.
124
+ * On exit pgtol is unchanged.
125
+ *
126
+ * wa is a double precision working array of length
127
+ * (2mmax + 5)nmax + 12mmax^2 + 12mmax.
128
+ *
129
+ * iwa is an long working array of length 3nmax.
130
+ *
131
+ * task is a working string of characters of length 60 indicating
132
+ * the current job when entering and quitting this subroutine.
133
+ *
134
+ * iprint is an long variable that must be set by the user.
135
+ * It controls the frequency and type of output generated:
136
+ * iprint<0 no output is generated;
137
+ * iprint=0 print only one line at the last iteration;
138
+ * 0<iprint<99 print also f and |proj g| every iprint iterations;
139
+ * iprint=99 print details of every iteration except n-vectors;
140
+ * iprint=100 print also the changes of active set and final x;
141
+ * iprint>100 print details of every iteration including x and g;
142
+ * When iprint > 0, the file iterate.dat will be created to
143
+ * summarize the iteration.
144
+ *
145
+ * csave is a working string of characters of length 60.
146
+ *
147
+ * lsave is a logical working array of dimension 4.
148
+ * On exit with 'task' = NEW_X, the following information is
149
+ * available:
150
+ * If lsave(1) = .true. then the initial X has been replaced by
151
+ * its projection in the feasible set;
152
+ * If lsave(2) = .true. then the problem is constrained;
153
+ * If lsave(3) = .true. then each variable has upper and lower
154
+ * bounds;
155
+ *
156
+ * isave is an long working array of dimension 44.
157
+ * On exit with 'task' = NEW_X, the following information is
158
+ * available:
159
+ * isave(22) = the total number of intervals explored in the
160
+ * search of Cauchy points;
161
+ * isave(26) = the total number of skipped BFGS updates before
162
+ * the current iteration;
163
+ * isave(30) = the number of current iteration;
164
+ * isave(31) = the total number of BFGS updates prior the current
165
+ * iteration;
166
+ * isave(33) = the number of intervals explored in the search of
167
+ * Cauchy point in the current iteration;
168
+ * isave(34) = the total number of function and gradient
169
+ * evaluations;
170
+ * isave(36) = the number of function value or gradient
171
+ * evaluations in the current iteration;
172
+ * if isave(37) = 0 then the subspace argmin is within the box;
173
+ * if isave(37) = 1 then the subspace argmin is beyond the box;
174
+ * isave(38) = the number of free variables in the current
175
+ * iteration;
176
+ * isave(39) = the number of active constraints in the current
177
+ * iteration;
178
+ * n + 1 - isave(40) = the number of variables leaving the set of
179
+ * active constraints in the current iteration;
180
+ * isave(41) = the number of variables entering the set of active
181
+ * constraints in the current iteration.
182
+ *
183
+ * dsave is a double precision working array of dimension 29.
184
+ * On exit with 'task' = NEW_X, the following information is
185
+ * available:
186
+ * dsave(1) = current 'theta' in the BFGS matrix;
187
+ * dsave(2) = f(x) in the previous iteration;
188
+ * dsave(3) = factr*epsmch;
189
+ * dsave(4) = 2-norm of the line search direction vector;
190
+ * dsave(5) = the machine precision epsmch generated by the code;
191
+ * dsave(7) = the accumulated time spent on searching for
192
+ * Cauchy points;
193
+ * dsave(8) = the accumulated time spent on
194
+ * subspace minimization;
195
+ * dsave(9) = the accumulated time spent on line search;
196
+ * dsave(11) = the slope of the line search function at
197
+ * the current point of line search;
198
+ * dsave(12) = the maximum relative step length imposed in
199
+ * line search;
200
+ * dsave(13) = the infinity norm of the projected gradient;
201
+ * dsave(14) = the relative step length in the line search;
202
+ * dsave(15) = the slope of the line search function at
203
+ * the starting point of the line search;
204
+ * dsave(16) = the square of the 2-norm of the line search
205
+ * direction vector.
206
+ *
207
+ * Subprograms called:
208
+ *
209
+ * L-BFGS-B Library ... mainlb.
210
+ *
211
+ *
212
+ * References:
213
+ *
214
+ * [1] R. H. Byrd, P. Lu, J. Nocedal and C. Zhu, ``A limited
215
+ * memory algorithm for bound constrained optimization'',
216
+ * SIAM J. Scientific Computing 16 (1995), no. 5, pp. 1190--1208.
217
+ *
218
+ * [2] C. Zhu, R.H. Byrd, P. Lu, J. Nocedal, ``L-BFGS-B: a
219
+ * limited memory FORTRAN code for solving bound constrained
220
+ * optimization problems'', Tech. Report, NAM-11, EECS Department,
221
+ * Northwestern University, 1994.
222
+ *
223
+ * (Postscript files of these papers are available via anonymous
224
+ * ftp to eecs.nwu.edu in the directory pub/lbfgs/lbfgs_bcm.)
225
+ *
226
+ * * * *
227
+ *
228
+ * NEOS, November 1994. (Latest revision June 1996.)
229
+ * Optimization Technology Center.
230
+ * Argonne National Laboratory and Northwestern University.
231
+ * Written by
232
+ * Ciyou Zhu
233
+ * in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
234
+ */
235
+ int setulb_(long *n, long *m, double *x,
236
+ double *l, double *u, long *nbd, double *f, double *g,
237
+ double *factr, double *pgtol, double *wa, long *iwa,
238
+ char *task, long *iprint, char *csave, long *lsave,
239
+ long *isave, double *dsave)
240
+ {
241
+ long i__1;
242
+
243
+ static long ld, lr, lt, lz, lwa, lwn, lss, lxp, lws, lwt, lsy, lwy, lsnd;
244
+
245
+ /* jlm-jn */
246
+ --iwa;
247
+ --g;
248
+ --nbd;
249
+ --u;
250
+ --l;
251
+ --x;
252
+ --wa;
253
+ --lsave;
254
+ --isave;
255
+ --dsave;
256
+
257
+ if (strncmp(task, "START", 5) == 0) {
258
+ isave[1] = *m * *n;
259
+ i__1 = *m;
260
+ isave[2] = i__1 * i__1;
261
+ i__1 = *m;
262
+ isave[3] = i__1 * i__1 << 2;
263
+ isave[4] = 1; /* ws m*n */
264
+ isave[5] = isave[4] + isave[1]; /* wy m*n */
265
+ isave[6] = isave[5] + isave[1]; /* wsy m**2 */
266
+ isave[7] = isave[6] + isave[2]; /* wss m**2 */
267
+ isave[8] = isave[7] + isave[2]; /* wt m**2 */
268
+ isave[9] = isave[8] + isave[2]; /* wn 4*m**2 */
269
+ isave[10] = isave[9] + isave[3]; /* wsnd 4*m**2 */
270
+ isave[11] = isave[10] + isave[3]; /* wz n */
271
+ isave[12] = isave[11] + *n; /* wr n */
272
+ isave[13] = isave[12] + *n; /* wd n */
273
+ isave[14] = isave[13] + *n; /* wt n */
274
+ isave[15] = isave[14] + *n; /* wxp n */
275
+ isave[16] = isave[15] + *n; /* wa 8*m */
276
+ }
277
+ lws = isave[4];
278
+ lwy = isave[5];
279
+ lsy = isave[6];
280
+ lss = isave[7];
281
+ lwt = isave[8];
282
+ lwn = isave[9];
283
+ lsnd = isave[10];
284
+ lz = isave[11];
285
+ lr = isave[12];
286
+ ld = isave[13];
287
+ lt = isave[14];
288
+ lxp = isave[15];
289
+ lwa = isave[16];
290
+ mainlb_(n, m, &x[1], &l[1], &u[1], &nbd[1], f, &g[1], factr, pgtol, &wa[lws],
291
+ &wa[lwy], &wa[lsy], &wa[lss], &wa[lwt], &wa[lwn], &wa[lsnd],
292
+ &wa[lz], &wa[lr], &wa[ld], &wa[lt], &wa[lxp], &wa[lwa], &iwa[1],
293
+ &iwa[*n + 1], &iwa[(*n << 1) + 1], task, iprint, csave, &lsave[1],
294
+ &isave[22], &dsave[1]);
295
+ return 0;
296
+ }
297
+
298
+ /**
299
+ * Subroutine mainlb
300
+ *
301
+ * This subroutine solves bound constrained optimization problems by
302
+ * using the compact formula of the limited memory BFGS updates.
303
+ *
304
+ * n is an long variable.
305
+ * On entry n is the number of variables.
306
+ * On exit n is unchanged.
307
+ *
308
+ * m is an long variable.
309
+ * On entry m is the maximum number of variable metric
310
+ * corrections allowed in the limited memory matrix.
311
+ * On exit m is unchanged.
312
+ *
313
+ * x is a double precision array of dimension n.
314
+ * On entry x is an approximation to the solution.
315
+ * On exit x is the current approximation.
316
+ *
317
+ * l is a double precision array of dimension n.
318
+ * On entry l is the lower bound of x.
319
+ * On exit l is unchanged.
320
+ *
321
+ * u is a double precision array of dimension n.
322
+ * On entry u is the upper bound of x.
323
+ * On exit u is unchanged.
324
+ *
325
+ * nbd is an long array of dimension n.
326
+ * On entry nbd represents the type of bounds imposed on the
327
+ * variables, and must be specified as follows:
328
+ * nbd(i)=0 if x(i) is unbounded,
329
+ * 1 if x(i) has only a lower bound,
330
+ * 2 if x(i) has both lower and upper bounds,
331
+ * 3 if x(i) has only an upper bound.
332
+ * On exit nbd is unchanged.
333
+ *
334
+ * f is a double precision variable.
335
+ * On first entry f is unspecified.
336
+ * On final exit f is the value of the function at x.
337
+ *
338
+ * g is a double precision array of dimension n.
339
+ * On first entry g is unspecified.
340
+ * On final exit g is the value of the gradient at x.
341
+ *
342
+ * factr is a double precision variable.
343
+ * On entry factr >= 0 is specified by the user. The iteration
344
+ * will stop when
345
+ *
346
+ * (f^k - f^{k+1})/max{|f^k|,|f^{k+1}|,1} <= factr*epsmch
347
+ *
348
+ * where epsmch is the machine precision, which is automatically
349
+ * generated by the code.
350
+ * On exit factr is unchanged.
351
+ *
352
+ * pgtol is a double precision variable.
353
+ * On entry pgtol >= 0 is specified by the user. The iteration
354
+ * will stop when
355
+ *
356
+ * max{|proj g_i | i = 1, ..., n} <= pgtol
357
+ *
358
+ * where pg_i is the ith component of the projected gradient.
359
+ * On exit pgtol is unchanged.
360
+ *
361
+ * ws, wy, sy, and wt are double precision working arrays used to
362
+ * store the following information defining the limited memory
363
+ * BFGS matrix:
364
+ * ws, of dimension n x m, stores S, the matrix of s-vectors;
365
+ * wy, of dimension n x m, stores Y, the matrix of y-vectors;
366
+ * sy, of dimension m x m, stores S'Y;
367
+ * ss, of dimension m x m, stores S'S;
368
+ * yy, of dimension m x m, stores Y'Y;
369
+ * wt, of dimension m x m, stores the Cholesky factorization
370
+ * of (theta*S'S+LD^(-1)L'); see eq.
371
+ * (2.26) in [3].
372
+ *
373
+ * wn is a double precision working array of dimension 2m x 2m
374
+ * used to store the LEL^T factorization of the indefinite matrix
375
+ * K = [-D -Y'ZZ'Y/theta L_a'-R_z' ]
376
+ * [L_a -R_z theta*S'AA'S ]
377
+ *
378
+ * where E = [-I 0]
379
+ * [ 0 I]
380
+ *
381
+ * snd is a double precision working array of dimension 2m x 2m
382
+ * used to store the lower triangular part of
383
+ * N = [Y' ZZ'Y L_a'+R_z']
384
+ * [L_a +R_z S'AA'S ]
385
+ *
386
+ * z(n),r(n),d(n),t(n), xp(n),wa(8*m) are double precision working arrays.
387
+ * z is used at different times to store the Cauchy point and
388
+ * the Newton point.
389
+ * xp is used to safeguard the projected Newton direction
390
+ *
391
+ * sg(m),sgo(m),yg(m),ygo(m) are double precision working arrays.
392
+ *
393
+ * index is an long working array of dimension n.
394
+ * In subroutine freev, index is used to store the free and fixed
395
+ * variables at the Generalized Cauchy Point (GCP).
396
+ *
397
+ * iwhere is an long working array of dimension n used to record
398
+ * the status of the vector x for GCP computation.
399
+ * iwhere(i)=0 or -3 if x(i) is free and has bounds,
400
+ * 1 if x(i) is fixed at l(i), and l(i) .ne. u(i)
401
+ * 2 if x(i) is fixed at u(i), and u(i) .ne. l(i)
402
+ * 3 if x(i) is always fixed, i.e., u(i)=x(i)=l(i)
403
+ * -1 if x(i) is always free, i.e., no bounds on it.
404
+ *
405
+ * indx2 is an long working array of dimension n.
406
+ * Within subroutine cauchy, indx2 corresponds to the array iorder.
407
+ * In subroutine freev, a list of variables entering and leaving
408
+ * the free set is stored in indx2, and it is passed on to
409
+ * subroutine formk with this information.
410
+ *
411
+ * task is a working string of characters of length 60 indicating
412
+ * the current job when entering and leaving this subroutine.
413
+ *
414
+ * iprint is an long variable that must be set by the user.
415
+ * It controls the frequency and type of output generated:
416
+ * iprint<0 no output is generated;
417
+ * iprint=0 print only one line at the last iteration;
418
+ * 0<iprint<99 print also f and |proj g| every iprint iterations;
419
+ * iprint=99 print details of every iteration except n-vectors;
420
+ * iprint=100 print also the changes of active set and final x;
421
+ * iprint>100 print details of every iteration including x and g;
422
+ * When iprint > 0, the file iterate.dat will be created to
423
+ * summarize the iteration.
424
+ *
425
+ * csave is a working string of characters of length 60.
426
+ *
427
+ * lsave is a logical working array of dimension 4.
428
+ *
429
+ * isave is an long working array of dimension 23.
430
+ *
431
+ * dsave is a double precision working array of dimension 29.
432
+ *
433
+ *
434
+ * Subprograms called
435
+ *
436
+ * L-BFGS-B Library ... cauchy, subsm, lnsrlb, formk,
437
+ *
438
+ * errclb, prn1lb, prn2lb, prn3lb, active, projgr,
439
+ *
440
+ * freev, cmprlb, matupd, formt.
441
+ *
442
+ * Minpack2 Library ... timer
443
+ *
444
+ * Linpack Library ... dcopy, ddot.
445
+ *
446
+ *
447
+ * References:
448
+ *
449
+ * [1] R. H. Byrd, P. Lu, J. Nocedal and C. Zhu, ``A limited
450
+ * memory algorithm for bound constrained optimization'',
451
+ * SIAM J. Scientific Computing 16 (1995), no. 5, pp. 1190--1208.
452
+ *
453
+ * [2] C. Zhu, R.H. Byrd, P. Lu, J. Nocedal, ``L-BFGS-B: FORTRAN
454
+ * Subroutines for Large Scale Bound Constrained Optimization''
455
+ * Tech. Report, NAM-11, EECS Department, Northwestern University,
456
+ * 1994.
457
+ *
458
+ * [3] R. Byrd, J. Nocedal and R. Schnabel "Representations of
459
+ * Quasi-Newton Matrices and their use in Limited Memory Methods'',
460
+ * Mathematical Programming 63 (1994), no. 4, pp. 129-156.
461
+ *
462
+ * (Postscript files of these papers are available via anonymous
463
+ * ftp to eecs.nwu.edu in the directory pub/lbfgs/lbfgs_bcm.)
464
+ *
465
+ * * * *
466
+ *
467
+ * NEOS, November 1994. (Latest revision June 1996.)
468
+ * Optimization Technology Center.
469
+ * Argonne National Laboratory and Northwestern University.
470
+ * Written by
471
+ * Ciyou Zhu
472
+ * in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
473
+ */
474
+ int mainlb_(long *n, long *m, double *x,
475
+ double *l, double *u, long *nbd, double *f, double *g,
476
+ double *factr, double *pgtol, double *ws, double *wy,
477
+ double *sy, double *ss, double *wt, double *wn,
478
+ double *snd, double *z__, double *r__, double *d__,
479
+ double *t, double *xp, double *wa, long *index,
480
+ long *iwhere, long *indx2, char *task, long *iprint,
481
+ char *csave, long *lsave, long *isave, double *dsave)
482
+ {
483
+ long ws_dim1, ws_offset, wy_dim1, wy_offset, sy_dim1, sy_offset,
484
+ ss_dim1, ss_offset, wt_dim1, wt_offset, wn_dim1, wn_offset,
485
+ snd_dim1, snd_offset, i__1;
486
+ double d__1, d__2;
487
+ FILE *itfptr;
488
+ static long i__, k;
489
+ static double gd, dr, rr, dtd;
490
+ static long col;
491
+ static double tol;
492
+ static long wrk;
493
+ static double stp, cpu1, cpu2;
494
+ static long head;
495
+ static double fold;
496
+ static long nact;
497
+ static double ddum;
498
+ static long info, nseg;
499
+ static double time;
500
+ static long nfgv, ifun, iter;
501
+ static char word[4];
502
+ static double time1, time2;
503
+ static long iback;
504
+ static double gdold;
505
+ static long nfree;
506
+ static long boxed;
507
+ static long itail;
508
+ static double theta;
509
+ static double dnorm;
510
+ static long nskip, iword;
511
+ static double xstep, stpmx;
512
+ static long ileave;
513
+ static double cachyt;
514
+ static long itfile;
515
+ static double epsmch;
516
+ static long updatd;
517
+ static double sbtime;
518
+ static long prjctd;
519
+ static long iupdat;
520
+ static double sbgnrm;
521
+ static long cnstnd;
522
+ static long nenter;
523
+ static double lnscht;
524
+ static long nintol;
525
+
526
+ --indx2;
527
+ --iwhere;
528
+ --index;
529
+ --xp;
530
+ --t;
531
+ --d__;
532
+ --r__;
533
+ --z__;
534
+ --g;
535
+ --nbd;
536
+ --u;
537
+ --l;
538
+ --x;
539
+ --wa;
540
+ snd_dim1 = 2 * *m;
541
+ snd_offset = 1 + snd_dim1;
542
+ snd -= snd_offset;
543
+ wn_dim1 = 2 * *m;
544
+ wn_offset = 1 + wn_dim1;
545
+ wn -= wn_offset;
546
+ wt_dim1 = *m;
547
+ wt_offset = 1 + wt_dim1;
548
+ wt -= wt_offset;
549
+ ss_dim1 = *m;
550
+ ss_offset = 1 + ss_dim1;
551
+ ss -= ss_offset;
552
+ sy_dim1 = *m;
553
+ sy_offset = 1 + sy_dim1;
554
+ sy -= sy_offset;
555
+ wy_dim1 = *n;
556
+ wy_offset = 1 + wy_dim1;
557
+ wy -= wy_offset;
558
+ ws_dim1 = *n;
559
+ ws_offset = 1 + ws_dim1;
560
+ ws -= ws_offset;
561
+ --lsave;
562
+ --isave;
563
+ --dsave;
564
+
565
+ /* jlm-jn */
566
+ if (strncmp(task, "START", 5) == 0) {
567
+ epsmch = DBL_EPSILON;
568
+ timer_(&time1);
569
+ /* Initialize counters and scalars when task='START'. */
570
+ /* for the limited memory BFGS matrices: */
571
+ col = 0;
572
+ head = 1;
573
+ theta = 1.;
574
+ iupdat = 0;
575
+ updatd = FALSE_;
576
+ iback = 0;
577
+ itail = 0;
578
+ iword = 0;
579
+ nact = 0;
580
+ ileave = 0;
581
+ nenter = 0;
582
+ fold = 0.;
583
+ dnorm = 0.;
584
+ cpu1 = 0.;
585
+ gd = 0.;
586
+ stpmx = 0.;
587
+ sbgnrm = 0.;
588
+ stp = 0.;
589
+ gdold = 0.;
590
+ dtd = 0.;
591
+ /* for operation counts: */
592
+ iter = 0;
593
+ nfgv = 0;
594
+ nseg = 0;
595
+ nintol = 0;
596
+ nskip = 0;
597
+ nfree = *n;
598
+ ifun = 0;
599
+ /* for stopping tolerance: */
600
+ tol = *factr * epsmch;
601
+ /* for measuring running time: */
602
+ cachyt = 0.;
603
+ sbtime = 0.;
604
+ lnscht = 0.;
605
+ /* 'word' records the status of subspace solutions. */
606
+ strcpy(word, "---");
607
+ /* 'info' records the termination information. */
608
+ info = 0;
609
+ itfile = 8;
610
+ /* Check the input arguments for errors. */
611
+ errclb_(n, m, factr, &l[1], &u[1], &nbd[1], task, &info, &k);
612
+ if (strncmp(task, "ERROR", 5) == 0) {
613
+ prn3lb_(n, &x[1], f, task, iprint, &info, &itfile, &iter, &nfgv, &nintol,
614
+ &nskip, &nact, &sbgnrm, &c_b9, &nseg, word, &iback,
615
+ &stp, &xstep, &k, &cachyt, &sbtime, &lnscht);
616
+ return 0;
617
+ }
618
+ prn1lb_(n, m, &l[1], &u[1], &x[1], iprint, &itfile, &epsmch);
619
+ /* Initialize iwhere & project x onto the feasible set. */
620
+ active_(n, &l[1], &u[1], &nbd[1], &x[1], &iwhere[1], iprint, &prjctd, &cnstnd, &boxed);
621
+ /* The end of the initialization. */
622
+ } else {
623
+ /* restore local variables. */
624
+ prjctd = lsave[1];
625
+ cnstnd = lsave[2];
626
+ boxed = lsave[3];
627
+ updatd = lsave[4];
628
+ nintol = isave[1];
629
+ itfile = isave[3];
630
+ iback = isave[4];
631
+ nskip = isave[5];
632
+ head = isave[6];
633
+ col = isave[7];
634
+ itail = isave[8];
635
+ iter = isave[9];
636
+ iupdat = isave[10];
637
+ nseg = isave[12];
638
+ nfgv = isave[13];
639
+ info = isave[14];
640
+ ifun = isave[15];
641
+ iword = isave[16];
642
+ nfree = isave[17];
643
+ nact = isave[18];
644
+ ileave = isave[19];
645
+ nenter = isave[20];
646
+ theta = dsave[1];
647
+ fold = dsave[2];
648
+ tol = dsave[3];
649
+ dnorm = dsave[4];
650
+ epsmch = dsave[5];
651
+ cpu1 = dsave[6];
652
+ cachyt = dsave[7];
653
+ sbtime = dsave[8];
654
+ lnscht = dsave[9];
655
+ time1 = dsave[10];
656
+ gd = dsave[11];
657
+ stpmx = dsave[12];
658
+ sbgnrm = dsave[13];
659
+ stp = dsave[14];
660
+ gdold = dsave[15];
661
+ dtd = dsave[16];
662
+ /* After returning from the driver go to the point where execution */
663
+ /* is to resume. */
664
+ if (strncmp(task, "FG_LN", 5) == 0) {
665
+ goto L666;
666
+ }
667
+ if (strncmp(task, "NEW_X", 5) == 0) {
668
+ goto L777;
669
+ }
670
+ if (strncmp(task, "FG_ST", 5) == 0) {
671
+ goto L111;
672
+ }
673
+ if (strncmp(task, "STOP", 4) == 0) {
674
+ if (strncmp(task + 6, "CPU", 3) == 0) {
675
+ /* restore the previous iterate. */
676
+ dcopy_(n, &t[1], &c__1, &x[1], &c__1);
677
+ dcopy_(n, &r__[1], &c__1, &g[1], &c__1);
678
+ *f = fold;
679
+ }
680
+ goto L999;
681
+ }
682
+ }
683
+ /* Compute f0 and g0. */
684
+ strcpy(task, "FG_START");
685
+ /* return to the driver to calculate f and g; reenter at 111. */
686
+ goto L1000;
687
+ L111:
688
+ nfgv = 1;
689
+ /* Compute the infinity norm of the (-) projected gradient. */
690
+ projgr_(n, &l[1], &u[1], &nbd[1], &x[1], &g[1], &sbgnrm);
691
+ if (*iprint >= 1) {
692
+ fprintf(stdout, "\nAt iterate%5ld f= %12.5E |proj g|= %12.5E\n", iter, *f, sbgnrm);
693
+ itfptr = fopen("iterate.dat", "a");
694
+ fprintf(itfptr, " %4ld %4ld - - - - - - %10.3E %10.3E\n", iter, nfgv, sbgnrm, *f);
695
+ fclose(itfptr);
696
+ }
697
+ if (sbgnrm <= *pgtol) {
698
+ /* terminate the algorithm. */
699
+ strcpy(task, "CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL");
700
+ goto L999;
701
+ }
702
+ /* ----------------- the beginning of the loop -------------------------- */
703
+ L222:
704
+ if (*iprint >= 99) {
705
+ i__1 = iter + 1;
706
+ fprintf(stdout, "\n\nITERATION %5ld\n", i__1);
707
+ }
708
+ iword = -1;
709
+
710
+ if (! cnstnd && col > 0) {
711
+ /* skip the search for GCP. */
712
+ dcopy_(n, &x[1], &c__1, &z__[1], &c__1);
713
+ wrk = updatd;
714
+ nseg = 0;
715
+ goto L333;
716
+ }
717
+ /**
718
+ * Compute the Generalized Cauchy Point (GCP).
719
+ */
720
+ timer_(&cpu1);
721
+ cauchy_(n, &x[1], &l[1], &u[1], &nbd[1], &g[1], &indx2[1], &iwhere[1], &t[1],
722
+ &d__[1], &z__[1], m, &wy[wy_offset], &ws[ws_offset], &sy[sy_offset],
723
+ &wt[wt_offset], &theta, &col, &head, &wa[1], &wa[(*m << 1) + 1],
724
+ &wa[(*m << 2) + 1], &wa[*m * 6 + 1], &nseg, iprint, &sbgnrm, &info, &epsmch);
725
+ if (info != 0) {
726
+ /* singular triangular system detected; refresh the lbfgs memory. */
727
+ if (*iprint >= 1) {
728
+ fprintf(stdout, "\n");
729
+ fprintf(stdout, " Singular triangular system detected;\n");
730
+ fprintf(stdout, " refresh the lbfgs memory and restart the iteration.\n");
731
+ }
732
+ info = 0;
733
+ col = 0;
734
+ head = 1;
735
+ theta = 1.;
736
+ iupdat = 0;
737
+ updatd = FALSE_;
738
+ timer_(&cpu2);
739
+ cachyt = cachyt + cpu2 - cpu1;
740
+ goto L222;
741
+ }
742
+ timer_(&cpu2);
743
+ cachyt = cachyt + cpu2 - cpu1;
744
+ nintol += nseg;
745
+ /* Count the entering and leaving variables for iter > 0; */
746
+ /* find the index set of free and active variables at the GCP. */
747
+ freev_(n, &nfree, &index[1], &nenter, &ileave, &indx2[1], &iwhere[1], &wrk, &updatd, &cnstnd, iprint, &iter);
748
+ nact = *n - nfree;
749
+ L333:
750
+ /* If there are no free variables or B=theta*I, then */
751
+ /* skip the subspace minimization. */
752
+ if (nfree == 0 || col == 0) {
753
+ goto L555;
754
+ }
755
+ /**
756
+ * Subspace minimization.
757
+ */
758
+ timer_(&cpu1);
759
+ /* Form the LEL^T factorization of the indefinite */
760
+ /* matrix K = [-D -Y'ZZ'Y/theta L_a'-R_z' ] */
761
+ /* [L_a -R_z theta*S'AA'S ] */
762
+ /* where E = [-I 0] */
763
+ /* [ 0 I] */
764
+ if (wrk) {
765
+ formk_(n, &nfree, &index[1], &nenter, &ileave, &indx2[1], &iupdat, &updatd,
766
+ &wn[wn_offset], &snd[snd_offset], m, &ws[ws_offset], &wy[wy_offset],
767
+ &sy[sy_offset], &theta, &col, &head, &info);
768
+ }
769
+ if (info != 0) {
770
+ /* nonpositive definiteness in Cholesky factorization; */
771
+ /* refresh the lbfgs memory and restart the iteration. */
772
+ if (*iprint >= 1) {
773
+ fprintf(stdout, "\n");
774
+ fprintf(stdout, " Nonpositive definiteness in Cholesky factorization in formk;\n");
775
+ fprintf(stdout, " refresh the lbfgs memory and restart the iteration.\n");
776
+ }
777
+ info = 0;
778
+ col = 0;
779
+ head = 1;
780
+ theta = 1.;
781
+ iupdat = 0;
782
+ updatd = FALSE_;
783
+ timer_(&cpu2);
784
+ sbtime = sbtime + cpu2 - cpu1;
785
+ goto L222;
786
+ }
787
+ /* compute r=-Z'B(xcp-xk)-Z'g (using wa(2m+1)=W'(xcp-x) */
788
+ /* from 'cauchy'). */
789
+ cmprlb_(n, m, &x[1], &g[1], &ws[ws_offset], &wy[wy_offset], &sy[sy_offset],
790
+ &wt[wt_offset], &z__[1], &r__[1], &wa[1], &index[1], &theta, &col,
791
+ &head, &nfree, &cnstnd, &info);
792
+ if (info != 0) {
793
+ goto L444;
794
+ }
795
+ /* jlm-jn call the direct method. */
796
+ subsm_(n, m, &nfree, &index[1], &l[1], &u[1], &nbd[1], &z__[1], &r__[1], &xp[1],
797
+ &ws[ws_offset], &wy[wy_offset], &theta, &x[1], &g[1], &col,
798
+ &head, &iword, &wa[1], &wn[wn_offset], iprint, &info);
799
+ L444:
800
+ if (info != 0) {
801
+ /* singular triangular system detected; */
802
+ /* refresh the lbfgs memory and restart the iteration. */
803
+ if (*iprint >= 1) {
804
+ fprintf(stdout, "\n");
805
+ fprintf(stdout, " Singular triangular system detected;\n");
806
+ fprintf(stdout, " refresh the lbfgs memory and restart the iteration.\n");
807
+ }
808
+ info = 0;
809
+ col = 0;
810
+ head = 1;
811
+ theta = 1.;
812
+ iupdat = 0;
813
+ updatd = FALSE_;
814
+ timer_(&cpu2);
815
+ sbtime = sbtime + cpu2 - cpu1;
816
+ goto L222;
817
+ }
818
+ timer_(&cpu2);
819
+ sbtime = sbtime + cpu2 - cpu1;
820
+ L555:
821
+ /**
822
+ * Line search and optimality tests.
823
+ */
824
+ /* Generate the search direction d:=z-x. */
825
+ i__1 = *n;
826
+ for (i__ = 1; i__ <= i__1; ++i__) {
827
+ d__[i__] = z__[i__] - x[i__];
828
+ }
829
+ timer_(&cpu1);
830
+ L666:
831
+ lnsrlb_(n, &l[1], &u[1], &nbd[1], &x[1], f, &fold, &gd, &gdold, &g[1],
832
+ &d__[1], &r__[1], &t[1], &z__[1], &stp, &dnorm, &dtd, &xstep,
833
+ &stpmx, &iter, &ifun, &iback, &nfgv, &info, task, &boxed, &cnstnd,
834
+ csave, &isave[22], &dsave[17]);
835
+ if (info != 0 || iback >= 20) {
836
+ /* restore the previous iterate. */
837
+ dcopy_(n, &t[1], &c__1, &x[1], &c__1);
838
+ dcopy_(n, &r__[1], &c__1, &g[1], &c__1);
839
+ *f = fold;
840
+ if (col == 0) {
841
+ /* abnormal termination. */
842
+ if (info == 0) {
843
+ info = -9;
844
+ /* restore the actual number of f and g evaluations etc. */
845
+ --nfgv;
846
+ --ifun;
847
+ --iback;
848
+ }
849
+ strcpy(task, "ABNORMAL_TERMINATION_IN_LNSRCH");
850
+ ++iter;
851
+ goto L999;
852
+ } else {
853
+ /* refresh the lbfgs memory and restart the iteration. */
854
+ if (*iprint >= 1) {
855
+ fprintf(stdout, "\n");
856
+ fprintf(stdout, " Bad direction in the line search;\n");
857
+ fprintf(stdout, " refresh the lbfgs memory and restart the iteration.\n");
858
+ }
859
+ if (info == 0) {
860
+ --nfgv;
861
+ }
862
+ info = 0;
863
+ col = 0;
864
+ head = 1;
865
+ theta = 1.;
866
+ iupdat = 0;
867
+ updatd = FALSE_;
868
+ strcpy(task, "RESTART_FROM_LNSRCH");
869
+ timer_(&cpu2);
870
+ lnscht = lnscht + cpu2 - cpu1;
871
+ goto L222;
872
+ }
873
+ } else if (strncmp(task, "FG_LN", 5) == 0) {
874
+ /* return to the driver for calculating f and g; reenter at 666. */
875
+ goto L1000;
876
+ } else {
877
+ /* calculate and print out the quantities related to the new X. */
878
+ timer_(&cpu2);
879
+ lnscht = lnscht + cpu2 - cpu1;
880
+ ++iter;
881
+ /* Compute the infinity norm of the projected (-)gradient. */
882
+ projgr_(n, &l[1], &u[1], &nbd[1], &x[1], &g[1], &sbgnrm);
883
+ /* Print iteration information. */
884
+ prn2lb_(n, &x[1], f, &g[1], iprint, &itfile, &iter, &nfgv, &nact,
885
+ &sbgnrm, &nseg, word, &iword, &iback, &stp, &xstep);
886
+ goto L1000;
887
+ }
888
+ L777:
889
+ /* Test for termination. */
890
+ if (sbgnrm <= *pgtol) {
891
+ /* terminate the algorithm. */
892
+ strcpy(task, "CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL");
893
+ goto L999;
894
+ }
895
+ d__1 = fabs(fold);
896
+ d__2 = fabs(*f);
897
+ d__1 = d__1 >= d__2 ? d__1 : d__2;
898
+ ddum = d__1 >= 1. ? d__1 : 1.;
899
+ if (fold - *f <= tol * ddum) {
900
+ /* terminate the algorithm. */
901
+ strcpy(task, "CONVERGENCE: REL_REDUCTION_OF_F_<=_FACTR*EPSMCH");
902
+ if (iback >= 10) {
903
+ info = -5;
904
+ }
905
+ /*i.e., to issue a warning if iback>10 in the line search. */
906
+ goto L999;
907
+ }
908
+ /* Compute d=newx-oldx, r=newg-oldg, rr=y'y and dr=y's. */
909
+ i__1 = *n;
910
+ for (i__ = 1; i__ <= i__1; ++i__) {
911
+ r__[i__] = g[i__] - r__[i__];
912
+ }
913
+ rr = ddot_(n, &r__[1], &c__1, &r__[1], &c__1);
914
+ if (stp == 1.) {
915
+ dr = gd - gdold;
916
+ ddum = -gdold;
917
+ } else {
918
+ dr = (gd - gdold) * stp;
919
+ dscal_(n, &stp, &d__[1], &c__1);
920
+ ddum = -gdold * stp;
921
+ }
922
+ if (dr <= epsmch * ddum) {
923
+ /* skip the L-BFGS update. */
924
+ ++nskip;
925
+ updatd = FALSE_;
926
+ if (*iprint >= 1) {
927
+ fprintf(stdout, " ys=%10.3E -gs=%10.3E BFGS update SKIPPED\n", dr, ddum);
928
+ }
929
+ goto L888;
930
+ }
931
+ /**
932
+ * Update the L-BFGS matrix.
933
+ */
934
+ updatd = TRUE_;
935
+ ++iupdat;
936
+ /* Update matrices WS and WY and form the middle matrix in B. */
937
+ matupd_(n, m, &ws[ws_offset], &wy[wy_offset], &sy[sy_offset],
938
+ &ss[ss_offset], &d__[1], &r__[1], &itail, &iupdat, &col, &head,
939
+ &theta, &rr, &dr, &stp, &dtd);
940
+ /* Form the upper half of the pds T = theta*SS + L*D^(-1)*L'; */
941
+ /* Store T in the upper triangular of the array wt; */
942
+ /* Cholesky factorize T to J*J' with */
943
+ /* J' stored in the upper triangular of wt. */
944
+ formt_(m, &wt[wt_offset], &sy[sy_offset], &ss[ss_offset], &col, &theta, &info);
945
+ if (info != 0) {
946
+ /* nonpositive definiteness in Cholesky factorization; */
947
+ /* refresh the lbfgs memory and restart the iteration. */
948
+ if (*iprint >= 1) {
949
+ fprintf(stdout, "\n");
950
+ fprintf(stdout, " Nonpositive definiteness in Cholesky factorization in formt;\n");
951
+ fprintf(stdout, " refresh the lbfgs memory and restart the iteration.\n");
952
+ }
953
+ info = 0;
954
+ col = 0;
955
+ head = 1;
956
+ theta = 1.;
957
+ iupdat = 0;
958
+ updatd = FALSE_;
959
+ goto L222;
960
+ }
961
+ /* Now the inverse of the middle matrix in B is */
962
+ /* [ D^(1/2) O ] [ -D^(1/2) D^(-1/2)*L' ] */
963
+ /* [ -L*D^(-1/2) J ] [ 0 J' ] */
964
+ L888:
965
+ /* -------------------- the end of the loop ----------------------------- */
966
+ goto L222;
967
+ L999:
968
+ timer_(&time2);
969
+ time = time2 - time1;
970
+ prn3lb_(n, &x[1], f, task, iprint, &info, &itfile, &iter, &nfgv, &nintol,
971
+ &nskip, &nact, &sbgnrm, &time, &nseg, word, &iback, &stp, &xstep,
972
+ &k, &cachyt, &sbtime, &lnscht);
973
+ L1000:
974
+ /* Save local variables. */
975
+ lsave[1] = prjctd;
976
+ lsave[2] = cnstnd;
977
+ lsave[3] = boxed;
978
+ lsave[4] = updatd;
979
+ isave[1] = nintol;
980
+ isave[3] = itfile;
981
+ isave[4] = iback;
982
+ isave[5] = nskip;
983
+ isave[6] = head;
984
+ isave[7] = col;
985
+ isave[8] = itail;
986
+ isave[9] = iter;
987
+ isave[10] = iupdat;
988
+ isave[12] = nseg;
989
+ isave[13] = nfgv;
990
+ isave[14] = info;
991
+ isave[15] = ifun;
992
+ isave[16] = iword;
993
+ isave[17] = nfree;
994
+ isave[18] = nact;
995
+ isave[19] = ileave;
996
+ isave[20] = nenter;
997
+ dsave[1] = theta;
998
+ dsave[2] = fold;
999
+ dsave[3] = tol;
1000
+ dsave[4] = dnorm;
1001
+ dsave[5] = epsmch;
1002
+ dsave[6] = cpu1;
1003
+ dsave[7] = cachyt;
1004
+ dsave[8] = sbtime;
1005
+ dsave[9] = lnscht;
1006
+ dsave[10] = time1;
1007
+ dsave[11] = gd;
1008
+ dsave[12] = stpmx;
1009
+ dsave[13] = sbgnrm;
1010
+ dsave[14] = stp;
1011
+ dsave[15] = gdold;
1012
+ dsave[16] = dtd;
1013
+ return 0;
1014
+ }
1015
+
1016
+ /**
1017
+ * Subroutine active
1018
+ *
1019
+ * This subroutine initializes iwhere and projects the initial x to
1020
+ * the feasible set if necessary.
1021
+ *
1022
+ * iwhere is an long array of dimension n.
1023
+ * On entry iwhere is unspecified.
1024
+ * On exit iwhere(i)=-1 if x(i) has no bounds
1025
+ * 3 if l(i)=u(i)
1026
+ * 0 otherwise.
1027
+ * In cauchy, iwhere is given finer gradations.
1028
+ *
1029
+ * * * *
1030
+ *
1031
+ * NEOS, November 1994. (Latest revision June 1996.)
1032
+ * Optimization Technology Center.
1033
+ * Argonne National Laboratory and Northwestern University.
1034
+ * Written by
1035
+ * Ciyou Zhu
1036
+ * in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
1037
+ */
1038
+ int active_(long *n, double *l, double *u,
1039
+ long *nbd, double *x, long *iwhere, long *iprint,
1040
+ long *prjctd, long *cnstnd, long *boxed)
1041
+ {
1042
+ long i__1;
1043
+ static long i__, nbdd;
1044
+ --iwhere;
1045
+ --x;
1046
+ --nbd;
1047
+ --u;
1048
+ --l;
1049
+
1050
+ /* Initialize nbdd, prjctd, cnstnd and boxed. */
1051
+ nbdd = 0;
1052
+ *prjctd = FALSE_;
1053
+ *cnstnd = FALSE_;
1054
+ *boxed = TRUE_;
1055
+ /* Project the initial x to the easible set if necessary. */
1056
+ i__1 = *n;
1057
+ for (i__ = 1; i__ <= i__1; ++i__) {
1058
+ if (nbd[i__] > 0) {
1059
+ if (nbd[i__] <= 2 && x[i__] <= l[i__]) {
1060
+ if (x[i__] < l[i__]) {
1061
+ *prjctd = TRUE_;
1062
+ x[i__] = l[i__];
1063
+ }
1064
+ ++nbdd;
1065
+ } else if (nbd[i__] >= 2 && x[i__] >= u[i__]) {
1066
+ if (x[i__] > u[i__]) {
1067
+ *prjctd = TRUE_;
1068
+ x[i__] = u[i__];
1069
+ }
1070
+ ++nbdd;
1071
+ }
1072
+ }
1073
+ }
1074
+ /* Initialize iwhere and assign values to cnstnd and boxed. */
1075
+ i__1 = *n;
1076
+ for (i__ = 1; i__ <= i__1; ++i__) {
1077
+ if (nbd[i__] != 2) {
1078
+ *boxed = FALSE_;
1079
+ }
1080
+ if (nbd[i__] == 0) {
1081
+ /* this variable is always free */
1082
+ iwhere[i__] = -1;
1083
+ /* otherwise set x(i)=mid(x(i), u(i), l(i)). */
1084
+ } else {
1085
+ *cnstnd = TRUE_;
1086
+ if (nbd[i__] == 2 && u[i__] - l[i__] <= 0.) {
1087
+ /* this variable is always fixed */
1088
+ iwhere[i__] = 3;
1089
+ } else {
1090
+ iwhere[i__] = 0;
1091
+ }
1092
+ }
1093
+ }
1094
+ if (*iprint >= 0) {
1095
+ if (*prjctd) {
1096
+ fprintf(stdout, " The initial X is infeasible. Restart with its projection.\n");
1097
+ }
1098
+ if (! (*cnstnd)) {
1099
+ fprintf(stdout, " This problem is unconstrained.\n");
1100
+ }
1101
+ }
1102
+ if (*iprint > 0) {
1103
+ fprintf(stdout, "\n");
1104
+ fprintf(stdout, "At X0 %9ld variables are exactly at the bounds\n", nbdd);
1105
+ }
1106
+ return 0;
1107
+ }
1108
+
1109
+ /**
1110
+ * Subroutine bmv
1111
+ *
1112
+ * This subroutine computes the product of the 2m x 2m middle matrix
1113
+ * in the compact L-BFGS formula of B and a 2m vector v;
1114
+ * it returns the product in p.
1115
+ *
1116
+ * m is an long variable.
1117
+ * On entry m is the maximum number of variable metric corrections
1118
+ * used to define the limited memory matrix.
1119
+ * On exit m is unchanged.
1120
+ *
1121
+ * sy is a double precision array of dimension m x m.
1122
+ * On entry sy specifies the matrix S'Y.
1123
+ * On exit sy is unchanged.
1124
+ *
1125
+ * wt is a double precision array of dimension m x m.
1126
+ * On entry wt specifies the upper triangular matrix J' which is
1127
+ * the Cholesky factor of (thetaS'S+LD^(-1)L').
1128
+ * On exit wt is unchanged.
1129
+ *
1130
+ * col is an long variable.
1131
+ * On entry col specifies the number of s-vectors (or y-vectors)
1132
+ * stored in the compact L-BFGS formula.
1133
+ * On exit col is unchanged.
1134
+ *
1135
+ * v is a double precision array of dimension 2col.
1136
+ * On entry v specifies vector v.
1137
+ * On exit v is unchanged.
1138
+ *
1139
+ * p is a double precision array of dimension 2col.
1140
+ * On entry p is unspecified.
1141
+ * On exit p is the product Mv.
1142
+ *
1143
+ * info is an long variable.
1144
+ * On entry info is unspecified.
1145
+ * On exit info = 0 for normal return,
1146
+ * = nonzero for abnormal return when the system
1147
+ * to be solved by dtrsl is singular.
1148
+ *
1149
+ * Subprograms called:
1150
+ *
1151
+ * Linpack ... dtrsl.
1152
+ *
1153
+ * * * *
1154
+ *
1155
+ * NEOS, November 1994. (Latest revision June 1996.)
1156
+ * Optimization Technology Center.
1157
+ * Argonne National Laboratory and Northwestern University.
1158
+ * Written by
1159
+ * Ciyou Zhu
1160
+ * in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
1161
+ */
1162
+ int bmv_(long *m, double *sy, double *wt, long
1163
+ *col, double *v, double *p, long *info)
1164
+ {
1165
+ long sy_dim1, sy_offset, wt_dim1, wt_offset, i__1, i__2;
1166
+ static long i__, k, i2;
1167
+ static double sum;
1168
+
1169
+ wt_dim1 = *m;
1170
+ wt_offset = 1 + wt_dim1;
1171
+ wt -= wt_offset;
1172
+ sy_dim1 = *m;
1173
+ sy_offset = 1 + sy_dim1;
1174
+ sy -= sy_offset;
1175
+ --p;
1176
+ --v;
1177
+
1178
+ if (*col == 0) {
1179
+ return 0;
1180
+ }
1181
+ /* PART I: solve [ D^(1/2) O ] [ p1 ] = [ v1 ] */
1182
+ /* [ -L*D^(-1/2) J ] [ p2 ] [ v2 ]. */
1183
+ /* solve Jp2=v2+LD^(-1)v1. */
1184
+ p[*col + 1] = v[*col + 1];
1185
+ i__1 = *col;
1186
+ for (i__ = 2; i__ <= i__1; ++i__) {
1187
+ i2 = *col + i__;
1188
+ sum = 0.;
1189
+ i__2 = i__ - 1;
1190
+ for (k = 1; k <= i__2; ++k) {
1191
+ sum += sy[i__ + k * sy_dim1] * v[k] / sy[k + k * sy_dim1];
1192
+ }
1193
+ p[i2] = v[i2] + sum;
1194
+ }
1195
+ /* Solve the triangular system */
1196
+ dtrsl_(&wt[wt_offset], m, col, &p[*col + 1], &c__11, info);
1197
+ if (*info != 0) {
1198
+ return 0;
1199
+ }
1200
+ /* solve D^(1/2)p1=v1. */
1201
+ i__1 = *col;
1202
+ for (i__ = 1; i__ <= i__1; ++i__) {
1203
+ p[i__] = v[i__] / sqrt(sy[i__ + i__ * sy_dim1]);
1204
+ }
1205
+ /* PART II: solve [ -D^(1/2) D^(-1/2)*L' ] [ p1 ] = [ p1 ] */
1206
+ /* [ 0 J' ] [ p2 ] [ p2 ]. */
1207
+ /* solve J^Tp2=p2. */
1208
+ dtrsl_(&wt[wt_offset], m, col, &p[*col + 1], &c__1, info);
1209
+ if (*info != 0) {
1210
+ return 0;
1211
+ }
1212
+ /* compute p1=-D^(-1/2)(p1-D^(-1/2)L'p2) */
1213
+ /* =-D^(-1/2)p1+D^(-1)L'p2. */
1214
+ i__1 = *col;
1215
+ for (i__ = 1; i__ <= i__1; ++i__) {
1216
+ p[i__] = -p[i__] / sqrt(sy[i__ + i__ * sy_dim1]);
1217
+ }
1218
+ i__1 = *col;
1219
+ for (i__ = 1; i__ <= i__1; ++i__) {
1220
+ sum = 0.;
1221
+ i__2 = *col;
1222
+ for (k = i__ + 1; k <= i__2; ++k) {
1223
+ sum += sy[k + i__ * sy_dim1] * p[*col + k] / sy[i__ + i__ * sy_dim1];
1224
+ }
1225
+ p[i__] += sum;
1226
+ }
1227
+ return 0;
1228
+ }
1229
+
1230
+ /**
1231
+ * Subroutine cauchy
1232
+ *
1233
+ * For given x, l, u, g (with sbgnrm > 0), and a limited memory
1234
+ * BFGS matrix B defined in terms of matrices WY, WS, WT, and
1235
+ * scalars head, col, and theta, this subroutine computes the
1236
+ * generalized Cauchy point (GCP), defined as the first local
1237
+ * minimizer of the quadratic
1238
+ *
1239
+ * Q(x + s) = g's + 1/2 s'Bs
1240
+ *
1241
+ * along the projected gradient direction P(x-tg,l,u).
1242
+ * The routine returns the GCP in xcp.
1243
+ *
1244
+ * n is an long variable.
1245
+ * On entry n is the dimension of the problem.
1246
+ * On exit n is unchanged.
1247
+ *
1248
+ * x is a double precision array of dimension n.
1249
+ * On entry x is the starting point for the GCP computation.
1250
+ * On exit x is unchanged.
1251
+ *
1252
+ * l is a double precision array of dimension n.
1253
+ * On entry l is the lower bound of x.
1254
+ * On exit l is unchanged.
1255
+ *
1256
+ * u is a double precision array of dimension n.
1257
+ * On entry u is the upper bound of x.
1258
+ * On exit u is unchanged.
1259
+ *
1260
+ * nbd is an long array of dimension n.
1261
+ * On entry nbd represents the type of bounds imposed on the
1262
+ * variables, and must be specified as follows:
1263
+ * nbd(i)=0 if x(i) is unbounded,
1264
+ * 1 if x(i) has only a lower bound,
1265
+ * 2 if x(i) has both lower and upper bounds, and
1266
+ * 3 if x(i) has only an upper bound.
1267
+ * On exit nbd is unchanged.
1268
+ *
1269
+ * g is a double precision array of dimension n.
1270
+ * On entry g is the gradient of f(x). g must be a nonzero vector.
1271
+ * On exit g is unchanged.
1272
+ *
1273
+ * iorder is an long working array of dimension n.
1274
+ * iorder will be used to store the breakpoints in the piecewise
1275
+ * linear path and free variables encountered. On exit,
1276
+ * iorder(1),...,iorder(nleft) are indices of breakpoints
1277
+ * which have not been encountered;
1278
+ * iorder(nleft+1),...,iorder(nbreak) are indices of
1279
+ * encountered breakpoints; and
1280
+ * iorder(nfree),...,iorder(n) are indices of variables which
1281
+ * have no bound constraits along the search direction.
1282
+ *
1283
+ * iwhere is an long array of dimension n.
1284
+ * On entry iwhere indicates only the permanently fixed (iwhere=3)
1285
+ * or free (iwhere= -1) components of x.
1286
+ * On exit iwhere records the status of the current x variables.
1287
+ * iwhere(i)=-3 if x(i) is free and has bounds, but is not moved
1288
+ * 0 if x(i) is free and has bounds, and is moved
1289
+ * 1 if x(i) is fixed at l(i), and l(i) .ne. u(i)
1290
+ * 2 if x(i) is fixed at u(i), and u(i) .ne. l(i)
1291
+ * 3 if x(i) is always fixed, i.e., u(i)=x(i)=l(i)
1292
+ * -1 if x(i) is always free, i.e., it has no bounds.
1293
+ *
1294
+ * t is a double precision working array of dimension n.
1295
+ * t will be used to store the break points.
1296
+ *
1297
+ * d is a double precision array of dimension n used to store
1298
+ * the Cauchy direction P(x-tg)-x.
1299
+ *
1300
+ * xcp is a double precision array of dimension n used to return the
1301
+ * GCP on exit.
1302
+ *
1303
+ * m is an long variable.
1304
+ * On entry m is the maximum number of variable metric corrections
1305
+ * used to define the limited memory matrix.
1306
+ * On exit m is unchanged.
1307
+ *
1308
+ * ws, wy, sy, and wt are double precision arrays.
1309
+ * On entry they store information that defines the
1310
+ * limited memory BFGS matrix:
1311
+ * ws(n,m) stores S, a set of s-vectors;
1312
+ * wy(n,m) stores Y, a set of y-vectors;
1313
+ * sy(m,m) stores S'Y;
1314
+ * wt(m,m) stores the
1315
+ * Cholesky factorization of (theta*S'S+LD^(-1)L').
1316
+ * On exit these arrays are unchanged.
1317
+ *
1318
+ * theta is a double precision variable.
1319
+ * On entry theta is the scaling factor specifying B_0 = theta I.
1320
+ * On exit theta is unchanged.
1321
+ *
1322
+ * col is an long variable.
1323
+ * On entry col is the actual number of variable metric
1324
+ * corrections stored so far.
1325
+ * On exit col is unchanged.
1326
+ *
1327
+ * head is an long variable.
1328
+ * On entry head is the location of the first s-vector (or y-vector)
1329
+ * in S (or Y).
1330
+ * On exit col is unchanged.
1331
+ *
1332
+ * p is a double precision working array of dimension 2m.
1333
+ * p will be used to store the vector p = W^(T)d.
1334
+ *
1335
+ * c is a double precision working array of dimension 2m.
1336
+ * c will be used to store the vector c = W^(T)(xcp-x).
1337
+ *
1338
+ * wbp is a double precision working array of dimension 2m.
1339
+ * wbp will be used to store the row of W corresponding
1340
+ * to a breakpoint.
1341
+ *
1342
+ * v is a double precision working array of dimension 2m.
1343
+ *
1344
+ * nseg is an long variable.
1345
+ * On exit nseg records the number of quadratic segments explored
1346
+ * in searching for the GCP.
1347
+ *
1348
+ * sg and yg are double precision arrays of dimension m.
1349
+ * On entry sg and yg store S'g and Y'g correspondingly.
1350
+ * On exit they are unchanged.
1351
+ *
1352
+ * iprint is an long variable that must be set by the user.
1353
+ * It controls the frequency and type of output generated:
1354
+ * iprint<0 no output is generated;
1355
+ * iprint=0 print only one line at the last iteration;
1356
+ * 0<iprint<99 print also f and |proj g| every iprint iterations;
1357
+ * iprint=99 print details of every iteration except n-vectors;
1358
+ * iprint=100 print also the changes of active set and final x;
1359
+ * iprint>100 print details of every iteration including x and g;
1360
+ * When iprint > 0, the file iterate.dat will be created to
1361
+ * summarize the iteration.
1362
+ *
1363
+ * sbgnrm is a double precision variable.
1364
+ * On entry sbgnrm is the norm of the projected gradient at x.
1365
+ * On exit sbgnrm is unchanged.
1366
+ *
1367
+ * info is an long variable.
1368
+ * On entry info is 0.
1369
+ * On exit info = 0 for normal return,
1370
+ * = nonzero for abnormal return when the the system
1371
+ * used in routine bmv is singular.
1372
+ *
1373
+ * Subprograms called:
1374
+ *
1375
+ * L-BFGS-B Library ... hpsolb, bmv.
1376
+ *
1377
+ * Linpack ... dscal dcopy, daxpy.
1378
+ *
1379
+ *
1380
+ * References:
1381
+ *
1382
+ * [1] R. H. Byrd, P. Lu, J. Nocedal and C. Zhu, ``A limited
1383
+ * memory algorithm for bound constrained optimization'',
1384
+ * SIAM J. Scientific Computing 16 (1995), no. 5, pp. 1190--1208.
1385
+ *
1386
+ * [2] C. Zhu, R.H. Byrd, P. Lu, J. Nocedal, ``L-BFGS-B: FORTRAN
1387
+ * Subroutines for Large Scale Bound Constrained Optimization''
1388
+ * Tech. Report, NAM-11, EECS Department, Northwestern University,
1389
+ * 1994.
1390
+ *
1391
+ * (Postscript files of these papers are available via anonymous
1392
+ * ftp to eecs.nwu.edu in the directory pub/lbfgs/lbfgs_bcm.)
1393
+ *
1394
+ * * * *
1395
+ *
1396
+ * NEOS, November 1994. (Latest revision June 1996.)
1397
+ * Optimization Technology Center.
1398
+ * Argonne National Laboratory and Northwestern University.
1399
+ * Written by
1400
+ * Ciyou Zhu
1401
+ * in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
1402
+ */
1403
+ int cauchy_(long *n, double *x, double *l,
1404
+ double *u, long *nbd, double *g, long *iorder, long *iwhere,
1405
+ double *t, double *d__, double *xcp, long *m,
1406
+ double *wy, double *ws, double *sy, double *wt,
1407
+ double *theta, long *col, long *head, double *p,
1408
+ double *c__, double *wbp, double *v, long *nseg,
1409
+ long *iprint, double *sbgnrm, long *info, double *epsmch)
1410
+ {
1411
+ long wy_dim1, wy_offset, ws_dim1, ws_offset, sy_dim1, sy_offset, wt_dim1, wt_offset, i__1, i__2;
1412
+ double d__1;
1413
+ static long i__, j;
1414
+ static double f1, f2, dt, tj, tl, tu, tj0;
1415
+ static long ibp;
1416
+ static double dtm;
1417
+ static double wmc, wmp, wmw;
1418
+ static long col2;
1419
+ static double dibp;
1420
+ static long iter;
1421
+ static double zibp, tsum, dibp2;
1422
+ static long bnded;
1423
+ static double neggi;
1424
+ static long nfree;
1425
+ static double bkmin;
1426
+ static long nleft;
1427
+ static double f2_org__;
1428
+ static long nbreak, ibkmin;
1429
+ static long pointr;
1430
+ static long xlower, xupper;
1431
+
1432
+ --xcp;
1433
+ --d__;
1434
+ --t;
1435
+ --iwhere;
1436
+ --iorder;
1437
+ --g;
1438
+ --nbd;
1439
+ --u;
1440
+ --l;
1441
+ --x;
1442
+ --v;
1443
+ --wbp;
1444
+ --c__;
1445
+ --p;
1446
+ wt_dim1 = *m;
1447
+ wt_offset = 1 + wt_dim1;
1448
+ wt -= wt_offset;
1449
+ sy_dim1 = *m;
1450
+ sy_offset = 1 + sy_dim1;
1451
+ sy -= sy_offset;
1452
+ ws_dim1 = *n;
1453
+ ws_offset = 1 + ws_dim1;
1454
+ ws -= ws_offset;
1455
+ wy_dim1 = *n;
1456
+ wy_offset = 1 + wy_dim1;
1457
+ wy -= wy_offset;
1458
+
1459
+ /* Check the status of the variables, reset iwhere(i) if necessary; */
1460
+ /* compute the Cauchy direction d and the breakpoints t; initialize */
1461
+ /* the derivative f1 and the vector p = W'd (for theta = 1). */
1462
+ if (*sbgnrm <= 0.) {
1463
+ if (*iprint >= 0) {
1464
+ fprintf(stdout, " Subgnorm = 0. GCP = X.\n");
1465
+ }
1466
+ dcopy_(n, &x[1], &c__1, &xcp[1], &c__1);
1467
+ return 0;
1468
+ }
1469
+ bnded = TRUE_;
1470
+ nfree = *n + 1;
1471
+ nbreak = 0;
1472
+ ibkmin = 0;
1473
+ bkmin = 0.;
1474
+ col2 = *col << 1;
1475
+ f1 = 0.;
1476
+ if (*iprint >= 99) {
1477
+ fprintf(stdout, "\n---------------- CAUCHY entered-------------------\n\n");
1478
+ }
1479
+ /* We set p to zero and build it up as we determine d. */
1480
+ i__1 = col2;
1481
+ for (i__ = 1; i__ <= i__1; ++i__) {
1482
+ p[i__] = 0.;
1483
+ }
1484
+ /* In the following loop we determine for each variable its bound */
1485
+ /* status and its breakpoint, and update p accordingly. */
1486
+ /* Smallest breakpoint is identified. */
1487
+ i__1 = *n;
1488
+ for (i__ = 1; i__ <= i__1; ++i__) {
1489
+ neggi = -g[i__];
1490
+ if (iwhere[i__] != 3 && iwhere[i__] != -1) {
1491
+ /* if x(i) is not a constant and has bounds, */
1492
+ /* compute the difference between x(i) and its bounds. */
1493
+ if (nbd[i__] <= 2) {
1494
+ tl = x[i__] - l[i__];
1495
+ }
1496
+ if (nbd[i__] >= 2) {
1497
+ tu = u[i__] - x[i__];
1498
+ }
1499
+ /* If a variable is close enough to a bound */
1500
+ /* we treat it as at bound. */
1501
+ xlower = nbd[i__] <= 2 && tl <= 0.;
1502
+ xupper = nbd[i__] >= 2 && tu <= 0.;
1503
+ /* reset iwhere(i). */
1504
+ iwhere[i__] = 0;
1505
+ if (xlower) {
1506
+ if (neggi <= 0.) {
1507
+ iwhere[i__] = 1;
1508
+ }
1509
+ } else if (xupper) {
1510
+ if (neggi >= 0.) {
1511
+ iwhere[i__] = 2;
1512
+ }
1513
+ } else {
1514
+ if (fabs(neggi) <= 0.) {
1515
+ iwhere[i__] = -3;
1516
+ }
1517
+ }
1518
+ }
1519
+ pointr = *head;
1520
+ if (iwhere[i__] != 0 && iwhere[i__] != -1) {
1521
+ d__[i__] = 0.;
1522
+ } else {
1523
+ d__[i__] = neggi;
1524
+ f1 -= neggi * neggi;
1525
+ /* calculate p := p - W'e_i* (g_i). */
1526
+ i__2 = *col;
1527
+ for (j = 1; j <= i__2; ++j) {
1528
+ p[j] += wy[i__ + pointr * wy_dim1] * neggi;
1529
+ p[*col + j] += ws[i__ + pointr * ws_dim1] * neggi;
1530
+ pointr = pointr % *m + 1;
1531
+ }
1532
+ if (nbd[i__] <= 2 && nbd[i__] != 0 && neggi < 0.) {
1533
+ /* x(i) + d(i) is bounded; compute t(i). */
1534
+ ++nbreak;
1535
+ iorder[nbreak] = i__;
1536
+ t[nbreak] = tl / (-neggi);
1537
+ if (nbreak == 1 || t[nbreak] < bkmin) {
1538
+ bkmin = t[nbreak];
1539
+ ibkmin = nbreak;
1540
+ }
1541
+ } else if (nbd[i__] >= 2 && neggi > 0.) {
1542
+ /* x(i) + d(i) is bounded; compute t(i). */
1543
+ ++nbreak;
1544
+ iorder[nbreak] = i__;
1545
+ t[nbreak] = tu / neggi;
1546
+ if (nbreak == 1 || t[nbreak] < bkmin) {
1547
+ bkmin = t[nbreak];
1548
+ ibkmin = nbreak;
1549
+ }
1550
+ } else {
1551
+ /* x(i) + d(i) is not bounded. */
1552
+ --nfree;
1553
+ iorder[nfree] = i__;
1554
+ if (fabs(neggi) > 0.) {
1555
+ bnded = FALSE_;
1556
+ }
1557
+ }
1558
+ }
1559
+ }
1560
+ /* The indices of the nonzero components of d are now stored */
1561
+ /* in iorder(1),...,iorder(nbreak) and iorder(nfree),...,iorder(n). */
1562
+ /* The smallest of the nbreak breakpoints is in t(ibkmin)=bkmin. */
1563
+ if (*theta != 1.) {
1564
+ /* complete the initialization of p for theta not= one. */
1565
+ dscal_(col, theta, &p[*col + 1], &c__1);
1566
+ }
1567
+ /* Initialize GCP xcp = x. */
1568
+ dcopy_(n, &x[1], &c__1, &xcp[1], &c__1);
1569
+ if (nbreak == 0 && nfree == *n + 1) {
1570
+ /* is a zero vector, return with the initial xcp as GCP. */
1571
+ if (*iprint > 100) {
1572
+ fprintf(stdout, "Cauchy X = \n");
1573
+ fprintf(stdout, " ");
1574
+ i__1 = *n;
1575
+ for (i__ = 1; i__ <= i__1; ++i__) {
1576
+ fprintf(stdout, " %11.4E", xcp[i__]);
1577
+ if (i__ % 6 == 0) {
1578
+ fprintf(stdout, "\n");
1579
+ fprintf(stdout, " ");
1580
+ }
1581
+ }
1582
+ fprintf(stdout, "\n");
1583
+ }
1584
+ return 0;
1585
+ }
1586
+ /* Initialize c = W'(xcp - x) = 0. */
1587
+ i__1 = col2;
1588
+ for (j = 1; j <= i__1; ++j) {
1589
+ c__[j] = 0.;
1590
+ }
1591
+ /* Initialize derivative f2. */
1592
+ f2 = -(*theta) * f1;
1593
+ f2_org__ = f2;
1594
+ if (*col > 0) {
1595
+ bmv_(m, &sy[sy_offset], &wt[wt_offset], col, &p[1], &v[1], info);
1596
+ if (*info != 0) {
1597
+ return 0;
1598
+ }
1599
+ f2 -= ddot_(&col2, &v[1], &c__1, &p[1], &c__1);
1600
+ }
1601
+ dtm = -f1 / f2;
1602
+ tsum = 0.;
1603
+ *nseg = 1;
1604
+ if (*iprint >= 99) {
1605
+ fprintf(stdout, " There are %3ld breakpoints \n", nbreak);
1606
+ }
1607
+ /* If there are no breakpoints, locate the GCP and return. */
1608
+ if (nbreak == 0) {
1609
+ goto L888;
1610
+ }
1611
+ nleft = nbreak;
1612
+ iter = 1;
1613
+ tj = 0.;
1614
+ /* ------------------- the beginning of the loop ------------------------- */
1615
+ L777:
1616
+ /* Find the next smallest breakpoint; */
1617
+ /* compute dt = t(nleft) - t(nleft + 1). */
1618
+ tj0 = tj;
1619
+ if (iter == 1) {
1620
+ /* Since we already have the smallest breakpoint we need not do */
1621
+ /* heapsort yet. Often only one breakpoint is used and the */
1622
+ /* cost of heapsort is avoided. */
1623
+ tj = bkmin;
1624
+ ibp = iorder[ibkmin];
1625
+ } else {
1626
+ if (iter == 2) {
1627
+ /* Replace the already used smallest breakpoint with the */
1628
+ /* breakpoint numbered nbreak > nlast, before heapsort call. */
1629
+ if (ibkmin != nbreak) {
1630
+ t[ibkmin] = t[nbreak];
1631
+ iorder[ibkmin] = iorder[nbreak];
1632
+ }
1633
+ /* Update heap structure of breakpoints */
1634
+ /* (if iter=2, initialize heap). */
1635
+ }
1636
+ i__1 = iter - 2;
1637
+ hpsolb_(&nleft, &t[1], &iorder[1], &i__1);
1638
+ tj = t[nleft];
1639
+ ibp = iorder[nleft];
1640
+ }
1641
+ dt = tj - tj0;
1642
+ if (dt != 0. && *iprint >= 100) {
1643
+ fprintf(stdout, "\n");
1644
+ fprintf(stdout, "Piece %3ld --f1, f2 at start point %11.4E %11.4E\n", *nseg, f1, f2);
1645
+ fprintf(stdout, "Distance to the next break point = %11.4E\n", dt);
1646
+ fprintf(stdout, "Distance to the stationary point = %11.4E\n", dtm);
1647
+ }
1648
+ /* If a minimizer is within this interval, locate the GCP and return. */
1649
+ if (dtm < dt) {
1650
+ goto L888;
1651
+ }
1652
+ /* Otherwise fix one variable and */
1653
+ /* reset the corresponding component of d to zero. */
1654
+ tsum += dt;
1655
+ --nleft;
1656
+ ++iter;
1657
+ dibp = d__[ibp];
1658
+ d__[ibp] = 0.;
1659
+ if (dibp > 0.) {
1660
+ zibp = u[ibp] - x[ibp];
1661
+ xcp[ibp] = u[ibp];
1662
+ iwhere[ibp] = 2;
1663
+ } else {
1664
+ zibp = l[ibp] - x[ibp];
1665
+ xcp[ibp] = l[ibp];
1666
+ iwhere[ibp] = 1;
1667
+ }
1668
+ if (*iprint >= 100) {
1669
+ fprintf(stdout, " Variable %ld is fixed.\n", ibp);
1670
+ }
1671
+ if (nleft == 0 && nbreak == *n) {
1672
+ /* all n variables are fixed, */
1673
+ /* return with xcp as GCP. */
1674
+ dtm = dt;
1675
+ goto L999;
1676
+ }
1677
+ /* Update the derivative information. */
1678
+ ++(*nseg);
1679
+ /* Computing 2nd power */
1680
+ d__1 = dibp;
1681
+ dibp2 = d__1 * d__1;
1682
+ /* Update f1 and f2. */
1683
+ /* temporarily set f1 and f2 for col=0. */
1684
+ f1 = f1 + dt * f2 + dibp2 - *theta * dibp * zibp;
1685
+ f2 -= *theta * dibp2;
1686
+ if (*col > 0) {
1687
+ /* update c = c + dt*p. */
1688
+ daxpy_(&col2, &dt, &p[1], &c__1, &c__[1], &c__1);
1689
+ /* choose wbp, */
1690
+ /* the row of W corresponding to the breakpoint encountered. */
1691
+ pointr = *head;
1692
+ i__1 = *col;
1693
+ for (j = 1; j <= i__1; ++j) {
1694
+ wbp[j] = wy[ibp + pointr * wy_dim1];
1695
+ wbp[*col + j] = *theta * ws[ibp + pointr * ws_dim1];
1696
+ pointr = pointr % *m + 1;
1697
+ }
1698
+ /* compute (wbp)Mc, (wbp)Mp, and (wbp)M(wbp)'. */
1699
+ bmv_(m, &sy[sy_offset], &wt[wt_offset], col, &wbp[1], &v[1], info);
1700
+ if (*info != 0) {
1701
+ return 0;
1702
+ }
1703
+ wmc = ddot_(&col2, &c__[1], &c__1, &v[1], &c__1);
1704
+ wmp = ddot_(&col2, &p[1], &c__1, &v[1], &c__1);
1705
+ wmw = ddot_(&col2, &wbp[1], &c__1, &v[1], &c__1);
1706
+ /* update p = p - dibp*wbp. */
1707
+ d__1 = -dibp;
1708
+ daxpy_(&col2, &d__1, &wbp[1], &c__1, &p[1], &c__1);
1709
+ /* complete updating f1 and f2 while col > 0. */
1710
+ f1 += dibp * wmc;
1711
+ f2 = f2 + dibp * 2. * wmp - dibp2 * wmw;
1712
+ }
1713
+ d__1 = *epsmch * f2_org__;
1714
+ f2 = d__1 > f2 ? d__1 : f2;
1715
+ if (nleft > 0) {
1716
+ dtm = -f1 / f2;
1717
+ goto L777;
1718
+ /* to repeat the loop for unsearched intervals. */
1719
+ } else if (bnded) {
1720
+ f1 = 0.;
1721
+ f2 = 0.;
1722
+ dtm = 0.;
1723
+ } else {
1724
+ dtm = -f1 / f2;
1725
+ }
1726
+ /* ------------------- the end of the loop ------------------------------- */
1727
+ L888:
1728
+ if (*iprint >= 99) {
1729
+ fprintf(stdout, "\n");
1730
+ fprintf(stdout, " GCP found in this segment\n");
1731
+ fprintf(stdout, "Piece %3ld --f1, f2 at start point %11.4E %11.4E\n", *nseg, f1, f2);
1732
+ fprintf(stdout, "Distance to the stationary point = %11.4E\n", dtm);
1733
+ }
1734
+ if (dtm <= 0.) {
1735
+ dtm = 0.;
1736
+ }
1737
+ tsum += dtm;
1738
+ /* Move free variables (i.e., the ones w/o breakpoints) and */
1739
+ /* the variables whose breakpoints haven't been reached. */
1740
+ daxpy_(n, &tsum, &d__[1], &c__1, &xcp[1], &c__1);
1741
+ L999:
1742
+ /* Update c = c + dtm*p = W'(x^c - x) */
1743
+ /* which will be used in computing r = Z'(B(x^c - x) + g). */
1744
+ if (*col > 0) {
1745
+ daxpy_(&col2, &dtm, &p[1], &c__1, &c__[1], &c__1);
1746
+ }
1747
+ if (*iprint > 100) {
1748
+ fprintf(stdout, "Cauchy X = \n");
1749
+ fprintf(stdout, " ");
1750
+ i__1 = *n;
1751
+ for (i__ = 1; i__ <= i__1; ++i__) {
1752
+ fprintf(stdout, " %11.4E", xcp[i__]);
1753
+ if (i__ % 6 == 0) {
1754
+ fprintf(stdout, "\n");
1755
+ fprintf(stdout, " ");
1756
+ }
1757
+ }
1758
+ fprintf(stdout, "\n");
1759
+ }
1760
+ if (*iprint >= 99) {
1761
+ fprintf(stdout, "\n---------------- exit CAUCHY----------------------\n\n");
1762
+ }
1763
+ return 0;
1764
+ }
1765
+
1766
+ /**
1767
+ * Subroutine cmprlb
1768
+ *
1769
+ * This subroutine computes r=-Z'B(xcp-xk)-Z'g by using
1770
+ * wa(2m+1)=W'(xcp-x) from subroutine cauchy.
1771
+ *
1772
+ * Subprograms called:
1773
+ *
1774
+ * L-BFGS-B Library ... bmv.
1775
+ *
1776
+ * * * *
1777
+ *
1778
+ * NEOS, November 1994. (Latest revision June 1996.)
1779
+ * Optimization Technology Center.
1780
+ * Argonne National Laboratory and Northwestern University.
1781
+ * Written by
1782
+ * Ciyou Zhu
1783
+ * in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
1784
+ */
1785
+ int cmprlb_(long *n, long *m, double *x,
1786
+ double *g, double *ws, double *wy, double *sy,
1787
+ double *wt, double *z__, double *r__, double *wa,
1788
+ long *index, double *theta, long *col, long *head,
1789
+ long *nfree, long *cnstnd, long *info)
1790
+ {
1791
+ long ws_dim1, ws_offset, wy_dim1, wy_offset, sy_dim1, sy_offset, wt_dim1, wt_offset, i__1, i__2;
1792
+ static long i__, j, k;
1793
+ static double a1, a2;
1794
+ static long pointr;
1795
+
1796
+ --index;
1797
+ --r__;
1798
+ --z__;
1799
+ --g;
1800
+ --x;
1801
+ --wa;
1802
+ wt_dim1 = *m;
1803
+ wt_offset = 1 + wt_dim1;
1804
+ wt -= wt_offset;
1805
+ sy_dim1 = *m;
1806
+ sy_offset = 1 + sy_dim1;
1807
+ sy -= sy_offset;
1808
+ wy_dim1 = *n;
1809
+ wy_offset = 1 + wy_dim1;
1810
+ wy -= wy_offset;
1811
+ ws_dim1 = *n;
1812
+ ws_offset = 1 + ws_dim1;
1813
+ ws -= ws_offset;
1814
+
1815
+ if (! (*cnstnd) && *col > 0) {
1816
+ i__1 = *n;
1817
+ for (i__ = 1; i__ <= i__1; ++i__) {
1818
+ r__[i__] = -g[i__];
1819
+ }
1820
+ } else {
1821
+ i__1 = *nfree;
1822
+ for (i__ = 1; i__ <= i__1; ++i__) {
1823
+ k = index[i__];
1824
+ r__[i__] = -(*theta) * (z__[k] - x[k]) - g[k];
1825
+ }
1826
+ bmv_(m, &sy[sy_offset], &wt[wt_offset], col, &wa[(*m << 1) + 1], &wa[1], info);
1827
+ if (*info != 0) {
1828
+ *info = -8;
1829
+ return 0;
1830
+ }
1831
+ pointr = *head;
1832
+ i__1 = *col;
1833
+ for (j = 1; j <= i__1; ++j) {
1834
+ a1 = wa[j];
1835
+ a2 = *theta * wa[*col + j];
1836
+ i__2 = *nfree;
1837
+ for (i__ = 1; i__ <= i__2; ++i__) {
1838
+ k = index[i__];
1839
+ r__[i__] = r__[i__] + wy[k + pointr * wy_dim1] * a1 + ws[k + pointr * ws_dim1] * a2;
1840
+ }
1841
+ pointr = pointr % *m + 1;
1842
+ }
1843
+ }
1844
+ return 0;
1845
+ }
1846
+
1847
+ /**
1848
+ * Subroutine errclb
1849
+ *
1850
+ * This subroutine checks the validity of the input data.
1851
+ *
1852
+ * * * *
1853
+ *
1854
+ * NEOS, November 1994. (Latest revision June 1996.)
1855
+ * Optimization Technology Center.
1856
+ * Argonne National Laboratory and Northwestern University.
1857
+ * Written by
1858
+ * Ciyou Zhu
1859
+ * in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
1860
+ */
1861
+ int errclb_(long *n, long *m, double *factr,
1862
+ double *l, double *u, long *nbd, char *task, long *info, long *k)
1863
+ {
1864
+ long i__1;
1865
+ static long i__;
1866
+ --nbd;
1867
+ --u;
1868
+ --l;
1869
+
1870
+ /* Check the input arguments for errors. */
1871
+ if (*n <= 0) {
1872
+ strcpy(task, "ERROR: N .LE. 0");
1873
+ }
1874
+ if (*m <= 0) {
1875
+ strcpy(task, "ERROR: M .LE. 0");
1876
+ }
1877
+ if (*factr < 0.) {
1878
+ strcpy(task, "ERROR: FACTR .LT. 0");
1879
+ }
1880
+ /* Check the validity of the arrays nbd(i), u(i), and l(i). */
1881
+ i__1 = *n;
1882
+ for (i__ = 1; i__ <= i__1; ++i__) {
1883
+ if (nbd[i__] < 0 || nbd[i__] > 3) {
1884
+ /* return */
1885
+ strcpy(task, "ERROR: INVALID NBD");
1886
+ *info = -6;
1887
+ *k = i__;
1888
+ }
1889
+ if (nbd[i__] == 2) {
1890
+ if (l[i__] > u[i__]) {
1891
+ /* return */
1892
+ strcpy(task, "ERROR: NO FEASIBLE SOLUTION");
1893
+ *info = -7;
1894
+ *k = i__;
1895
+ }
1896
+ }
1897
+ }
1898
+ return 0;
1899
+ }
1900
+
1901
+ /**
1902
+ * Subroutine formk
1903
+ *
1904
+ * This subroutine forms the LEL^T factorization of the indefinite
1905
+ *
1906
+ * matrix K = [-D -Y'ZZ'Y/theta L_a'-R_z' ]
1907
+ * [L_a -R_z theta*S'AA'S ]
1908
+ * where E = [-I 0]
1909
+ * [ 0 I]
1910
+ * The matrix K can be shown to be equal to the matrix M^[-1]N
1911
+ * occurring in section 5.1 of [1], as well as to the matrix
1912
+ * Mbar^[-1] Nbar in section 5.3.
1913
+ *
1914
+ * n is an long variable.
1915
+ * On entry n is the dimension of the problem.
1916
+ * On exit n is unchanged.
1917
+ *
1918
+ * nsub is an long variable
1919
+ * On entry nsub is the number of subspace variables in free set.
1920
+ * On exit nsub is not changed.
1921
+ *
1922
+ * ind is an long array of dimension nsub.
1923
+ * On entry ind specifies the indices of subspace variables.
1924
+ * On exit ind is unchanged.
1925
+ *
1926
+ * nenter is an long variable.
1927
+ * On entry nenter is the number of variables entering the
1928
+ * free set.
1929
+ * On exit nenter is unchanged.
1930
+ *
1931
+ * ileave is an long variable.
1932
+ * On entry indx2(ileave),...,indx2(n) are the variables leaving
1933
+ * the free set.
1934
+ * On exit ileave is unchanged.
1935
+ *
1936
+ * indx2 is an long array of dimension n.
1937
+ * On entry indx2(1),...,indx2(nenter) are the variables entering
1938
+ * the free set, while indx2(ileave),...,indx2(n) are the
1939
+ * variables leaving the free set.
1940
+ * On exit indx2 is unchanged.
1941
+ *
1942
+ * iupdat is an long variable.
1943
+ * On entry iupdat is the total number of BFGS updates made so far.
1944
+ * On exit iupdat is unchanged.
1945
+ *
1946
+ * updatd is a logical variable.
1947
+ * On entry 'updatd' is true if the L-BFGS matrix is updatd.
1948
+ * On exit 'updatd' is unchanged.
1949
+ *
1950
+ * wn is a double precision array of dimension 2m x 2m.
1951
+ * On entry wn is unspecified.
1952
+ * On exit the upper triangle of wn stores the LEL^T factorization
1953
+ * of the 2*col x 2*col indefinite matrix
1954
+ * [-D -Y'ZZ'Y/theta L_a'-R_z' ]
1955
+ * [L_a -R_z theta*S'AA'S ]
1956
+ *
1957
+ * wn1 is a double precision array of dimension 2m x 2m.
1958
+ * On entry wn1 stores the lower triangular part of
1959
+ * [Y' ZZ'Y L_a'+R_z']
1960
+ * [L_a+R_z S'AA'S ]
1961
+ * in the previous iteration.
1962
+ * On exit wn1 stores the corresponding updated matrices.
1963
+ * The purpose of wn1 is just to store these inner products
1964
+ * so they can be easily updated and inserted into wn.
1965
+ *
1966
+ * m is an long variable.
1967
+ * On entry m is the maximum number of variable metric corrections
1968
+ * used to define the limited memory matrix.
1969
+ * On exit m is unchanged.
1970
+ *
1971
+ * ws, wy, sy, and wtyy are double precision arrays;
1972
+ * theta is a double precision variable;
1973
+ * col is an long variable;
1974
+ * head is an long variable.
1975
+ * On entry they store the information defining the
1976
+ * limited memory BFGS matrix:
1977
+ * ws(n,m) stores S, a set of s-vectors;
1978
+ * wy(n,m) stores Y, a set of y-vectors;
1979
+ * sy(m,m) stores S'Y;
1980
+ * wtyy(m,m) stores the Cholesky factorization
1981
+ * of (theta*S'S+LD^(-1)L')
1982
+ * theta is the scaling factor specifying B_0 = theta I;
1983
+ * col is the number of variable metric corrections stored;
1984
+ * head is the location of the 1st s- (or y-) vector in S (or Y).
1985
+ * On exit they are unchanged.
1986
+ *
1987
+ * info is an long variable.
1988
+ * On entry info is unspecified.
1989
+ * On exit info = 0 for normal return;
1990
+ * = -1 when the 1st Cholesky factorization failed;
1991
+ * = -2 when the 2st Cholesky factorization failed.
1992
+ *
1993
+ * Subprograms called:
1994
+ *
1995
+ * Linpack ... dcopy, dpofa, dtrsl.
1996
+ *
1997
+ *
1998
+ * References:
1999
+ * [1] R. H. Byrd, P. Lu, J. Nocedal and C. Zhu, ``A limited
2000
+ * memory algorithm for bound constrained optimization'',
2001
+ * SIAM J. Scientific Computing 16 (1995), no. 5, pp. 1190--1208.
2002
+ *
2003
+ * [2] C. Zhu, R.H. Byrd, P. Lu, J. Nocedal, ``L-BFGS-B: a
2004
+ * limited memory FORTRAN code for solving bound constrained
2005
+ * optimization problems'', Tech. Report, NAM-11, EECS Department,
2006
+ * Northwestern University, 1994.
2007
+ *
2008
+ * (Postscript files of these papers are available via anonymous
2009
+ * ftp to eecs.nwu.edu in the directory pub/lbfgs/lbfgs_bcm.)
2010
+ *
2011
+ * * * *
2012
+ *
2013
+ * NEOS, November 1994. (Latest revision June 1996.)
2014
+ * Optimization Technology Center.
2015
+ * Argonne National Laboratory and Northwestern University.
2016
+ * Written by
2017
+ * Ciyou Zhu
2018
+ * in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
2019
+ */
2020
+ int formk_(long *n, long *nsub, long *ind, long *nenter,
2021
+ long *ileave, long *indx2, long *iupdat, long *updatd,
2022
+ double *wn, double *wn1, long *m, double *ws,
2023
+ double *wy, double *sy, double *theta, long *col,
2024
+ long *head, long *info)
2025
+ {
2026
+ long wn_dim1, wn_offset, wn1_dim1, wn1_offset, ws_dim1, ws_offset,
2027
+ wy_dim1, wy_offset, sy_dim1, sy_offset, i__1, i__2, i__3;
2028
+ static long i__, k, k1, m2, is, js, iy, jy, is1, js1, col2, dend, pend;
2029
+ static long upcl;
2030
+ static double temp1, temp2, temp3, temp4;
2031
+ static long ipntr, jpntr, dbegin, pbegin;
2032
+
2033
+ --indx2;
2034
+ --ind;
2035
+ sy_dim1 = *m;
2036
+ sy_offset = 1 + sy_dim1;
2037
+ sy -= sy_offset;
2038
+ wy_dim1 = *n;
2039
+ wy_offset = 1 + wy_dim1;
2040
+ wy -= wy_offset;
2041
+ ws_dim1 = *n;
2042
+ ws_offset = 1 + ws_dim1;
2043
+ ws -= ws_offset;
2044
+ wn1_dim1 = 2 * *m;
2045
+ wn1_offset = 1 + wn1_dim1;
2046
+ wn1 -= wn1_offset;
2047
+ wn_dim1 = 2 * *m;
2048
+ wn_offset = 1 + wn_dim1;
2049
+ wn -= wn_offset;
2050
+
2051
+ /* Form the lower triangular part of */
2052
+ /* WN1 = [Y' ZZ'Y L_a'+R_z'] */
2053
+ /* [L_a+R_z S'AA'S ] */
2054
+ /* where L_a is the strictly lower triangular part of S'AA'Y */
2055
+ /* R_z is the upper triangular part of S'ZZ'Y. */
2056
+ if (*updatd) {
2057
+ if (*iupdat > *m) {
2058
+ /* shift old part of WN1. */
2059
+ i__1 = *m - 1;
2060
+ for (jy = 1; jy <= i__1; ++jy) {
2061
+ js = *m + jy;
2062
+ i__2 = *m - jy;
2063
+ dcopy_(&i__2, &wn1[jy + 1 + (jy + 1) * wn1_dim1], &c__1, &wn1[jy + jy * wn1_dim1], &c__1);
2064
+ i__2 = *m - jy;
2065
+ dcopy_(&i__2, &wn1[js + 1 + (js + 1) * wn1_dim1], &c__1, &wn1[js + js * wn1_dim1], &c__1);
2066
+ i__2 = *m - 1;
2067
+ dcopy_(&i__2, &wn1[*m + 2 + (jy + 1) * wn1_dim1], &c__1, &wn1[*m + 1 + jy * wn1_dim1], &c__1);
2068
+ }
2069
+ }
2070
+ /* put new rows in blocks (1,1), (2,1) and (2,2). */
2071
+ pbegin = 1;
2072
+ pend = *nsub;
2073
+ dbegin = *nsub + 1;
2074
+ dend = *n;
2075
+ iy = *col;
2076
+ is = *m + *col;
2077
+ ipntr = *head + *col - 1;
2078
+ if (ipntr > *m) {
2079
+ ipntr -= *m;
2080
+ }
2081
+ jpntr = *head;
2082
+ i__1 = *col;
2083
+ for (jy = 1; jy <= i__1; ++jy) {
2084
+ js = *m + jy;
2085
+ temp1 = 0.;
2086
+ temp2 = 0.;
2087
+ temp3 = 0.;
2088
+ /* compute element jy of row 'col' of Y'ZZ'Y */
2089
+ i__2 = pend;
2090
+ for (k = pbegin; k <= i__2; ++k) {
2091
+ k1 = ind[k];
2092
+ temp1 += wy[k1 + ipntr * wy_dim1] * wy[k1 + jpntr * wy_dim1];
2093
+ }
2094
+ /* compute elements jy of row 'col' of L_a and S'AA'S */
2095
+ i__2 = dend;
2096
+ for (k = dbegin; k <= i__2; ++k) {
2097
+ k1 = ind[k];
2098
+ temp2 += ws[k1 + ipntr * ws_dim1] * ws[k1 + jpntr * ws_dim1];
2099
+ temp3 += ws[k1 + ipntr * ws_dim1] * wy[k1 + jpntr * wy_dim1];
2100
+ }
2101
+ wn1[iy + jy * wn1_dim1] = temp1;
2102
+ wn1[is + js * wn1_dim1] = temp2;
2103
+ wn1[is + jy * wn1_dim1] = temp3;
2104
+ jpntr = jpntr % *m + 1;
2105
+ }
2106
+ /* put new column in block (2,1). */
2107
+ jy = *col;
2108
+ jpntr = *head + *col - 1;
2109
+ if (jpntr > *m) {
2110
+ jpntr -= *m;
2111
+ }
2112
+ ipntr = *head;
2113
+ i__1 = *col;
2114
+ for (i__ = 1; i__ <= i__1; ++i__) {
2115
+ is = *m + i__;
2116
+ temp3 = 0.;
2117
+ /* compute element i of column 'col' of R_z */
2118
+ i__2 = pend;
2119
+ for (k = pbegin; k <= i__2; ++k) {
2120
+ k1 = ind[k];
2121
+ temp3 += ws[k1 + ipntr * ws_dim1] * wy[k1 + jpntr * wy_dim1];
2122
+ }
2123
+ ipntr = ipntr % *m + 1;
2124
+ wn1[is + jy * wn1_dim1] = temp3;
2125
+ }
2126
+ upcl = *col - 1;
2127
+ } else {
2128
+ upcl = *col;
2129
+ }
2130
+ /* modify the old parts in blocks (1,1) and (2,2) due to changes */
2131
+ /* in the set of free variables. */
2132
+ ipntr = *head;
2133
+ i__1 = upcl;
2134
+ for (iy = 1; iy <= i__1; ++iy) {
2135
+ is = *m + iy;
2136
+ jpntr = *head;
2137
+ i__2 = iy;
2138
+ for (jy = 1; jy <= i__2; ++jy) {
2139
+ js = *m + jy;
2140
+ temp1 = 0.;
2141
+ temp2 = 0.;
2142
+ temp3 = 0.;
2143
+ temp4 = 0.;
2144
+ i__3 = *nenter;
2145
+ for (k = 1; k <= i__3; ++k) {
2146
+ k1 = indx2[k];
2147
+ temp1 += wy[k1 + ipntr * wy_dim1] * wy[k1 + jpntr * wy_dim1];
2148
+ temp2 += ws[k1 + ipntr * ws_dim1] * ws[k1 + jpntr * ws_dim1];
2149
+ }
2150
+ i__3 = *n;
2151
+ for (k = *ileave; k <= i__3; ++k) {
2152
+ k1 = indx2[k];
2153
+ temp3 += wy[k1 + ipntr * wy_dim1] * wy[k1 + jpntr * wy_dim1];
2154
+ temp4 += ws[k1 + ipntr * ws_dim1] * ws[k1 + jpntr * ws_dim1];
2155
+ }
2156
+ wn1[iy + jy * wn1_dim1] = wn1[iy + jy * wn1_dim1] + temp1 - temp3;
2157
+ wn1[is + js * wn1_dim1] = wn1[is + js * wn1_dim1] - temp2 + temp4;
2158
+ jpntr = jpntr % *m + 1;
2159
+ }
2160
+ ipntr = ipntr % *m + 1;
2161
+ }
2162
+ /* modify the old parts in block (2,1). */
2163
+ ipntr = *head;
2164
+ i__1 = *m + upcl;
2165
+ for (is = *m + 1; is <= i__1; ++is) {
2166
+ jpntr = *head;
2167
+ i__2 = upcl;
2168
+ for (jy = 1; jy <= i__2; ++jy) {
2169
+ temp1 = 0.;
2170
+ temp3 = 0.;
2171
+ i__3 = *nenter;
2172
+ for (k = 1; k <= i__3; ++k) {
2173
+ k1 = indx2[k];
2174
+ temp1 += ws[k1 + ipntr * ws_dim1] * wy[k1 + jpntr * wy_dim1];
2175
+ }
2176
+ i__3 = *n;
2177
+ for (k = *ileave; k <= i__3; ++k) {
2178
+ k1 = indx2[k];
2179
+ temp3 += ws[k1 + ipntr * ws_dim1] * wy[k1 + jpntr * wy_dim1];
2180
+ }
2181
+ if (is <= jy + *m) {
2182
+ wn1[is + jy * wn1_dim1] = wn1[is + jy * wn1_dim1] + temp1 - temp3;
2183
+ } else {
2184
+ wn1[is + jy * wn1_dim1] = wn1[is + jy * wn1_dim1] - temp1 + temp3;
2185
+ }
2186
+ jpntr = jpntr % *m + 1;
2187
+ }
2188
+ ipntr = ipntr % *m + 1;
2189
+ }
2190
+ /* Form the upper triangle of WN = [D+Y' ZZ'Y/theta -L_a'+R_z' ] */
2191
+ /* [-L_a +R_z S'AA'S*theta] */
2192
+ m2 = *m << 1;
2193
+ i__1 = *col;
2194
+ for (iy = 1; iy <= i__1; ++iy) {
2195
+ is = *col + iy;
2196
+ is1 = *m + iy;
2197
+ i__2 = iy;
2198
+ for (jy = 1; jy <= i__2; ++jy) {
2199
+ js = *col + jy;
2200
+ js1 = *m + jy;
2201
+ wn[jy + iy * wn_dim1] = wn1[iy + jy * wn1_dim1] / *theta;
2202
+ wn[js + is * wn_dim1] = wn1[is1 + js1 * wn1_dim1] * *theta;
2203
+ }
2204
+ i__2 = iy - 1;
2205
+ for (jy = 1; jy <= i__2; ++jy) {
2206
+ wn[jy + is * wn_dim1] = -wn1[is1 + jy * wn1_dim1];
2207
+ }
2208
+ i__2 = *col;
2209
+ for (jy = iy; jy <= i__2; ++jy) {
2210
+ wn[jy + is * wn_dim1] = wn1[is1 + jy * wn1_dim1];
2211
+ }
2212
+ wn[iy + iy * wn_dim1] += sy[iy + iy * sy_dim1];
2213
+ }
2214
+ /* Form the upper triangle of WN= [ LL' L^-1(-L_a'+R_z')] */
2215
+ /* [(-L_a +R_z)L'^-1 S'AA'S*theta ] */
2216
+ /* first Cholesky factor (1,1) block of wn to get LL' */
2217
+ /* with L' stored in the upper triangle of wn. */
2218
+ dpofa_(&wn[wn_offset], &m2, col, info);
2219
+ if (*info != 0) {
2220
+ *info = -1;
2221
+ return 0;
2222
+ }
2223
+ /* then form L^-1(-L_a'+R_z') in the (1,2) block. */
2224
+ col2 = *col << 1;
2225
+ i__1 = col2;
2226
+ for (js = *col + 1; js <= i__1; ++js) {
2227
+ dtrsl_(&wn[wn_offset], &m2, col, &wn[js * wn_dim1 + 1], &c__11, info);
2228
+ }
2229
+ /* Form S'AA'S*theta + (L^-1(-L_a'+R_z'))'L^-1(-L_a'+R_z') in the */
2230
+ /* upper triangle of (2,2) block of wn. */
2231
+ i__1 = col2;
2232
+ for (is = *col + 1; is <= i__1; ++is) {
2233
+ i__2 = col2;
2234
+ for (js = is; js <= i__2; ++js) {
2235
+ wn[is + js * wn_dim1] += ddot_(col, &wn[is * wn_dim1 + 1], &c__1, &wn[js * wn_dim1 + 1], &c__1);
2236
+ }
2237
+ }
2238
+ /* Cholesky factorization of (2,2) block of wn. */
2239
+ dpofa_(&wn[*col + 1 + (*col + 1) * wn_dim1], &m2, col, info);
2240
+ if (*info != 0) {
2241
+ *info = -2;
2242
+ return 0;
2243
+ }
2244
+ return 0;
2245
+ }
2246
+
2247
+ /**
2248
+ * Subroutine formt
2249
+ *
2250
+ * This subroutine forms the upper half of the pos. def. and symm.
2251
+ * T = theta*SS + L*D^(-1)*L', stores T in the upper triangle
2252
+ * of the array wt, and performs the Cholesky factorization of T
2253
+ * to produce J*J', with J' stored in the upper triangle of wt.
2254
+ *
2255
+ * Subprograms called:
2256
+ *
2257
+ * Linpack ... dpofa.
2258
+ *
2259
+ * * * *
2260
+ *
2261
+ * NEOS, November 1994. (Latest revision June 1996.)
2262
+ * Optimization Technology Center.
2263
+ * Argonne National Laboratory and Northwestern University.
2264
+ * Written by
2265
+ * Ciyou Zhu
2266
+ * in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
2267
+ */
2268
+ int formt_(long *m, double *wt, double *sy,
2269
+ double *ss, long *col, double *theta, long *info)
2270
+ {
2271
+ long wt_dim1, wt_offset, sy_dim1, sy_offset, ss_dim1, ss_offset, i__1, i__2, i__3;
2272
+ static long i__, j, k, k1;
2273
+ static double ddum;
2274
+
2275
+ ss_dim1 = *m;
2276
+ ss_offset = 1 + ss_dim1;
2277
+ ss -= ss_offset;
2278
+ sy_dim1 = *m;
2279
+ sy_offset = 1 + sy_dim1;
2280
+ sy -= sy_offset;
2281
+ wt_dim1 = *m;
2282
+ wt_offset = 1 + wt_dim1;
2283
+ wt -= wt_offset;
2284
+
2285
+ /* Form the upper half of T = theta*SS + L*D^(-1)*L', */
2286
+ /* store T in the upper triangle of the array wt. */
2287
+ i__1 = *col;
2288
+ for (j = 1; j <= i__1; ++j) {
2289
+ wt[j * wt_dim1 + 1] = *theta * ss[j * ss_dim1 + 1];
2290
+ }
2291
+ i__1 = *col;
2292
+ for (i__ = 2; i__ <= i__1; ++i__) {
2293
+ i__2 = *col;
2294
+ for (j = i__; j <= i__2; ++j) {
2295
+ k1 = (i__ <= j ? i__ : j) - 1;
2296
+ ddum = 0.;
2297
+ i__3 = k1;
2298
+ for (k = 1; k <= i__3; ++k) {
2299
+ ddum += sy[i__ + k * sy_dim1] * sy[j + k * sy_dim1] / sy[k + k * sy_dim1];
2300
+ }
2301
+ wt[i__ + j * wt_dim1] = ddum + *theta * ss[i__ + j * ss_dim1];
2302
+ }
2303
+ }
2304
+ /* Cholesky factorize T to J*J' with */
2305
+ /* J' stored in the upper triangle of wt. */
2306
+ dpofa_(&wt[wt_offset], m, col, info);
2307
+ if (*info != 0) {
2308
+ *info = -3;
2309
+ }
2310
+ return 0;
2311
+ }
2312
+
2313
+ /**
2314
+ * Subroutine freev
2315
+ *
2316
+ * This subroutine counts the entering and leaving variables when
2317
+ * iter > 0, and finds the index set of free and active variables
2318
+ * at the GCP.
2319
+ *
2320
+ * cnstnd is a logical variable indicating whether bounds are present
2321
+ *
2322
+ * index is an long array of dimension n
2323
+ * for i=1,...,nfree, index(i) are the indices of free variables
2324
+ * for i=nfree+1,...,n, index(i) are the indices of bound variables
2325
+ * On entry after the first iteration, index gives
2326
+ * the free variables at the previous iteration.
2327
+ * On exit it gives the free variables based on the determination
2328
+ * in cauchy using the array iwhere.
2329
+ *
2330
+ * indx2 is an long array of dimension n
2331
+ * On entry indx2 is unspecified.
2332
+ * On exit with iter>0, indx2 indicates which variables
2333
+ * have changed status since the previous iteration.
2334
+ * For i= 1,...,nenter, indx2(i) have changed from bound to free.
2335
+ * For i= ileave+1,...,n, indx2(i) have changed from free to bound.
2336
+ *
2337
+ * * * *
2338
+ *
2339
+ * NEOS, November 1994. (Latest revision June 1996.)
2340
+ * Optimization Technology Center.
2341
+ * Argonne National Laboratory and Northwestern University.
2342
+ * Written by
2343
+ * Ciyou Zhu
2344
+ * in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
2345
+ */
2346
+ int freev_(long *n, long *nfree, long *index,
2347
+ long *nenter, long *ileave, long *indx2, long *iwhere,
2348
+ long *wrk, long *updatd, long *cnstnd, long *iprint,
2349
+ long *iter)
2350
+ {
2351
+ long i__1;
2352
+ static long i__, k, iact;
2353
+
2354
+ --iwhere;
2355
+ --indx2;
2356
+ --index;
2357
+
2358
+ *nenter = 0;
2359
+ *ileave = *n + 1;
2360
+ if (*iter > 0 && *cnstnd) {
2361
+ /* count the entering and leaving variables. */
2362
+ i__1 = *nfree;
2363
+ for (i__ = 1; i__ <= i__1; ++i__) {
2364
+ k = index[i__];
2365
+ /* write(6,*) ' k = index(i) ', k */
2366
+ /* write(6,*) ' index = ', i */
2367
+ if (iwhere[k] > 0) {
2368
+ --(*ileave);
2369
+ indx2[*ileave] = k;
2370
+ if (*iprint >= 100) {
2371
+ fprintf(stdout, " Variable %2ld leaves the set of free variables\n", k);
2372
+ }
2373
+ }
2374
+ }
2375
+ i__1 = *n;
2376
+ for (i__ = *nfree + 1; i__ <= i__1; ++i__) {
2377
+ k = index[i__];
2378
+ if (iwhere[k] <= 0) {
2379
+ ++(*nenter);
2380
+ indx2[*nenter] = k;
2381
+ if (*iprint >= 100) {
2382
+ fprintf(stdout, " Variable %2ld enters the set of free variables\n", k);
2383
+ }
2384
+ }
2385
+ }
2386
+ if (*iprint >= 99) {
2387
+ i__1 = *n + 1 - *ileave;
2388
+ fprintf(stdout, " %2ld variables leave; %2ld variables enter\n", i__1, *nenter);
2389
+ }
2390
+ }
2391
+ *wrk = *ileave < *n + 1 || *nenter > 0 || *updatd;
2392
+ /* Find the index set of free and active variables at the GCP. */
2393
+ *nfree = 0;
2394
+ iact = *n + 1;
2395
+ i__1 = *n;
2396
+ for (i__ = 1; i__ <= i__1; ++i__) {
2397
+ if (iwhere[i__] <= 0) {
2398
+ ++(*nfree);
2399
+ index[*nfree] = i__;
2400
+ } else {
2401
+ --iact;
2402
+ index[iact] = i__;
2403
+ }
2404
+ }
2405
+ if (*iprint >= 99) {
2406
+ i__1 = *iter + 1;
2407
+ fprintf(stdout, " %2ld variables are free at GCP %3ld\n", *nfree, i__1);
2408
+ }
2409
+ return 0;
2410
+ }
2411
+
2412
+ /**
2413
+ * Subroutine hpsolb
2414
+ *
2415
+ * This subroutine sorts out the least element of t, and puts the
2416
+ * remaining elements of t in a heap.
2417
+ *
2418
+ * n is an long variable.
2419
+ * On entry n is the dimension of the arrays t and iorder.
2420
+ * On exit n is unchanged.
2421
+ *
2422
+ * t is a double precision array of dimension n.
2423
+ * On entry t stores the elements to be sorted,
2424
+ * On exit t(n) stores the least elements of t, and t(1) to t(n-1)
2425
+ * stores the remaining elements in the form of a heap.
2426
+ *
2427
+ * iorder is an long array of dimension n.
2428
+ * On entry iorder(i) is the index of t(i).
2429
+ * On exit iorder(i) is still the index of t(i), but iorder may be
2430
+ * permuted in accordance with t.
2431
+ *
2432
+ * iheap is an long variable specifying the task.
2433
+ * On entry iheap should be set as follows:
2434
+ * iheap .eq. 0 if t(1) to t(n) is not in the form of a heap,
2435
+ * iheap .ne. 0 if otherwise.
2436
+ * On exit iheap is unchanged.
2437
+ *
2438
+ *
2439
+ * References:
2440
+ * Algorithm 232 of CACM (J. W. J. Williams): HEAPSORT.
2441
+ *
2442
+ * * * *
2443
+ *
2444
+ * NEOS, November 1994. (Latest revision June 1996.)
2445
+ * Optimization Technology Center.
2446
+ * Argonne National Laboratory and Northwestern University.
2447
+ * Written by
2448
+ * Ciyou Zhu
2449
+ * in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
2450
+ */
2451
+ int hpsolb_(long *n, double *t, long *iorder, long *iheap)
2452
+ {
2453
+ long i__1;
2454
+ static long i__, j, k;
2455
+ static double out, ddum;
2456
+ static long indxin, indxou;
2457
+
2458
+ --iorder;
2459
+ --t;
2460
+
2461
+ if (*iheap == 0) {
2462
+ /* Rearrange the elements t(1) to t(n) to form a heap. */
2463
+ i__1 = *n;
2464
+ for (k = 2; k <= i__1; ++k) {
2465
+ ddum = t[k];
2466
+ indxin = iorder[k];
2467
+ /* Add ddum to the heap. */
2468
+ i__ = k;
2469
+ L10:
2470
+ if (i__ > 1) {
2471
+ j = i__ / 2;
2472
+ if (ddum < t[j]) {
2473
+ t[i__] = t[j];
2474
+ iorder[i__] = iorder[j];
2475
+ i__ = j;
2476
+ goto L10;
2477
+ }
2478
+ }
2479
+ t[i__] = ddum;
2480
+ iorder[i__] = indxin;
2481
+ }
2482
+ }
2483
+ /* Assign to 'out' the value of t(1), the least member of the heap, */
2484
+ /* and rearrange the remaining members to form a heap as */
2485
+ /* elements 1 to n-1 of t. */
2486
+ if (*n > 1) {
2487
+ i__ = 1;
2488
+ out = t[1];
2489
+ indxou = iorder[1];
2490
+ ddum = t[*n];
2491
+ indxin = iorder[*n];
2492
+ /* Restore the heap */
2493
+ L30:
2494
+ j = i__ + i__;
2495
+ if (j <= *n - 1) {
2496
+ if (t[j + 1] < t[j]) {
2497
+ ++j;
2498
+ }
2499
+ if (t[j] < ddum) {
2500
+ t[i__] = t[j];
2501
+ iorder[i__] = iorder[j];
2502
+ i__ = j;
2503
+ goto L30;
2504
+ }
2505
+ }
2506
+ t[i__] = ddum;
2507
+ iorder[i__] = indxin;
2508
+ /* Put the least member in t(n). */
2509
+ t[*n] = out;
2510
+ iorder[*n] = indxou;
2511
+ }
2512
+ return 0;
2513
+ }
2514
+
2515
+ /**
2516
+ * Subroutine lnsrlb
2517
+ *
2518
+ * This subroutine calls subroutine dcsrch from the Minpack2 library
2519
+ * to perform the line search. Subroutine dscrch is safeguarded so
2520
+ * that all trial points lie within the feasible region.
2521
+ *
2522
+ * Subprograms called:
2523
+ *
2524
+ * Minpack2 Library ... dcsrch.
2525
+ *
2526
+ * Linpack ... dtrsl, ddot.
2527
+ *
2528
+ * * * *
2529
+ *
2530
+ * NEOS, November 1994. (Latest revision June 1996.)
2531
+ * Optimization Technology Center.
2532
+ * Argonne National Laboratory and Northwestern University.
2533
+ * Written by
2534
+ * Ciyou Zhu
2535
+ * in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
2536
+ */
2537
+ int lnsrlb_(long *n, double *l, double *u,
2538
+ long *nbd, double *x, double *f, double *fold,
2539
+ double *gd, double *gdold, double *g, double *d__,
2540
+ double *r__, double *t, double *z__, double *stp,
2541
+ double *dnorm, double *dtd, double *xstep, double *stpmx,
2542
+ long *iter, long *ifun, long *iback, long *nfgv,
2543
+ long *info, char *task, long *boxed, long *cnstnd,
2544
+ char *csave, long *isave, double *dsave)
2545
+ {
2546
+ long i__1;
2547
+ double d__1;
2548
+ static long i__;
2549
+ static double a1, a2;
2550
+
2551
+ --z__;
2552
+ --t;
2553
+ --r__;
2554
+ --d__;
2555
+ --g;
2556
+ --x;
2557
+ --nbd;
2558
+ --u;
2559
+ --l;
2560
+ --isave;
2561
+ --dsave;
2562
+
2563
+ if (strncmp(task, "FG_LN", 5) == 0) {
2564
+ goto L556;
2565
+ }
2566
+ *dtd = ddot_(n, &d__[1], &c__1, &d__[1], &c__1);
2567
+ *dnorm = sqrt(*dtd);
2568
+ /* Determine the maximum step length. */
2569
+ *stpmx = 1e10;
2570
+ if (*cnstnd) {
2571
+ if (*iter == 0) {
2572
+ *stpmx = 1.;
2573
+ } else {
2574
+ i__1 = *n;
2575
+ for (i__ = 1; i__ <= i__1; ++i__) {
2576
+ a1 = d__[i__];
2577
+ if (nbd[i__] != 0) {
2578
+ if (a1 < 0. && nbd[i__] <= 2) {
2579
+ a2 = l[i__] - x[i__];
2580
+ if (a2 >= 0.) {
2581
+ *stpmx = 0.;
2582
+ } else if (a1 * *stpmx < a2) {
2583
+ *stpmx = a2 / a1;
2584
+ }
2585
+ } else if (a1 > 0. && nbd[i__] >= 2) {
2586
+ a2 = u[i__] - x[i__];
2587
+ if (a2 <= 0.) {
2588
+ *stpmx = 0.;
2589
+ } else if (a1 * *stpmx > a2) {
2590
+ *stpmx = a2 / a1;
2591
+ }
2592
+ }
2593
+ }
2594
+ }
2595
+ }
2596
+ }
2597
+ if (*iter == 0 && ! (*boxed)) {
2598
+ d__1 = 1. / *dnorm;
2599
+ *stp = d__1 <= *stpmx ? d__1 : *stpmx;
2600
+ } else {
2601
+ *stp = 1.;
2602
+ }
2603
+ dcopy_(n, &x[1], &c__1, &t[1], &c__1);
2604
+ dcopy_(n, &g[1], &c__1, &r__[1], &c__1);
2605
+ *fold = *f;
2606
+ *ifun = 0;
2607
+ *iback = 0;
2608
+ strcpy(csave, "START");
2609
+ L556:
2610
+ *gd = ddot_(n, &g[1], &c__1, &d__[1], &c__1);
2611
+ if (*ifun == 0) {
2612
+ *gdold = *gd;
2613
+ if (*gd >= 0.) {
2614
+ /* the directional derivative >=0. */
2615
+ /* Line search is impossible. */
2616
+ fprintf(stdout, " ascent direction in projection gd = %.8E\n", *gd);
2617
+ *info = -4;
2618
+ return 0;
2619
+ }
2620
+ }
2621
+ dcsrch_(f, gd, stp, &c_b280, &c_b281, &c_b282, &c_b9, stpmx, csave, &isave[1], &dsave[1]);
2622
+ *xstep = *stp * *dnorm;
2623
+ if (strncmp(csave, "CONV", 4) != 0 && strncmp(csave, "WARN", 4) != 0) {
2624
+ strcpy(task, "FG_LNSRCH");
2625
+ ++(*ifun);
2626
+ ++(*nfgv);
2627
+ *iback = *ifun - 1;
2628
+ if (*stp == 1.) {
2629
+ dcopy_(n, &z__[1], &c__1, &x[1], &c__1);
2630
+ } else {
2631
+ i__1 = *n;
2632
+ for (i__ = 1; i__ <= i__1; ++i__) {
2633
+ x[i__] = *stp * d__[i__] + t[i__];
2634
+ }
2635
+ }
2636
+ } else {
2637
+ strcpy(task, "NEW_X");
2638
+ }
2639
+ return 0;
2640
+ }
2641
+
2642
+ /**
2643
+ * Subroutine matupd
2644
+ *
2645
+ * This subroutine updates matrices WS and WY, and forms the
2646
+ * middle matrix in B.
2647
+ *
2648
+ * Subprograms called:
2649
+ *
2650
+ * Linpack ... dcopy, ddot.
2651
+ *
2652
+ * * * *
2653
+ *
2654
+ * NEOS, November 1994. (Latest revision June 1996.)
2655
+ * Optimization Technology Center.
2656
+ * Argonne National Laboratory and Northwestern University.
2657
+ * Written by
2658
+ * Ciyou Zhu
2659
+ * in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
2660
+ */
2661
+ int matupd_(long *n, long *m, double *ws,
2662
+ double *wy, double *sy, double *ss, double *d__,
2663
+ double *r__, long *itail, long *iupdat, long *col,
2664
+ long *head, double *theta, double *rr, double *dr,
2665
+ double *stp, double *dtd)
2666
+ {
2667
+ long ws_dim1, ws_offset, wy_dim1, wy_offset, sy_dim1, sy_offset, ss_dim1, ss_offset, i__1, i__2;
2668
+ static long j;
2669
+ static long pointr;
2670
+
2671
+ --r__;
2672
+ --d__;
2673
+
2674
+ ss_dim1 = *m;
2675
+ ss_offset = 1 + ss_dim1;
2676
+ ss -= ss_offset;
2677
+ sy_dim1 = *m;
2678
+ sy_offset = 1 + sy_dim1;
2679
+ sy -= sy_offset;
2680
+ wy_dim1 = *n;
2681
+ wy_offset = 1 + wy_dim1;
2682
+ wy -= wy_offset;
2683
+ ws_dim1 = *n;
2684
+ ws_offset = 1 + ws_dim1;
2685
+ ws -= ws_offset;
2686
+
2687
+ /* Set pointers for matrices WS and WY. */
2688
+ if (*iupdat <= *m) {
2689
+ *col = *iupdat;
2690
+ *itail = (*head + *iupdat - 2) % *m + 1;
2691
+ } else {
2692
+ *itail = *itail % *m + 1;
2693
+ *head = *head % *m + 1;
2694
+ }
2695
+ /* Update matrices WS and WY. */
2696
+ dcopy_(n, &d__[1], &c__1, &ws[*itail * ws_dim1 + 1], &c__1);
2697
+ dcopy_(n, &r__[1], &c__1, &wy[*itail * wy_dim1 + 1], &c__1);
2698
+ /* Set theta=yy/ys. */
2699
+ *theta = *rr / *dr;
2700
+ /* Form the middle matrix in B. */
2701
+ /* update the upper triangle of SS, */
2702
+ /* and the lower triangle of SY: */
2703
+ if (*iupdat > *m) {
2704
+ /* move old information */
2705
+ i__1 = *col - 1;
2706
+ for (j = 1; j <= i__1; ++j) {
2707
+ dcopy_(&j, &ss[(j + 1) * ss_dim1 + 2], &c__1, &ss[j * ss_dim1 + 1], &c__1);
2708
+ i__2 = *col - j;
2709
+ dcopy_(&i__2, &sy[j + 1 + (j + 1) * sy_dim1], &c__1, &sy[j + j * sy_dim1], &c__1);
2710
+ }
2711
+ }
2712
+ /* add new information: the last row of SY */
2713
+ /* and the last column of SS: */
2714
+ pointr = *head;
2715
+ i__1 = *col - 1;
2716
+ for (j = 1; j <= i__1; ++j) {
2717
+ sy[*col + j * sy_dim1] = ddot_(n, &d__[1], &c__1, &wy[pointr * wy_dim1 + 1], &c__1);
2718
+ ss[j + *col * ss_dim1] = ddot_(n, &ws[pointr * ws_dim1 + 1], &c__1, &d__[1], &c__1);
2719
+ pointr = pointr % *m + 1;
2720
+ }
2721
+ if (*stp == 1.) {
2722
+ ss[*col + *col * ss_dim1] = *dtd;
2723
+ } else {
2724
+ ss[*col + *col * ss_dim1] = *stp * *stp * *dtd;
2725
+ }
2726
+ sy[*col + *col * sy_dim1] = *dr;
2727
+ return 0;
2728
+ }
2729
+
2730
+ /**
2731
+ * Subroutine prn1lb
2732
+ *
2733
+ * This subroutine prints the input data, initial point, upper and
2734
+ * lower bounds of each variable, machine precision, as well as
2735
+ * the headings of the output.
2736
+ *
2737
+ * * * *
2738
+ *
2739
+ * NEOS, November 1994. (Latest revision June 1996.)
2740
+ * Optimization Technology Center.
2741
+ * Argonne National Laboratory and Northwestern University.
2742
+ * Written by
2743
+ * Ciyou Zhu
2744
+ * in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
2745
+ */
2746
+ int prn1lb_(long *n, long *m, double *l,
2747
+ double *u, double *x, long *iprint, long *itfile,
2748
+ double *epsmch)
2749
+ {
2750
+ long i__1;
2751
+ FILE *itfptr;
2752
+ static long i__;
2753
+
2754
+ --x;
2755
+ --u;
2756
+ --l;
2757
+
2758
+ if (*iprint >= 0) {
2759
+ fprintf(stdout, "RUNNING THE L-BFGS-B CODE\n\n");
2760
+ fprintf(stdout, " * * *\n\n");
2761
+ fprintf(stdout, "Machine precision = %.3E\n", *epsmch);
2762
+ fprintf(stdout, " N = %3ld M = %2ld\n", *n, *m);
2763
+ if (*iprint >= 1) {
2764
+ itfptr = fopen("iterate.dat", "w");
2765
+ fprintf(itfptr, "RUNNING THE L-BFGS-B CODE\n");
2766
+ fprintf(itfptr, "\n");
2767
+ fprintf(itfptr, "it = iteration number\n");
2768
+ fprintf(itfptr, "nf = number of function evaluations\n");
2769
+ fprintf(itfptr, "nseg = number of segments explored during the Cauchy search\n");
2770
+ fprintf(itfptr, "nact = number of active bounds at the generalized Cauchy point\n");
2771
+ fprintf(itfptr, "sub = manner in which the subspace minimization terminated:\n");
2772
+ fprintf(itfptr, " con = converged, bnd = a bound was reached\n");
2773
+ fprintf(itfptr, "itls = number of iterations performed in the line search\n");
2774
+ fprintf(itfptr, "stepl = step length used\n");
2775
+ fprintf(itfptr, "tstep = norm of the displacement (total step)\n");
2776
+ fprintf(itfptr, "projg = norm of the projected gradient\n");
2777
+ fprintf(itfptr, "f = function value\n");
2778
+ fprintf(itfptr, "\n");
2779
+ fprintf(itfptr, " * * *\n\n");
2780
+ fprintf(itfptr, "Machine precision = %.3E\n", *epsmch);
2781
+ fprintf(itfptr, " N = %3ld M = %2ld\n", *n, *m);
2782
+ fprintf(itfptr, "\n");
2783
+ fprintf(itfptr, " it nf nseg nact sub itls stepl tstep projg f\n");
2784
+ fclose(itfptr);
2785
+
2786
+ if (*iprint > 100) {
2787
+ fprintf(stdout, "\n");
2788
+ fprintf(stdout, " L = ");
2789
+ i__1 = *n;
2790
+ for (i__ = 1; i__ <= i__1; ++i__) {
2791
+ fprintf(stdout, " %11.4E", l[i__]);
2792
+ if (i__ % 6 == 0) {
2793
+ fprintf(stdout, "\n");
2794
+ fprintf(stdout, " ");
2795
+ }
2796
+ }
2797
+ fprintf(stdout, "\n");
2798
+
2799
+ fprintf(stdout, "\n");
2800
+ fprintf(stdout, " X0 =");
2801
+ i__1 = *n;
2802
+ for (i__ = 1; i__ <= i__1; ++i__) {
2803
+ fprintf(stdout, " %11.4E", x[i__]);
2804
+ if (i__ % 6 == 0) {
2805
+ fprintf(stdout, "\n");
2806
+ fprintf(stdout, " ");
2807
+ }
2808
+ }
2809
+ fprintf(stdout, "\n");
2810
+
2811
+ fprintf(stdout, "\n");
2812
+ fprintf(stdout, " U = ");
2813
+ i__1 = *n;
2814
+ for (i__ = 1; i__ <= i__1; ++i__) {
2815
+ fprintf(stdout, " %11.4E", u[i__]);
2816
+ if (i__ % 6 == 0) {
2817
+ fprintf(stdout, "\n");
2818
+ fprintf(stdout, " ");
2819
+ }
2820
+ }
2821
+ fprintf(stdout, "\n");
2822
+ }
2823
+ }
2824
+ }
2825
+ return 0;
2826
+ }
2827
+
2828
+ /**
2829
+ * Subroutine prn2lb
2830
+ *
2831
+ * This subroutine prints out new information after a successful
2832
+ * line search.
2833
+ *
2834
+ * * * *
2835
+ *
2836
+ * NEOS, November 1994. (Latest revision June 1996.)
2837
+ * Optimization Technology Center.
2838
+ * Argonne National Laboratory and Northwestern University.
2839
+ * Written by
2840
+ * Ciyou Zhu
2841
+ * in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
2842
+ */
2843
+ int prn2lb_(long *n, double *x, double *f,
2844
+ double *g, long *iprint, long *itfile, long *iter,
2845
+ long *nfgv, long *nact, double *sbgnrm, long *nseg, char*word,
2846
+ long *iword, long *iback, double *stp, double *xstep)
2847
+ {
2848
+ long i__1;
2849
+ static long i__, imod;
2850
+ FILE *itfptr;
2851
+ --g;
2852
+ --x;
2853
+
2854
+ /* 'word' records the status of subspace solutions. */
2855
+ if (*iword == 0) {
2856
+ /* the subspace minimization converged. */
2857
+ strcpy(word, "con");
2858
+ } else if (*iword == 1) {
2859
+ /* the subspace minimization stopped at a bound. */
2860
+ strcpy(word, "bnd");
2861
+ } else if (*iword == 5) {
2862
+ /* the truncated Newton step has been used. */
2863
+ strcpy(word, "TNT");
2864
+ } else {
2865
+ strcpy(word, "---");
2866
+ }
2867
+ if (*iprint >= 99) {
2868
+ fprintf(stdout, "LINE SEARCH %ld times; norm of step = %E\n", *iback, *xstep);
2869
+ fprintf(stdout, "\nAt iterate%5ld f= %12.5E |proj g|= %12.5E\n", *iter, *f, *sbgnrm);
2870
+
2871
+ if (*iprint > 100) {
2872
+ fprintf(stdout, "X =");
2873
+ i__1 = *n;
2874
+ for (i__ = 1; i__ <= i__1; ++i__) {
2875
+ fprintf(stdout, "%11.4E ", x[i__]);
2876
+ }
2877
+ fprintf(stdout, "\n");
2878
+ fprintf(stdout, "G =");
2879
+ i__1 = *n;
2880
+ for (i__ = 1; i__ <= i__1; ++i__) {
2881
+ fprintf(stdout, "%11.4E ", g[i__]);
2882
+ }
2883
+ fprintf(stdout, "\n");
2884
+ }
2885
+ } else if (*iprint > 0) {
2886
+ imod = *iter % *iprint;
2887
+ if (imod == 0) {
2888
+ fprintf(stdout, "\nAt iterate%5ld f= %12.5E |proj g|= %12.5E\n", *iter, *f, *sbgnrm);
2889
+ }
2890
+ }
2891
+ if (*iprint >= 1) {
2892
+ itfptr = fopen("iterate.dat", "a");
2893
+ fprintf(itfptr, " %4ld %4ld %5ld %5ld %3s %4ld %7.1E %7.1E %10.3E %10.3E\n",
2894
+ *iter, *nfgv, *nseg, *nact, word, *iback, *stp, *xstep, *sbgnrm, *f);
2895
+ fclose(itfptr);
2896
+ }
2897
+ return 0;
2898
+ }
2899
+
2900
+ /**
2901
+ * Subroutine prn3lb
2902
+ *
2903
+ * This subroutine prints out information when either a built-in
2904
+ * convergence test is satisfied or when an error message is
2905
+ * generated.
2906
+ *
2907
+ * * * *
2908
+ *
2909
+ * NEOS, November 1994. (Latest revision June 1996.)
2910
+ * Optimization Technology Center.
2911
+ * Argonne National Laboratory and Northwestern University.
2912
+ * Written by
2913
+ * Ciyou Zhu
2914
+ * in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
2915
+ */
2916
+ int prn3lb_(long *n, double *x, double *f, char *task,
2917
+ long *iprint, long *info, long *itfile, long *iter,
2918
+ long *nfgv, long *nintol, long *nskip, long *nact,
2919
+ double *sbgnrm, double *time, long *nseg, char *word,
2920
+ long *iback, double *stp, double *xstep, long *k,
2921
+ double *cachyt, double *sbtime, double *lnscht)
2922
+ {
2923
+ long i__1;
2924
+ FILE *itfptr;
2925
+ static long i__;
2926
+
2927
+ --x;
2928
+
2929
+ if (strncmp(task, "ERROR", 5) == 0) {
2930
+ goto L999;
2931
+ }
2932
+ if (*iprint >= 0) {
2933
+ fprintf(stdout, "\n");
2934
+ fprintf(stdout, " * * *\n");
2935
+ fprintf(stdout, "\n");
2936
+ fprintf(stdout, "Tit = total number of iterations\n");
2937
+ fprintf(stdout, "Tnf = total number of function evaluations\n");
2938
+ fprintf(stdout, "Tnint = total number of segments explored during Cauchy searches\n");
2939
+ fprintf(stdout, "Skip = number of BFGS updates skipped\n");
2940
+ fprintf(stdout, "Nact = number of active bounds at final generalized Cauchy point\n");
2941
+ fprintf(stdout, "Projg = norm of the final projected gradient\n");
2942
+ fprintf(stdout, "F = final function value\n");
2943
+ fprintf(stdout, "\n");
2944
+ fprintf(stdout, " * * *\n");
2945
+ fprintf(stdout, "\n");
2946
+ fprintf(stdout, " N Tit Tnf Tnint Skip Nact Projg F\n");
2947
+ fprintf(stdout, "%5ld %6ld %6ld %6ld %5ld %5ld %10.3E %10.3E\n", *n, *iter, *nfgv, *nintol, *nskip, *nact, *sbgnrm, *f);
2948
+ if (*iprint >= 100) {
2949
+ fprintf(stdout, "\n");
2950
+ fprintf(stdout, " X =");
2951
+ i__1 = *n;
2952
+ for (i__ = 1; i__ <= i__1; ++i__) {
2953
+ fprintf(stdout, " %11.4E", x[i__]);
2954
+ if (i__ % 6 == 0) {
2955
+ fprintf(stdout, "\n");
2956
+ fprintf(stdout, " ");
2957
+ }
2958
+ }
2959
+ fprintf(stdout, "\n");
2960
+ }
2961
+ if (*iprint >= 1) {
2962
+ fprintf(stdout, " F = %3.8E\n", *f);
2963
+ }
2964
+ }
2965
+ L999:
2966
+ if (*iprint >= 0) {
2967
+ fprintf(stdout, "\n");
2968
+ fprintf(stdout, "%s\n", task);
2969
+ if (*info != 0) {
2970
+ if (*info == -1) {
2971
+ fprintf(stdout, "\n");
2972
+ fprintf(stdout, " Matrix in 1st Cholesky factorization in formk is not Pos. Def.\n");
2973
+ }
2974
+ if (*info == -2) {
2975
+ fprintf(stdout, "\n");
2976
+ fprintf(stdout, " Matrix in 2st Cholesky factorization in formk is not Pos. Def.\n");
2977
+ }
2978
+ if (*info == -3) {
2979
+ fprintf(stdout, "\n");
2980
+ fprintf(stdout, " Matrix in the Cholesky factorization in formt is not Pos. Def.\n");
2981
+ }
2982
+ if (*info == -4) {
2983
+ fprintf(stdout, "\n");
2984
+ fprintf(stdout, " Derivative >= 0, backtracking line search impossible.\n");
2985
+ fprintf(stdout, " Previous x, f and g restored.\n");
2986
+ fprintf(stdout, " Possible causes: 1 error in function or gradient evaluation;\n");
2987
+ fprintf(stdout, " 2 rounding errors dominate computation.\n");
2988
+ }
2989
+ if (*info == -5) {
2990
+ fprintf(stdout, "\n");
2991
+ fprintf(stdout, " Warning: more than 10 function and gradient\n");
2992
+ fprintf(stdout, " evaluations in the last line search. Termination\n");
2993
+ fprintf(stdout, " may possibly be caused by a bad search direction.\n");
2994
+ }
2995
+ if (*info == -6) {
2996
+ fprintf(stdout, " Input nbd(%2ld) is invalid.\n", *k);
2997
+ }
2998
+ if (*info == -7) {
2999
+ fprintf(stdout, " l(%2ld) > u(%2ld). No feasible solution.\n", *k, *k);
3000
+ }
3001
+ if (*info == -8) {
3002
+ fprintf(stdout, "\n");
3003
+ fprintf(stdout, " The triangular system is singular.\n");
3004
+ }
3005
+ if (*info == -9) {
3006
+ fprintf(stdout, "\n");
3007
+ fprintf(stdout, " Line search cannot locate an adequate point after 20 function\n");
3008
+ fprintf(stdout, " and gradient evaluations. Previous x, f and g restored.\n");
3009
+ fprintf(stdout, " Possible causes: 1 error in function or gradient evaluation;\n");
3010
+ fprintf(stdout, " 2 rounding error dominate computation.\n");
3011
+ }
3012
+ }
3013
+ if (*iprint >= 1) {
3014
+ fprintf(stdout, "\n");
3015
+ fprintf(stdout, " Cauchy time %1.3E seconds.\n", *cachyt);
3016
+ fprintf(stdout, " Subspace minimization time %1.3E seconds.\n", *sbtime);
3017
+ fprintf(stdout, " Line search time %1.3E seconds.\n", *lnscht);
3018
+ }
3019
+ fprintf(stdout, "\n");
3020
+ fprintf(stdout, " Total User time %1.3E seconds.\n", *time);
3021
+ fprintf(stdout, "\n");
3022
+
3023
+ if (*iprint >= 1) {
3024
+ itfptr = fopen("iterate.dat", "a");
3025
+ if (*info == -4 || *info == -9) {
3026
+ fprintf(itfptr, " %4ld %4ld %5ld %5ld %3s %4ld %7.1E %7.1E - -\n",
3027
+ *iter, *nfgv, *nseg, *nact, word, *iback, *stp, *xstep);
3028
+ }
3029
+ fprintf(itfptr, "\n");
3030
+ fprintf(itfptr, "%s\n", task);
3031
+ if (*info != 0) {
3032
+ if (*info == -1) {
3033
+ fprintf(itfptr, "\n");
3034
+ fprintf(itfptr, " Matrix in 1st Cholesky factorization in formk is not Pos. Def.\n");
3035
+ }
3036
+ if (*info == -2) {
3037
+ fprintf(itfptr, "\n");
3038
+ fprintf(itfptr, " Matrix in 2st Cholesky factorization in formk is not Pos. Def.\n");
3039
+ }
3040
+ if (*info == -3) {
3041
+ fprintf(itfptr, "\n");
3042
+ fprintf(itfptr, " Matrix in the Cholesky factorization in formt is not Pos. Def.\n");
3043
+ }
3044
+ if (*info == -4) {
3045
+ fprintf(itfptr, "\n");
3046
+ fprintf(itfptr, " Derivative >= 0, backtracking line search impossible.\n");
3047
+ fprintf(itfptr, " Previous x, f and g restored.\n");
3048
+ fprintf(itfptr, " Possible causes: 1 error in function or gradient evaluation;\n");
3049
+ fprintf(itfptr, " 2 rounding errors dominate computation.\n");
3050
+ }
3051
+ if (*info == -5) {
3052
+ fprintf(itfptr, "\n");
3053
+ fprintf(itfptr, " Warning: more than 10 function and gradient\n");
3054
+ fprintf(itfptr, " evaluations in the last line search. Termination\n");
3055
+ fprintf(itfptr, " may possibly be caused by a bad search direction.\n");
3056
+ }
3057
+ if (*info == -8) {
3058
+ fprintf(itfptr, "\n");
3059
+ fprintf(itfptr, " The triangular system is singular.\n");
3060
+ }
3061
+ if (*info == -9) {
3062
+ fprintf(itfptr, "\n");
3063
+ fprintf(itfptr, " Line search cannot locate an adequate point after 20 function\n");
3064
+ fprintf(itfptr, " and gradient evaluations. Previous x, f and g restored.\n");
3065
+ fprintf(itfptr, " Possible causes: 1 error in function or gradient evaluation;\n");
3066
+ fprintf(itfptr, " 2 rounding error dominate computation.\n");
3067
+ }
3068
+ }
3069
+ fprintf(itfptr, "\n");
3070
+ fprintf(itfptr, " Total User time %1.3E seconds.\n", *time);
3071
+ fprintf(itfptr, "\n");
3072
+ fclose(itfptr);
3073
+ }
3074
+ }
3075
+ return 0;
3076
+ }
3077
+
3078
+ /**
3079
+ * Subroutine projgr
3080
+ *
3081
+ * This subroutine computes the infinity norm of the projected
3082
+ * gradient.
3083
+ *
3084
+ * * * *
3085
+ *
3086
+ * NEOS, November 1994. (Latest revision June 1996.)
3087
+ * Optimization Technology Center.
3088
+ * Argonne National Laboratory and Northwestern University.
3089
+ * Written by
3090
+ * Ciyou Zhu
3091
+ * in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal.
3092
+ */
3093
+ int projgr_(long *n, double *l, double *u,
3094
+ long *nbd, double *x, double *g, double *sbgnrm)
3095
+ {
3096
+ long i__1;
3097
+ double d__1, d__2;
3098
+ static long i__;
3099
+ static double gi;
3100
+
3101
+ --g;
3102
+ --x;
3103
+ --nbd;
3104
+ --u;
3105
+ --l;
3106
+
3107
+ *sbgnrm = 0.;
3108
+ i__1 = *n;
3109
+ for (i__ = 1; i__ <= i__1; ++i__) {
3110
+ gi = g[i__];
3111
+ if (nbd[i__] != 0) {
3112
+ if (gi < 0.) {
3113
+ if (nbd[i__] >= 2) {
3114
+ d__1 = x[i__] - u[i__];
3115
+ gi = d__1 >= gi ? d__1 : gi;
3116
+ }
3117
+ } else {
3118
+ if (nbd[i__] <= 2) {
3119
+ d__1 = x[i__] - l[i__];
3120
+ gi = d__1 <= gi ? d__1 : gi;
3121
+ }
3122
+ }
3123
+ }
3124
+ d__1 = *sbgnrm, d__2 = fabs(gi);
3125
+ *sbgnrm = d__1 >= d__2 ? d__1 : d__2;
3126
+ }
3127
+ return 0;
3128
+ }
3129
+
3130
+ /* **********************************************************************
3131
+ *
3132
+ * This routine contains the major changes in the updated version.
3133
+ * The changes are described in the accompanying paper
3134
+ *
3135
+ * Jose Luis Morales, Jorge Nocedal
3136
+ * "Remark On Algorithm 788: L-BFGS-B: Fortran Subroutines for Large-Scale
3137
+ * Bound Constrained Optimization". Decemmber 27, 2010.
3138
+ *
3139
+ * J.L. Morales Departamento de Matematicas,
3140
+ * Instituto Tecnologico Autonomo de Mexico
3141
+ * Mexico D.F.
3142
+ *
3143
+ * J, Nocedal Department of Electrical Engineering and
3144
+ * Computer Science.
3145
+ * Northwestern University. Evanston, IL. USA
3146
+ *
3147
+ * January 17, 2011
3148
+ *
3149
+ * ********************************************************************** */
3150
+ /**
3151
+ * Subroutine subsm
3152
+ *
3153
+ * Given xcp, l, u, r, an index set that specifies
3154
+ * the active set at xcp, and an l-BFGS matrix B
3155
+ * (in terms of WY, WS, SY, WT, head, col, and theta),
3156
+ * this subroutine computes an approximate solution
3157
+ * of the subspace problem
3158
+ *
3159
+ * (P) min Q(x) = r'(x-xcp) + 1/2 (x-xcp)' B (x-xcp)
3160
+ *
3161
+ * subject to l<=x<=u
3162
+ * x_i=xcp_i for all i in A(xcp)
3163
+ *
3164
+ * along the subspace unconstrained Newton direction
3165
+ *
3166
+ * d = -(Z'BZ)^(-1) r.
3167
+ *
3168
+ * The formula for the Newton direction, given the L-BFGS matrix
3169
+ * and the Sherman-Morrison formula, is
3170
+ *
3171
+ * d = (1/theta)r + (1/theta*2) Z'WK^(-1)W'Z r.
3172
+ *
3173
+ * where
3174
+ * K = [-D -Y'ZZ'Y/theta L_a'-R_z' ]
3175
+ * [L_a -R_z theta*S'AA'S ]
3176
+ *
3177
+ * Note that this procedure for computing d differs
3178
+ * from that described in [1]. One can show that the matrix K is
3179
+ * equal to the matrix M^[-1]N in that paper.
3180
+ *
3181
+ * n is an long variable.
3182
+ * On entry n is the dimension of the problem.
3183
+ * On exit n is unchanged.
3184
+ *
3185
+ * m is an long variable.
3186
+ * On entry m is the maximum number of variable metric corrections
3187
+ * used to define the limited memory matrix.
3188
+ * On exit m is unchanged.
3189
+ *
3190
+ * nsub is an long variable.
3191
+ * On entry nsub is the number of free variables.
3192
+ * On exit nsub is unchanged.
3193
+ *
3194
+ * ind is an long array of dimension nsub.
3195
+ * On entry ind specifies the coordinate indices of free variables.
3196
+ * On exit ind is unchanged.
3197
+ *
3198
+ * l is a double precision array of dimension n.
3199
+ * On entry l is the lower bound of x.
3200
+ * On exit l is unchanged.
3201
+ *
3202
+ * u is a double precision array of dimension n.
3203
+ * On entry u is the upper bound of x.
3204
+ * On exit u is unchanged.
3205
+ *
3206
+ * nbd is a long array of dimension n.
3207
+ * On entry nbd represents the type of bounds imposed on the
3208
+ * variables, and must be specified as follows:
3209
+ * nbd(i)=0 if x(i) is unbounded,
3210
+ * 1 if x(i) has only a lower bound,
3211
+ * 2 if x(i) has both lower and upper bounds, and
3212
+ * 3 if x(i) has only an upper bound.
3213
+ * On exit nbd is unchanged.
3214
+ *
3215
+ * x is a double precision array of dimension n.
3216
+ * On entry x specifies the Cauchy point xcp.
3217
+ * On exit x(i) is the minimizer of Q over the subspace of
3218
+ * free variables.
3219
+ *
3220
+ * d is a double precision array of dimension n.
3221
+ * On entry d is the reduced gradient of Q at xcp.
3222
+ * On exit d is the Newton direction of Q.
3223
+ *
3224
+ * xp is a double precision array of dimension n.
3225
+ * used to safeguard the projected Newton direction
3226
+ *
3227
+ * xx is a double precision array of dimension n
3228
+ * On entry it holds the current iterate
3229
+ * On output it is unchanged
3230
+ * gg is a double precision array of dimension n
3231
+ * On entry it holds the gradient at the current iterate
3232
+ * On output it is unchanged
3233
+ *
3234
+ * ws and wy are double precision arrays;
3235
+ * theta is a double precision variable;
3236
+ * col is an long variable;
3237
+ * head is an long variable.
3238
+ * On entry they store the information defining the
3239
+ * limited memory BFGS matrix:
3240
+ * ws(n,m) stores S, a set of s-vectors;
3241
+ * wy(n,m) stores Y, a set of y-vectors;
3242
+ * theta is the scaling factor specifying B_0 = theta I;
3243
+ * col is the number of variable metric corrections stored;
3244
+ * head is the location of the 1st s- (or y-) vector in S (or Y).
3245
+ * On exit they are unchanged.
3246
+ *
3247
+ * iword is an long variable.
3248
+ * On entry iword is unspecified.
3249
+ * On exit iword specifies the status of the subspace solution.
3250
+ * iword = 0 if the solution is in the box,
3251
+ * 1 if some bound is encountered.
3252
+ *
3253
+ * wv is a double precision working array of dimension 2m.
3254
+ *
3255
+ * wn is a double precision array of dimension 2m x 2m.
3256
+ * On entry the upper triangle of wn stores the LEL^T factorization
3257
+ * of the indefinite matrix
3258
+ *
3259
+ * K = [-D -Y'ZZ'Y/theta L_a'-R_z' ]
3260
+ * [L_a -R_z theta*S'AA'S ]
3261
+ * where E = [-I 0]
3262
+ * [ 0 I]
3263
+ * On exit wn is unchanged.
3264
+ *
3265
+ * iprint is an long variable that must be set by the user.
3266
+ * It controls the frequency and type of output generated:
3267
+ * iprint<0 no output is generated;
3268
+ * iprint=0 print only one line at the last iteration;
3269
+ * 0<iprint<99 print also f and |proj g| every iprint iterations;
3270
+ * iprint=99 print details of every iteration except n-vectors;
3271
+ * iprint=100 print also the changes of active set and final x;
3272
+ * iprint>100 print details of every iteration including x and g;
3273
+ * When iprint > 0, the file iterate.dat will be created to
3274
+ * summarize the iteration.
3275
+ *
3276
+ * info is an long variable.
3277
+ * On entry info is unspecified.
3278
+ * On exit info = 0 for normal return,
3279
+ * = nonzero for abnormal return
3280
+ * when the matrix K is ill-conditioned.
3281
+ *
3282
+ * Subprograms called:
3283
+ *
3284
+ * Linpack dtrsl.
3285
+ *
3286
+ *
3287
+ * References:
3288
+ *
3289
+ * [1] R. H. Byrd, P. Lu, J. Nocedal and C. Zhu, ``A limited
3290
+ * memory algorithm for bound constrained optimization'',
3291
+ * SIAM J. Scientific Computing 16 (1995), no. 5, pp. 1190--1208.
3292
+ *
3293
+ * * * *
3294
+ *
3295
+ * NEOS, November 1994. (Latest revision June 1996.)
3296
+ * Optimization Technology Center.
3297
+ * Argonne National Laboratory and Northwestern University.
3298
+ * Written by
3299
+ * Ciyou Zhu
3300
+ * in collaboration with R.H. Byrd, P. Lu-Chen and J. Nocedal
3301
+ */
3302
+ int subsm_(long *n, long *m, long *nsub, long *ind,
3303
+ double *l, double *u, long *nbd, double *x,
3304
+ double *d__, double *xp, double *ws, double *wy,
3305
+ double *theta, double *xx, double *gg, long *col,
3306
+ long *head, long *iword, double *wv, double *wn,
3307
+ long *iprint, long *info)
3308
+ {
3309
+ long ws_dim1, ws_offset, wy_dim1, wy_offset, wn_dim1, wn_offset, i__1, i__2;
3310
+ double d__1, d__2;
3311
+ static long i__, j, k, m2;
3312
+ static double dk;
3313
+ static long js, jy;
3314
+ static double xk;
3315
+ static long ibd, col2;
3316
+ static double dd_p__, temp1, temp2, alpha;
3317
+ static long pointr;
3318
+
3319
+ --gg;
3320
+ --xx;
3321
+ --xp;
3322
+ --d__;
3323
+ --x;
3324
+ --nbd;
3325
+ --u;
3326
+ --l;
3327
+ wn_dim1 = 2 * *m;
3328
+ wn_offset = 1 + wn_dim1;
3329
+ wn -= wn_offset;
3330
+ --wv;
3331
+ wy_dim1 = *n;
3332
+ wy_offset = 1 + wy_dim1;
3333
+ wy -= wy_offset;
3334
+ ws_dim1 = *n;
3335
+ ws_offset = 1 + ws_dim1;
3336
+ ws -= ws_offset;
3337
+ --ind;
3338
+
3339
+ if (*nsub <= 0) {
3340
+ return 0;
3341
+ }
3342
+ if (*iprint >= 99) {
3343
+ fprintf(stdout, "\n----------------SUBSM entered-----------------\n\n");
3344
+ }
3345
+ /* Compute wv = W'Zd. */
3346
+ pointr = *head;
3347
+ i__1 = *col;
3348
+ for (i__ = 1; i__ <= i__1; ++i__) {
3349
+ temp1 = 0.;
3350
+ temp2 = 0.;
3351
+ i__2 = *nsub;
3352
+ for (j = 1; j <= i__2; ++j) {
3353
+ k = ind[j];
3354
+ temp1 += wy[k + pointr * wy_dim1] * d__[j];
3355
+ temp2 += ws[k + pointr * ws_dim1] * d__[j];
3356
+ }
3357
+ wv[i__] = temp1;
3358
+ wv[*col + i__] = *theta * temp2;
3359
+ pointr = pointr % *m + 1;
3360
+ }
3361
+ /* Compute wv:=K^(-1)wv. */
3362
+ m2 = *m << 1;
3363
+ col2 = *col << 1;
3364
+ dtrsl_(&wn[wn_offset], &m2, &col2, &wv[1], &c__11, info);
3365
+ if (*info != 0) {
3366
+ return 0;
3367
+ }
3368
+ i__1 = *col;
3369
+ for (i__ = 1; i__ <= i__1; ++i__) {
3370
+ wv[i__] = -wv[i__];
3371
+ }
3372
+ dtrsl_(&wn[wn_offset], &m2, &col2, &wv[1], &c__1, info);
3373
+ if (*info != 0) {
3374
+ return 0;
3375
+ }
3376
+ /* Compute d = (1/theta)d + (1/theta**2)Z'W wv. */
3377
+ pointr = *head;
3378
+ i__1 = *col;
3379
+ for (jy = 1; jy <= i__1; ++jy) {
3380
+ js = *col + jy;
3381
+ i__2 = *nsub;
3382
+ for (i__ = 1; i__ <= i__2; ++i__) {
3383
+ k = ind[i__];
3384
+ d__[i__] = d__[i__] + wy[k + pointr * wy_dim1] * wv[jy] / *theta
3385
+ + ws[k + pointr * ws_dim1] * wv[js];
3386
+ }
3387
+ pointr = pointr % *m + 1;
3388
+ }
3389
+ d__1 = 1. / *theta;
3390
+ dscal_(nsub, &d__1, &d__[1], &c__1);
3391
+
3392
+ /* ----------------------------------------------------------------- */
3393
+ /* Let us try the projection, d is the Newton direction */
3394
+ *iword = 0;
3395
+ dcopy_(n, &x[1], &c__1, &xp[1], &c__1);
3396
+
3397
+ i__1 = *nsub;
3398
+ for (i__ = 1; i__ <= i__1; ++i__) {
3399
+ k = ind[i__];
3400
+ dk = d__[i__];
3401
+ xk = x[k];
3402
+ if (nbd[k] != 0) {
3403
+ if (nbd[k] == 1) {
3404
+ /* lower bounds only */
3405
+ d__1 = l[k], d__2 = xk + dk;
3406
+ x[k] = d__1 >= d__2 ? d__1 : d__2;
3407
+ if (x[k] == l[k]) {
3408
+ *iword = 1;
3409
+ }
3410
+ } else {
3411
+ if (nbd[k] == 2) {
3412
+ /* upper and lower bounds */
3413
+ d__1 = l[k], d__2 = xk + dk;
3414
+ xk = d__1 >= d__2 ? d__1 : d__2;
3415
+ d__1 = u[k];
3416
+ x[k] = d__1 <= xk ? d__1 : xk;
3417
+ if (x[k] == l[k] || x[k] == u[k]) {
3418
+ *iword = 1;
3419
+ }
3420
+ } else {
3421
+ if (nbd[k] == 3) {
3422
+ /* upper bounds only */
3423
+ d__1 = u[k], d__2 = xk + dk;
3424
+ x[k] = d__1 <= d__2 ? d__1 : d__2;
3425
+ if (x[k] == u[k]) {
3426
+ *iword = 1;
3427
+ }
3428
+ }
3429
+ }
3430
+ }
3431
+ } else {
3432
+ /* free variables */
3433
+ x[k] = xk + dk;
3434
+ }
3435
+ }
3436
+
3437
+ if (*iword == 0) {
3438
+ goto L911;
3439
+ }
3440
+
3441
+ /* check sign of the directional derivative */
3442
+ dd_p__ = 0.;
3443
+ i__1 = *n;
3444
+ for (i__ = 1; i__ <= i__1; ++i__) {
3445
+ dd_p__ += (x[i__] - xx[i__]) * gg[i__];
3446
+ }
3447
+ if (dd_p__ > 0.) {
3448
+ dcopy_(n, &xp[1], &c__1, &x[1], &c__1);
3449
+ fprintf(stderr, " Positive dir derivative in projection\n");
3450
+ fprintf(stderr, " Using the backtracking step\n");
3451
+ } else {
3452
+ goto L911;
3453
+ }
3454
+
3455
+ /* ----------------------------------------------------------------- */
3456
+
3457
+ alpha = 1.;
3458
+ temp1 = alpha;
3459
+ ibd = 0;
3460
+ i__1 = *nsub;
3461
+ for (i__ = 1; i__ <= i__1; ++i__) {
3462
+ k = ind[i__];
3463
+ dk = d__[i__];
3464
+ if (nbd[k] != 0) {
3465
+ if (dk < 0. && nbd[k] <= 2) {
3466
+ temp2 = l[k] - x[k];
3467
+ if (temp2 >= 0.) {
3468
+ temp1 = 0.;
3469
+ } else if (dk * alpha < temp2) {
3470
+ temp1 = temp2 / dk;
3471
+ }
3472
+ } else if (dk > 0. && nbd[k] >= 2) {
3473
+ temp2 = u[k] - x[k];
3474
+ if (temp2 <= 0.) {
3475
+ temp1 = 0.;
3476
+ } else if (dk * alpha > temp2) {
3477
+ temp1 = temp2 / dk;
3478
+ }
3479
+ }
3480
+ if (temp1 < alpha) {
3481
+ alpha = temp1;
3482
+ ibd = i__;
3483
+ }
3484
+ }
3485
+ }
3486
+ if (alpha < 1.) {
3487
+ dk = d__[ibd];
3488
+ k = ind[ibd];
3489
+ if (dk > 0.) {
3490
+ x[k] = u[k];
3491
+ d__[ibd] = 0.;
3492
+ } else if (dk < 0.) {
3493
+ x[k] = l[k];
3494
+ d__[ibd] = 0.;
3495
+ }
3496
+ }
3497
+ i__1 = *nsub;
3498
+ for (i__ = 1; i__ <= i__1; ++i__) {
3499
+ k = ind[i__];
3500
+ x[k] += alpha * d__[i__];
3501
+ }
3502
+ /* ccccc */
3503
+ L911:
3504
+ if (*iprint >= 99) {
3505
+ fprintf(stdout, "\n----------------exit SUBSM --------------------\n\n");
3506
+ }
3507
+ return 0;
3508
+ }
3509
+
3510
+ /**
3511
+ * Subroutine dcsrch
3512
+ *
3513
+ * This subroutine finds a step that satisfies a sufficient
3514
+ * decrease condition and a curvature condition.
3515
+ *
3516
+ * Each call of the subroutine updates an interval with
3517
+ * endpoints stx and sty. The interval is initially chosen
3518
+ * so that it contains a minimizer of the modified function
3519
+ *
3520
+ * psi(stp) = f(stp) - f(0) - ftol*stp*f'(0).
3521
+ *
3522
+ * If psi(stp) <= 0 and f'(stp) >= 0 for some step, then the
3523
+ * interval is chosen so that it contains a minimizer of f.
3524
+ *
3525
+ * The algorithm is designed to find a step that satisfies
3526
+ * the sufficient decrease condition
3527
+ *
3528
+ * f(stp) <= f(0) + ftol*stp*f'(0),
3529
+ *
3530
+ * and the curvature condition
3531
+ *
3532
+ * abs(f'(stp)) <= gtol*abs(f'(0)).
3533
+ *
3534
+ * If ftol is less than gtol and if, for example, the function
3535
+ * is bounded below, then there is always a step which satisfies
3536
+ * both conditions.
3537
+ *
3538
+ * If no step can be found that satisfies both conditions, then
3539
+ * the algorithm stops with a warning. In this case stp only
3540
+ * satisfies the sufficient decrease condition.
3541
+ *
3542
+ * A typical invocation of dcsrch has the following outline:
3543
+ *
3544
+ * task = 'START'
3545
+ * 10 continue
3546
+ * call dcsrch( ... )
3547
+ * if (task .eq. 'FG') then
3548
+ * Evaluate the function and the gradient at stp
3549
+ * goto 10
3550
+ * end if
3551
+ *
3552
+ * NOTE: The user must no alter work arrays between calls.
3553
+ *
3554
+ * The subroutine statement is
3555
+ *
3556
+ * subroutine dcsrch(f,g,stp,ftol,gtol,xtol,stpmin,stpmax,
3557
+ * task,isave,dsave)
3558
+ * where
3559
+ *
3560
+ * f is a double precision variable.
3561
+ * On initial entry f is the value of the function at 0.
3562
+ * On subsequent entries f is the value of the
3563
+ * function at stp.
3564
+ * On exit f is the value of the function at stp.
3565
+ *
3566
+ * g is a double precision variable.
3567
+ * On initial entry g is the derivative of the function at 0.
3568
+ * On subsequent entries g is the derivative of the
3569
+ * function at stp.
3570
+ * On exit g is the derivative of the function at stp.
3571
+ *
3572
+ * stp is a double precision variable.
3573
+ * On entry stp is the current estimate of a satisfactory
3574
+ * step. On initial entry, a positive initial estimate
3575
+ * must be provided.
3576
+ * On exit stp is the current estimate of a satisfactory step
3577
+ * if task = 'FG'. If task = 'CONV' then stp satisfies
3578
+ * the sufficient decrease and curvature condition.
3579
+ *
3580
+ * ftol is a double precision variable.
3581
+ * On entry ftol specifies a nonnegative tolerance for the
3582
+ * sufficient decrease condition.
3583
+ * On exit ftol is unchanged.
3584
+ *
3585
+ * gtol is a double precision variable.
3586
+ * On entry gtol specifies a nonnegative tolerance for the
3587
+ * curvature condition.
3588
+ * On exit gtol is unchanged.
3589
+ *
3590
+ * xtol is a double precision variable.
3591
+ * On entry xtol specifies a nonnegative relative tolerance
3592
+ * for an acceptable step. The subroutine exits with a
3593
+ * warning if the relative difference between sty and stx
3594
+ * is less than xtol.
3595
+ * On exit xtol is unchanged.
3596
+ *
3597
+ * stpmin is a double precision variable.
3598
+ * On entry stpmin is a nonnegative lower bound for the step.
3599
+ * On exit stpmin is unchanged.
3600
+ *
3601
+ * stpmax is a double precision variable.
3602
+ * On entry stpmax is a nonnegative upper bound for the step.
3603
+ * On exit stpmax is unchanged.
3604
+ *
3605
+ * task is a character variable of length at least 60.
3606
+ * On initial entry task must be set to 'START'.
3607
+ * On exit task indicates the required action:
3608
+ *
3609
+ * If task(1:2) = 'FG' then evaluate the function and
3610
+ * derivative at stp and call dcsrch again.
3611
+ *
3612
+ * If task(1:4) = 'CONV' then the search is successful.
3613
+ *
3614
+ * If task(1:4) = 'WARN' then the subroutine is not able
3615
+ * to satisfy the convergence conditions. The exit value of
3616
+ * stp contains the best point found during the search.
3617
+ *
3618
+ * If task(1:5) = 'ERROR' then there is an error in the
3619
+ * input arguments.
3620
+ *
3621
+ * On exit with convergence, a warning or an error, the
3622
+ * variable task contains additional information.
3623
+ *
3624
+ * isave is an long work array of dimension 2.
3625
+ *
3626
+ * dsave is a double precision work array of dimension 13.
3627
+ *
3628
+ * Subprograms called
3629
+ *
3630
+ * MINPACK-2 ... dcstep
3631
+ *
3632
+ * MINPACK-1 Project. June 1983.
3633
+ * Argonne National Laboratory.
3634
+ * Jorge J. More' and David J. Thuente.
3635
+ *
3636
+ * MINPACK-2 Project. October 1993.
3637
+ * Argonne National Laboratory and University of Minnesota.
3638
+ * Brett M. Averick, Richard G. Carter, and Jorge J. More'.
3639
+ */
3640
+ int dcsrch_(double *f, double *g, double *stp,
3641
+ double *ftol, double *gtol, double *xtol,
3642
+ double *stpmin, double *stpmax,
3643
+ char *task, long *isave, double *dsave)
3644
+ {
3645
+
3646
+ double d__1;
3647
+ static double fm, gm, fx, fy, gx, gy, fxm, fym, gxm, gym, stx, sty;
3648
+ static long stage;
3649
+ static double finit, ginit, width, ftest, gtest, stmin, stmax, width1;
3650
+ static long brackt;
3651
+
3652
+ --dsave;
3653
+ --isave;
3654
+
3655
+ if (strncmp(task, "START", 5) == 0) {
3656
+ /* Check the input arguments for errors. */
3657
+ if (*stp < *stpmin) {
3658
+ strcpy(task, "ERROR: STP .LT. STPMIN");
3659
+ }
3660
+ if (*stp > *stpmax) {
3661
+ strcpy(task, "ERROR: STP .GT. STPMAX");
3662
+ }
3663
+ if (*g >= 0.) {
3664
+ strcpy(task, "ERROR: INITIAL G .GE. ZERO");
3665
+ }
3666
+ if (*ftol < 0.) {
3667
+ strcpy(task, "ERROR: FTOL .LT. ZERO");
3668
+ }
3669
+ if (*gtol < 0.) {
3670
+ strcpy(task, "ERROR: GTOL .LT. ZERO");
3671
+ }
3672
+ if (*xtol < 0.) {
3673
+ strcpy(task, "ERROR: XTOL .LT. ZERO");
3674
+ }
3675
+ if (*stpmin < 0.) {
3676
+ strcpy(task, "ERROR: STPMIN .LT. ZERO");
3677
+ }
3678
+ if (*stpmax < *stpmin) {
3679
+ strcpy(task, "ERROR: STPMAX .LT. STPMIN");
3680
+ }
3681
+ /* Exit if there are errors on input. */
3682
+ if (strncmp(task, "ERROR", 5) == 0) {
3683
+ return 0;
3684
+ }
3685
+ /* Initialize local variables. */
3686
+ brackt = FALSE_;
3687
+ stage = 1;
3688
+ finit = *f;
3689
+ ginit = *g;
3690
+ gtest = *ftol * ginit;
3691
+ width = *stpmax - *stpmin;
3692
+ width1 = width / .5;
3693
+ /* The variables stx, fx, gx contain the values of the step, */
3694
+ /* function, and derivative at the best step. */
3695
+ /* The variables sty, fy, gy contain the value of the step, */
3696
+ /* function, and derivative at sty. */
3697
+ /* The variables stp, f, g contain the values of the step, */
3698
+ /* function, and derivative at stp. */
3699
+ stx = 0.;
3700
+ fx = finit;
3701
+ gx = ginit;
3702
+ sty = 0.;
3703
+ fy = finit;
3704
+ gy = ginit;
3705
+ stmin = 0.;
3706
+ stmax = *stp + *stp * 4.;
3707
+ strcpy(task, "FG");
3708
+ goto L1000;
3709
+ } else {
3710
+ /* Restore local variables. */
3711
+ if (isave[1] == 1) {
3712
+ brackt = TRUE_;
3713
+ } else {
3714
+ brackt = FALSE_;
3715
+ }
3716
+ stage = isave[2];
3717
+ ginit = dsave[1];
3718
+ gtest = dsave[2];
3719
+ gx = dsave[3];
3720
+ gy = dsave[4];
3721
+ finit = dsave[5];
3722
+ fx = dsave[6];
3723
+ fy = dsave[7];
3724
+ stx = dsave[8];
3725
+ sty = dsave[9];
3726
+ stmin = dsave[10];
3727
+ stmax = dsave[11];
3728
+ width = dsave[12];
3729
+ width1 = dsave[13];
3730
+ }
3731
+ /* If psi(stp) <= 0 and f'(stp) >= 0 for some step, then the */
3732
+ /* algorithm enters the second stage. */
3733
+ ftest = finit + *stp * gtest;
3734
+ if (stage == 1 && *f <= ftest && *g >= 0.) {
3735
+ stage = 2;
3736
+ }
3737
+ /* Test for warnings. */
3738
+ if (brackt && (*stp <= stmin || *stp >= stmax)) {
3739
+ strcpy(task, "WARNING: ROUNDING ERRORS PREVENT PROGRESS");
3740
+ }
3741
+ if (brackt && stmax - stmin <= *xtol * stmax) {
3742
+ strcpy(task, "WARNING: XTOL TEST SATISFIED");
3743
+ }
3744
+ if (*stp == *stpmax && *f <= ftest && *g <= gtest) {
3745
+ strcpy(task, "WARNING: STP = STPMAX");
3746
+ }
3747
+ if (*stp == *stpmin && (*f > ftest || *g >= gtest)) {
3748
+ strcpy(task, "WARNING: STP = STPMIN");
3749
+ }
3750
+ /* Test for convergence. */
3751
+ if (*f <= ftest && fabs(*g) <= *gtol * (-ginit)) {
3752
+ strcpy(task, "CONVERGENCE");
3753
+ }
3754
+ /* Test for termination. */
3755
+ if (strncmp(task, "WARN", 4) == 0 || strncmp(task, "CONV", 4) == 0) {
3756
+ goto L1000;
3757
+ }
3758
+ /* A modified function is used to predict the step during the */
3759
+ /* first stage if a lower function value has been obtained but */
3760
+ /* the decrease is not sufficient. */
3761
+ if (stage == 1 && *f <= fx && *f > ftest) {
3762
+ /* Define the modified function and derivative values. */
3763
+ fm = *f - *stp * gtest;
3764
+ fxm = fx - stx * gtest;
3765
+ fym = fy - sty * gtest;
3766
+ gm = *g - gtest;
3767
+ gxm = gx - gtest;
3768
+ gym = gy - gtest;
3769
+ /* Call dcstep to update stx, sty, and to compute the new step. */
3770
+ dcstep_(&stx, &fxm, &gxm, &sty, &fym, &gym, stp, &fm, &gm, &brackt, &stmin, &stmax);
3771
+ /* Reset the function and derivative values for f. */
3772
+ fx = fxm + stx * gtest;
3773
+ fy = fym + sty * gtest;
3774
+ gx = gxm + gtest;
3775
+ gy = gym + gtest;
3776
+ } else {
3777
+ /* Call dcstep to update stx, sty, and to compute the new step. */
3778
+ dcstep_(&stx, &fx, &gx, &sty, &fy, &gy, stp, f, g, &brackt, &stmin, &stmax);
3779
+ }
3780
+ /* Decide if a bisection step is needed. */
3781
+ if (brackt) {
3782
+ if ((d__1 = sty - stx, fabs(d__1)) >= width1 * .66) {
3783
+ *stp = stx + (sty - stx) * .5;
3784
+ }
3785
+ width1 = width;
3786
+ width = (d__1 = sty - stx, fabs(d__1));
3787
+ }
3788
+ /* Set the minimum and maximum steps allowed for stp. */
3789
+ if (brackt) {
3790
+ stmin = stx <= sty ? stx : sty;
3791
+ stmax = stx >= sty ? stx : sty;
3792
+ } else {
3793
+ stmin = *stp + (*stp - stx) * 1.1;
3794
+ stmax = *stp + (*stp - stx) * 4.;
3795
+ }
3796
+ /* Force the step to be within the bounds stpmax and stpmin. */
3797
+ *stp = *stp >= *stpmin ? *stp : *stpmin;
3798
+ *stp = *stp <= *stpmax ? *stp : *stpmax;
3799
+ /* If further progress is not possible, let stp be the best */
3800
+ /* point obtained during the search. */
3801
+ if ((brackt && (*stp <= stmin || *stp >= stmax)) || (brackt && (stmax - stmin <= *xtol * stmax))) {
3802
+ *stp = stx;
3803
+ }
3804
+ /* Obtain another function and derivative. */
3805
+ strcpy(task, "FG");
3806
+ L1000:
3807
+ /* Save local variables. */
3808
+ if (brackt) {
3809
+ isave[1] = 1;
3810
+ } else {
3811
+ isave[1] = 0;
3812
+ }
3813
+ isave[2] = stage;
3814
+ dsave[1] = ginit;
3815
+ dsave[2] = gtest;
3816
+ dsave[3] = gx;
3817
+ dsave[4] = gy;
3818
+ dsave[5] = finit;
3819
+ dsave[6] = fx;
3820
+ dsave[7] = fy;
3821
+ dsave[8] = stx;
3822
+ dsave[9] = sty;
3823
+ dsave[10] = stmin;
3824
+ dsave[11] = stmax;
3825
+ dsave[12] = width;
3826
+ dsave[13] = width1;
3827
+ return 0;
3828
+ }
3829
+
3830
+ /**
3831
+ * Subroutine dcstep
3832
+ *
3833
+ * This subroutine computes a safeguarded step for a search
3834
+ * procedure and updates an interval that contains a step that
3835
+ * satisfies a sufficient decrease and a curvature condition.
3836
+ *
3837
+ * The parameter stx contains the step with the least function
3838
+ * value. If brackt is set to .true. then a minimizer has
3839
+ * been bracketed in an interval with endpoints stx and sty.
3840
+ * The parameter stp contains the current step.
3841
+ * The subroutine assumes that if brackt is set to .true. then
3842
+ *
3843
+ * min(stx,sty) < stp < max(stx,sty),
3844
+ *
3845
+ * and that the derivative at stx is negative in the direction
3846
+ * of the step.
3847
+ *
3848
+ * The subroutine statement is
3849
+ *
3850
+ * subroutine dcstep(stx,fx,dx,sty,fy,dy,stp,fp,dp,brackt,
3851
+ * stpmin,stpmax)
3852
+ *
3853
+ * where
3854
+ *
3855
+ * stx is a double precision variable.
3856
+ * On entry stx is the best step obtained so far and is an
3857
+ * endpoint of the interval that contains the minimizer.
3858
+ * On exit stx is the updated best step.
3859
+ *
3860
+ * fx is a double precision variable.
3861
+ * On entry fx is the function at stx.
3862
+ * On exit fx is the function at stx.
3863
+ *
3864
+ * dx is a double precision variable.
3865
+ * On entry dx is the derivative of the function at
3866
+ * stx. The derivative must be negative in the direction of
3867
+ * the step, that is, dx and stp - stx must have opposite
3868
+ * signs.
3869
+ * On exit dx is the derivative of the function at stx.
3870
+ *
3871
+ * sty is a double precision variable.
3872
+ * On entry sty is the second endpoint of the interval that
3873
+ * contains the minimizer.
3874
+ * On exit sty is the updated endpoint of the interval that
3875
+ * contains the minimizer.
3876
+ *
3877
+ * fy is a double precision variable.
3878
+ * On entry fy is the function at sty.
3879
+ * On exit fy is the function at sty.
3880
+ *
3881
+ * dy is a double precision variable.
3882
+ * On entry dy is the derivative of the function at sty.
3883
+ * On exit dy is the derivative of the function at the exit sty.
3884
+ *
3885
+ * stp is a double precision variable.
3886
+ * On entry stp is the current step. If brackt is set to .true.
3887
+ * then on input stp must be between stx and sty.
3888
+ * On exit stp is a new trial step.
3889
+ *
3890
+ * fp is a double precision variable.
3891
+ * On entry fp is the function at stp
3892
+ * On exit fp is unchanged.
3893
+ *
3894
+ * dp is a double precision variable.
3895
+ * On entry dp is the the derivative of the function at stp.
3896
+ * On exit dp is unchanged.
3897
+ *
3898
+ * brackt is an logical variable.
3899
+ * On entry brackt specifies if a minimizer has been bracketed.
3900
+ * Initially brackt must be set to .false.
3901
+ * On exit brackt specifies if a minimizer has been bracketed.
3902
+ * When a minimizer is bracketed brackt is set to .true.
3903
+ *
3904
+ * stpmin is a double precision variable.
3905
+ * On entry stpmin is a lower bound for the step.
3906
+ * On exit stpmin is unchanged.
3907
+ *
3908
+ * stpmax is a double precision variable.
3909
+ * On entry stpmax is an upper bound for the step.
3910
+ * On exit stpmax is unchanged.
3911
+ *
3912
+ * MINPACK-1 Project. June 1983
3913
+ * Argonne National Laboratory.
3914
+ * Jorge J. More' and David J. Thuente.
3915
+ *
3916
+ * MINPACK-2 Project. October 1993.
3917
+ * Argonne National Laboratory and University of Minnesota.
3918
+ * Brett M. Averick and Jorge J. More'.
3919
+ */
3920
+ int dcstep_(double *stx, double *fx, double *dx,
3921
+ double *sty, double *fy, double *dy, double *stp,
3922
+ double *fp, double *dp, long *brackt, double *stpmin,
3923
+ double *stpmax)
3924
+ {
3925
+ double d__1, d__2, d__3;
3926
+ static double p, q, r__, s, sgnd, stpc, stpf, stpq, gamma, theta;
3927
+
3928
+ sgnd = *dp * (*dx / fabs(*dx));
3929
+ /* First case: A higher function value. The minimum is bracketed. */
3930
+ /* If the cubic step is closer to stx than the quadratic step, the */
3931
+ /* cubic step is taken, otherwise the average of the cubic and */
3932
+ /* quadratic steps is taken. */
3933
+ if (*fp > *fx) {
3934
+ theta = (*fx - *fp) * 3. / (*stp - *stx) + *dx + *dp;
3935
+ d__1 = fabs(theta);
3936
+ d__2 = fabs(*dx);
3937
+ d__1 = d__1 >= d__2 ? d__1 : d__2;
3938
+ d__2 = fabs(*dp);
3939
+ s = d__1 >= d__2 ? d__1 : d__2;
3940
+ d__1 = theta / s;
3941
+ gamma = s * sqrt(d__1 * d__1 - *dx / s * (*dp / s));
3942
+ if (*stp < *stx) {
3943
+ gamma = -gamma;
3944
+ }
3945
+ p = gamma - *dx + theta;
3946
+ q = gamma - *dx + gamma + *dp;
3947
+ r__ = p / q;
3948
+ stpc = *stx + r__ * (*stp - *stx);
3949
+ stpq = *stx + *dx / ((*fx - *fp) / (*stp - *stx) + *dx) / 2. * (*stp - *stx);
3950
+ if ((d__1 = stpc - *stx, fabs(d__1)) < (d__2 = stpq - *stx, fabs(d__2))) {
3951
+ stpf = stpc;
3952
+ } else {
3953
+ stpf = stpc + (stpq - stpc) / 2.;
3954
+ }
3955
+ *brackt = TRUE_;
3956
+ /* Second case: A lower function value and derivatives of opposite */
3957
+ /* sign. The minimum is bracketed. If the cubic step is farther from */
3958
+ /* stp than the secant step, the cubic step is taken, otherwise the */
3959
+ /* secant step is taken. */
3960
+ } else if (sgnd < 0.) {
3961
+ theta = (*fx - *fp) * 3. / (*stp - *stx) + *dx + *dp;
3962
+ d__1 = fabs(theta);
3963
+ d__2 = fabs(*dx);
3964
+ d__1 = d__1 >= d__2 ? d__1 : d__2;
3965
+ d__2 = fabs(*dp);
3966
+ s = d__1 >= d__2 ? d__1 : d__2;
3967
+ d__1 = theta / s;
3968
+ gamma = s * sqrt(d__1 * d__1 - *dx / s * (*dp / s));
3969
+ if (*stp > *stx) {
3970
+ gamma = -gamma;
3971
+ }
3972
+ p = gamma - *dp + theta;
3973
+ q = gamma - *dp + gamma + *dx;
3974
+ r__ = p / q;
3975
+ stpc = *stp + r__ * (*stx - *stp);
3976
+ stpq = *stp + *dp / (*dp - *dx) * (*stx - *stp);
3977
+ if ((d__1 = stpc - *stp, fabs(d__1)) > (d__2 = stpq - *stp, fabs(d__2))) {
3978
+ stpf = stpc;
3979
+ } else {
3980
+ stpf = stpq;
3981
+ }
3982
+ *brackt = TRUE_;
3983
+ /* Third case: A lower function value, derivatives of the same sign, */
3984
+ /* and the magnitude of the derivative decreases. */
3985
+ } else if (fabs(*dp) < fabs(*dx)) {
3986
+ /* The cubic step is computed only if the cubic tends to infinity */
3987
+ /* in the direction of the step or if the minimum of the cubic */
3988
+ /* is beyond stp. Otherwise the cubic step is defined to be the */
3989
+ /* secant step. */
3990
+ theta = (*fx - *fp) * 3. / (*stp - *stx) + *dx + *dp;
3991
+ d__1 = fabs(theta);
3992
+ d__2 = fabs(*dx);
3993
+ d__1 = d__1 >= d__2 ? d__1 : d__2;
3994
+ d__2 = fabs(*dp);
3995
+ s = d__1 >= d__2 ? d__1 : d__2;
3996
+ /* The case gamma = 0 only arises if the cubic does not tend */
3997
+ /* to infinity in the direction of the step. */
3998
+ d__3 = theta / s;
3999
+ d__1 = 0.;
4000
+ d__2 = d__3 * d__3 - *dx / s * (*dp / s);
4001
+ gamma = s * sqrt(d__1 >= d__2 ? d__1 : d__2);
4002
+ if (*stp > *stx) {
4003
+ gamma = -gamma;
4004
+ }
4005
+ p = gamma - *dp + theta;
4006
+ q = gamma + (*dx - *dp) + gamma;
4007
+ r__ = p / q;
4008
+ if (r__ < 0. && gamma != 0.) {
4009
+ stpc = *stp + r__ * (*stx - *stp);
4010
+ } else if (*stp > *stx) {
4011
+ stpc = *stpmax;
4012
+ } else {
4013
+ stpc = *stpmin;
4014
+ }
4015
+ stpq = *stp + *dp / (*dp - *dx) * (*stx - *stp);
4016
+ if (*brackt) {
4017
+ /* A minimizer has been bracketed. If the cubic step is */
4018
+ /* closer to stp than the secant step, the cubic step is */
4019
+ /* taken, otherwise the secant step is taken. */
4020
+ if ((d__1 = stpc - *stp, fabs(d__1)) < (d__2 = stpq - *stp, fabs(d__2))) {
4021
+ stpf = stpc;
4022
+ } else {
4023
+ stpf = stpq;
4024
+ }
4025
+ if (*stp > *stx) {
4026
+ d__1 = *stp + (*sty - *stp) * .66;
4027
+ stpf = d__1 <= stpf ? d__1 : stpf;
4028
+ } else {
4029
+ d__1 = *stp + (*sty - *stp) * .66;
4030
+ stpf = d__1 >= stpf ? d__1 : stpf;
4031
+ }
4032
+ } else {
4033
+ /* A minimizer has not been bracketed. If the cubic step is */
4034
+ /* farther from stp than the secant step, the cubic step is */
4035
+ /* taken, otherwise the secant step is taken. */
4036
+ if ((d__1 = stpc - *stp, fabs(d__1)) > (d__2 = stpq - *stp, fabs(d__2))) {
4037
+ stpf = stpc;
4038
+ } else {
4039
+ stpf = stpq;
4040
+ }
4041
+ stpf = *stpmax <= stpf ? *stpmax : stpf;
4042
+ stpf = *stpmin >= stpf ? *stpmin : stpf;
4043
+ }
4044
+ /* Fourth case: A lower function value, derivatives of the same sign, */
4045
+ /* and the magnitude of the derivative does not decrease. If the */
4046
+ /* minimum is not bracketed, the step is either stpmin or stpmax, */
4047
+ /* otherwise the cubic step is taken. */
4048
+ } else {
4049
+ if (*brackt) {
4050
+ theta = (*fp - *fy) * 3. / (*sty - *stp) + *dy + *dp;
4051
+ d__1 = fabs(theta);
4052
+ d__2 = fabs(*dy);
4053
+ d__1 = d__1 >= d__2 ? d__1 : d__2;
4054
+ d__2 = fabs(*dp);
4055
+ s = d__1 >= d__2 ? d__1: d__2;
4056
+ d__1 = theta / s;
4057
+ gamma = s * sqrt(d__1 * d__1 - *dy / s * (*dp / s));
4058
+ if (*stp > *sty) {
4059
+ gamma = -gamma;
4060
+ }
4061
+ p = gamma - *dp + theta;
4062
+ q = gamma - *dp + gamma + *dy;
4063
+ r__ = p / q;
4064
+ stpc = *stp + r__ * (*sty - *stp);
4065
+ stpf = stpc;
4066
+ } else if (*stp > *stx) {
4067
+ stpf = *stpmax;
4068
+ } else {
4069
+ stpf = *stpmin;
4070
+ }
4071
+ }
4072
+ /* Update the interval which contains a minimizer. */
4073
+ if (*fp > *fx) {
4074
+ *sty = *stp;
4075
+ *fy = *fp;
4076
+ *dy = *dp;
4077
+ } else {
4078
+ if (sgnd < 0.) {
4079
+ *sty = *stx;
4080
+ *fy = *fx;
4081
+ *dy = *dx;
4082
+ }
4083
+ *stx = *stp;
4084
+ *fx = *fp;
4085
+ *dx = *dp;
4086
+ }
4087
+ /* Compute the new step. */
4088
+ *stp = stpf;
4089
+ return 0;
4090
+ }
4091
+
4092
+ int timer_(double *ttime)
4093
+ {
4094
+ *ttime = (double)clock() / CLOCKS_PER_SEC;
4095
+ return 0;
4096
+ }