Coverage Report

Created: 2026-10-28 06:40

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