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