Xmipp  v3.23.11-Nereus
numerical_recipes.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Carlos Oscar S. Sorzano (coss@cnb.csic.es)
4  *
5  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20  * 02111-1307 USA
21  *
22  * All comments concerning this program package may be sent to the
23  * e-mail address 'xmipp@cnb.csic.es'
24  ***************************************************************************/
25 
26 #include <iostream>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <vector>
31 #include "numerical_recipes.h"
32 
33 
34 /* NUMERICAL UTILITIES ----------------------------------------------------- */
35 void nrerror(const char error_text[])
36 {
37  fprintf(stderr, "Numerical Recipes run-time error...\n");
38  fprintf(stderr, "%s\n", error_text);
39  fprintf(stderr, "...now exiting to system...\n");
40  exit(1);
41 }
42 #define NRSIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
43 
44 /* RANDOM NUMBERS ---------------------------------------------------------- */
45 #define M1 259200
46 #define IA1 7141
47 #define IC1 54773
48 #define RM1 (1.0/M1)
49 #define M2 134456
50 #define IA2 8121
51 #define IC2 28411
52 #define RM2 (1.0/M2)
53 #define M3 243000
54 #define IA3 4561
55 #define IC3 51349
56 
57 /* Chapter 7 Section 1: UNIFORM RANDOM NUMBERS */
58 double ran1(int *idum)
59 {
60  static long ix1, ix2, ix3;
61  static double r[98];
62  double temp;
63  static int iff = 0;
64  int j;
65 
66  if (*idum < 0 || iff == 0)
67  {
68  iff = 1;
69  ix1 = (IC1 - (*idum)) % M1;
70  ix1 = (IA1 * ix1 + IC1) % M1;
71  ix2 = ix1 % M2;
72  ix1 = (IA1 * ix1 + IC1) % M1;
73  ix3 = ix1 % M3;
74  for (j = 1;j <= 97;j++)
75  {
76  ix1 = (IA1 * ix1 + IC1) % M1;
77  ix2 = (IA2 * ix2 + IC2) % M2;
78  r[j] = (ix1 + ix2 * RM2) * RM1;
79  }
80  *idum = 1;
81  }
82  ix1 = (IA1 * ix1 + IC1) % M1;
83  ix2 = (IA2 * ix2 + IC2) % M2;
84  ix3 = (IA3 * ix3 + IC3) % M3;
85  j = 1 + ((97 * ix3) / M3);
86  if (j > 97 || j < 1)
87  nrerror("RAN1: This cannot happen.");
88  temp = r[j];
89  r[j] = (ix1 + ix2 * RM2) * RM1;
90  return temp;
91 }
92 
93 #undef M1
94 #undef IA1
95 #undef IC1
96 #undef RM1
97 #undef M2
98 #undef IA2
99 #undef IC2
100 #undef RM2
101 #undef M3
102 #undef IA3
103 #undef IC3
104 
105 /* Chapter 7 Section 3: GAUSSIAN RANDOM NUMBERS */
106 double gasdev(int *idum)
107 {
108  static int iset = 0;
109  static double gset;
110  double fac, r, v1, v2;
111 
112  if (iset == 0)
113  {
114  do
115  {
116  v1 = 2.0 * ran1(idum) - 1.0;
117  v2 = 2.0 * ran1(idum) - 1.0;
118  r = v1 * v1 + v2 * v2;
119  }
120  while (r >= 1.0);
121  fac = sqrt(-2.0 * log(r) / r);
122  gset = v1 * fac;
123  iset = 1;
124  return v2*fac;
125  }
126  else
127  {
128  iset = 0;
129  return gset;
130  }
131 }
132 
133 // t-distribution (nor Numerical Recipes, but Mathematics of Computation, vol. 62, 779-781.
134 // I downloaded sem-code from http://ideas.repec.org/c/ega/comcod/200703.html
135 // Sjors May 2008
136 double tdev(double nu, int *idum)
137 {
138  static int iset = 0;
139  static double gset;
140  double fac, r, v1, v2;
141 
142  if (iset == 0)
143  {
144  do
145  {
146  v1 = 2.0 * ran1(idum) - 1.0;
147  v2 = 2.0 * ran1(idum) - 1.0;
148  r = v1 * v1 + v2 * v2;
149  }
150  while (r >= 1.0);
151  fac = sqrt(nu*(pow(r,-2.0/nu) -1.0)/r);
152  gset = v1 * fac;
153  iset = 1;
154  return v2*fac;
155  }
156  else
157  {
158  iset = 0;
159  return gset;
160  }
161 }
162 
163 
164 // Kolmogorov-Smirnov test
165 void ksone(double data[], int n, double(*func)(double), double * d, double * prob)
166 {
167  std::sort(data, data + n);
168  double fn, ff, en, dt, fo=0.;
169  en = (double)n;
170  *d = 0.;
171  for (int j=1; j<=n; j++)
172  {
173  fn = j / en;
174  ff = (*func)(data[j]);
175  dt = XMIPP_MAX(fabs(fo - ff), fabs(fn - ff));
176  if (dt> *d)
177  *d = dt;
178  fo = fn;
179  }
180  *prob = probks(sqrt(en)*(*d));
181 }
182 
183 // Calculate KS-confidence level
184 double probks(double alam)
185 {
186  int j;
187  double a2, fac=2.0, sum=0.0, term, termbf=0.0;
188  double EPS1=0.001, EPS2=1.0e-8;
189 
190  a2 = -2.0 * alam * alam;
191  for (j = 1; j<= 100; j++)
192  {
193  term = fac * exp(a2*j*j);
194  sum += term;
195  if (fabs(term) <= EPS1*termbf || fabs(term) <= EPS2*sum)
196  return sum;
197  fac = -fac;
198  termbf = fabs(term);
199  }
200  return 1.0;
201 
202 }
203 
204 /* SORTING ----------------------------------------------------------------- */
205 /* Chapter 8, Section 3: Indexing */
206 void indexx(int n, double arrin[], int indx[])
207 {
208  int l, j, ir, indxt, i;
209  double q;
210 
211  for (j = 1;j <= n;j++)
212  indx[j] = j;
213  l = (n >> 1) + 1;
214  ir = n;
215  for (;;)
216  {
217  if (l > 1)
218  q = arrin[(indxt=indx[--l])];
219  else
220  {
221  q = arrin[(indxt=indx[ir])];
222  indx[ir] = indx[1];
223  if (--ir == 1)
224  {
225  indx[1] = indxt;
226  return;
227  }
228  }
229  i = l;
230  j = l << 1;
231  while (j <= ir)
232  {
233  if (j < ir && arrin[indx[j]] < arrin[indx[j+1]])
234  j++;
235  if (q < arrin[indx[j]])
236  {
237  indx[i] = indx[j];
238  j += (i = j);
239  }
240  else
241  j = ir + 1;
242  }
243  indx[i] = indxt;
244  }
245 }
246 
247 /* BESSEL FUNCTIONS -------------------------------------------------------- */
248 /* CO: They may not come in the numerical recipes but it is not a bad
249  idea to put them here, in fact they come from Gabor's group in Feb'84 */
250 double bessj0(double x)
251 {
252  double ax, z;
253  double xx, y, ans, ans1, ans2;
254 
255  if ((ax = fabs(x)) < 8.0)
256  {
257  y = x * x;
258  ans1 = 57568490574.0 + y * (-13362590354.0 +
259  y * (651619640.7
260  + y * (-11214424.18 +
261  y * (77392.33017 +
262  y * (-184.9052456)))));
263  ans2 = 57568490411.0 + y * (1029532985.0 +
264  y * (9494680.718
265  + y * (59272.64853 +
266  y * (267.8532712 +
267  y * 1.0))));
268  ans = ans1 / ans2;
269  }
270  else
271  {
272  z = 8.0 / ax;
273  y = z * z;
274  xx = ax - 0.785398164;
275  ans1 = 1.0 + y * (-0.1098628627e-2 + y * (0.2734510407e-4
276  + y * (-0.2073370639e-5 + y * 0.2093887211e-6)));
277  ans2 = -0.1562499995e-1 + y * (0.1430488765e-3
278  + y * (-0.6911147651e-5 + y * (0.7621095161e-6
279  - y * 0.934935152e-7)));
280  ans = sqrt(0.636619772 / ax) * (cos(xx) * ans1 - z * sin(xx) * ans2);
281  }
282  return ans;
283 }
284 
285 /*............................................................................*/
286 double bessi0(double x)
287 {
288  double y, ax, ans;
289  if ((ax = fabs(x)) < 3.75)
290  {
291  y = x / 3.75;
292  y *= y;
293  ans = 1.0 + y * (3.5156229 + y * (3.0899424 + y * (1.2067492
294  + y * (0.2659732 + y * (0.360768e-1 + y * 0.45813e-2)))));
295  }
296  else
297  {
298  y = 3.75 / ax;
299  ans = (exp(ax) / sqrt(ax)) * (0.39894228 + y * (0.1328592e-1
300  + y * (0.225319e-2 + y * (-0.157565e-2 + y * (0.916281e-2
301  + y * (-0.2057706e-1 + y * (0.2635537e-1 + y * (-0.1647633e-1
302  + y * 0.392377e-2))))))));
303  }
304  return ans;
305 }
306 
307 /*............................................................................*/
308 double bessi1(double x)
309 {
310  double ax, ans;
311  double y;
312  if ((ax = fabs(x)) < 3.75)
313  {
314  y = x / 3.75;
315  y *= y;
316  ans = ax * (0.5 + y * (0.87890594 + y * (0.51498869 + y * (0.15084934
317  + y * (0.2658733e-1 + y * (0.301532e-2 + y * 0.32411e-3))))));
318  }
319  else
320  {
321  y = 3.75 / ax;
322  ans = 0.2282967e-1 + y * (-0.2895312e-1 + y * (0.1787654e-1
323  - y * 0.420059e-2));
324  ans = 0.39894228 + y * (-0.3988024e-1 + y * (-0.362018e-2
325  + y * (0.163801e-2 + y * (-0.1031555e-1 + y * ans))));
326  ans *= (exp(ax) / sqrt(ax));
327  }
328  return x < 0.0 ? -ans : ans;
329 }
330 
331 /* General Bessel functions ------------------------------------------------ */
332 double chebev(double a, double b, double c[], int m, double x)
333 {
334  double d = 0.0, dd = 0.0, sv, y, y2;
335  int j;
336 
337  if ((x - a)*(x - b) > 0.0)
338  nrerror("x not in range in routine chebev");
339  y2 = 2.0 * (y = (2.0 * x - a - b) / (b - a));
340  for (j = m - 1;j >= 1;j--)
341  {
342  sv = d;
343  d = y2 * d - dd + c[j];
344  dd = sv;
345  }
346  return y*d - dd + 0.5*c[0];
347 }
348 #define NUSE1 5
349 #define NUSE2 5
350 
351 void beschb(double x, double *gam1, double *gam2, double *gampl, double *gammi)
352 {
353  double xx;
354  static double c1[] =
355  {
356  -1.142022680371172e0, 6.516511267076e-3,
357  3.08709017308e-4, -3.470626964e-6, 6.943764e-9,
358  3.6780e-11, -1.36e-13
359  };
360  static double c2[] =
361  {
362  1.843740587300906e0, -0.076852840844786e0,
363  1.271927136655e-3, -4.971736704e-6, -3.3126120e-8,
364  2.42310e-10, -1.70e-13, -1.0e-15
365  };
366 
367  xx = 8.0 * x * x - 1.0;
368  *gam1 = chebev(-1.0, 1.0, c1, NUSE1, xx);
369  *gam2 = chebev(-1.0, 1.0, c2, NUSE2, xx);
370  *gampl = *gam2 - x * (*gam1);
371  *gammi = *gam2 + x * (*gam1);
372 }
373 
374 #undef NUSE1
375 #undef NUSE2
376 
377 #define EPS 1.0e-16
378 #define FPMIN 1.0e-30
379 #define MAXIT 10000
380 #define XMIN 2.0
381 void bessjy(double x, double xnu, double *rj, double *ry, double *rjp, double *ryp)
382 {
383  int i, isign, l, nl;
384  double a, b, br, bi, c, cr, ci, d, del, del1, den, di, dlr, dli, dr, e, f, fact, fact2,
385  fact3, ff, gam, gam1, gam2, gammi, gampl, h, p, pimu, pimu2, q, r, rjl,
386  rjl1, rjmu, rjp1, rjpl, rjtemp, ry1, rymu, rymup, rytemp, sum, sum1,
387  temp, w, x2, xi, xi2, xmu, xmu2;
388 
389  if (x <= 0.0 || xnu < 0.0)
390  nrerror("bad arguments in bessjy");
391  nl = (x < XMIN ? (int)(xnu + 0.5) : XMIPP_MAX(0, (int)(xnu - x + 1.5)));
392  xmu = xnu - nl;
393  xmu2 = xmu * xmu;
394  xi = 1.0 / x;
395  xi2 = 2.0 * xi;
396  w = xi2 / PI;
397  isign = 1;
398  h = xnu * xi;
399  if (h < FPMIN)
400  h = FPMIN;
401  b = xi2 * xnu;
402  d = 0.0;
403  c = h;
404  for (i = 1;i <= MAXIT;i++)
405  {
406  b += xi2;
407  d = b - d;
408  if (fabs(d) < FPMIN)
409  d = FPMIN;
410  c = b - 1.0 / c;
411  if (fabs(c) < FPMIN)
412  c = FPMIN;
413  d = 1.0 / d;
414  del = c * d;
415  h = del * h;
416  if (d < 0.0)
417  isign = -isign;
418  if (fabs(del - 1.0) < EPS)
419  break;
420  }
421  if (i > MAXIT)
422  nrerror("x too large in bessjy; try asymptotic expansion");
423  rjl = isign * FPMIN;
424  rjpl = h * rjl;
425  rjl1 = rjl;
426  rjp1 = rjpl;
427  fact = xnu * xi;
428  for (l = nl;l >= 1;l--)
429  {
430  rjtemp = fact * rjl + rjpl;
431  fact -= xi;
432  rjpl = fact * rjtemp - rjl;
433  rjl = rjtemp;
434  }
435  if (rjl == 0.0)
436  rjl = EPS;
437  f = rjpl / rjl;
438  if (x < XMIN)
439  {
440  x2 = 0.5 * x;
441  pimu = PI * xmu;
442  fact = (fabs(pimu) < EPS ? 1.0 : pimu / sin(pimu));
443  d = -log(x2);
444  e = xmu * d;
445  fact2 = (fabs(e) < EPS ? 1.0 : sinh(e) / e);
446  beschb(xmu, &gam1, &gam2, &gampl, &gammi);
447  ff = 2.0 / PI * fact * (gam1 * cosh(e) + gam2 * fact2 * d);
448  e = exp(e);
449  p = e / (gampl * PI);
450  q = 1.0 / (e * PI * gammi);
451  pimu2 = 0.5 * pimu;
452  fact3 = (fabs(pimu2) < EPS ? 1.0 : sin(pimu2) / pimu2);
453  r = PI * pimu2 * fact3 * fact3;
454  c = 1.0;
455  d = -x2 * x2;
456  sum = ff + r * q;
457  sum1 = p;
458  for (i = 1;i <= MAXIT;i++)
459  {
460  ff = (i * ff + p + q) / (i * i - xmu2);
461  c *= (d / i);
462  p /= (i - xmu);
463  q /= (i + xmu);
464  del = c * (ff + r * q);
465  sum += del;
466  del1 = c * p - i * del;
467  sum1 += del1;
468  if (fabs(del) < (1.0 + fabs(sum))*EPS)
469  break;
470  }
471  if (i > MAXIT)
472  nrerror("bessy series failed to converge");
473  rymu = -sum;
474  ry1 = -sum1 * xi2;
475  rymup = xmu * xi * rymu - ry1;
476  rjmu = w / (rymup - f * rymu);
477  }
478  else
479  {
480  a = 0.25 - xmu2;
481  p = -0.5 * xi;
482  q = 1.0;
483  br = 2.0 * x;
484  bi = 2.0;
485  fact = a * xi / (p * p + q * q);
486  cr = br + q * fact;
487  ci = bi + p * fact;
488  den = br * br + bi * bi;
489  dr = br / den;
490  di = -bi / den;
491  dlr = cr * dr - ci * di;
492  dli = cr * di + ci * dr;
493  temp = p * dlr - q * dli;
494  q = p * dli + q * dlr;
495  p = temp;
496  for (i = 2;i <= MAXIT;i++)
497  {
498  a += 2 * (i - 1);
499  bi += 2.0;
500  dr = a * dr + br;
501  di = a * di + bi;
502  if (fabs(dr) + fabs(di) < FPMIN)
503  dr = FPMIN;
504  fact = a / (cr * cr + ci * ci);
505  cr = br + cr * fact;
506  ci = bi - ci * fact;
507  if (fabs(cr) + fabs(ci) < FPMIN)
508  cr = FPMIN;
509  den = dr * dr + di * di;
510  dr /= den;
511  di /= -den;
512  dlr = cr * dr - ci * di;
513  dli = cr * di + ci * dr;
514  temp = p * dlr - q * dli;
515  q = p * dli + q * dlr;
516  p = temp;
517  if (fabs(dlr - 1.0) + fabs(dli) < EPS)
518  break;
519  }
520  if (i > MAXIT)
521  nrerror("cf2 failed in bessjy");
522  gam = (p - f) / q;
523  rjmu = sqrt(w / ((p - f) * gam + q));
524  rjmu = NRSIGN(rjmu, rjl);
525  rymu = rjmu * gam;
526  rymup = rymu * (p + q / gam);
527  ry1 = xmu * xi * rymu - rymup;
528  }
529  fact = rjmu / rjl;
530  *rj = rjl1 * fact;
531  *rjp = rjp1 * fact;
532  for (i = 1;i <= nl;i++)
533  {
534  rytemp = (xmu + i) * xi2 * ry1 - rymu;
535  rymu = ry1;
536  ry1 = rytemp;
537  }
538  *ry = rymu;
539  *ryp = xnu * xi * rymu - ry1;
540 }
541 #undef EPS
542 #undef FPMIN
543 #undef MAXIT
544 #undef XMIN
545 
546 /*............................................................................*/
547 double bessi0_5(double x)
548 {
549  return (x == 0) ? 0 : sqrt(2 / (PI*x))*sinh(x);
550 }
551 double bessi1_5(double x)
552 {
553  return (x == 0) ? 0 : sqrt(2 / (PI*x))*(cosh(x) - sinh(x) / x);
554 }
555 double bessi2(double x)
556 {
557  return (x == 0) ? 0 : bessi0(x) - ((2*1) / x) * bessi1(x);
558 }
559 double bessi2_5(double x)
560 {
561  return (x == 0) ? 0 : bessi0_5(x) - ((2*1.5) / x) * bessi1_5(x);
562 }
563 double bessi3(double x)
564 {
565  return (x == 0) ? 0 : bessi1(x) - ((2*2) / x) * bessi2(x);
566 }
567 double bessi3_5(double x)
568 {
569  return (x == 0) ? 0 : bessi1_5(x) - ((2*2.5) / x) * bessi2_5(x);
570 }
571 double bessi4(double x)
572 {
573  return (x == 0) ? 0 : bessi2(x) - ((2*3) / x) * bessi3(x);
574 }
575 double bessj1_5(double x)
576 {
577  double rj, ry, rjp, ryp;
578  bessjy(x, 1.5, &rj, &ry, &rjp, &ryp);
579  return rj;
580 }
581 double bessj3_5(double x)
582 {
583  double rj, ry, rjp, ryp;
584  bessjy(x, 3.5, &rj, &ry, &rjp, &ryp);
585  return rj;
586 }
587 
588 /* Special functions ------------------------------------------------------- */
589 double gammln(double xx)
590 {
591  double x, tmp, ser;
592  static double cof[6] =
593  {
594  76.18009173, -86.50532033, 24.01409822,
595  -1.231739516, 0.120858003e-2, -0.536382e-5
596  };
597  int j;
598 
599  x = xx - 1.0;
600  tmp = x + 5.5;
601  tmp -= (x + 0.5) * log(tmp);
602  ser = 1.0;
603  for (j = 0;j <= 5;j++)
604  {
605  x += 1.0;
606  ser += cof[j] / x;
607  }
608  return -tmp + log(2.50662827465*ser);
609 }
610 
611 
612 double betai(double a, double b, double x)
613 {
614  double bt;
615  if (x < 0.0 || x > 1.0)
616  nrerror("Bad x in routine BETAI");
617  if (x == 0.0 || x == 1.0)
618  bt = 0.0;
619  else
620  bt = exp(gammln(a + b) - gammln(a) - gammln(b) + a * log(x) + b * log(1.0 - x));
621  if (x < (a + 1.0) / (a + b + 2.0))
622  return bt*betacf(a, b, x) / a;
623  else
624  return 1.0 -bt*betacf(b, a, 1.0 - x) / b;
625 
626 }
627 
628 #define ITMAX 100
629 #define EPS 3.0e-7
630 double betacf(double a, double b, double x)
631 {
632  double qap, qam, qab, em, tem, d;
633  double bz, bm = 1.0, bp, bpp;
634  double az = 1.0, am = 1.0, ap, app, aold;
635  int m;
636 
637  qab = a + b;
638  qap = a + 1.0;
639  qam = a - 1.0;
640  bz = 1.0 - qab * x / qap;
641  for (m = 1;m <= ITMAX;m++)
642  {
643  em = (double) m;
644  tem = em + em;
645  d = em * (b - em) * x / ((qam + tem) * (a + tem));
646  ap = az + d * am;
647  bp = bz + d * bm;
648  d = -(a + em) * (qab + em) * x / ((qap + tem) * (a + tem));
649  app = ap + d * az;
650  bpp = bp + d * bz;
651  aold = az;
652  am = ap / bpp;
653  bm = bp / bpp;
654  az = app / bpp;
655  bz = 1.0;
656  if (fabs(az - aold) < (EPS*fabs(az)))
657  return az;
658  }
659  nrerror("a or b too big, or ITMAX too small in BETACF");
660  return 0;
661 }
662 #undef ITMAX
663 #undef EPS
664 
665 /* Optimization ------------------------------------------------------------ */
666 #undef MAX
667 #undef SIGN
668 #define GOLD 1.618034
669 #define GLIMIT 100.0
670 #define TINY 1.0e-20
671 #define MAX(a,b) ((a) > (b) ? (a) : (b))
672 #define SIGN(a,b) ((b) > 0.0 ? fabs(a) : -fabs(a))
673 #define SHFT(a,b,c,d) (a)=(b);(b)=(c);(c)=(d);
674 #define F1DIM(x,f) {\
675  for (int j = 1; j<=ncom; j++) \
676  xt[j] = pcom[j] + x * xicom[j]; \
677  f = (*func)(xt,prm);}
678 
679 void mnbrak(double *ax, double *bx, double *cx,
680  double *fa, double *fb, double *fc, double(*func)(double *, void*),
681  void *prm, int ncom, double *pcom, double *xicom)
682 {
683  double ulim, u, r, q, fu, dum;
684  std::vector<double> buffer(ncom);
685  auto *xt= buffer.data()-1;
686 
687  F1DIM(*ax,*fa);
688  F1DIM(*bx,*fb);
689  if (*fb > *fa)
690  {
691  SHFT(dum, *ax, *bx, dum)
692  SHFT(dum, *fb, *fa, dum)
693  }
694  *cx = (*bx) + GOLD * (*bx - *ax);
695  F1DIM(*cx,*fc);
696  while (*fb > *fc)
697  {
698  r = (*bx - *ax) * (*fb - *fc);
699  q = (*bx - *cx) * (*fb - *fa);
700  u = (*bx) - ((*bx - *cx) * q - (*bx - *ax) * r) /
701  (2.0 * SIGN(MAX(fabs(q - r), TINY), q - r));
702  ulim = (*bx) + GLIMIT * (*cx - *bx);
703  if ((*bx - u)*(u - *cx) > 0.0)
704  {
705  F1DIM(u,fu);
706  if (fu < *fc)
707  {
708  *ax = (*bx);
709  *bx = u;
710  *fa = (*fb);
711  *fb = fu;
712  return;
713  }
714  else if (fu > *fb)
715  {
716  *cx = u;
717  *fc = fu;
718  return;
719  }
720  u = (*cx) + GOLD * (*cx - *bx);
721  F1DIM(u,fu);
722  }
723  else if ((*cx - u)*(u - ulim) > 0.0)
724  {
725  F1DIM(u,fu);
726  if (fu < *fc)
727  {
728  SHFT(*bx, *cx, u, *cx + GOLD*(*cx - *bx))
729  double aux;
730  F1DIM(u,aux);
731  SHFT(*fb, *fc, fu, aux)
732  }
733  }
734  else if ((u - ulim)*(ulim - *cx) >= 0.0)
735  {
736  u = ulim;
737  F1DIM(u,fu);
738  }
739  else
740  {
741  u = (*cx) + GOLD * (*cx - *bx);
742  F1DIM(u,fu);
743  }
744  SHFT(*ax, *bx, *cx, u)
745  SHFT(*fa, *fb, *fc, fu)
746  }
747 }
748 
749 #undef GOLD
750 #undef GLIMIT
751 #undef TINY
752 #undef MAX
753 
754 #define ITMAX 100
755 #define CGOLD 0.3819660
756 #define ZEPS 1.0e-10
757 double brent(double ax, double bx, double cx, double(*func)(double *,void*),
758  void *prm, double tol, double *xmin,
759  int ncom, double *pcom, double *xicom)
760 {
761  int iter;
762  double a, b, d, etemp, fu, fv, fw, fx, p, q, r, tol1, tol2, u, v, w, x, xm;
763  double e = 0.0;
764  std::vector<double> buffer(ncom);
765  auto *xt= buffer.data()-1;
766 
767  a = (ax < cx ? ax : cx);
768  b = (ax > cx ? ax : cx);
769  x = w = v = bx;
770  F1DIM(x,fx);
771  fw = fv = fx;
772  for (iter = 1;iter <= ITMAX;iter++)
773  {
774  xm = 0.5 * (a + b);
775  tol2 = 2.0 * (tol1 = tol * fabs(x) + ZEPS);
776  if (fabs(x - xm) <= (tol2 - 0.5*(b - a)))
777  {
778  *xmin = x;
779  return fx;
780  }
781  if (fabs(e) > tol1)
782  {
783  r = (x - w) * (fx - fv);
784  q = (x - v) * (fx - fw);
785  p = (x - v) * q - (x - w) * r;
786  q = 2.0 * (q - r);
787  if (q > 0.0)
788  p = -p;
789  q = fabs(q);
790  etemp = e;
791  e = d;
792  if (fabs(p) >= fabs(0.5*q*etemp) || p <= q*(a - x) || p >= q*(b - x))
793  d = CGOLD * (e = (x >= xm ? a - x : b - x));
794  else
795  {
796  d = p / q;
797  u = x + d;
798  if (u - a < tol2 || b - u < tol2)
799  d = SIGN(tol1, xm - x);
800  }
801  }
802  else
803  {
804  d = CGOLD * (e = (x >= xm ? a - x : b - x));
805  }
806  u = (fabs(d) >= tol1 ? x + d : x + SIGN(tol1, d));
807  F1DIM(u,fu);
808  if (fu <= fx)
809  {
810  if (u >= x)
811  a = x;
812  else
813  b = x;
814  SHFT(v, w, x, u)
815  SHFT(fv, fw, fx, fu)
816  }
817  else
818  {
819  if (u < x)
820  a = u;
821  else
822  b = u;
823  if (fu <= fw || w == x)
824  {
825  v = w;
826  w = u;
827  fv = fw;
828  fw = fu;
829  }
830  else if (fu <= fv || v == x || v == w)
831  {
832  v = u;
833  fv = fu;
834  }
835  }
836  }
837  nrerror("Too many iterations in brent");
838  *xmin = x;
839  return fx;
840 }
841 #undef ITMAX
842 #undef CGOLD
843 #undef ZEPS
844 #undef SHFT
845 #undef F1DIM
846 
847 #define TOL 2.0e-4
848 void linmin(double *p, double *xi, int n, double &fret,
849  double(*func)(double *, void*), void *prm)
850 {
851  int j;
852  double xx, xmin, fx, fb, fa, bx, ax;
853 
854  int ncom = n;
855  std::vector<double> buffer(2*n);
856  auto *pcom= buffer.data()-1;
857  auto *xicom= pcom + n;
858  for (j = 1;j <= n;j++)
859  {
860  pcom[j] = p[j];
861  xicom[j] = xi[j];
862  }
863  ax = 0.0;
864  xx = 1.0;
865  bx = 2.0;
866  mnbrak(&ax, &xx, &bx, &fa, &fx, &fb, func, prm, ncom, pcom, xicom);
867  fret = brent(ax, xx, bx, func, prm, TOL, &xmin, ncom, pcom, xicom);
868  for (j = 1;j <= n;j++)
869  {
870  xi[j] *= xmin;
871  p[j] += xi[j];
872  }
873 }
874 #undef TOL
875 
876 #define ITMAX 200
877 void powell(double *p, double *xi, int n, double ftol, int &iter,
878  double &fret, double(*func)(double *, void *), void *prm,
879  bool show)
880 {
881  int i, ibig, j;
882  double t, fptt, fp, del;
883  std::vector<double> buffer(3*n);
884  auto *pt= buffer.data()-1;
885  auto *ptt= pt + n;
886  auto *xit= ptt + n;
887  bool different_from_0;
888 
889  fret = (*func)(p,prm);
890  for (j = 1;j <= n;j++)
891  pt[j] = p[j];
892 
893  for (iter = 1;;(iter)++)
894  {
895  /* By coss ----- */
896  if (show)
897  {
898  std::cout << iter << " (" << p[1];
899  for (int co = 2; co <= n; co++)
900  std::cout << "," << p[co];
901  std::cout << ")--->" << fret << std::endl;
902  }
903  /* ------------- */
904 
905  fp = fret;
906  ibig = 0;
907  del = 0.0;
908  for (i = 1;i <= n;i++)
909  {
910  different_from_0 = false; // CO
911  for (j = 1;j <= n;j++)
912  {
913  xit[j] = xi[j*n+i];
914  if (xit[j] != 0)
915  different_from_0 = true;
916  }
917  if (different_from_0)
918  {
919  fptt = fret;
920  linmin(p, xit, n, fret, func, prm);
921  if (fabs(fptt - fret) > del)
922  {
923  del = fabs(fptt - fret);
924  ibig = i;
925  }
926  /* By coss ----- */
927  if (show)
928  {
929  std::cout << " (";
930  if (i == 1)
931  std::cout << "***";
932  std::cout << p[1];
933  for (int co = 2; co <= n; co++)
934  {
935  std::cout << ",";
936  if (co == i)
937  std::cout << "***";
938  std::cout << p[co];
939  }
940  std::cout << ")--->" << fret << std::endl;
941  }
942  /* ------------- */
943  }
944  }
945  if (2.0*fabs(fp - fret) <= ftol*(fabs(fp) + fabs(fret)) || n==1) return;
946  if (iter == ITMAX)
947  nrerror("Too many iterations in routine POWELL");
948  for (j = 1;j <= n;j++)
949  {
950  ptt[j] = 2.0 * p[j] - pt[j];
951  xit[j] = p[j] - pt[j];
952  pt[j] = p[j];
953  }
954  fptt = (*func)(ptt,prm);
955  if (fptt < fp)
956  {
957 #define SQR(a) ((a)*(a))
958  t = 2.0 * (fp - 2.0 * fret + fptt) * SQR(fp - fret - del) - del * SQR(fp - fptt);
959  if (t < 0.0)
960  {
961  linmin(p, xit, n, fret, func, prm);
962  for (j = 1;j <= n;j++)
963  xi[j*n+ibig] = xit[j];
964  }
965  }
966  }
967 }
968 #undef ITMAX
969 #undef SQR
970 
971 /* Non linear least squares ------------------------------------------------ */
972 // These routines have been taken from
973 // http://users.utu.fi/vesoik/userdocs/programs/libpet
974 // and they implement an algorithm of Lawson-Hanson of
975 // nonnegative least squares
976 
977 /* Example of use:
978  double a[]={ 5, 0, -2,
979  0, 3, 0,
980  1, 1, -1,
981  -1, 1, -1,
982  9, 9, -9};
983  double b[]={1, 9, -1};
984  double x[5];
985  double rnorm;
986  int i;
987 
988  int success=nnls(a,3,5,b,x,&rnorm,NULL,NULL,NULL);
989  printf("success=%d\n",success);
990  printf("rnorm=%d\n",rnorm);
991  for (i=0; i<5; i++)
992  printf("%f\n",x[i]);
993 
994  In this case: x=0 2.666 0 0 0.111
995 
996  This program resolves A^t*x=b subject to x>=0.
997  In terms of basis vectors, the rows of A are the basis axes, b is
998  the vector we want to represent in the subspace spanned by the rows of A
999  and x are the nonnegative coordinates of the representation of b in A.
1000 */
1001 
1002 /*****************************************************************************
1003  *
1004  * Compute orthogonal rotation matrix:
1005  * (C, S) so that (C, S)(A) = (sqrt(A**2+B**2))
1006  * (-S,C) (-S,C)(B) ( 0 )
1007  * Compute sig = sqrt(A**2+B**2):
1008  * sig is computed last to allow for the possibility that sig may be in
1009  * the same location as A or B.
1010  */
1011 void _nnls_g1(double a, double b, double *cterm, double *sterm, double *sig)
1012 {
1013  double d1, xr, yr;
1014 
1015  if (fabs(a) > fabs(b))
1016  {
1017  xr = b / a;
1018  d1 = xr;
1019  yr = sqrt(d1 * d1 + 1.);
1020  d1 = 1. / yr;
1021  *cterm = (a >= 0.0 ? fabs(d1) : -fabs(d1));
1022  *sterm = (*cterm) * xr;
1023  *sig = fabs(a) * yr;
1024  }
1025  else if (b != 0.)
1026  {
1027  xr = a / b;
1028  d1 = xr;
1029  yr = sqrt(d1 * d1 + 1.);
1030  d1 = 1. / yr;
1031  *sterm = (b >= 0.0 ? fabs(d1) : -fabs(d1));
1032  *cterm = (*sterm) * xr;
1033  *sig = fabs(b) * yr;
1034  }
1035  else
1036  {
1037  *sig = 0.;
1038  *cterm = 0.;
1039  *sterm = 1.;
1040  }
1041 } /* _nnls_g1 */
1042 /****************************************************************************/
1043 
1044 /*****************************************************************************
1045  *
1046  * Construction and/or application of a single Householder transformation:
1047  * Q = I + U*(U**T)/B
1048  *
1049  * Function returns 0 if successful, or >0 in case of erroneous parameters.
1050  *
1051  */
1053  int mode,
1054  /* mode=1 to construct and apply a Householder transformation, or
1055  mode=2 to apply a previously constructed transformation */
1056  int lpivot, /* Index of the pivot element */
1057  int l1, int m,
1058  /* Transformation is constructed to zero elements indexed from l1 to M */
1059  double *u, int u_dim1, double *up,
1060  /* With mode=1: On entry, u[] must contain the pivot vector.
1061  On exit, u[] and up contain quantities defining the vector u[] of
1062  the Householder transformation. */
1063  /* With mode=2: On entry, u[] and up should contain quantities previously
1064  computed with mode=1. These will not be modified. */
1065  /* u_dim1 is the storage increment between elements. */
1066  double *cm,
1067  /* On entry, cm[] must contain the matrix (set of vectors) to which the
1068  Householder transformation is to be applied. On exit, cm[] will contain
1069  the set of transformed vectors */
1070  int ice, /* Storage increment between elements of vectors in cm[] */
1071  int icv, /* Storage increment between vectors in cm[] */
1072  int ncv /* Nr of vectors in cm[] to be transformed;
1073  if ncv<=0, then no operations will be done on cm[] */
1074 )
1075 {
1076  double d1, d2, b, clinv, cl, sm;
1077  int incr, k, j, i2, i3, i4;
1078 
1079  /* Check parameters */
1080  if (mode != 1 && mode != 2)
1081  return(1);
1082  if (m < 1 || u == NULL || u_dim1 < 1 || cm == NULL)
1083  return(2);
1084  if (lpivot < 0 || lpivot >= l1 || l1 >= m)
1085  return(0);
1086  /* Function Body */
1087  cl = (d1 = u[lpivot*u_dim1], fabs(d1));
1088  if (mode == 2)
1089  { /* Apply transformation I+U*(U**T)/B to cm[] */
1090  if (cl <= 0.)
1091  return(0);
1092  }
1093  else
1094  { /* Construct the transformation */
1095  for (j = l1; j < m; j++)
1096  { /* Computing MAX */
1097  d2 = (d1 = u[j*u_dim1], fabs(d1));
1098  if (d2 > cl)
1099  cl = d2;
1100  }
1101  if (cl <= 0.)
1102  return(0);
1103  clinv = 1.0 / cl;
1104  /* Computing 2nd power */
1105  d1 = u[lpivot*u_dim1] * clinv;
1106  sm = d1 * d1;
1107  for (j = l1; j < m; j++)
1108  {
1109  d1 = u[j*u_dim1] * clinv;
1110  sm += d1 * d1;
1111  }
1112  cl *= sqrt(sm);
1113  if (u[lpivot*u_dim1] > 0.)
1114  cl = -cl;
1115  *up = u[lpivot*u_dim1] - cl;
1116  u[lpivot*u_dim1] = cl;
1117  }
1118  if (ncv <= 0)
1119  return(0);
1120  b = (*up) * u[lpivot*u_dim1];
1121  /* b must be nonpositive here; if b>=0., then return */
1122  if (b >= 0.)
1123  return(0);
1124  b = 1.0 / b;
1125  i2 = 1 - icv + ice * lpivot;
1126  incr = ice * (l1 - lpivot);
1127  for (j = 0; j < ncv; j++)
1128  {
1129  i2 += icv;
1130  i3 = i2 + incr;
1131  i4 = i3;
1132  sm = cm[i2-1] * (*up);
1133  for (k = l1; k < m; k++)
1134  {
1135  sm += cm[i3-1] * u[k*u_dim1];
1136  i3 += ice;
1137  }
1138  if (sm != 0.0)
1139  {
1140  sm *= b;
1141  cm[i2-1] += sm * (*up);
1142  for (k = l1; k < m; k++)
1143  {
1144  cm[i4-1] += sm * u[k*u_dim1];
1145  i4 += ice;
1146  }
1147  }
1148  }
1149  return(0);
1150 } /* _nnls_h12 */
1151 
1152 /*****************************************************************************
1153  * Algorithm NNLS (Non-negative least-squares)
1154  *
1155  * Given an m by n matrix A, and an m-vector B, computes an n-vector X,
1156  * that solves the least squares problem
1157  * A * X = B , subject to X>=0
1158  *
1159  * Function returns 0 if successful, 1, if iteration count exceeded 3*N,
1160  * or 2 in case of invalid problem dimensions or memory allocation error.
1161  *
1162  * Instead of pointers for working space, NULL can be given to let this
1163  * function to allocate and free the required memory.
1164  */
1165 int nnls(
1166  double *a, int m, int n,
1167  /* On entry, a[n][m] contains the m by n matrix A. On exit, a[][] contains
1168  the product matrix Q*A, where Q is an m by n orthogonal matrix generated
1169  implicitly by this function.*/
1170  double *b,
1171  /* On entry, b[] must contain the m-vector B.
1172  On exit, b[] contains Q*B */
1173  double *x,
1174  /* On exit, x[] will contain the solution vector */
1175  double *rnorm,
1176  /* On exit, rnorm contains the Euclidean norm of the residual vector */
1177  double *wp, /* An n-array of working space, w[]. */
1178  /* On exit, w[] will contain the dual solution vector.
1179  w[i]=0.0 for all i in set p and w[i]<=0.0 for all i in set z. */
1180  double *zzp, /* An m-array of working space, zz[]. */
1181  int *indexp /* An n-array of working space, index[]. */
1182 )
1183 {
1184  int pfeas, ret = 0, iz, jz, iz1, iz2, npp1, *index;
1185  double d1, d2, sm, up, ss, *w, *zz;
1186  int iter, k, j = 0, l, itmax, izmax = 0, nsetp, ii, jj = 0, ip;
1187  double temp, wmax, t, alpha, asave, dummy, unorm, ztest, cc;
1188 
1189 
1190  /* Check the parameters and data */
1191  if (m <= 0 || n <= 0 || a == NULL || b == NULL || x == NULL)
1192  return(2);
1193  /* Allocate memory for working space, if required */
1194  if (wp != NULL)
1195  w = wp;
1196  else
1197  w = (double*)calloc(n, sizeof(double));
1198  if (zzp != NULL)
1199  zz = zzp;
1200  else
1201  zz = (double*)calloc(m, sizeof(double));
1202  if (indexp != NULL)
1203  index = indexp;
1204  else
1205  index = (int*)calloc(n, sizeof(int));
1206  if (w == NULL || zz == NULL || index == NULL)
1207  return(2);
1208 
1209  /* Initialize the arrays INDEX[] and X[] */
1210  for (k = 0; k < n; k++)
1211  {
1212  x[k] = 0.;
1213  index[k] = k;
1214  }
1215  iz2 = n - 1;
1216  iz1 = 0;
1217  nsetp = 0;
1218  npp1 = 0;
1219 
1220  /* Main loop; quit if all coeffs are already in the solution or */
1221  /* if M cols of A have been triangularized */
1222  iter = 0;
1223  itmax = n * 3;
1224  while (iz1 <= iz2 && nsetp < m)
1225  {
1226  /* Compute components of the dual (negative gradient) vector W[] */
1227  for (iz = iz1; iz <= iz2; iz++)
1228  {
1229  j = index[iz];
1230  sm = 0.;
1231  for (l = npp1; l < m; l++)
1232  sm += a[j*m+l] * b[l];
1233  w[j] = sm;
1234  }
1235 
1236  while (1)
1237  {
1238  /* Find largest positive W[j] */
1239  for (wmax = 0., iz = iz1; iz <= iz2; iz++)
1240  {
1241  j = index[iz];
1242  if (w[j] > wmax)
1243  {
1244  wmax = w[j];
1245  izmax = iz;
1246  }
1247  }
1248 
1249  /* Terminate if wmax<=0.; */
1250  /* it indicates satisfaction of the Kuhn-Tucker conditions */
1251  if (wmax <= 0.0)
1252  break;
1253  iz = izmax;
1254  j = index[iz];
1255 
1256  /* The sign of W[j] is ok for j to be moved to set P. */
1257  /* Begin the transformation and check new diagonal element to avoid */
1258  /* near linear dependence. */
1259  asave = a[j*m+npp1];
1260  _nnls_h12(1, npp1, npp1 + 1, m, &a[j*m+0], 1, &up, &dummy, 1, 1, 0);
1261  unorm = 0.;
1262  if (nsetp != 0)
1263  for (l = 0; l < nsetp; l++)
1264  {
1265  d1 = a[j*m+l];
1266  unorm += d1 * d1;
1267  }
1268  unorm = sqrt(unorm);
1269  d2 = unorm + (d1 = a[j*m+npp1], fabs(d1)) * 0.01;
1270  if ((d2 - unorm) > 0.)
1271  {
1272  /* Col j is sufficiently independent. Copy B into ZZ, update ZZ */
1273  /* and solve for ztest ( = proposed new value for X[j] ) */
1274  for (l = 0; l < m; l++)
1275  zz[l] = b[l];
1276  _nnls_h12(2, npp1, npp1 + 1, m, &a[j*m+0], 1, &up, zz, 1, 1, 1);
1277  ztest = zz[npp1] / a[j*m+npp1];
1278  /* See if ztest is positive */
1279  if (ztest > 0.)
1280  break;
1281  }
1282 
1283  /* Reject j as a candidate to be moved from set Z to set P. Restore */
1284  /* A[npp1,j], set W[j]=0., and loop back to test dual coeffs again */
1285  a[j*m+npp1] = asave;
1286  w[j] = 0.;
1287  } /* while(1) */
1288  if (wmax <= 0.0)
1289  break;
1290 
1291  /* Index j=INDEX[iz] has been selected to be moved from set Z to set P. */
1292  /* Update B and indices, apply householder transformations to cols in */
1293  /* new set Z, zero subdiagonal elts in col j, set W[j]=0. */
1294  for (l = 0; l < m; ++l)
1295  b[l] = zz[l];
1296  index[iz] = index[iz1];
1297  index[iz1] = j;
1298  iz1++;
1299  nsetp = npp1 + 1;
1300  npp1++;
1301  if (iz1 <= iz2)
1302  for (jz = iz1; jz <= iz2; jz++)
1303  {
1304  jj = index[jz];
1305  _nnls_h12(2, nsetp - 1, npp1, m, &a[j*m+0], 1, &up,
1306  &a[jj*m+0], 1, m, 1);
1307  }
1308  if (nsetp != m)
1309  for (l = npp1; l < m; l++)
1310  a[j*m+l] = 0.;
1311  w[j] = 0.;
1312  /* Solve the triangular system; store the solution temporarily in Z[] */
1313  for (l = 0; l < nsetp; l++)
1314  {
1315  ip = nsetp - (l + 1);
1316  if (l != 0)
1317  for (ii = 0; ii <= ip; ii++)
1318  zz[ii] -= a[jj*m+ii] * zz[ip+1];
1319  jj = index[ip];
1320  zz[ip] /= a[jj*m+ip];
1321  }
1322 
1323  /* Secondary loop begins here */
1324  while (++iter < itmax)
1325  {
1326  /* See if all new constrained coeffs are feasible; if not, compute alpha */
1327  for (alpha = 2.0, ip = 0; ip < nsetp; ip++)
1328  {
1329  l = index[ip];
1330  if (zz[ip] <= 0.)
1331  {
1332  t = -x[l] / (zz[ip] - x[l]);
1333  if (alpha > t)
1334  {
1335  alpha = t;
1336  jj = ip - 1;
1337  }
1338  }
1339  }
1340 
1341  /* If all new constrained coeffs are feasible then still alpha==2. */
1342  /* If so, then exit from the secondary loop to main loop */
1343  if (alpha == 2.0)
1344  break;
1345  /* Use alpha (0.<alpha<1.) to interpolate between old X and new ZZ */
1346  for (ip = 0; ip < nsetp; ip++)
1347  {
1348  l = index[ip];
1349  x[l] += alpha * (zz[ip] - x[l]);
1350  }
1351 
1352  /* Modify A and B and the INDEX arrays to move coefficient i */
1353  /* from set P to set Z. */
1354  k = index[jj+1];
1355  pfeas = 1;
1356  do
1357  {
1358  x[k] = 0.;
1359  if (jj != (nsetp - 1))
1360  {
1361  jj++;
1362  for (j = jj + 1; j < nsetp; j++)
1363  {
1364  ii = index[j];
1365  index[j-1] = ii;
1366  _nnls_g1(a[ii*m+j-1], a[ii*m+j], &cc, &ss, &a[ii*m+j-1]);
1367  for (a[ii*m+j] = 0., l = 0; l < n; l++)
1368  if (l != ii)
1369  {
1370  /* Apply procedure G2 (CC,SS,A(J-1,L),A(J,L)) */
1371  temp = a[l*m+j-1];
1372  a[l*m+j-1] = cc * temp + ss * a[l*m+j];
1373  a[l*m+j] = -ss * temp + cc * a[l*m+j];
1374  }
1375  /* Apply procedure G2 (CC,SS,B(J-1),B(J)) */
1376  temp = b[j-1];
1377  b[j-1] = cc * temp + ss * b[j];
1378  b[j] = -ss * temp + cc * b[j];
1379  }
1380  }
1381  npp1 = nsetp - 1;
1382  nsetp--;
1383  iz1--;
1384  index[iz1] = k;
1385 
1386  /* See if the remaining coeffs in set P are feasible; they should */
1387  /* be because of the way alpha was determined. If any are */
1388  /* infeasible it is due to round-off error. Any that are */
1389  /* nonpositive will be set to zero and moved from set P to set Z */
1390  for (jj = 0; jj < nsetp; jj++)
1391  {
1392  k = index[jj];
1393  if (x[k] <= 0.)
1394  {
1395  pfeas = 0;
1396  break;
1397  }
1398  }
1399  }
1400  while (pfeas == 0);
1401 
1402  /* Copy B[] into zz[], then solve again and loop back */
1403  for (k = 0; k < m; k++)
1404  zz[k] = b[k];
1405  for (l = 0; l < nsetp; l++)
1406  {
1407  ip = nsetp - (l + 1);
1408  if (l != 0)
1409  for (ii = 0; ii <= ip; ii++)
1410  zz[ii] -= a[jj*m+ii] * zz[ip+1];
1411  jj = index[ip];
1412  zz[ip] /= a[jj*m+ip];
1413  }
1414  } /* end of secondary loop */
1415  if (iter > itmax)
1416  {
1417  ret = 1;
1418  break;
1419  }
1420  for (ip = 0; ip < nsetp; ip++)
1421  {
1422  k = index[ip];
1423  x[k] = zz[ip];
1424  }
1425  } /* end of main loop */
1426  /* Compute the norm of the final residual vector */
1427  sm = 0.;
1428  if (npp1 < m)
1429  for (k = npp1; k < m; k++)
1430  sm += (b[k] * b[k]);
1431  else
1432  for (j = 0; j < n; j++)
1433  w[j] = 0.;
1434  *rnorm = sqrt(sm);
1435  /* Free working space, if it was allocated here */
1436  if (wp == NULL)
1437  free(w);
1438  if (zzp == NULL)
1439  free(zz);
1440  if (indexp == NULL)
1441  free(index);
1442  return(ret);
1443 } /* nnls_ */
1444 /****************************************************************************/
1445 /****************************************************************************/
1446 /*
1447  nnlsWght()
1448 
1449  Algorithm for weighting the problem that is given to nnls-algorithm.
1450  Square roots of weights are used because in nnls the difference
1451  w*A-w*b is squared.
1452  Algorithm returns zero if successful, 1 if arguments are inappropriate.
1453 
1454 */
1455 int nnlsWght(int N, int M, double *A, double *b, double *weight)
1456 {
1457  int n, m;
1458  double *w;
1459 
1460  /* Check the arguments */
1461  if (N < 1 || M < 1 || A == NULL || b == NULL || weight == NULL)
1462  return(1);
1463 
1464  /* Allocate memory */
1465  w = (double*)malloc(M * sizeof(double));
1466  if (w == NULL)
1467  return(2);
1468 
1469  /* Check that weights are not zero and get the square roots of them to w[] */
1470  for (m = 0; m < M; m++)
1471  {
1472  if (weight[m] <= 1.0e-20)
1473  w[m] = 0.0;
1474  else
1475  w[m] = sqrt(weight[m]);
1476  }
1477 
1478  /* Multiply rows of matrix A and elements of vector b with weights*/
1479  for (m = 0; m < M; m++)
1480  {
1481  for (n = 0; n < N; n++)
1482  {
1483  A[n*M+m] *= w[m];
1484  }
1485  b[m] *= w[m];
1486  }
1487 
1488  free(w);
1489  return(0);
1490 }
1491 /****************************************************************************/
1492 
1493 /* Singular value descomposition ------------------------------------------- */
1494 /* Copied from Bilib library (linearalgebra.h) */
1495 double Pythag(double a, double b)
1496 {
1497  double absa, absb;
1498  absa = fabs(a);
1499  absb = fabs(b);
1500  if (absb < absa)
1501  return(absa * sqrt(1.0 + absb * absb / (absa * absa)));
1502  else
1503  return((absb == 0.0) ? (0.0) : (absb * sqrt(1.0 + absa * absa / (absb * absb))));
1504 }
1505 
1506 #define SVDMAXITER 1000
1507 void svdcmp(double *U, int Lines, int Columns, double *W, double *V)
1508 {
1509  double Norm, Scale;
1510  double c, f, g, h, s;
1511  double x, y, z;
1512  long i, its, j, jj, k, l = 0L, nm = 0L;
1513  bool Flag;
1514  int MaxIterations = SVDMAXITER;
1515 
1516  std::vector<double> buffer(Columns*Columns);
1517  auto *rv1= buffer.data();
1518  g = Scale = Norm = 0.0;
1519  for (i = 0L; (i < Columns); i++)
1520  {
1521  l = i + 1L;
1522  rv1[i] = Scale * g;
1523  g = s = Scale = 0.0;
1524  if (i < Lines)
1525  {
1526  for (k = i; (k < Lines); k++)
1527  {
1528  Scale += fabs(U[k * Columns + i]);
1529  }
1530  if (Scale != 0.0)
1531  {
1532  for (k = i; (k < Lines); k++)
1533  {
1534  U[k * Columns + i] /= Scale;
1535  s += U[k * Columns + i] * U[k * Columns + i];
1536  }
1537  f = U[i * Columns + i];
1538  g = (0.0 <= f) ? (-sqrt(s)) : (sqrt(s));
1539  h = f * g - s;
1540  U[i * Columns + i] = f - g;
1541  for (j = l; (j < Columns); j++)
1542  {
1543  for (s = 0.0, k = i; (k < Lines); k++)
1544  {
1545  s += U[k * Columns + i] * U[k * Columns + j];
1546  }
1547  f = s / h;
1548  for (k = i; (k < Lines); k++)
1549  {
1550  U[k * Columns + j] += f * U[k * Columns + i];
1551  }
1552  }
1553  for (k = i; (k < Lines); k++)
1554  {
1555  U[k * Columns + i] *= Scale;
1556  }
1557  }
1558  }
1559  W[i] = Scale * g;
1560  g = s = Scale = 0.0;
1561  if ((i < Lines) && (i != (Columns - 1L)))
1562  {
1563  for (k = l; (k < Columns); k++)
1564  {
1565  Scale += fabs(U[i * Columns + k]);
1566  }
1567  if (Scale != 0.0)
1568  {
1569  for (k = l; (k < Columns); k++)
1570  {
1571  U[i * Columns + k] /= Scale;
1572  s += U[i * Columns + k] * U[i * Columns + k];
1573  }
1574  f = U[i * Columns + l];
1575  g = (0.0 <= f) ? (-sqrt(s)) : (sqrt(s));
1576  h = f * g - s;
1577  U[i * Columns + l] = f - g;
1578  for (k = l; (k < Columns); k++)
1579  {
1580  rv1[k] = U[i * Columns + k] / h;
1581  }
1582  for (j = l; (j < Lines); j++)
1583  {
1584  for (s = 0.0, k = l; (k < Columns); k++)
1585  {
1586  s += U[j * Columns + k] * U[i * Columns + k];
1587  }
1588  for (k = l; (k < Columns); k++)
1589  {
1590  U[j * Columns + k] += s * rv1[k];
1591  }
1592  }
1593  for (k = l; (k < Columns); k++)
1594  {
1595  U[i * Columns + k] *= Scale;
1596  }
1597  }
1598  }
1599  Norm = ((fabs(W[i]) + fabs(rv1[i])) < Norm) ? (Norm) : (fabs(W[i]) + fabs(rv1[i]));
1600  }
1601  for (i = Columns - 1L; (0L <= i); i--)
1602  {
1603  if (i < (Columns - 1L))
1604  {
1605  if (g != 0.0)
1606  {
1607  for (j = l; (j < Columns); j++)
1608  {
1609  V[j * Columns + i] = U[i * Columns + j] / (U[i * Columns + l] * g);
1610  }
1611  for (j = l; (j < Columns); j++)
1612  {
1613  for (s = 0.0, k = l; (k < Columns); k++)
1614  {
1615  s += U[i * Columns + k] * V[k * Columns + j];
1616  }
1617  for (k = l; (k < Columns); k++)
1618  {
1619  if (s != 0.0)
1620  {
1621  V[k * Columns + j] += s * V[k * Columns + i];
1622  }
1623  }
1624  }
1625  }
1626  for (j = l; (j < Columns); j++)
1627  {
1628  V[i * Columns + j] = V[j * Columns + i] = 0.0;
1629  }
1630  }
1631  V[i * Columns + i] = 1.0;
1632  g = rv1[i];
1633  l = i;
1634  }
1635  for (i = (Lines < Columns) ? (Lines - 1L) : (Columns - 1L); (0L <= i); i--)
1636  {
1637  l = i + 1L;
1638  g = W[i];
1639  for (j = l; (j < Columns); j++)
1640  {
1641  U[i * Columns + j] = 0.0;
1642  }
1643  if (g != 0.0)
1644  {
1645  g = 1.0 / g;
1646  for (j = l; (j < Columns); j++)
1647  {
1648  for (s = 0.0, k = l; (k < Lines); k++)
1649  {
1650  s += U[k * Columns + i] * U[k * Columns + j];
1651  }
1652  f = s * g / U[i * Columns + i];
1653  for (k = i; (k < Lines); k++)
1654  {
1655  if (f != 0.0)
1656  {
1657  U[k * Columns + j] += f * U[k * Columns + i];
1658  }
1659  }
1660  }
1661  for (j = i; (j < Lines); j++)
1662  {
1663  U[j * Columns + i] *= g;
1664  }
1665  }
1666  else
1667  {
1668  for (j = i; (j < Lines); j++)
1669  {
1670  U[j * Columns + i] = 0.0;
1671  }
1672  }
1673  U[i * Columns + i] += 1.0;
1674  }
1675  for (k = Columns - 1L; (0L <= k); k--)
1676  {
1677  for (its = 1L; (its <= MaxIterations); its++)
1678  {
1679  Flag = true;
1680  for (l = k; (0L <= l); l--)
1681  {
1682  nm = l - 1L;
1683  if ((fabs(rv1[l]) + Norm) == Norm)
1684  {
1685  Flag = false;
1686  break;
1687  }
1688  if ((fabs(W[nm]) + Norm) == Norm)
1689  {
1690  break;
1691  }
1692  }
1693  if (Flag)
1694  {
1695  c = 0.0;
1696  s = 1.0;
1697  for (i = l; (i <= k); i++)
1698  {
1699  f = s * rv1[i];
1700  rv1[i] *= c;
1701  if ((fabs(f) + Norm) == Norm)
1702  {
1703  break;
1704  }
1705  g = W[i];
1706  h = Pythag(f, g);
1707  W[i] = h;
1708  h = 1.0 / h;
1709  c = g * h;
1710  s = -f * h;
1711  for (j = 0L; (j < Lines); j++)
1712  {
1713  y = U[j * Columns + nm];
1714  z = U[j * Columns + i];
1715  U[j * Columns + nm] = y * c + z * s;
1716  U[j * Columns + i] = z * c - y * s;
1717  }
1718  }
1719  }
1720  z = W[k];
1721  if (l == k)
1722  {
1723  if (z < 0.0)
1724  {
1725  W[k] = -z;
1726  for (j = 0L; (j < Columns); j++)
1727  {
1728  V[j * Columns + k] = -V[j * Columns + k];
1729  }
1730  }
1731  break;
1732  }
1733  if (its == MaxIterations) return;
1734  x = W[l];
1735  nm = k - 1L;
1736  y = W[nm];
1737  g = rv1[nm];
1738  h = rv1[k];
1739  f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y);
1740  g = Pythag(f, 1.0);
1741  f = ((x - z) * (x + z) + h * ((y / (f + ((0.0 <= f) ? (fabs(g))
1742  : (-fabs(g))))) - h)) / x;
1743  c = s = 1.0;
1744  for (j = l; (j <= nm); j++)
1745  {
1746  i = j + 1L;
1747  g = rv1[i];
1748  y = W[i];
1749  h = s * g;
1750  g = c * g;
1751  z = Pythag(f, h);
1752  rv1[j] = z;
1753  c = f / z;
1754  s = h / z;
1755  f = x * c + g * s;
1756  g = g * c - x * s;
1757  h = y * s;
1758  y *= c;
1759  for (jj = 0L; (jj < Columns); jj++)
1760  {
1761  x = V[jj * Columns + j];
1762  z = V[jj * Columns + i];
1763  V[jj * Columns + j] = x * c + z * s;
1764  V[jj * Columns + i] = z * c - x * s;
1765  }
1766  z = Pythag(f, h);
1767  W[j] = z;
1768  if (z != 0.0)
1769  {
1770  z = 1.0 / z;
1771  c = f * z;
1772  s = h * z;
1773  }
1774  f = c * g + s * y;
1775  x = c * y - s * g;
1776  for (jj = 0L; (jj < Lines); jj++)
1777  {
1778  y = U[jj * Columns + j];
1779  z = U[jj * Columns + i];
1780  U[jj * Columns + j] = y * c + z * s;
1781  U[jj * Columns + i] = z * c - y * s;
1782  }
1783  }
1784  rv1[l] = 0.0;
1785  rv1[k] = f;
1786  W[k] = x;
1787  }
1788  }
1789 }
1790 
1791 void svbksb(double *u, double *w, double *v, int m, int n, double *b, double *x)
1792 {
1793  int jj, j, i;
1794  double s;
1795 
1796  std::vector<double> buffer(n);
1797  auto *tmp= buffer.data()-1;
1798  for (j = 1;j <= n;j++)
1799  {
1800  s = 0.0;
1801  if (w[j])
1802  {
1803  for (i = 1;i <= m;i++)
1804  s += u[i*n+j] * b[i];
1805  s /= w[j];
1806  }
1807  tmp[j] = s;
1808  }
1809  for (j = 1;j <= n;j++)
1810  {
1811  s = 0.0;
1812  for (jj = 1;jj <= n;jj++)
1813  s += v[j*n+jj] * tmp[jj];
1814  x[j] = s;
1815  }
1816 }
1817 
1818 // CFSQP -------------------------------------------------------------------
1819 
1820 #ifndef TRUE
1821 #define TRUE 1
1822 #endif
1823 #ifndef FALSE
1824 #define FALSE 0
1825 #endif
1827 
1828 /* Declare and initialize user-accessible stopping criterion */
1829 double objeps = -1.e0;
1830 double objrep = -1.e0;
1831 double gLgeps = -1.e0;
1832 extern int nstop;
1833 
1834 /* CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
1835  !!!! NOTICE !!!!
1836 
1837 1. The routines contained in this file are due to Prof. K.Schittkowski
1838  of the University of Bayreuth, Germany (modification of routines
1839  due to Prof. MJD Powell at the University of Cambridge). They can
1840  be freely distributed.
1841 
1842 2. A few minor modifications were performed at the University of
1843  Maryland. They are marked in the code by "umd".
1844 
1845  A.L. Tits, J.L. Zhou, and
1846  Craig Lawrence
1847  University of Maryland
1848 
1849  ***********************************************************************
1850 
1851 
1852 
1853  SOLUTION OF QUADRATIC PROGRAMMING PROBLEMS
1854 
1855 
1856 
1857  QL0001 SOLVES THE QUADRATIC PROGRAMMING PROBLEM
1858 
1859  MINIMIZE .5*X'*C*X + D'*X
1860  SUBJECT TO A(J)*X + B(J) = 0 , J=1,...,ME
1861  A(J)*X + B(J) >= 0 , J=ME+1,...,M
1862  XL <= X <= XU
1863 
1864 HERE C MUST BE AN N BY N SYMMETRIC AND POSITIVE MATRIX, D AN N-DIMENSIONAL
1865 VECTOR, A AN M BY N MATRIX AND B AN M-DIMENSIONAL VECTOR. THE ABOVE
1866 SITUATION IS INDICATED BY IWAR(1)=1. ALTERNATIVELY, I.E. IF IWAR(1)=0,
1867 THE OBJECTIVE FUNCTION MATRIX CAN ALSO BE PROVIDED IN FACTORIZED FORM.
1868 IN THIS CASE, C IS AN UPPER TRIANGULAR MATRIX.
1869 
1870 THE SUBROUTINE REORGANIZES SOME DATA SO THAT THE PROBLEM CAN BE SOLVED
1871 BY A MODIFICATION OF AN ALGORITHM PROPOSED BY POWELL (1983).
1872 
1873 
1874 USAGE:
1875 
1876  QL0001(M,ME,MMAX,N,NMAX,MNN,C,D,A,B,XL,XU,X,U,IOUT,IFAIL,IPRINT,
1877  WAR,LWAR,IWAR,LIWAR)
1878 
1879 
1880  DEFINITION OF THE PARAMETERS:
1881 
1882  M : TOTAL NUMBER OF CONSTRAINTS.
1883  ME : NUMBER OF EQUALITY CONSTRAINTS.
1884  MMAX : ROW DIMENSION OF A. MMAX MUST BE AT LEAST ONE AND GREATER
1885  THAN M.
1886  N : NUMBER OF VARIABLES.
1887  NMAX : ROW DIMENSION OF C. NMAX MUST BE GREATER OR EQUAL TO N.
1888  MNN : MUST BE EQUAL TO M + N + N.
1889  C(NMAX,NMAX): OBJECTIVE FUNCTION MATRIX WHICH SHOULD BE SYMMETRIC AND
1890  POSITIVE DEFINITE. IF IWAR(1) = 0, C IS SUPPOSED TO BE THE
1891  CHOLESKEY-FACTOR OF ANOTHER MATRIX, I.E. C IS UPPER
1892  TRIANGULAR.
1893  D(NMAX) : CONTAINS THE CONSTANT VECTOR OF THE OBJECTIVE FUNCTION.
1894  A(MMAX,NMAX): CONTAINS THE DATA MATRIX OF THE LINEAR CONSTRAINTS.
1895  B(MMAX) : CONTAINS THE CONSTANT DATA OF THE LINEAR CONSTRAINTS.
1896  XL(N),XU(N): CONTAIN THE LOWER AND UPPER BOUNDS FOR THE VARIABLES.
1897  X(N) : ON RETURN, X CONTAINS THE OPTIMAL SOLUTION VECTOR.
1898  U(MNN) : ON RETURN, U CONTAINS THE LAGRANGE MULTIPLIERS. THE FIRST
1899  M POSITIONS ARE RESERVED FOR THE MULTIPLIERS OF THE M
1900  LINEAR CONSTRAINTS AND THE SUBSEQUENT ONES FOR THE
1901  MULTIPLIERS OF THE LOWER AND UPPER BOUNDS. ON SUCCESSFUL
1902  TERMINATION, ALL VALUES OF U WITH RESPECT TO INEQUALITIES
1903  AND BOUNDS SHOULD BE GREATER OR EQUAL TO ZERO.
1904  IOUT : INTEGER INDICATING THE DESIRED OUTPUT UNIT NUMBER, I.E.
1905  ALL WRITE-STATEMENTS START WITH 'WRITE(IOUT,... '.
1906  IFAIL : SHOWS THE TERMINATION REASON.
1907  IFAIL = 0 : SUCCESSFUL RETURN.
1908  IFAIL = 1 : TOO MANY ITERATIONS (MORE THAN 40*(N+M)).
1909  IFAIL = 2 : ACCURACY INSUFFICIENT TO SATISFY CONVERGENCE
1910  CRITERION.
1911  IFAIL = 5 : LENGTH OF A WORKING ARRAY IS TOO SHORT.
1912  IFAIL > 10 : THE CONSTRAINTS ARE INCONSISTENT.
1913  IPRINT : OUTPUT CONTROL.
1914  IPRINT = 0 : NO OUTPUT OF QL0001.
1915  IPRINT > 0 : BRIEF OUTPUT IN ERROR CASES.
1916  WAR(LWAR) : REAL WORKING ARRAY. THE LENGTH LWAR SHOULD BE GRATER THAN
1917  3*NMAX*NMAX/2 + 10*NMAX + 2*MMAX.
1918  IWAR(LIWAR): INTEGER WORKING ARRAY. THE LENGTH LIWAR SHOULD BE AT
1919  LEAST N.
1920  IF IWAR(1)=0 INITIALLY, THEN THE CHOLESKY DECOMPOSITION
1921  WHICH IS REQUIRED BY THE DUAL ALGORITHM TO GET THE FIRST
1922  UNCONSTRAINED MINIMUM OF THE OBJECTIVE FUNCTION, IS
1923  PERFORMED INTERNALLY. OTHERWISE, I.E. IF IWAR(1)=1, THEN
1924  IT IS ASSUMED THAT THE USER PROVIDES THE INITIAL FAC-
1925  TORIZATION BY HIMSELF AND STORES IT IN THE UPPER TRIAN-
1926  GULAR PART OF THE ARRAY C.
1927 
1928  A NAMED COMMON-BLOCK /CMACHE/EPS MUST BE PROVIDED BY THE USER,
1929  WHERE EPS DEFINES A GUESS FOR THE UNDERLYING MACHINE PRECISION.
1930 
1931 
1932  AUTHOR: K. SCHITTKOWSKI,
1933  MATHEMATISCHES INSTITUT,
1934  UNIVERSITAET BAYREUTH,
1935  8580 BAYREUTH,
1936  GERMANY, F.R.
1937 
1938 
1939  VERSION: 1.4 (MARCH, 1987)
1940 */
1941 /* f2c.h -- Standard Fortran to C header file */
1942 
1947 #ifndef F2C_INCLUDE
1948 #define F2C_INCLUDE
1949 
1950 typedef int integer;
1951 typedef char *address;
1952 typedef short int shortint;
1953 typedef float cfsqpreal;
1954 typedef double doublereal;
1955 typedef struct
1956 {
1957  cfsqpreal r, i;
1958 }
1959 cfsqpcomplex;
1960 typedef struct
1961 {
1962  doublereal r, i;
1963 }
1965 typedef long int logical;
1966 typedef short int shortlogical;
1967 
1968 #define TRUE_ (1)
1969 #define FALSE_ (0)
1970 
1971 /* Extern is for use with -E */
1972 #ifndef Extern
1973 #define Extern extern
1974 #endif
1975 
1976 /* I/O stuff */
1977 
1978 #ifdef f2c_i2
1979 /* for -i2 */
1980 typedef short flag;
1981 typedef short ftnlen;
1982 typedef short ftnint;
1983 #else
1984 typedef long flag;
1985 typedef long ftnlen;
1986 typedef long ftnint;
1987 #endif
1988 
1989 /*external read, write*/
1990 typedef struct
1991 {
1992  flag cierr;
1993  ftnint ciunit;
1994  flag ciend;
1995  char *cifmt;
1996  ftnint cirec;
1997 }
1998 cilist;
1999 
2000 /*internal read, write*/
2001 typedef struct
2002 {
2003  flag icierr;
2004  char *iciunit;
2005  flag iciend;
2006  char *icifmt;
2007  ftnint icirlen;
2008  ftnint icirnum;
2009 }
2010 icilist;
2011 
2012 /*open*/
2013 typedef struct
2014 {
2015  flag oerr;
2016  ftnint ounit;
2017  char *ofnm;
2018  ftnlen ofnmlen;
2019  char *osta;
2020  char *oacc;
2021  char *ofm;
2022  ftnint orl;
2023  char *oblnk;
2024 }
2025 olist;
2026 
2027 /*close*/
2028 typedef struct
2029 {
2030  flag cerr;
2031  ftnint cunit;
2032  char *csta;
2033 }
2034 cllist;
2035 
2036 /*rewind, backspace, endfile*/
2037 typedef struct
2038 {
2039  flag aerr;
2040  ftnint aunit;
2041 }
2042 alist;
2043 
2044 /* inquire */
2045 typedef struct
2046 {
2047  flag inerr;
2048  ftnint inunit;
2049  char *infile;
2050  ftnlen infilen;
2051  ftnint *inex; /*parameters in standard's order*/
2052  ftnint *inopen;
2053  ftnint *innum;
2054  ftnint *innamed;
2055  char *inname;
2056  ftnlen innamlen;
2057  char *inacc;
2058  ftnlen inacclen;
2059  char *inseq;
2060  ftnlen inseqlen;
2061  char *indir;
2062  ftnlen indirlen;
2063  char *infmt;
2064  ftnlen infmtlen;
2065  char *inform;
2066  ftnint informlen;
2067  char *inunf;
2068  ftnlen inunflen;
2069  ftnint *inrecl;
2070  ftnint *innrec;
2071  char *inblank;
2072  ftnlen inblanklen;
2073 }
2074 inlist;
2075 
2076 #define VOID void
2077 
2078 union Multitype { /* for multiple entry points */
2079  shortint h;
2080  integer i;
2081  cfsqpreal r;
2082  doublereal d;
2085 };
2086 
2087 typedef union Multitype Multitype;
2088 
2089 typedef long Long;
2090 
2091 struct Vardesc
2092 { /* for Namelist */
2093  char *name;
2094  char *addr;
2095  Long *dims;
2096  int type;
2097 };
2098 typedef struct Vardesc Vardesc;
2099 
2100 struct Namelist
2101 {
2102  char *name;
2104  int nvars;
2105 };
2106 typedef struct Namelist Namelist;
2107 
2108 #define abs(x) ((x) >= 0 ? (x) : -(x))
2109 #define dabs(x) (doublereal)abs(x)
2110 #define min(a,b) ((a) <= (b) ? (a) : (b))
2111 #define max(a,b) ((a) >= (b) ? (a) : (b))
2112 #define dmin(a,b) (doublereal)min(a,b)
2113 #define dmax(a,b) (doublereal)max(a,b)
2114 
2115 /* procedure parameter types for -A and -C++ */
2116 
2117 #define F2C_proc_par_types 1
2118 #ifdef __cplusplus
2119 typedef int /* Unknown procedure type */ (*U_fp)(...);
2120 typedef shortint(*J_fp)(...);
2121 typedef integer(*I_fp)(...);
2122 typedef cfsqpreal(*R_fp)(...);
2123 typedef doublereal(*D_fp)(...), (*E_fp)(...);
2124 typedef /* Complex */ VOID(*C_fp)(...);
2125 typedef /* Double Complex */ VOID(*Z_fp)(...);
2126 typedef logical(*L_fp)(...);
2127 typedef shortlogical(*K_fp)(...);
2128 typedef /* Character */ VOID(*H_fp)(...);
2129 typedef /* Subroutine */ int(*S_fp)(...);
2130 #else
2131 typedef int /* Unknown procedure type */ (*U_fp)();
2132 typedef shortint(*J_fp)();
2133 typedef integer(*I_fp)();
2134 typedef cfsqpreal(*R_fp)();
2135 typedef doublereal(*D_fp)(), (*E_fp)();
2136 typedef /* Complex */ VOID(*C_fp)();
2137 typedef /* Double Complex */ VOID(*Z_fp)();
2138 typedef logical(*L_fp)();
2139 typedef shortlogical(*K_fp)();
2140 typedef /* Character */ VOID(*H_fp)();
2141 typedef /* Subroutine */ int(*S_fp)();
2142 #endif
2143 /* E_fp is for real functions when -R is not specified */
2144 typedef VOID C_f; /* complex function */
2145 typedef VOID H_f; /* character function */
2146 typedef VOID Z_f; /* double complex function */
2147 typedef doublereal E_f; /* real function with -R not specified */
2148 
2149 /* undef any lower-case symbols that your C compiler predefines, e.g.: */
2150 
2151 /* asolano: confuses Portland Group compiler, doesn't seem to affect anything */
2152 #define Skip_f2c_Undefs
2153 
2154 #ifndef Skip_f2c_Undefs
2155 #undef cray
2156 #undef gcos
2157 #undef mc68010
2158 #undef mc68020
2159 #undef mips
2160 #undef pdp11
2161 #undef sgi
2162 #undef sparc
2163 #undef sun
2164 #undef sun2
2165 #undef sun3
2166 #undef sun4
2167 #undef u370
2168 #undef u3b
2169 #undef u3b2
2170 #undef u3b5
2171 #undef unix
2172 #undef vax
2173 #endif
2174 #endif
2175 
2176 
2177 
2178 /* Common Block Declarations */
2179 
2180 struct Tcmache
2181 {
2183 }
2184 cmache_;
2185 
2186 #define cmache_1 cmache_
2187 
2188 /* umd */
2189 /*
2190 ql0002_ is declared here to provide ANSI C compliance.
2191 (Thanks got to Martin Wauchope for providing this correction)
2192 */
2193 #ifdef __STDC__
2194 
2196  integer *mn, integer *mnn, integer *nmax,
2197  logical *lql,
2200  integer *nact, integer *iact, integer *maxit,
2201  doublereal *vsmall,
2202  integer *info,
2203  doublereal *diag, doublereal *w,
2204  integer *lw);
2205 #else
2206 int ql0002_();
2207 #endif
2208 /* umd */
2209 /*
2210 When the fortran code was f2c converted, the use of fortran COMMON
2211 blocks was no longer available. Thus an additional variable, eps1,
2212 was added to the parameter list to account for this.
2213 */
2214 /* umd */
2215 /*
2216 Two alternative definitions are provided in order to give ANSI
2217 compliance.
2218 */
2219 #ifdef __STDC__
2220 int ql0001_(int *m, int *me, int *mmax, int *n, int *nmax, int *mnn,
2221  double *c, double *d, double *a, double *b, double *xl,
2222  double *xu, double *x, double *u, int *iout, int *ifail,
2223  int *iprint, double *war, int *lwar, int *iwar, int *liwar,
2224  double *eps1)
2225 #else
2226 /* Subroutine */
2227 int ql0001_(m, me, mmax, n, nmax, mnn, c, d, a, b, xl, xu, x,
2228  u, iout, ifail, iprint, war, lwar, iwar, liwar, eps1)
2229 integer *m, *me, *mmax, *n, *nmax, *mnn;
2230 doublereal *c, *d, *a, *b, *xl, *xu, *x, *u;
2231 integer *iout, *ifail, *iprint;
2233 integer *lwar, *iwar, *liwar;
2235 #endif
2236 {
2237  /* System generated locals */
2239 
2240  /* Builtin functions */
2241  /* integer s_wsfe(), do_fio(), e_wsfe(); */
2242 
2243  /* Local variables */
2244  static doublereal diag;
2245  /* extern int ql0002_(); */
2246  static integer nact, info;
2247  static doublereal zero;
2248  static integer i, j, maxit;
2249  static doublereal qpeps;
2250  static integer in, mn, lw;
2251  static logical lql;
2252  static integer inw1, inw2;
2253 
2254  /* INTRINSIC FUNCTIONS: DSQRT */
2255 
2256  /* Parameter adjustments */
2257  --iwar;
2258  --war;
2259  --u;
2260  --x;
2261  --xu;
2262  --xl;
2263  --b;
2264  a_dim1 = *mmax;
2265  a_offset = a_dim1 + 1;
2266  a -= a_offset;
2267  --d;
2268  c_dim1 = *nmax;
2269  c_offset = c_dim1 + 1;
2270  c -= c_offset;
2271 
2272  /* Function Body */
2273  cmache_1.eps = *eps1;
2274 
2275  /* CONSTANT DATA */
2276 
2277  /* ################################################################# */
2278 
2279  if (fabs(c[*nmax + *nmax * c_dim1]) == 0.e0)
2280  {
2281  c[*nmax + *nmax * c_dim1] = cmache_1.eps;
2282  }
2283 
2284  /* umd */
2285  /* This prevents a subsequent more major modification of the Hessian */
2286  /* matrix in the important case when a minmax problem (yielding a */
2287  /* singular Hessian matrix) is being solved. */
2288  /* ----UMCP, April 1991, Jian L. Zhou */
2289  /* ################################################################# */
2290 
2291  lql = FALSE_;
2292  if (iwar[1] == 1)
2293  {
2294  lql = TRUE_;
2295  }
2296  zero = 0.;
2297  maxit = (*m + *n) * 40;
2298  qpeps = cmache_1.eps;
2299  inw1 = 1;
2300  inw2 = inw1 + *mmax;
2301 
2302  /* PREPARE PROBLEM DATA FOR EXECUTION */
2303 
2304  if (*m <= 0)
2305  {
2306  goto L20;
2307  }
2308  in = inw1;
2309  i__1 = *m;
2310  for (j = 1; j <= i__1; ++j)
2311  {
2312  war[in] = -b[j];
2313  /* L10: */
2314  ++in;
2315  }
2316 L20:
2317  lw = *nmax * 3 * *nmax / 2 + *nmax * 10 + *m;
2318  if (inw2 + lw > *lwar)
2319  {
2320  goto L80;
2321  }
2322  if (*liwar < *n)
2323  {
2324  goto L81;
2325  }
2326  if (*mnn < *m + *n + *n)
2327  {
2328  goto L82;
2329  }
2330  mn = *m + *n;
2331 
2332  /* CALL OF QL0002 */
2333 
2334  ql0002_(n, m, me, mmax, &mn, mnn, nmax, &lql, &a[a_offset], &war[inw1], &
2335  d[1], &c[c_offset], &xl[1], &xu[1], &x[1], &nact, &iwar[1], &
2336  maxit, &qpeps, &info, &diag, &war[inw2], &lw);
2337 
2338  /* TEST OF MATRIX CORRECTIONS */
2339 
2340  *ifail = 0;
2341  if (info == 1)
2342  {
2343  goto L40;
2344  }
2345  if (info == 2)
2346  {
2347  goto L90;
2348  }
2349  if (info < 0)
2350  {
2351  goto L70;
2352  }
2353 
2354  /* REORDER MULTIPLIER */
2355 
2356  i__1 = *mnn;
2357  for (j = 1; j <= i__1; ++j)
2358  {
2359  /* L50: */
2360  u[j] = zero;
2361  }
2362  in = inw2 - 1;
2363  if (nact == 0)
2364  {
2365  goto L30;
2366  }
2367  i__1 = nact;
2368  for (i = 1; i <= i__1; ++i)
2369  {
2370  j = iwar[i];
2371  u[j] = war[in + i];
2372  /* L60: */
2373  }
2374 L30:
2375  return 0;
2376 
2377  /* ERROR MESSAGES */
2378 
2379 L70:
2380  *ifail = -info + 10;
2381  /*
2382  if (*iprint > 0 && nact > 0) {
2383  io___18.ciunit = *iout;
2384  s_wsfe(&io___18);
2385  i__1 = -info;
2386  do_fio(&c__1, (char *)&i__1, (ftnlen)sizeof(integer));
2387  i__2 = nact;
2388  for (i = 1; i <= i__2; ++i) {
2389  do_fio(&c__1, (char *)&iwar[i], (ftnlen)sizeof(integer));
2390  }
2391  e_wsfe();
2392  }
2393  */
2394  return 0;
2395 L80:
2396  *ifail = 5;
2397  /*
2398  if (*iprint > 0) {
2399  io___19.ciunit = *iout;
2400  s_wsfe(&io___19);
2401  e_wsfe();
2402  }
2403  */
2404  return 0;
2405 L81:
2406  *ifail = 5;
2407  /*
2408  if (*iprint > 0) {
2409  io___20.ciunit = *iout;
2410  s_wsfe(&io___20);
2411  e_wsfe();
2412  }
2413  */
2414  return 0;
2415 L82:
2416  *ifail = 5;
2417  /*
2418  if (*iprint > 0) {
2419  io___21.ciunit = *iout;
2420  s_wsfe(&io___21);
2421  e_wsfe();
2422  }
2423  */
2424  return 0;
2425 L40:
2426  *ifail = 1;
2427  /*
2428  if (*iprint > 0) {
2429  io___22.ciunit = *iout;
2430  s_wsfe(&io___22);
2431  do_fio(&c__1, (char *)&maxit, (ftnlen)sizeof(integer));
2432  e_wsfe();
2433  }
2434  */
2435  return 0;
2436 L90:
2437  *ifail = 2;
2438  /*
2439  if (*iprint > 0) {
2440  io___23.ciunit = *iout;
2441  s_wsfe(&io___23);
2442  e_wsfe();
2443  }
2444  */
2445  return 0;
2446 
2447  /* FORMAT-INSTRUCTIONS */
2448 
2449 } /* ql0001_ */
2450 
2451 
2452 /* umd
2453 Two alternative definitions are provided in order to give ANSI
2454 compliance.
2455 (Thanks got to Martin Wauchope for providing this correction)
2456 */
2457 #ifdef __STDC__
2458 int ql0002_(integer *n, integer *m, integer *meq, integer *mmax,
2459  integer *mn, integer *mnn, integer *nmax,
2460  logical *lql,
2462  doublereal *g, doublereal *xl, doublereal *xu, doublereal *x,
2463  integer *nact, integer *iact, integer *maxit,
2464  doublereal *vsmall,
2465  integer *info,
2466  doublereal *diag, doublereal *w,
2467  integer *lw)
2468 #else
2469 /* Subroutine */ int ql0002_(n, m, meq, mmax, mn, mnn, nmax, lql, a, b, grad,
2470  g, xl, xu, x, nact, iact, maxit, vsmall, info, diag, w, lw)
2471 integer *n, *m, *meq, *mmax, *mn, *mnn, *nmax;
2472 logical *lql;
2473 doublereal *a, *b, *grad, *g, *xl, *xu, *x;
2474 integer *nact, *iact, *maxit;
2475 doublereal *vsmall;
2476 integer *info;
2477 doublereal *diag, *w;
2478 integer *lw;
2479 #endif
2481  /* System generated locals */
2482  integer a_dim1, a_offset, g_dim1, g_offset, i__1, i__2, i__3, i__4;
2484 
2485  /* Builtin functions */
2486  /* umd */
2487  /* double sqrt(); */
2488 
2489  /* Local variables */
2490  static doublereal onha, xmag, suma, sumb, sumc, temp, step, zero;
2491  static integer iwwn;
2492  static doublereal sumx, sumy;
2493  static integer i, j, k;
2494  static doublereal fdiff;
2495  static integer iflag, jflag, kflag, lflag;
2496  static doublereal diagr;
2497  static integer ifinc, kfinc, jfinc, mflag, nflag;
2498  static doublereal vfact, tempa;
2499  static integer iterc, itref;
2500  static doublereal cvmax, ratio, xmagr;
2501  static integer kdrop;
2502  static logical lower;
2503  static integer knext, k1;
2504  static doublereal ga, gb;
2505  static integer ia, id;
2506  static doublereal fdiffa;
2507  static integer ii, il, kk, jl, ir, nm, is, iu, iw, ju, ix, iz, nu, iy;
2508 
2509  static doublereal parinc, parnew;
2510  static integer ira, irb, iwa;
2511  static doublereal one;
2512  static integer iwd, iza;
2513  static doublereal res;
2514  static integer iwr, iws;
2515  static doublereal sum;
2516  static integer iww, iwx, iwy;
2517  static doublereal two;
2518  static integer iwz;
2519 
2520 
2521  /* WHETHER THE CONSTRAINT IS ACTIVE. */
2522 
2523 
2524  /* AUTHOR: K. SCHITTKOWSKI, */
2525  /* MATHEMATISCHES INSTITUT, */
2526  /* UNIVERSITAET BAYREUTH, */
2527  /* 8580 BAYREUTH, */
2528  /* GERMANY, F.R. */
2529 
2530  /* AUTHOR OF ORIGINAL VERSION: */
2531  /* M.J.D. POWELL, DAMTP, */
2532  /* UNIVERSITY OF CAMBRIDGE, SILVER STREET */
2533  /* CAMBRIDGE, */
2534  /* ENGLAND */
2535 
2536 
2537  /* REFERENCE: M.J.D. POWELL: ZQPCVX, A FORTRAN SUBROUTINE FOR CONVEX */
2538  /* PROGRAMMING, REPORT DAMTP/1983/NA17, UNIVERSITY OF */
2539  /* CAMBRIDGE, ENGLAND, 1983. */
2540 
2541 
2542  /* VERSION : 2.0 (MARCH, 1987) */
2543 
2544 
2545  /************************************************************************
2546  ***/
2547 
2548 
2549  /* INTRINSIC FUNCTIONS: DMAX1,DSQRT,DABS,DMIN1 */
2550 
2551 
2552  /* INITIAL ADDRESSES */
2553 
2554  /* Parameter adjustments */
2555  --w;
2556  --iact;
2557  --x;
2558  --xu;
2559  --xl;
2560  g_dim1 = *nmax;
2561  g_offset = g_dim1 + 1;
2562  g -= g_offset;
2563  --grad;
2564  --b;
2565  a_dim1 = *mmax;
2566  a_offset = a_dim1 + 1;
2567  a -= a_offset;
2568 
2569  /* Function Body */
2570  iwz = *nmax;
2571  iwr = iwz + *nmax * *nmax;
2572  iww = iwr + *nmax * (*nmax + 3) / 2;
2573  iwd = iww + *nmax;
2574  iwx = iwd + *nmax;
2575  iwa = iwx + *nmax;
2576 
2577  /* SET SOME CONSTANTS. */
2578 
2579  zero = 0.;
2580  one = 1.;
2581  two = 2.;
2582  onha = 1.5;
2583  vfact = 1.;
2584 
2585  /* SET SOME PARAMETERS. */
2586  /* NUMBER LESS THAN VSMALL ARE ASSUMED TO BE NEGLIGIBLE. */
2587  /* THE MULTIPLE OF I THAT IS ADDED TO G IS AT MOST DIAGR TIMES */
2588  /* THE LEAST MULTIPLE OF I THAT GIVES POSITIVE DEFINITENESS. */
2589  /* X IS RE-INITIALISED IF ITS MAGNITUDE IS REDUCED BY THE */
2590  /* FACTOR XMAGR. */
2591  /* A CHECK IS MADE FOR AN INCREASE IN F EVERY IFINC ITERATIONS, */
2592  /* AFTER KFINC ITERATIONS ARE COMPLETED. */
2593 
2594  diagr = two;
2595  xmagr = .01;
2596  ifinc = 3;
2597  kfinc = max(10, *n);
2598 
2599  /* FIND THE RECIPROCALS OF THE LENGTHS OF THE CONSTRAINT NORMALS. */
2600  /* RETURN IF A CONSTRAINT IS INFEASIBLE DUE TO A ZERO NORMAL. */
2601 
2602  *nact = 0;
2603  if (*m <= 0)
2604  {
2605  goto L45;
2606  }
2607  i__1 = *m;
2608  for (k = 1; k <= i__1; ++k)
2609  {
2610  sum = zero;
2611  i__2 = *n;
2612  for (i = 1; i <= i__2; ++i)
2613  {
2614  /* L10: */
2615  /* Computing 2nd power */
2616  d__1 = a[k + i * a_dim1];
2617  sum += d__1 * d__1;
2618  }
2619  if (sum > zero)
2620  {
2621  goto L20;
2622  }
2623  if (b[k] == zero)
2624  {
2625  goto L30;
2626  }
2627  *info = -k;
2628  if (k <= *meq)
2629  {
2630  goto L730;
2631  }
2632  if (b[k] <= 0.)
2633  {
2634  goto L30;
2635  }
2636  else
2637  {
2638  goto L730;
2639  }
2640 L20:
2641  sum = one / sqrt(sum);
2642 L30:
2643  ia = iwa + k;
2644  /* L40: */
2645  w[ia] = sum;
2646  }
2647 L45:
2648  i__1 = *n;
2649  for (k = 1; k <= i__1; ++k)
2650  {
2651  ia = iwa + *m + k;
2652  /* L50: */
2653  w[ia] = one;
2654  }
2655 
2656  /* IF NECESSARY INCREASE THE DIAGONAL ELEMENTS OF G. */
2657 
2658  if (!(*lql))
2659  {
2660  goto L165;
2661  }
2662  *diag = zero;
2663  i__1 = *n;
2664  for (i = 1; i <= i__1; ++i)
2665  {
2666  id = iwd + i;
2667  w[id] = g[i + i * g_dim1];
2668  /* Computing MAX */
2669  d__1 = *diag, d__2 = *vsmall - w[id];
2670  *diag = max(d__1, d__2);
2671  if (i == *n)
2672  {
2673  goto L60;
2674  }
2675  ii = i + 1;
2676  i__2 = *n;
2677  for (j = ii; j <= i__2; ++j)
2678  {
2679  /* Computing MIN */
2680  d__1 = w[id], d__2 = g[j + j * g_dim1];
2681  ga = -min(d__1, d__2);
2682  gb = (d__1 = w[id] - g[j + j * g_dim1], abs(d__1)) + (d__2 = g[i
2683  + j * g_dim1], abs(d__2));
2684  if (gb > zero)
2685  {
2686  /* Computing 2nd power */
2687  d__1 = g[i + j * g_dim1];
2688  ga += d__1 * d__1 / gb;
2689  }
2690  /* L55: */
2691  *diag = max(*diag, ga);
2692  }
2693 L60:
2694  ;
2695  }
2696  if (*diag <= zero)
2697  {
2698  goto L90;
2699  }
2700 L70:
2701  *diag = diagr * *diag;
2702  i__1 = *n;
2703  for (i = 1; i <= i__1; ++i)
2704  {
2705  id = iwd + i;
2706  /* L80: */
2707  g[i + i * g_dim1] = *diag + w[id];
2708  }
2709 
2710  /* FORM THE CHOLESKY FACTORISATION OF G. THE TRANSPOSE */
2711  /* OF THE FACTOR WILL BE PLACED IN THE R-PARTITION OF W. */
2712 
2713 L90:
2714  ir = iwr;
2715  i__1 = *n;
2716  for (j = 1; j <= i__1; ++j)
2717  {
2718  ira = iwr;
2719  irb = ir + 1;
2720  i__2 = j;
2721  for (i = 1; i <= i__2; ++i)
2722  {
2723  temp = g[i + j * g_dim1];
2724  if (i == 1)
2725  {
2726  goto L110;
2727  }
2728  i__3 = ir;
2729  for (k = irb; k <= i__3; ++k)
2730  {
2731  ++ira;
2732  /* L100: */
2733  temp -= w[k] * w[ira];
2734  }
2735 L110:
2736  ++ir;
2737  ++ira;
2738  if (i < j)
2739  {
2740  w[ir] = temp / w[ira];
2741  }
2742  /* L120: */
2743  }
2744  if (temp < *vsmall)
2745  {
2746  goto L140;
2747  }
2748  /* L130: */
2749  w[ir] = sqrt(temp);
2750  }
2751  goto L170;
2752 
2753  /* INCREASE FURTHER THE DIAGONAL ELEMENT OF G. */
2754 
2755 L140:
2756  w[j] = one;
2757  sumx = one;
2758  k = j;
2759 L150:
2760  sum = zero;
2761  ira = ir - 1;
2762  i__1 = j;
2763  for (i = k; i <= i__1; ++i)
2764  {
2765  sum -= w[ira] * w[i];
2766  /* L160: */
2767  ira += i;
2768  }
2769  ir -= k;
2770  --k;
2771  w[k] = sum / w[ir];
2772  /* Computing 2nd power */
2773  d__1 = w[k];
2774  sumx += d__1 * d__1;
2775  if (k >= 2)
2776  {
2777  goto L150;
2778  }
2779  *diag = *diag + *vsmall - temp / sumx;
2780  goto L70;
2781 
2782  /* STORE THE CHOLESKY FACTORISATION IN THE R-PARTITION */
2783  /* OF W. */
2784 
2785 L165:
2786  ir = iwr;
2787  i__1 = *n;
2788  for (i = 1; i <= i__1; ++i)
2789  {
2790  i__2 = i;
2791  for (j = 1; j <= i__2; ++j)
2792  {
2793  ++ir;
2794  /* L166: */
2795  w[ir] = g[j + i * g_dim1];
2796  }
2797  }
2798 
2799  /* SET Z THE INVERSE OF THE MATRIX IN R. */
2800 
2801 L170:
2802  nm = *n - 1;
2803  i__2 = *n;
2804  for (i = 1; i <= i__2; ++i)
2805  {
2806  iz = iwz + i;
2807  if (i == 1)
2808  {
2809  goto L190;
2810  }
2811  i__1 = i;
2812  for (j = 2; j <= i__1; ++j)
2813  {
2814  w[iz] = zero;
2815  /* L180: */
2816  iz += *n;
2817  }
2818 L190:
2819  ir = iwr + (i + i * i) / 2;
2820  w[iz] = one / w[ir];
2821  if (i == *n)
2822  {
2823  goto L220;
2824  }
2825  iza = iz;
2826  i__1 = nm;
2827  for (j = i; j <= i__1; ++j)
2828  {
2829  ir += i;
2830  sum = zero;
2831  i__3 = iz;
2832  i__4 = *n;
2833  for (k = iza; i__4 < 0 ? k >= i__3 : k <= i__3; k += i__4)
2834  {
2835  sum += w[k] * w[ir];
2836  /* L200: */
2837  ++ir;
2838  }
2839  iz += *n;
2840  /* L210: */
2841  w[iz] = -sum / w[ir];
2842  }
2843 L220:
2844  ;
2845  }
2846 
2847  /* SET THE INITIAL VALUES OF SOME VARIABLES. */
2848  /* ITERC COUNTS THE NUMBER OF ITERATIONS. */
2849  /* ITREF IS SET TO ONE WHEN ITERATIVE REFINEMENT IS REQUIRED. */
2850  /* JFINC INDICATES WHEN TO TEST FOR AN INCREASE IN F. */
2851 
2852  iterc = 1;
2853  itref = 0;
2854  jfinc = -kfinc;
2855 
2856  /* SET X TO ZERO AND SET THE CORRESPONDING RESIDUALS OF THE */
2857  /* KUHN-TUCKER CONDITIONS. */
2858 
2859 L230:
2860  iflag = 1;
2861  iws = iww - *n;
2862  i__2 = *n;
2863  for (i = 1; i <= i__2; ++i)
2864  {
2865  x[i] = zero;
2866  iw = iww + i;
2867  w[iw] = grad[i];
2868  if (i > *nact)
2869  {
2870  goto L240;
2871  }
2872  w[i] = zero;
2873  is = iws + i;
2874  k = iact[i];
2875  if (k <= *m)
2876  {
2877  goto L235;
2878  }
2879  if (k > *mn)
2880  {
2881  goto L234;
2882  }
2883  k1 = k - *m;
2884  w[is] = xl[k1];
2885  goto L240;
2886 L234:
2887  k1 = k - *mn;
2888  w[is] = -xu[k1];
2889  goto L240;
2890 L235:
2891  w[is] = b[k];
2892 L240:
2893  ;
2894  }
2895  xmag = zero;
2896  vfact = 1.;
2897  if (*nact <= 0)
2898  {
2899  goto L340;
2900  }
2901  else
2902  {
2903  goto L280;
2904  }
2905 
2906  /* SET THE RESIDUALS OF THE KUHN-TUCKER CONDITIONS FOR GENERAL X. */
2907 
2908 L250:
2909  iflag = 2;
2910  iws = iww - *n;
2911  i__2 = *n;
2912  for (i = 1; i <= i__2; ++i)
2913  {
2914  iw = iww + i;
2915  w[iw] = grad[i];
2916  if (*lql)
2917  {
2918  goto L259;
2919  }
2920  id = iwd + i;
2921  w[id] = zero;
2922  i__1 = *n;
2923  for (j = i; j <= i__1; ++j)
2924  {
2925  /* L251: */
2926  w[id] += g[i + j * g_dim1] * x[j];
2927  }
2928  i__1 = i;
2929  for (j = 1; j <= i__1; ++j)
2930  {
2931  id = iwd + j;
2932  /* L252: */
2933  w[iw] += g[j + i * g_dim1] * w[id];
2934  }
2935  goto L260;
2936 L259:
2937  i__1 = *n;
2938  for (j = 1; j <= i__1; ++j)
2939  {
2940  /* L261: */
2941  w[iw] += g[i + j * g_dim1] * x[j];
2942  }
2943 L260:
2944  ;
2945  }
2946  if (*nact == 0)
2947  {
2948  goto L340;
2949  }
2950  i__2 = *nact;
2951  for (k = 1; k <= i__2; ++k)
2952  {
2953  kk = iact[k];
2954  is = iws + k;
2955  if (kk > *m)
2956  {
2957  goto L265;
2958  }
2959  w[is] = b[kk];
2960  i__1 = *n;
2961  for (i = 1; i <= i__1; ++i)
2962  {
2963  iw = iww + i;
2964  w[iw] -= w[k] * a[kk + i * a_dim1];
2965  /* L264: */
2966  w[is] -= x[i] * a[kk + i * a_dim1];
2967  }
2968  goto L270;
2969 L265:
2970  if (kk > *mn)
2971  {
2972  goto L266;
2973  }
2974  k1 = kk - *m;
2975  iw = iww + k1;
2976  w[iw] -= w[k];
2977  w[is] = xl[k1] - x[k1];
2978  goto L270;
2979 L266:
2980  k1 = kk - *mn;
2981  iw = iww + k1;
2982  w[iw] += w[k];
2983  w[is] = -xu[k1] + x[k1];
2984 L270:
2985  ;
2986  }
2987 
2988  /* PRE-MULTIPLY THE VECTOR IN THE S-PARTITION OF W BY THE */
2989  /* INVERS OF R TRANSPOSE. */
2990 
2991 L280:
2992  ir = iwr;
2993  il = iws + 1;
2994  iu = iws + *nact;
2995  i__2 = iu;
2996  for (i = il; i <= i__2; ++i)
2997  {
2998  sum = zero;
2999  if (i == il)
3000  {
3001  goto L300;
3002  }
3003  ju = i - 1;
3004  i__1 = ju;
3005  for (j = il; j <= i__1; ++j)
3006  {
3007  ++ir;
3008  /* L290: */
3009  sum += w[ir] * w[j];
3010  }
3011 L300:
3012  ++ir;
3013  /* L310: */
3014  w[i] = (w[i] - sum) / w[ir];
3015  }
3016 
3017  /* SHIFT X TO SATISFY THE ACTIVE CONSTRAINTS AND MAKE THE */
3018  /* CORRESPONDING CHANGE TO THE GRADIENT RESIDUALS. */
3019 
3020  i__2 = *n;
3021  for (i = 1; i <= i__2; ++i)
3022  {
3023  iz = iwz + i;
3024  sum = zero;
3025  i__1 = iu;
3026  for (j = il; j <= i__1; ++j)
3027  {
3028  sum += w[j] * w[iz];
3029  /* L320: */
3030  iz += *n;
3031  }
3032  x[i] += sum;
3033  if (*lql)
3034  {
3035  goto L329;
3036  }
3037  id = iwd + i;
3038  w[id] = zero;
3039  i__1 = *n;
3040  for (j = i; j <= i__1; ++j)
3041  {
3042  /* L321: */
3043  w[id] += g[i + j * g_dim1] * sum;
3044  }
3045  iw = iww + i;
3046  i__1 = i;
3047  for (j = 1; j <= i__1; ++j)
3048  {
3049  id = iwd + j;
3050  /* L322: */
3051  w[iw] += g[j + i * g_dim1] * w[id];
3052  }
3053  goto L330;
3054 L329:
3055  i__1 = *n;
3056  for (j = 1; j <= i__1; ++j)
3057  {
3058  iw = iww + j;
3059  /* L331: */
3060  w[iw] += sum * g[i + j * g_dim1];
3061  }
3062 L330:
3063  ;
3064  }
3065 
3066  /* FORM THE SCALAR PRODUCT OF THE CURRENT GRADIENT RESIDUALS */
3067  /* WITH EACH COLUMN OF Z. */
3068 
3069 L340:
3070  kflag = 1;
3071  goto L930;
3072 L350:
3073  if (*nact == *n)
3074  {
3075  goto L380;
3076  }
3077 
3078  /* SHIFT X SO THAT IT SATISFIES THE REMAINING KUHN-TUCKER */
3079  /* CONDITIONS. */
3080 
3081  il = iws + *nact + 1;
3082  iza = iwz + *nact * *n;
3083  i__2 = *n;
3084  for (i = 1; i <= i__2; ++i)
3085  {
3086  sum = zero;
3087  iz = iza + i;
3088  i__1 = iww;
3089  for (j = il; j <= i__1; ++j)
3090  {
3091  sum += w[iz] * w[j];
3092  /* L360: */
3093  iz += *n;
3094  }
3095  /* L370: */
3096  x[i] -= sum;
3097  }
3098  *info = 0;
3099  if (*nact == 0)
3100  {
3101  goto L410;
3102  }
3103 
3104  /* UPDATE THE LAGRANGE MULTIPLIERS. */
3105 
3106 L380:
3107  lflag = 3;
3108  goto L740;
3109 L390:
3110  i__2 = *nact;
3111  for (k = 1; k <= i__2; ++k)
3112  {
3113  iw = iww + k;
3114  /* L400: */
3115  w[k] += w[iw];
3116  }
3117 
3118  /* REVISE THE VALUES OF XMAG. */
3119  /* BRANCH IF ITERATIVE REFINEMENT IS REQUIRED. */
3120 
3121 L410:
3122  jflag = 1;
3123  goto L910;
3124 L420:
3125  if (iflag == itref)
3126  {
3127  goto L250;
3128  }
3129 
3130  /* DELETE A CONSTRAINT IF A LAGRANGE MULTIPLIER OF AN */
3131  /* INEQUALITY CONSTRAINT IS NEGATIVE. */
3132 
3133  kdrop = 0;
3134  goto L440;
3135 L430:
3136  ++kdrop;
3137  if (w[kdrop] >= zero)
3138  {
3139  goto L440;
3140  }
3141  if (iact[kdrop] <= *meq)
3142  {
3143  goto L440;
3144  }
3145  nu = *nact;
3146  mflag = 1;
3147  goto L800;
3148 L440:
3149  if (kdrop < *nact)
3150  {
3151  goto L430;
3152  }
3153 
3154  /* SEEK THE GREATEAST NORMALISED CONSTRAINT VIOLATION, DISREGARDING */
3155 
3156  /* ANY THAT MAY BE DUE TO COMPUTER ROUNDING ERRORS. */
3157 
3158 L450:
3159  cvmax = zero;
3160  if (*m <= 0)
3161  {
3162  goto L481;
3163  }
3164  i__2 = *m;
3165  for (k = 1; k <= i__2; ++k)
3166  {
3167  ia = iwa + k;
3168  if (w[ia] <= zero)
3169  {
3170  goto L480;
3171  }
3172  sum = -b[k];
3173  i__1 = *n;
3174  for (i = 1; i <= i__1; ++i)
3175  {
3176  /* L460: */
3177  sum += x[i] * a[k + i * a_dim1];
3178  }
3179  sumx = -sum * w[ia];
3180  if (k <= *meq)
3181  {
3182  sumx = abs(sumx);
3183  }
3184  if (sumx <= cvmax)
3185  {
3186  goto L480;
3187  }
3188  temp = (d__1 = b[k], abs(d__1));
3189  i__1 = *n;
3190  for (i = 1; i <= i__1; ++i)
3191  {
3192  /* L470: */
3193  temp += (d__1 = x[i] * a[k + i * a_dim1], abs(d__1));
3194  }
3195  tempa = temp + abs(sum);
3196  if (tempa <= temp)
3197  {
3198  goto L480;
3199  }
3200  temp += onha * abs(sum);
3201  if (temp <= tempa)
3202  {
3203  goto L480;
3204  }
3205  cvmax = sumx;
3206  res = sum;
3207  knext = k;
3208 L480:
3209  ;
3210  }
3211 L481:
3212  i__2 = *n;
3213  for (k = 1; k <= i__2; ++k)
3214  {
3215  lower = TRUE_;
3216  ia = iwa + *m + k;
3217  if (w[ia] <= zero)
3218  {
3219  goto L485;
3220  }
3221  sum = xl[k] - x[k];
3222  if (sum < 0.)
3223  {
3224  goto L482;
3225  }
3226  else if (sum == 0)
3227  {
3228  goto L485;
3229  }
3230  else
3231  {
3232  goto L483;
3233  }
3234 L482:
3235  sum = x[k] - xu[k];
3236  lower = FALSE_;
3237 L483:
3238  if (sum <= cvmax)
3239  {
3240  goto L485;
3241  }
3242  cvmax = sum;
3243  res = -sum;
3244  knext = k + *m;
3245  if (lower)
3246  {
3247  goto L485;
3248  }
3249  knext = k + *mn;
3250 L485:
3251  ;
3252  }
3253 
3254  /* TEST FOR CONVERGENCE */
3255 
3256  *info = 0;
3257  if (cvmax <= *vsmall)
3258  {
3259  goto L700;
3260  }
3261 
3262  /* RETURN IF, DUE TO ROUNDING ERRORS, THE ACTUAL CHANGE IN */
3263  /* X MAY NOT INCREASE THE OBJECTIVE FUNCTION */
3264 
3265  ++jfinc;
3266  if (jfinc == 0)
3267  {
3268  goto L510;
3269  }
3270  if (jfinc != ifinc)
3271  {
3272  goto L530;
3273  }
3274  fdiff = zero;
3275  fdiffa = zero;
3276  i__2 = *n;
3277  for (i = 1; i <= i__2; ++i)
3278  {
3279  sum = two * grad[i];
3280  sumx = abs(sum);
3281  if (*lql)
3282  {
3283  goto L489;
3284  }
3285  id = iwd + i;
3286  w[id] = zero;
3287  i__1 = *n;
3288  for (j = i; j <= i__1; ++j)
3289  {
3290  ix = iwx + j;
3291  /* L486: */
3292  w[id] += g[i + j * g_dim1] * (w[ix] + x[j]);
3293  }
3294  i__1 = i;
3295  for (j = 1; j <= i__1; ++j)
3296  {
3297  id = iwd + j;
3298  temp = g[j + i * g_dim1] * w[id];
3299  sum += temp;
3300  /* L487: */
3301  sumx += abs(temp);
3302  }
3303  goto L495;
3304 L489:
3305  i__1 = *n;
3306  for (j = 1; j <= i__1; ++j)
3307  {
3308  ix = iwx + j;
3309  temp = g[i + j * g_dim1] * (w[ix] + x[j]);
3310  sum += temp;
3311  /* L490: */
3312  sumx += abs(temp);
3313  }
3314 L495:
3315  ix = iwx + i;
3316  fdiff += sum * (x[i] - w[ix]);
3317  /* L500: */
3318  fdiffa += sumx * (d__1 = x[i] - w[ix], abs(d__1));
3319  }
3320  *info = 2;
3321  sum = fdiffa + fdiff;
3322  if (sum <= fdiffa)
3323  {
3324  goto L700;
3325  }
3326  temp = fdiffa + onha * fdiff;
3327  if (temp <= sum)
3328  {
3329  goto L700;
3330  }
3331  jfinc = 0;
3332  *info = 0;
3333 L510:
3334  i__2 = *n;
3335  for (i = 1; i <= i__2; ++i)
3336  {
3337  ix = iwx + i;
3338  /* L520: */
3339  w[ix] = x[i];
3340  }
3341 
3342  /* FORM THE SCALAR PRODUCT OF THE NEW CONSTRAINT NORMAL WITH EACH */
3343  /* COLUMN OF Z. PARNEW WILL BECOME THE LAGRANGE MULTIPLIER OF */
3344  /* THE NEW CONSTRAINT. */
3345 
3346 L530:
3347  ++iterc;
3348  if (iterc <= *maxit)
3349  {
3350  goto L531;
3351  }
3352  *info = 1;
3353  goto L710;
3354 L531:
3355  iws = iwr + (*nact + *nact * *nact) / 2;
3356  if (knext > *m)
3357  {
3358  goto L541;
3359  }
3360  i__2 = *n;
3361  for (i = 1; i <= i__2; ++i)
3362  {
3363  iw = iww + i;
3364  /* L540: */
3365  w[iw] = a[knext + i * a_dim1];
3366  }
3367  goto L549;
3368 L541:
3369  i__2 = *n;
3370  for (i = 1; i <= i__2; ++i)
3371  {
3372  iw = iww + i;
3373  /* L542: */
3374  w[iw] = zero;
3375  }
3376  k1 = knext - *m;
3377  if (k1 > *n)
3378  {
3379  goto L545;
3380  }
3381  iw = iww + k1;
3382  w[iw] = one;
3383  iz = iwz + k1;
3384  i__2 = *n;
3385  for (i = 1; i <= i__2; ++i)
3386  {
3387  is = iws + i;
3388  w[is] = w[iz];
3389  /* L543: */
3390  iz += *n;
3391  }
3392  goto L550;
3393 L545:
3394  k1 = knext - *mn;
3395  iw = iww + k1;
3396  w[iw] = -one;
3397  iz = iwz + k1;
3398  i__2 = *n;
3399  for (i = 1; i <= i__2; ++i)
3400  {
3401  is = iws + i;
3402  w[is] = -w[iz];
3403  /* L546: */
3404  iz += *n;
3405  }
3406  goto L550;
3407 L549:
3408  kflag = 2;
3409  goto L930;
3410 L550:
3411  parnew = zero;
3412 
3413  /* APPLY GIVENS ROTATIONS TO MAKE THE LAST (N-NACT-2) SCALAR */
3414  /* PRODUCTS EQUAL TO ZERO. */
3415 
3416  if (*nact == *n)
3417  {
3418  goto L570;
3419  }
3420  nu = *n;
3421  nflag = 1;
3422  goto L860;
3423 
3424  /* BRANCH IF THERE IS NO NEED TO DELETE A CONSTRAINT. */
3425 
3426 L560:
3427  is = iws + *nact;
3428  if (*nact == 0)
3429  {
3430  goto L640;
3431  }
3432  suma = zero;
3433  sumb = zero;
3434  sumc = zero;
3435  iz = iwz + *nact * *n;
3436  i__2 = *n;
3437  for (i = 1; i <= i__2; ++i)
3438  {
3439  ++iz;
3440  iw = iww + i;
3441  suma += w[iw] * w[iz];
3442  sumb += (d__1 = w[iw] * w[iz], abs(d__1));
3443  /* L563: */
3444  /* Computing 2nd power */
3445  d__1 = w[iz];
3446  sumc += d__1 * d__1;
3447  }
3448  temp = sumb + abs(suma) * .1;
3449  tempa = sumb + abs(suma) * .2;
3450  if (temp <= sumb)
3451  {
3452  goto L570;
3453  }
3454  if (tempa <= temp)
3455  {
3456  goto L570;
3457  }
3458  if (sumb > *vsmall)
3459  {
3460  goto L5;
3461  }
3462  goto L570;
3463 L5:
3464  sumc = sqrt(sumc);
3465  ia = iwa + knext;
3466  if (knext <= *m)
3467  {
3468  sumc /= w[ia];
3469  }
3470  temp = sumc + abs(suma) * .1;
3471  tempa = sumc + abs(suma) * .2;
3472  if (temp <= sumc)
3473  {
3474  goto L567;
3475  }
3476  if (tempa <= temp)
3477  {
3478  goto L567;
3479  }
3480  goto L640;
3481 
3482  /* CALCULATE THE MULTIPLIERS FOR THE NEW CONSTRAINT NORMAL */
3483  /* EXPRESSED IN TERMS OF THE ACTIVE CONSTRAINT NORMALS. */
3484  /* THEN WORK OUT WHICH CONTRAINT TO DROP. */
3485 
3486 L567:
3487  lflag = 4;
3488  goto L740;
3489 L570:
3490  lflag = 1;
3491  goto L740;
3492 
3493  /* COMPLETE THE TEST FOR LINEARLY DEPENDENT CONSTRAINTS. */
3494 
3495 L571:
3496  if (knext > *m)
3497  {
3498  goto L574;
3499  }
3500  i__2 = *n;
3501  for (i = 1; i <= i__2; ++i)
3502  {
3503  suma = a[knext + i * a_dim1];
3504  sumb = abs(suma);
3505  if (*nact == 0)
3506  {
3507  goto L581;
3508  }
3509  i__1 = *nact;
3510  for (k = 1; k <= i__1; ++k)
3511  {
3512  kk = iact[k];
3513  if (kk <= *m)
3514  {
3515  goto L568;
3516  }
3517  kk -= *m;
3518  temp = zero;
3519  if (kk == i)
3520  {
3521  temp = w[iww + kk];
3522  }
3523  kk -= *n;
3524  if (kk == i)
3525  {
3526  temp = -w[iww + kk];
3527  }
3528  goto L569;
3529 L568:
3530  iw = iww + k;
3531  temp = w[iw] * a[kk + i * a_dim1];
3532 L569:
3533  suma -= temp;
3534  /* L572: */
3535  sumb += abs(temp);
3536  }
3537 L581:
3538  if (suma <= *vsmall)
3539  {
3540  goto L573;
3541  }
3542  temp = sumb + abs(suma) * .1;
3543  tempa = sumb + abs(suma) * .2;
3544  if (temp <= sumb)
3545  {
3546  goto L573;
3547  }
3548  if (tempa <= temp)
3549  {
3550  goto L573;
3551  }
3552  goto L630;
3553 L573:
3554  ;
3555  }
3556  lflag = 1;
3557  goto L775;
3558 L574:
3559  k1 = knext - *m;
3560  if (k1 > *n)
3561  {
3562  k1 -= *n;
3563  }
3564  i__2 = *n;
3565  for (i = 1; i <= i__2; ++i)
3566  {
3567  suma = zero;
3568  if (i != k1)
3569  {
3570  goto L575;
3571  }
3572  suma = one;
3573  if (knext > *mn)
3574  {
3575  suma = -one;
3576  }
3577 L575:
3578  sumb = abs(suma);
3579  if (*nact == 0)
3580  {
3581  goto L582;
3582  }
3583  i__1 = *nact;
3584  for (k = 1; k <= i__1; ++k)
3585  {
3586  kk = iact[k];
3587  if (kk <= *m)
3588  {
3589  goto L579;
3590  }
3591  kk -= *m;
3592  temp = zero;
3593  if (kk == i)
3594  {
3595  temp = w[iww + kk];
3596  }
3597  kk -= *n;
3598  if (kk == i)
3599  {
3600  temp = -w[iww + kk];
3601  }
3602  goto L576;
3603 L579:
3604  iw = iww + k;
3605  temp = w[iw] * a[kk + i * a_dim1];
3606 L576:
3607  suma -= temp;
3608  /* L577: */
3609  sumb += abs(temp);
3610  }
3611 L582:
3612  temp = sumb + abs(suma) * .1;
3613  tempa = sumb + abs(suma) * .2;
3614  if (temp <= sumb)
3615  {
3616  goto L578;
3617  }
3618  if (tempa <= temp)
3619  {
3620  goto L578;
3621  }
3622  goto L630;
3623 L578:
3624  ;
3625  }
3626  lflag = 1;
3627  goto L775;
3628 
3629  /* BRANCH IF THE CONTRAINTS ARE INCONSISTENT. */
3630 
3631 L580:
3632  *info = -knext;
3633  if (kdrop == 0)
3634  {
3635  goto L700;
3636  }
3637  parinc = ratio;
3638  parnew = parinc;
3639 
3640  /* REVISE THE LAGRANGE MULTIPLIERS OF THE ACTIVE CONSTRAINTS. */
3641 
3642 L590:
3643  if (*nact == 0)
3644  {
3645  goto L601;
3646  }
3647  i__2 = *nact;
3648  for (k = 1; k <= i__2; ++k)
3649  {
3650  iw = iww + k;
3651  w[k] -= parinc * w[iw];
3652  if (iact[k] > *meq)
3653  {
3654  /* Computing MAX */
3655  d__1 = zero, d__2 = w[k];
3656  w[k] = max(d__1, d__2);
3657  }
3658  /* L600: */
3659  }
3660 L601:
3661  if (kdrop == 0)
3662  {
3663  goto L680;
3664  }
3665 
3666  /* DELETE THE CONSTRAINT TO BE DROPPED. */
3667  /* SHIFT THE VECTOR OF SCALAR PRODUCTS. */
3668  /* THEN, IF APPROPRIATE, MAKE ONE MORE SCALAR PRODUCT ZERO. */
3669 
3670  nu = *nact + 1;
3671  mflag = 2;
3672  goto L800;
3673 L610:
3674  iws = iws - *nact - 1;
3675  nu = min(*n, nu);
3676  i__2 = nu;
3677  for (i = 1; i <= i__2; ++i)
3678  {
3679  is = iws + i;
3680  j = is + *nact;
3681  /* L620: */
3682  w[is] = w[j + 1];
3683  }
3684  nflag = 2;
3685  goto L860;
3686 
3687  /* CALCULATE THE STEP TO THE VIOLATED CONSTRAINT. */
3688 
3689 L630:
3690  is = iws + *nact;
3691 L640:
3692  sumy = w[is + 1];
3693  step = -res / sumy;
3694  parinc = step / sumy;
3695  if (*nact == 0)
3696  {
3697  goto L660;
3698  }
3699 
3700  /* CALCULATE THE CHANGES TO THE LAGRANGE MULTIPLIERS, AND REDUCE */
3701  /* THE STEP ALONG THE NEW SEARCH DIRECTION IF NECESSARY. */
3702 
3703  lflag = 2;
3704  goto L740;
3705 L650:
3706  if (kdrop == 0)
3707  {
3708  goto L660;
3709  }
3710  temp = one - ratio / parinc;
3711  if (temp <= zero)
3712  {
3713  kdrop = 0;
3714  }
3715  if (kdrop == 0)
3716  {
3717  goto L660;
3718  }
3719  step = ratio * sumy;
3720  parinc = ratio;
3721  res = temp * res;
3722 
3723  /* UPDATE X AND THE LAGRANGE MULTIPIERS. */
3724  /* DROP A CONSTRAINT IF THE FULL STEP IS NOT TAKEN. */
3725 
3726 L660:
3727  iwy = iwz + *nact * *n;
3728  i__2 = *n;
3729  for (i = 1; i <= i__2; ++i)
3730  {
3731  iy = iwy + i;
3732  /* L670: */
3733  x[i] += step * w[iy];
3734  }
3735  parnew += parinc;
3736  if (*nact >= 1)
3737  {
3738  goto L590;
3739  }
3740 
3741  /* ADD THE NEW CONSTRAINT TO THE ACTIVE SET. */
3742 
3743 L680:
3744  ++(*nact);
3745  w[*nact] = parnew;
3746  iact[*nact] = knext;
3747  ia = iwa + knext;
3748  if (knext > *mn)
3749  {
3750  ia -= *n;
3751  }
3752  w[ia] = -w[ia];
3753 
3754  /* ESTIMATE THE MAGNITUDE OF X. THEN BEGIN A NEW ITERATION, */
3755  /* RE-INITILISING X IF THIS MAGNITUDE IS SMALL. */
3756 
3757  jflag = 2;
3758  goto L910;
3759 L690:
3760  if (sum < xmagr * xmag)
3761  {
3762  goto L230;
3763  }
3764  if (itref <= 0)
3765  {
3766  goto L450;
3767  }
3768  else
3769  {
3770  goto L250;
3771  }
3772 
3773  /* INITIATE ITERATIVE REFINEMENT IF IT HAS NOT YET BEEN USED, */
3774  /* OR RETURN AFTER RESTORING THE DIAGONAL ELEMENTS OF G. */
3775 
3776 L700:
3777  if (iterc == 0)
3778  {
3779  goto L710;
3780  }
3781  ++itref;
3782  jfinc = -1;
3783  if (itref == 1)
3784  {
3785  goto L250;
3786  }
3787 L710:
3788  if (!(*lql))
3789  {
3790  return 0;
3791  }
3792  i__2 = *n;
3793  for (i = 1; i <= i__2; ++i)
3794  {
3795  id = iwd + i;
3796  /* L720: */
3797  g[i + i * g_dim1] = w[id];
3798  }
3799 L730:
3800  return 0;
3801 
3802 
3803  /* THE REMAINIG INSTRUCTIONS ARE USED AS SUBROUTINES. */
3804 
3805 
3806  /* ******************************************************************** */
3807 
3808 
3809 
3810  /* CALCULATE THE LAGRANGE MULTIPLIERS BY PRE-MULTIPLYING THE */
3811  /* VECTOR IN THE S-PARTITION OF W BY THE INVERSE OF R. */
3812 
3813 L740:
3814  ir = iwr + (*nact + *nact * *nact) / 2;
3815  i = *nact;
3816  sum = zero;
3817  goto L770;
3818 L750:
3819  ira = ir - 1;
3820  sum = zero;
3821  if (*nact == 0)
3822  {
3823  goto L761;
3824  }
3825  i__2 = *nact;
3826  for (j = i; j <= i__2; ++j)
3827  {
3828  iw = iww + j;
3829  sum += w[ira] * w[iw];
3830  /* L760: */
3831  ira += j;
3832  }
3833 L761:
3834  ir -= i;
3835  --i;
3836 L770:
3837  iw = iww + i;
3838  is = iws + i;
3839  w[iw] = (w[is] - sum) / w[ir];
3840  if (i > 1)
3841  {
3842  goto L750;
3843  }
3844  if (lflag == 3)
3845  {
3846  goto L390;
3847  }
3848  if (lflag == 4)
3849  {
3850  goto L571;
3851  }
3852 
3853  /* CALCULATE THE NEXT CONSTRAINT TO DROP. */
3854 
3855 L775:
3856  kdrop = 0;
3857  if (*nact == 0)
3858  {
3859  goto L791;
3860  }
3861  i__2 = *nact;
3862  for (k = 1; k <= i__2; ++k)
3863  {
3864  if (iact[k] <= *meq)
3865  {
3866  goto L790;
3867  }
3868  iw = iww + k;
3869  if (res * w[iw] >= zero)
3870  {
3871  goto L790;
3872  }
3873  temp = w[k] / w[iw];
3874  if (kdrop == 0)
3875  {
3876  goto L780;
3877  }
3878  if (abs(temp) >= abs(ratio))
3879  {
3880  goto L790;
3881  }
3882 L780:
3883  kdrop = k;
3884  ratio = temp;
3885 L790:
3886  ;
3887  }
3888 L791:
3889  switch ((int)lflag)
3890  {
3891  case 1:
3892  goto L580;
3893  case 2:
3894  goto L650;
3895  }
3896 
3897 
3898  /* ******************************************************************** */
3899 
3900 
3901 
3902  /* DROP THE CONSTRAINT IN POSITION KDROP IN THE ACTIVE SET. */
3903 
3904 L800:
3905  ia = iwa + iact[kdrop];
3906  if (iact[kdrop] > *mn)
3907  {
3908  ia -= *n;
3909  }
3910  w[ia] = -w[ia];
3911  if (kdrop == *nact)
3912  {
3913  goto L850;
3914  }
3915 
3916  /* SET SOME INDICES AND CALCULATE THE ELEMENTS OF THE NEXT */
3917  /* GIVENS ROTATION. */
3918 
3919  iz = iwz + kdrop * *n;
3920  ir = iwr + (kdrop + kdrop * kdrop) / 2;
3921 L810:
3922  ira = ir;
3923  ir = ir + kdrop + 1;
3924  /* Computing MAX */
3925  d__3 = (d__1 = w[ir - 1], abs(d__1)), d__4 = (d__2 = w[ir], abs(d__2));
3926  temp = max(d__3, d__4);
3927  /* Computing 2nd power */
3928  d__1 = w[ir - 1] / temp;
3929  /* Computing 2nd power */
3930  d__2 = w[ir] / temp;
3931  sum = temp * sqrt(d__1 * d__1 + d__2 * d__2);
3932  ga = w[ir - 1] / sum;
3933  gb = w[ir] / sum;
3934 
3935  /* EXCHANGE THE COLUMNS OF R. */
3936 
3937  i__2 = kdrop;
3938  for (i = 1; i <= i__2; ++i)
3939  {
3940  ++ira;
3941  j = ira - kdrop;
3942  temp = w[ira];
3943  w[ira] = w[j];
3944  /* L820: */
3945  w[j] = temp;
3946  }
3947  w[ir] = zero;
3948 
3949  /* APPLY THE ROTATION TO THE ROWS OF R. */
3950 
3951  w[j] = sum;
3952  ++kdrop;
3953  i__2 = nu;
3954  for (i = kdrop; i <= i__2; ++i)
3955  {
3956  temp = ga * w[ira] + gb * w[ira + 1];
3957  w[ira + 1] = ga * w[ira + 1] - gb * w[ira];
3958  w[ira] = temp;
3959  /* L830: */
3960  ira += i;
3961  }
3962 
3963  /* APPLY THE ROTATION TO THE COLUMNS OF Z. */
3964 
3965  i__2 = *n;
3966  for (i = 1; i <= i__2; ++i)
3967  {
3968  ++iz;
3969  j = iz - *n;
3970  temp = ga * w[j] + gb * w[iz];
3971  w[iz] = ga * w[iz] - gb * w[j];
3972  /* L840: */
3973  w[j] = temp;
3974  }
3975 
3976  /* REVISE IACT AND THE LAGRANGE MULTIPLIERS. */
3977 
3978  iact[kdrop - 1] = iact[kdrop];
3979  w[kdrop - 1] = w[kdrop];
3980  if (kdrop < *nact)
3981  {
3982  goto L810;
3983  }
3984 L850:
3985  --(*nact);
3986  switch ((int)mflag)
3987  {
3988  case 1:
3989  goto L250;
3990  case 2:
3991  goto L610;
3992  }
3993 
3994 
3995  /* ******************************************************************** */
3996 
3997 
3998 
3999  /* APPLY GIVENS ROTATION TO REDUCE SOME OF THE SCALAR */
4000  /* PRODUCTS IN THE S-PARTITION OF W TO ZERO. */
4001 
4002 L860:
4003  iz = iwz + nu * *n;
4004 L870:
4005  iz -= *n;
4006 L880:
4007  is = iws + nu;
4008  --nu;
4009  if (nu == *nact)
4010  {
4011  goto L900;
4012  }
4013  if (w[is] == zero)
4014  {
4015  goto L870;
4016  }
4017  /* Computing MAX */
4018  d__3 = (d__1 = w[is - 1], abs(d__1)), d__4 = (d__2 = w[is], abs(d__2));
4019  temp = max(d__3, d__4);
4020  /* Computing 2nd power */
4021  d__1 = w[is - 1] / temp;
4022  /* Computing 2nd power */
4023  d__2 = w[is] / temp;
4024  sum = temp * sqrt(d__1 * d__1 + d__2 * d__2);
4025  ga = w[is - 1] / sum;
4026  gb = w[is] / sum;
4027  w[is - 1] = sum;
4028  i__2 = *n;
4029  for (i = 1; i <= i__2; ++i)
4030  {
4031  k = iz + *n;
4032  temp = ga * w[iz] + gb * w[k];
4033  w[k] = ga * w[k] - gb * w[iz];
4034  w[iz] = temp;
4035  /* L890: */
4036  --iz;
4037  }
4038  goto L880;
4039 L900:
4040  switch ((int)nflag)
4041  {
4042  case 1:
4043  goto L560;
4044  case 2:
4045  goto L630;
4046  }
4047 
4048 
4049  /* ******************************************************************** */
4050 
4051 
4052 
4053  /* CALCULATE THE MAGNITUDE OF X AN REVISE XMAG. */
4054 
4055 L910:
4056  sum = zero;
4057  i__2 = *n;
4058  for (i = 1; i <= i__2; ++i)
4059  {
4060  sum += (d__1 = x[i], abs(d__1)) * vfact * ((d__2 = grad[i], abs(d__2))
4061  + (d__3 = g[i + i * g_dim1] * x[i], abs(d__3)));
4062  if (*lql)
4063  {
4064  goto L920;
4065  }
4066  if (sum < 1e-30)
4067  {
4068  goto L920;
4069  }
4070  vfact *= 1e-10;
4071  sum *= 1e-10;
4072  xmag *= 1e-10;
4073 L920:
4074  ;
4075  }
4076  /* L925: */
4077  xmag = max(xmag, sum);
4078  switch ((int)jflag)
4079  {
4080  case 1:
4081  goto L420;
4082  case 2:
4083  goto L690;
4084  }
4085 
4086 
4087  /* ******************************************************************** */
4088 
4089 
4090 
4091  /* PRE-MULTIPLY THE VECTOR IN THE W-PARTITION OF W BY Z TRANSPOSE. */
4092 
4093 L930:
4094  jl = iww + 1;
4095  iz = iwz;
4096  i__2 = *n;
4097  for (i = 1; i <= i__2; ++i)
4098  {
4099  is = iws + i;
4100  w[is] = zero;
4101  iwwn = iww + *n;
4102  i__1 = iwwn;
4103  for (j = jl; j <= i__1; ++j)
4104  {
4105  ++iz;
4106  /* L940: */
4107  w[is] += w[iz] * w[j];
4108  }
4109  }
4110  switch ((int)kflag)
4111  {
4112  case 1:
4113  goto L350;
4114  case 2:
4115  goto L550;
4116  }
4117  return 0;
4118 } /* ql0002_ */
4119 
4120 #ifdef uNdEfInEd
4121 comments from the converter:
4122 (stderr from f2c)
4123 ql0001:
4124 ql0002:
4125 #endif
4126 
4127 
4128 #define DMAX1(a, b) ((a) > (b) ? (a) : (b))
4129 #define DMIN1(a, b) ((a) < (b) ? (a) : (b))
4130 #ifndef TRUE
4131 #define TRUE 1
4132 #endif
4133 #ifndef FALSE
4134 #define FALSE 0
4135 #endif
4136 #define NONE 0
4137 #define OBJECT 1
4138 #define CONSTR 2
4139 
4140 /***************************************************************/
4141 /* Global Variables and Data Structures */
4142 /***************************************************************/
4143 
4145 {
4146  double val;
4147  double *grad;
4148  double mult;
4149  double mult_L; /* mode A=1 */
4150  int act_sip; /* SIP */
4151 };
4152 
4154 {
4155  double val;
4156  double *grad;
4157  double mult;
4158  int act_sip; /* SIP */
4159  int d1bind; /* SR constraints */
4160 };
4161 
4163 {
4164  double *x;
4165  double *bl;
4166  double *bu;
4167  double *mult;
4168  void *cd; /* Client data pointer */
4169 };
4170 
4172 { /* SIP */
4173  int type;
4174  int index;
4175 };
4176 
4177 double bgbnd, tolfea;
4178 int nstop, maxit;
4179 
4181 {
4184 }
4185 glob_info;
4186 
4188 {
4189  int iprint, info, ipd, iter, initvl, iter_mod;
4190  FILE *io;
4191 }
4192 glob_prnt;
4193 
4195 {
4197 }
4198 glob_grd;
4199 
4201 {
4203 }
4204 glob_log;
4205 
4206 /* User-accessible stopping criterion (see cfsqpusr.h) */
4207 extern double objeps;
4208 extern double objrep;
4209 extern double gLgeps;
4210 extern int x_is_new;
4211 
4212 /* Workspace */
4213 int *iw;
4214 double *w;
4216 
4217 /***************************************************************/
4218 /* Memory Utilities */
4219 /***************************************************************/
4220 
4221 #ifdef __STDC__
4222 static int *make_iv(int);
4223 static double *make_dv(int);
4224 static double **make_dm(int, int);
4225 static void free_iv(int *);
4226 static void free_dv(double *);
4227 static void free_dm(double **, int);
4228 static double *convert(double **, int, int);
4229 #else
4230 static int *make_iv();
4231 static double *make_dv();
4232 static double **make_dm();
4233 static void free_iv();
4234 static void free_dv();
4235 static void free_dm();
4236 static double *convert();
4237 #endif
4238 
4239 /***************************************************************/
4240 /* Utility Subroutines */
4241 /***************************************************************/
4242 
4243 #ifdef __STDC__
4244 int
4245 ql0001_(int *, int *, int *, int *, int *, int *, double *, double *,
4246  double *, double *, double *, double *, double *, double *,
4247  int *, int *, int *, double *, int *, int *, int *, double *);
4248 static void diagnl(int, double, double **);
4249 static void error(const char string[], int *);
4250 static void
4251 estlam(int, int, int *, double, double **, double *, double *, double *,
4252  struct _constraint *, double *, double *, double *, double *);
4253 static double *colvec(double **, int, int);
4254 static double scaprd(int, double *, double *);
4255 static double smallNumber();
4256 static int fuscmp(double, double);
4257 static int indexs(int, int);
4258 static void matrcp(int, double **, int, double **);
4259 static void matrvc(int, int, double **, double *, double *);
4260 static void nullvc(int, double *);
4261 static void
4262 resign(int, int, double *, double *, double *, struct _constraint *,
4263  double *, int, int);
4264 static void sbout1(FILE *, int, const char *, double, double *, int, int);
4265 static void sbout2(FILE *, int, int, const char *, const char *, double *);
4266 static void shift(int, int, int *);
4267 static double
4268 slope(int, int, int, int, int, struct _objective *, double *, double *,
4269  double *, double, double, int, double *, int);
4270 static int element(int *, int, int);
4271 #else
4272 int ql0001_(); /* QLD Subroutine */
4273 static void diagnl();
4274 static void error();
4275 static void estlam();
4276 static double *colvec();
4277 static double scaprd();
4278 static double smallNumber();
4279 static int fuscmp();
4280 static int indexs();
4281 static void matrcp();
4282 static void matrvc();
4283 static void nullvc();
4284 static void resign();
4285 static void sbout1();
4286 static void sbout2();
4287 static void shift();
4288 static double slope();
4289 static int element();
4290 #endif
4291 
4292 /**************************************************************/
4293 /* Gradients - Finite Difference */
4294 /**************************************************************/
4295 
4296 #ifdef __STDC__
4297 void grobfd(int, int, double *, double *, void(*)(int, int,
4298  double *, double *, void *), void *);
4299 void grcnfd(int, int, double *, double *, void(*)(int, int,
4300  double *, double *, void *), void *);
4301 #else
4302 void grobfd();
4303 void grcnfd();
4304 #endif
4305 
4306 /**************************************************************/
4307 /* Main routines for optimization - */
4308 /**************************************************************/
4309 
4310 #ifdef __STDC__
4311 static void
4312 cfsqp1(int, int, int, int, int, int, int, int, int, int, int *, int,
4313  int, int, int, double, double, int *, int *, struct _parameter *,
4314  struct _constraint *, struct _objective *, double *,
4315  void(*)(int, int, double *, double *, void *),
4316  void(*)(int, int, double *, double *, void *),
4317  void(*)(int, int, double *, double *,
4318  void(*)(int, int, double *, double *, void *), void *),
4319  void(*)(int, int, double *, double *,
4320  void(*)(int, int, double *, double *, void *), void *));
4321 static void
4322 check(int, int, int, int *, int, int, int, int, int, int, int, int *, double,
4323  double, struct _parameter *);
4324 static void
4325 initpt(int, int, int, int, int, int, int, struct _parameter *,
4326  struct _constraint *, void(*)(int, int, double *, double *, void *),
4327  void(*)(int, int, double *, double *,
4328  void(*)(int, int, double *, double *, void *), void *));
4329 static void
4330 dir(int, int, int, int, int, int, int, int, int, int, int, int, double *,
4331  double, double, double *, double *, double, double *, double *, int *,
4332  int *, int *, int *, int *, int *, struct _parameter *, double *,
4333  double *, struct _constraint *, struct _objective *, double *,
4334  double *, double *, double *, double *, double *, double **, double *,
4335  double *, double *, double *, double **, double **, double *,
4336  double *, struct _violation *, void(*)(int, int, double *, double *,
4337  void *), void(*)(int, int, double *, double *, void *));
4338 static void
4339 step1(int, int, int, int, int, int, int, int, int, int, int, int *, int *, int *,
4340  int *, int *, int *, int *, int *, int, double, struct _objective *,
4341  double *, double *, double *, double *, double *, double *, double *,
4342  double *, double *, double *, double *, struct _constraint *,
4343  double *, double *, struct _violation *viol,
4344  void(*)(int, int, double *, double *, void *),
4345  void(*)(int, int, double *, double *, void *), void *);
4346 static void
4347 hessian(int, int, int, int, int, int, int, int, int, int, int, int *, int,
4348  double *, struct _parameter *, struct _objective *,
4349  double, double *, double *, double *, double *, double *,
4350  struct _constraint *, double *, int *, int *, double *,
4351  double *, double *, double **, double *, double, int *,
4352  double *, double *, void(*)(int, int, double *, double *, void *),
4353  void(*)(int, int, double *, double *, void *),
4354  void(*)(int, int, double *, double *,
4355  void(*)(int, int, double *, double *, void *), void *),
4356  void(*)(int, int, double *, double *,
4357  void(*)(int, int, double *, double *, void *), void *),
4358  double **, double *, double *, struct _violation *);
4359 static void
4360 out(int, int, int, int, int, int, int, int, int, int, int, int *, double *,
4361  struct _constraint *, struct _objective *, double,
4362  double, double, double, double, int);
4363 static void
4364 update_omega(int, int, int, int *, int, int, int, int, double, double,
4365  struct _constraint *, struct _objective *, double *,
4366  struct _violation *, void(*)(int, int, double *, double *,
4367  void *), void(*)(int, int, double *, double *, void *),
4368  void(*)(int, int, double *, double *,
4369  void(*)(int, int, double *, double *, void *), void *),
4370  void(*)(int, int, double *, double *,
4371  void(*)(int, int, double *, double *, void *), void *),
4372  void *, int);
4373 #else
4374 static void cfsqp1();
4375 static void check();
4376 static void initpt();
4377 static void dir();
4378 static void step1();
4379 static void hessian();
4380 static void out();
4381 static void update_omega();
4382 #endif
4383 
4384 #ifdef __STDC__
4385 static void
4386 dealloc(int, int, double *, int *, int *, struct _constraint *cs,
4387  struct _parameter *);
4388 #else
4389 static void dealloc();
4390 #endif
4391 
4392 #ifdef __STDC__
4393 void
4394 cfsqp(int nparam, int nf, int nfsr, int nineqn, int nineq, int neqn,
4395  int neq, int ncsrl, int ncsrn, int *mesh_pts,
4396  int mode, int iprint, int miter, int *inform, double bigbnd,
4397  double eps, double epseqn, double udelta, double *bl, double *bu,
4398  double *x, double *f, double *g, double *lambda,
4399  void(*obj)(int, int, double *, double *, void *),
4400  void(*constr)(int, int, double *, double *, void *),
4401  void(*gradob)(int, int, double *, double *,
4402  void(*)(int, int, double *, double *, void *), void *),
4403  void(*gradcn)(int, int, double *, double *,
4404  void(*)(int, int, double *, double *, void *), void *),
4405  void *cd)
4406 #else
4407 void
4408 cfsqp(nparam, nf, nfsr, nineqn, nineq, neqn, neq, ncsrl, ncsrn, mesh_pts,
4409  mode, iprint, miter, inform, bigbnd, eps, epseqn, udelta, bl, bu, x,
4410  f, g, lambda, obj, constr, gradob, gradcn, cd)
4411 int nparam, nf, nfsr, neqn, nineqn, nineq, neq, ncsrl, ncsrn, mode,
4412 iprint, miter, *mesh_pts, *inform;
4413 double bigbnd, eps, epseqn, udelta;
4414 double *bl, *bu, *x, *f, *g, *lambda;
4415 void(* obj)(), (* constr)(), (* gradob)(), (* gradcn)();
4416 void *cd;
4417 #endif
4418 
4419 /*---------------------------------------------------------------------
4420 * Brief specification of various arrays and parameters in the calling
4421 * sequence. See manual for a more detailed description.
4422 *
4423 * nparam : number of variables
4424 * nf : number of objective functions (count each set of sequentially
4425 * related objective functions once)
4426 * nfsr : number of sets of sequentially related objectives (possibly
4427 * zero)
4428 * nineqn : number of nonlinear inequality constraints
4429 * nineq : total number of inequality constraints
4430 * neqn : number of nonlinear equality constraints
4431 * neq : total number of equality constraints
4432 * ncsrl : number of sets of linear sequentially related inequality
4433 * constraints
4434 * ncsrn : number of sets of nonlinear sequentially related inequality
4435 * constraints
4436 * mesh_pts : array of integers giving the number of actual objectives/
4437 * constraints in each sequentially related objective or
4438 * constraint set. The order is as follows:
4439 * (i) objective sets, (ii) nonlinear constraint sets,
4440 * (iii) linear constraint sets. If one or no sequentially
4441 * related constraint or objectives sets are present, the
4442 * user may simply pass the address of an integer variable
4443 * containing the appropriate number (possibly zero).
4444 * mode : mode=CBA specifies job options as described below:
4445 * A = 0 : ordinary minimax problems
4446 * = 1 : ordinary minimax problems with each individual
4447 * function replaced by its absolute value, ie,
4448 * an L_infty problem
4449 * B = 0 : monotone decrease of objective function
4450 * after each iteration
4451 * = 1 : monotone decrease of objective function after
4452 * at most four iterations
4453 * C = 1 : default operation.
4454 * = 2 : requires that constraints always be evaluated
4455 * before objectives during the line search.
4456 * iprint : print level indicator with the following options-
4457 * iprint=0: no normal output, only error information
4458 * (this option is imposed during phase 1)
4459 * iprint=1: a final printout at a local solution
4460 * iprint=2: a brief printout at the end of each iteration
4461 * iprint=3: detailed information is printed out at the end
4462 * of each iteration (for debugging purposes)
4463 * For iprint=2 or 3, the information may be printed at
4464 * iterations that are multiples of 10, instead of every
4465 * iteration. This may be done by adding the desired number
4466 * of iterations to skip printing to the desired iprint value
4467 * as specified above. e.g., sending iprint=23 would give
4468 * the iprint=3 information once every 20 iterations.
4469 * miter : maximum number of iterations allowed by the user to solve
4470 * the problem
4471 * inform : status report at the end of execution
4472 * inform= 0:normal termination
4473 * inform= 1:no feasible point found for linear constraints
4474 * inform= 2:no feasible point found for nonlinear constraints
4475 * inform= 3:no solution has been found in miter iterations
4476 * inform= 4:stepsize smaller than machine precision before
4477 * a successful new iterate is found
4478 * inform= 5:failure in attempting to construct d0
4479 * inform= 6:failure in attempting to construct d1
4480 * inform= 7:inconsistent input data
4481 * inform= 8:new iterate essentially identical to previous
4482 * iterate, though stopping criterion not satisfied.
4483 * inform= 9:penalty parameter too large, unable to satisfy
4484 * nonlinear equality constraint
4485 * bigbnd : plus infinity
4486 * eps : stopping criterion. Execution stopped when the norm of the
4487 * Newton direction vector is smaller than eps
4488 * epseqn : tolerance of the violation of nonlinear equality constraints
4489 * allowed by the user at an optimal solution
4490 * udelta : perturbation size in computing gradients by finite
4491 * difference. The actual perturbation is determined by
4492 * sign(x_i) X max{udelta, rteps X max{1, |x_i|}} for each
4493 * component of x, where rteps is the square root of machine
4494 * precision.
4495 * bl : array of dimension nparam,containing lower bound of x
4496 * bu : array of dimension nparam,containing upper bound of x
4497 * x : array of dimension nparam,containing initial guess in input
4498 * and final iterate at the end of execution
4499 * f : array of dimension sufficient enough to hold the value of
4500 * all regular objective functions and the value of all
4501 * members of the sequentially related objective sets.
4502 * (dimension must be at least 1)
4503 * g : array of dimension sufficient enough to hold the value of
4504 * all regular constraint functions and the value of all
4505 * members of the sequentially related constraint sets.
4506 * (dimension must be at least 1)
4507 * lambda : array of dimension nparam+dim(f)+dim(g), containing
4508 * Lagrange multiplier values at x in output. (A concerns the
4509 * mode, see above). The first nparam positions contain the
4510 * multipliers associated with the simple bounds, the next
4511 * dim(g) positions contain the multipliers associated with
4512 * the constraints. The final dim(f) positions contain the
4513 * multipliers associated with the objective functions. The
4514 * multipliers are in the order they were specified in the
4515 * user-defined objective and constraint functions.
4516 * obj : Pointer to function that returns the value of objective
4517 * functions, one upon each call
4518 * constr : Pointer to function that returns the value of constraints
4519 * one upon each call
4520 * gradob : Pointer to function that computes gradients of f,
4521 * alternatively it can be replaced by grobfd to compute
4522 * finite difference approximations
4523 * gradcn : Pointer to function that computes gradients of g,
4524 * alternatively it can be replaced by grcnfd to compute
4525 * finite difference approximations
4526 * cd : Void pointer that may be used by the user for the passing of
4527 * "client data" (untouched by CFSQP)
4528 *
4529 *----------------------------------------------------------------------
4530 *
4531 *
4532 * CFSQP Version 2.5b
4533 *
4534 * Craig Lawrence, Jian L. Zhou
4535 * and Andre Tits
4536 * Institute for Systems Research
4537 * and
4538 * Electrical Engineering Department
4539 * University of Maryland
4540 * College Park, Md 20742
4541 *
4542 * June, 1997
4543 *
4544 *
4545 * The purpose of CFSQP is to solve general nonlinear constrained
4546 * minimax optimization problems of the form
4547 *
4548 * (A=0 in mode) minimize max_i f_i(x) for i=1,...,n_f
4549 * or
4550 * (A=1 in mode) minimize max_j |f_i(x)| for i=1,...,n_f
4551 * s.t. bl <= x <= bu
4552 * g_j(x) <= 0, for j=1,...,nineqn
4553 * A_1 x - B_1 <= 0
4554 *
4555 * h_i(x) = 0, for i=1,...,neqn
4556 * A_2 x - B_2 = 0
4557 *
4558 * CFSQP is also able to efficiently handle problems with large sets of
4559 * sequentially related objectives or constraints, see the manual for
4560 * details.
4561 *
4562 *
4563 * Conditions for External Use
4564 * ===========================
4565 *
4566 * 1. The CFSQP routines may not be distributed to third parties.
4567 * Interested parties should contact the authors directly.
4568 * 2. If modifications are performed on the routines, these
4569 * modifications will be communicated to the authors. The
4570 * modified routines will remain the sole property of the authors.
4571 * 3. Due acknowledgment must be made of the use of the CFSQP
4572 * routines in research reports or publications. Whenever
4573 * such reports are released for public access, a copy should
4574 * be forwarded to the authors.
4575 * 4. The CFSQP routines may only be used for research and
4576 * development, unless it has been agreed otherwise with the
4577 * authors in writing.
4578 *
4579 * Copyright (c) 1993-1997 by Craig T. Lawrence, Jian L. Zhou, and
4580 * Andre L. Tits
4581 * All Rights Reserved.
4582 *
4583 *
4584 * Enquiries should be directed to:
4585 *
4586 * Prof. Andre L. Tits
4587 * Electrical Engineering Dept.
4588 * and Systems Research Center
4589 * University of Maryland
4590 * College Park, Md 20742
4591 * U. S. A.
4592 *
4593 * Phone : 301-405-3669
4594 * Fax : 301-405-6707
4595 * E-mail: andre@eng.umd.edu
4596 *
4597 * References:
4598 * [1] E. Panier and A. Tits, `On Combining Feasibility, Descent and
4599 * Superlinear Convergence In Inequality Constrained Optimization',
4600 * Mathematical Programming, Vol. 59(1993), 261-276.
4601 * [2] J. F. Bonnans, E. Panier, A. Tits and J. Zhou, `Avoiding the
4602 * Maratos Effect by Means of a Nonmonotone Line search: II.
4603 * Inequality Problems - Feasible Iterates', SIAM Journal on
4604 * Numerical Analysis, Vol. 29, No. 4, 1992, pp. 1187-1202.
4605 * [3] J.L. Zhou and A. Tits, `Nonmonotone Line Search for Minimax
4606 * Problems', Journal of Optimization Theory and Applications,
4607 * Vol. 76, No. 3, 1993, pp. 455-476.
4608 * [4] C.T. Lawrence, J.L. Zhou and A. Tits, `User's Guide for CFSQP
4609 * Version 2.5: A C Code for Solving (Large Scale) Constrained
4610 * Nonlinear (Minimax) Optimization Problems, Generating Iterates
4611 * Satisfying All Inequality Constraints,' Institute for
4612 * Systems Research, University of Maryland,Technical Report
4613 * TR-94-16r1, College Park, MD 20742, 1997.
4614 * [5] C.T. Lawrence and A.L. Tits, `Nonlinear Equality Constraints
4615 * in Feasible Sequential Quadratic Programming,' Optimization
4616 * Methods and Software, Vol. 6, March, 1996, pp. 265-282.
4617 * [6] J.L. Zhou and A.L. Tits, `An SQP Algorithm for Finely
4618 * Discretized Continuous Minimax Problems and Other Minimax
4619 * Problems With Many Objective Functions,' SIAM Journal on
4620 * Optimization, Vol. 6, No. 2, May, 1996, pp. 461--487.
4621 * [7] C. T. Lawrence and A. L. Tits, `Feasible Sequential Quadratic
4622 * Programming for Finely Discretized Problems from SIP,'
4623 * To appear in R. Reemtsen, J.-J. Ruckmann (eds.): Semi-Infinite
4624 * Programming, in the series Nonconcex Optimization and its
4625 * Applications. Kluwer Academic Publishers, 1997.
4626 *
4627 ***********************************************************************
4628 */
4630  int i, ipp, j, ncnstr, nclin, nctotl, nob, nobL, modem=0, nn,
4634  double *signeq;
4635  double xi, gi, gmax, dummy, epskt;
4636  struct _constraint *cs; /* pointer to array of constraints */
4637  struct _objective *ob; /* pointer to array of objectives */
4638  struct _parameter *param; /* pointer to parameter structure */
4640 
4641  /* Make adjustments to parameters for SIP constraints */
4643  mesh_pts = mesh_pts - 1;
4647  nf = nf - nfsr;
4648  nfsip1 = nfsr;
4649  nfsr = 0;
4650  for (i = 1; i <= nfsip1; i++)
4651  nfsr = nfsr + mesh_pts[i];
4652  nf = nf + nfsr;
4653  nineqn = nineqn - ncsrn;
4654  nineq = nineq - ncsrl - ncsrn;
4655  ncsipl1 = ncsrl;
4656  ncsipn1 = ncsrn;
4657  ncsrl = 0;
4658  ncsrn = 0;
4659  if (ncsipn1)
4660  for (i = 1; i <= ncsipn1; i++)
4661  ncsrn = ncsrn + mesh_pts[nfsip1+i];
4662  if (ncsipl1)
4663  for (i = 1; i <= ncsipl1; i++)
4664  ncsrl = ncsrl + mesh_pts[nfsip1+ncsipn1+i];
4665  nineqn = nineqn + ncsrn;
4666  nineq = nineq + ncsrn + ncsrl;
4667  /* Create array of constraint structures */
4668  cs = (struct _constraint *)calloc(nineq + neq + 1,
4669  sizeof(struct _constraint));
4670  for (i = 1; i <= nineq + neq; i++)
4671  {
4672  cs[i].grad = make_dv(nparam);
4673  cs[i].act_sip = FALSE;
4674  cs[i].d1bind = FALSE;
4675  }
4676  /* Create parameter structure */
4677  _param.x = make_dv(nparam + 1);
4678  _param.bl = make_dv(nparam);
4679  _param.bu = make_dv(nparam);
4680  _param.mult = make_dv(nparam + 1);
4681  param = &_param;
4682 
4683  /* Initialize, compute the machine precision, etc. */
4684  bl = bl - 1;
4685  bu = bu - 1;
4686  x = x - 1;
4687  for (i = 1; i <= nparam; i++)
4688  {
4689  param->x[i] = x[i];
4690  param->bl[i] = bl[i];
4691  param->bu[i] = bu[i];
4692  }
4693  param->cd = cd; /* Initialize client data */
4694  dummy = 0.e0;
4695  f = f - 1;
4696  g = g - 1;
4697  lambda = lambda - 1;
4699  nstop = 1;
4700  nn = nineqn + neqn;
4701  glob_grd.epsmac = smallNumber();
4702  tolfea = glob_grd.epsmac * 1.e2;
4703  bgbnd = bigbnd;
4708  signeq = make_dv(neqn);
4709 
4710  nob = 0;
4711  gmax = -bgbnd;
4712  glob_prnt.info = 0;
4713  glob_prnt.iprint = iprint % 10;
4714  ipp = iprint;
4715  glob_prnt.iter_mod = DMAX1(iprint - iprint % 10, 1);
4716  glob_prnt.io = stdout;
4717  ncnstr = nineq + neq;
4720  {
4722  "\n\n CFSQP Version 2.5b (Released June 1997) \n");
4724  " Copyright (c) 1993 --- 1997 \n");
4726  " C.T. Lawrence, J.L. Zhou \n");
4728  " and A.L. Tits \n");
4730  " All Rights Reserved \n\n");
4731  }
4732  /*-----------------------------------------------------*/
4733  /* Check the input data */
4734  /*-----------------------------------------------------*/
4735  check(nparam, nf, nfsr, &Linfty, nineq, nineqn, neq, neqn,
4736  ncsrl, ncsrn, mode, &modem, eps, bgbnd, param);
4737  if (glob_prnt.info == 7)
4738  {
4739  *inform = glob_prnt.info;
4740  return;
4741  }
4742 
4743  maxit = DMAX1(DMAX1(miter, 10 * DMAX1(nparam, ncnstr)), 1000);
4744  feasb = TRUE;
4745  feasbl = TRUE;
4746  prnt = FALSE;
4747  nppram = nparam + 1;
4748 
4749  /*-----------------------------------------------------*/
4750  /* Check whether x is within bounds */
4751  /*-----------------------------------------------------*/
4752  for (i = 1; i <= nparam; i++)
4753  {
4754  xi = param->x[i];
4755  if (param->bl[i] <= xi && param->bu[i] >= xi)
4756  continue;
4757  feasbl = FALSE;
4758  break;
4759  }
4760  nclin = ncnstr - nn;
4761  /*-----------------------------------------------------*/
4762  /* Check whether linear constraints are feasbile */
4763  /*-----------------------------------------------------*/
4764  if (nclin != 0)
4765  {
4766  for (i = 1; i <= nclin; i++)
4767  {
4768  j = i + nineqn;
4769  if (j <= nineq)
4770  {
4771  constr(nparam, j, (param->x) + 1, &gi, param->cd);
4772  if (gi > glob_grd.epsmac)
4773  feasbl = FALSE;
4774  }
4775  else
4776  {
4777  constr(nparam, j + neqn, (param->x) + 1, &gi, param->cd);
4778  if (fabs(gi) > glob_grd.epsmac)
4779  feasbl = FALSE;
4780  }
4781  cs[j].val = gi;
4782  }
4783  }
4784  /*-------------------------------------------------------*/
4785  /* Generate a new point if infeasible */
4786  /*-------------------------------------------------------*/
4787  if (!feasbl)
4788  {
4789  if (glob_prnt.iprint > 0)
4790  {
4792  " The given initial point is infeasible for inequality\n");
4794  " constraints and linear equality constraints:\n");
4795  sbout1(glob_prnt.io, nparam, " ", dummy,
4796  param->x, 2, 1);
4797  prnt = TRUE;
4798  }
4799  nctotl = nparam + nclin;
4800  lenw = 2 * nparam * nparam + 10 * nparam + 2 * nctotl + 1;
4801  leniw = DMAX1(2 * nparam + 2 * nctotl + 3, 2 * nclin + 2 * nparam + 6);
4802  /*-----------------------------------------------------*/
4803  /* Attempt to generate a point satisfying all linear */
4804  /* constraints. */
4805  /*-----------------------------------------------------*/
4806  nrowa = DMAX1(nclin, 1);
4807  iw = make_iv(leniw);
4808  w = make_dv(lenw);
4809  initpt(nparam, nineqn, neq, neqn, nclin, nctotl, nrowa, param,
4810  &cs[nineqn], constr, gradcn);
4811  free_iv(iw);
4812  free_dv(w);
4813  if (glob_prnt.info != 0)
4814  {
4815  *inform = glob_prnt.info;
4816  return;
4817  }
4818  }
4819  indxob = make_iv(DMAX1(nineq + neq, nf));
4820  indxcn = make_iv(nineq + neq);
4821 L510:
4822  if (glob_prnt.info != -1)
4823  {
4824  for (i = 1; i <= nineqn; i++)
4825  {
4826  constr(nparam, i, (param->x) + 1, &(cs[i].val), param->cd);
4827  if (cs[i].val > 0.e0)
4828  feasb = FALSE;
4829  }
4831  if (!feasb)
4832  {
4833  /* Create array of objective structures for Phase 1 */
4834  ob = (struct _objective *)calloc(nineqn + 1,
4835  sizeof(struct _objective));
4836  for (i = 1; i <= nineqn; i++)
4837  {
4838  ob[i].grad = make_dv(nparam);
4839  ob[i].act_sip = FALSE;
4840  }
4841  for (i = 1; i <= nineqn; i++)
4842  {
4843  nob++;
4844  indxob[nob] = i;
4845  ob[nob].val = cs[i].val;
4846  gmax = DMAX1(gmax, ob[nob].val);
4847  }
4848  for (i = 1; i <= nineq - nineqn; i++)
4849  indxcn[i] = nineqn + i;
4850  for (i = 1; i <= neq - neqn; i++)
4851  indxcn[i+nineq-nineqn] = nineq + neqn + i;
4852  goto L605;
4853  }
4854  }
4855 
4856  /* Create array of objective structures for Phase 2 and */
4857  /* initialize. */
4858  ob = (struct _objective *)calloc(nf + 1, sizeof(struct _objective));
4859  for (i = 1; i <= nf; i++)
4860  {
4861  ob[i].grad = make_dv(nparam);
4862  ob[i].act_sip = FALSE;
4863  }
4864  for (i = 1; i <= nineqn; i++)
4865  {
4866  indxcn[i] = i;
4867  }
4868  for (i = 1; i <= neq - neqn; i++)
4869  cs[i+nineq+neqn].val = cs[i+nineq].val;
4870  for (i = 1; i <= neqn; i++)
4871  {
4872  j = i + nineq;
4873  constr(nparam, j, (param->x) + 1, &(cs[j].val), param->cd);
4874  indxcn[nineqn+i] = j;
4875  }
4876  for (i = 1; i <= nineq - nineqn; i++)
4877  indxcn[i+nn] = nineqn + i;
4878  for (i = 1; i <= neq - neqn; i++)
4879  indxcn[i+nineq+neqn] = nineq + neqn + i;
4880  glob_info.ncallg += neqn;
4881 
4882  L605:
4883  if (glob_prnt.iprint > 0 && feasb && !prnt)
4884  {
4886  "The given initial point is feasible for inequality\n");
4888  " constraints and linear equality constraints:\n");
4889  sbout1(glob_prnt.io, nparam, " ", dummy,
4890  param->x, 2, 1);
4891  prnt = TRUE;
4892  }
4893  if (nob == 0)
4894  {
4895  if (glob_prnt.iprint > 0)
4896  {
4897  if (glob_prnt.info != 0)
4898  {
4900  "To generate a feasible point for nonlinear inequality\n");
4902  "constraints and linear equality constraints, ");
4903  fprintf(glob_prnt.io, "ncallg = %10d\n", glob_info.ncallg);
4904  if (ipp == 0)
4905  fprintf(glob_prnt.io, " iteration %26d\n",
4906  glob_prnt.iter);
4907  if (ipp > 0)
4908  fprintf(glob_prnt.io, " iteration %26d\n",
4909  glob_prnt.iter - 1);
4910  if (ipp == 0)
4911  glob_prnt.iter++;
4912  }
4913  if (feasb && !feasbl)
4914  {
4916  "Starting from the generated point feasible for\n");
4918  "inequality constraints and linear equality constraints:\n");
4919  sbout1(glob_prnt.io, nparam, " ",
4920  dummy, param->x, 2, 1);
4921 
4922  }
4923  if (glob_prnt.info != 0 || !prnt || !feasb)
4924  {
4926  "Starting from the generated point feasible for\n");
4928  "inequality constraints and linear equality constraints:\n");
4929  sbout1(glob_prnt.io, nparam, " ",
4930  dummy, param->x, 2, 1);
4931  }
4932  }
4933  feasb = TRUE;
4934  feasbl = TRUE;
4935  }
4936  if (ipp > 0 && !feasb && !prnt)
4937  {
4939  " The given initial point is infeasible for inequality\n");
4941  " constraints and linear equality constraints:\n");
4942  sbout1(glob_prnt.io, nparam, " ", dummy,
4943  param->x, 2, 1);
4944  prnt = TRUE;
4945  }
4946  if (nob == 0)
4947  nob = 1;
4948  if (feasb)
4949  {
4950  nob = nf;
4951  glob_prnt.info = 0;
4952  glob_prnt.iprint = iprint % 10;
4953  ipp = iprint;
4954  glob_prnt.iter_mod = DMAX1(iprint - iprint % 10, 1);
4955  glob_info.mode = modem;
4956  epskt = eps;
4957  if (Linfty)
4958  nobL = 2 * nob;
4959  else
4960  nobL = nob;
4961  if (nob != 0 || neqn != 0)
4962  goto L910;
4964  "current feasible iterate with no objective specified\n");
4965  *inform = glob_prnt.info;
4966  for (i = 1; i <= nineq + neq; i++)
4967  g[i] = cs[i].val;
4968  dealloc(nineq, neq, signeq, indxcn, indxob, cs, param);
4969  free((char *) ob);
4970  return;
4971  }
4972  ipp = 0;
4973  glob_info.mode = 0;
4974  nobL = nob;
4975  glob_prnt.info = -1;
4976  epskt = 1.e-10;
4977  L910:
4978  nctotl = nppram + ncnstr + DMAX1(nobL, 1);
4979  leniw = 2 * (ncnstr + DMAX1(nobL, 1)) + 2 * nppram + 6;
4980  lenw = 2 * nppram * nppram + 10 * nppram + 6 * (ncnstr + DMAX1(nobL, 1) + 1);
4981  glob_info.M = 4;
4982  if (modem == 1 && nn == 0)
4983  glob_info.M = 3;
4984 
4985  param->x[nparam+1] = gmax;
4986  if (feasb)
4987  {
4988  for (i = 1; i <= neqn; i++)
4989  {
4990  if (cs[i+nineq].val > 0.e0)
4991  signeq[i] = -1.e0;
4992  else
4993  signeq[i] = 1.e0;
4994  }
4995  }
4996  if (!feasb)
4997  {
4998  ncsipl1 = ncsrl;
4999  ncsipn1 = 0;
5000  nfsip1 = ncsrn;
5001  mesh_pts1 = &mesh_pts[nfsr];
5002  }
5003  else
5004  {
5005  ncsipl1 = ncsrl;
5006  ncsipn1 = ncsrn;
5007  nfsip1 = nfsr;
5008  mesh_pts1 = mesh_pts;
5009  }
5010  /*---------------------------------------------------------------*/
5011  /* either attempt to generate a point satisfying all */
5012  /* constraints or try to solve the original problem */
5013  /*---------------------------------------------------------------*/
5014  nrowa = DMAX1(ncnstr + DMAX1(nobL, 1), 1);
5015  w = make_dv(lenw);
5016  iw = make_iv(leniw);
5017 
5018  cfsqp1(miter, nparam, nob, nobL, nfsip1, nineqn, neq, neqn, ncsipl1, ncsipn1,
5019  mesh_pts1, ncnstr, nctotl, nrowa, feasb, epskt, epseqn, indxob,
5020  indxcn, param, cs, ob, signeq, obj, constr, gradob, gradcn);
5021 
5022  free_iv(iw);
5023  free_dv(w);
5024  if (glob_prnt.info == -1)
5025  { /* Successful phase 1 termination */
5026  for (i = 1; i <= nob; i++)
5027  cs[i].val = ob[i].val;
5028  nob = 0;
5029  for (i = 1; i <= nineqn; i++)
5030  free_dv(ob[i].grad);
5031  free((char *) ob);
5032  goto L510;
5033  }
5034  if (glob_prnt.info != 0)
5035  {
5036  if (feasb)
5037  {
5038  for (i = 1; i <= nparam; i++)
5039  x[i] = param->x[i];
5040  for (i = 1; i <= nineq + neq; i++)
5041  g[i] = cs[i].val;
5042  *inform = glob_prnt.info;
5043  dealloc(nineq, neq, signeq, indxcn, indxob, cs, param);
5044  for (i = 1; i <= nf; i++)
5045  {
5046  f[i] = ob[i].val;
5047  free_dv(ob[i].grad);
5048  }
5049  free((char *) ob);
5050  return;
5051  }
5052  glob_prnt.info = 2;
5054  "Error: No feasible point is found for nonlinear inequality\n");
5056  "constraints and linear equality constraints\n");
5057  *inform = glob_prnt.info;
5058  dealloc(nineq, neq, signeq, indxcn, indxob, cs, param);
5059  for (i = 1; i <= nineqn; i++)
5060  free_dv(ob[i].grad);
5061  free((char *) ob);
5062  return;
5063  }
5064  /* Successful phase 2 termination */
5065  *inform = glob_prnt.info;
5066  for (i = 1; i <= nparam; i++)
5067  {
5068  x[i] = param->x[i];
5069  lambda[i] = param->mult[i];
5070  }
5071  for (i = 1; i <= nineq + neq; i++)
5072  {
5073  g[i] = cs[i].val;
5074  lambda[i+nparam] = cs[i].mult;
5075  }
5076  for (i = 1; i <= nf; i++)
5077  {
5078  f[i] = ob[i].val;
5079  lambda[i+nparam+nineq+neq] = ob[i].mult;
5080  free_dv(ob[i].grad);
5081  }
5082  /* If just one objective, set multiplier=1 */
5083  if (nf == 1)
5084  lambda[1+nparam+nineq+neq] = 1.e0;
5085  free((char *) ob);
5086  dealloc(nineq, neq, signeq, indxcn, indxob, cs, param);
5087  return;
5088 }
5089 
5090 /***************************************************************/
5091 /* Free allocated memory */
5092 /***************************************************************/
5093 
5094 #ifdef __STDC__
5095 static void
5096 dealloc(int nineq, int neq, double *signeq, int *indxob,
5097  int *indxcn, struct _constraint *cs, struct _parameter *param)
5098 #else
5099 static void
5100 dealloc(nineq, neq, signeq, indxob, indxcn, cs, param)
5101 int nineq, neq;
5102 double *signeq;
5103 int *indxob, *indxcn;
5104 struct _constraint *cs;
5105 struct _parameter *param;
5106 #endif
5107 {
5108  int i;
5109 
5110  free_dv(param->x);
5111  free_dv(param->bl);
5112  free_dv(param->bu);
5113  free_dv(param->mult);
5114  free_dv(signeq);
5115  free_iv(indxob);
5116  free_iv(indxcn);
5117  for (i = 1; i <= nineq + neq; i++)
5118  free_dv(cs[i].grad);
5119  free((char *) cs);
5120 }
5121 /************************************************************/
5122 /* CFSQP : Main routine */
5123 /************************************************************/
5124 
5125 
5126 #ifdef __STDC__
5127 static void
5128 dealloc1(int, int, double **, double **, double **, double *, double *,
5129  double *, double *, double *, double *, double *, double *,
5130  double *, double *, double *, double *, int *, int *, int *);
5131 #else
5132 static void dealloc1();
5133 #endif
5134 
5135 #ifdef __STDC__
5136 static void
5137 cfsqp1(int miter, int nparam, int nob, int nobL, int nfsip, int nineqn,
5138  int neq, int neqn, int ncsipl, int ncsipn, int *mesh_pts, int ncnstr,
5139  int nctotl, int nrowa, int feasb, double epskt, double epseqn,
5140  int *indxob, int *indxcn, struct _parameter *param,
5141  struct _constraint *cs, struct _objective *ob,
5142  double *signeq, void(*obj)(int, int, double *, double *, void *),
5143  void(*constr)(int, int, double *, double *, void *),
5144  void(*gradob)(int, int, double *, double *,
5145  void(*)(int, int, double *, double *, void *), void *),
5146  void(*gradcn)(int, int, double *, double *,
5147  void(*)(int, int, double *, double *, void *), void *))
5148 #else
5149 static void
5150 cfsqp1(miter, nparam, nob, nobL, nfsip, nineqn, neq, neqn, ncsipl, ncsipn,
5151  mesh_pts, ncnstr, nctotl, nrowa, feasb, epskt, epseqn, indxob,
5152  indxcn, param, cs, ob, signeq, obj, constr, gradob, gradcn)
5153 int miter, nparam, nob, nobL, nfsip, nineqn, neq, neqn, ncnstr,
5154 nctotl, nrowa, feasb, ncsipl, ncsipn, *mesh_pts;
5155 int *indxob, *indxcn;
5156 double epskt, epseqn;
5157 double *signeq;
5158 struct _constraint *cs;
5159 struct _objective *ob;
5160 struct _parameter *param;
5161 void(* obj)(), (* constr)(), (* gradob)(), (* gradcn)();
5162 #endif
5164  int i, iskp, nfs, ncf, ncg, nn, nstart, nrst, ncnst1;
5165  int *iact, *iskip, *istore;
5166  double Cbar, Ck, dbar, fmax, fM, fMp, steps, d0nm, dummy,
5167  sktnom, scvneq, grdftd, psf;
5168  double *di, *d, *gm, *grdpsf, *penp, *bl, *bu, *clamda,
5169  *cvec, *psmu, *span, *backup;
5170  double **hess, **hess1, **a;
5171  double *tempv;
5172  struct _violation *viol;
5174 
5175  /* Allocate memory */
5176 
5177  hess = make_dm(nparam, nparam);
5178  hess1 = make_dm(nparam + 1, nparam + 1);
5179  a = make_dm(nrowa, nparam + 2);
5180  di = make_dv(nparam + 1);
5181  d = make_dv(nparam + 1);
5182  gm = make_dv(4 * neqn);
5183  grdpsf = make_dv(nparam);
5184  penp = make_dv(neqn);
5185  bl = make_dv(nctotl);
5186  bu = make_dv(nctotl);
5187  clamda = make_dv(nctotl + nparam + 1);
5188  cvec = make_dv(nparam + 1);
5189  psmu = make_dv(neqn);
5190  span = make_dv(4);
5191  backup = make_dv(nob + ncnstr);
5192  iact = make_iv(nob + nineqn + neqn);
5193  iskip = make_iv(glob_info.nnineq + 1);
5194  istore = make_iv(nineqn + nob + neqn);
5195 
5196  viol = &_viol;
5197  viol->index = 0;
5198  viol->type = NONE;
5199 
5202  nrst = glob_prnt.ipd = 0;
5203  dummy = 0.e0;
5204  scvneq = 0.e0;
5205  steps = 0.e0;
5206  sktnom = 0.e0;
5207  d0nm = 0.e0;
5208  if (glob_prnt.iter == 0)
5209  diagnl(nparam, 1.e0, hess);
5210  if (feasb)
5211  {
5212  glob_log.first = TRUE;
5213  if (glob_prnt.iter > 0)
5214  glob_prnt.iter--;
5215  if (glob_prnt.iter != 0)
5216  diagnl(nparam, 1.e0, hess);
5217  }
5218  Ck = Cbar = 1.e-2;
5219  dbar = 5.e0;
5220  nstart = 1;
5222  nstop = 1;
5223  nfs = 0;
5224  if (glob_info.mode != 0)
5225  nfs = glob_info.M;
5226  if (feasb)
5227  {
5228  nn = nineqn + neqn;
5229  ncnst1 = ncnstr;
5230  }
5231  else
5232  {
5233  nn = 0;
5234  ncnst1 = ncnstr - nineqn - neqn;
5235  }
5236  scvneq = 0.e0;
5237  for (i = 1; i <= ncnst1; i++)
5238  {
5239  glob_grd.valnom = cs[indxcn[i]].val;
5240  backup[i] = glob_grd.valnom;
5241  if (feasb && i > nineqn && i <= nn)
5242  {
5243  gm[i-nineqn] = glob_grd.valnom * signeq[i-nineqn];
5244  scvneq = scvneq + fabs(glob_grd.valnom);
5245  }
5246  if (feasb && i <= nn)
5247  {
5248  iact[i] = indxcn[i];
5249  istore[i] = 0;
5250  if (i > nineqn)
5251  penp[i-nineqn] = 2.e0;
5252  }
5253  gradcn(nparam, indxcn[i], (param->x) + 1, (cs[indxcn[i]].grad) + 1,
5254  constr, param->cd);
5255  }
5256  nullvc(nparam, grdpsf);
5257  psf = 0.e0;
5258  if (feasb && neqn != 0)
5259  resign(nparam, neqn, &psf, grdpsf, penp, cs, signeq, 12, 12);
5260  fmax = -bgbnd;
5261  for (i = 1; i <= nob; i++)
5262  {
5263  if (!feasb)
5264  {
5265  glob_grd.valnom = ob[i].val;
5266  iact[i] = i;
5267  istore[i] = 0;
5268  gradcn(nparam, indxob[i], (param->x) + 1, (ob[i].grad) + 1, constr,
5269  param->cd);
5270  }
5271  else
5272  {
5273  iact[nn+i] = i;
5274  istore[nn+i] = 0;
5275  obj(nparam, i, (param->x) + 1, &(ob[i].val), param->cd);
5276  glob_grd.valnom = ob[i].val;
5277  backup[i+ncnst1] = glob_grd.valnom;
5278  gradob(nparam, i, (param->x) + 1, (ob[i].grad) + 1, obj, param->cd);
5279  glob_info.ncallf++;
5280  if (nobL != nob)
5281  fmax = DMAX1(fmax, -ob[i].val);
5282  }
5283  fmax = DMAX1(fmax, ob[i].val);
5284  }
5285  if (feasb && nob == 0)
5286  fmax = 0.e0;
5287  fM = fmax;
5288  fMp = fmax - psf;
5289  span[1] = fM;
5290 
5292  {
5293  for (i = 1; i <= nob; i++)
5294  {
5295  if (feasb)
5296  {
5297  if (nob > 1)
5298  {
5299  tempv = ob[i].grad;
5300  sbout2(glob_prnt.io, nparam, i, "gradf(j,", ")", tempv);
5301  }
5302  if (nob == 1)
5303  {
5304  tempv = ob[1].grad;
5305  sbout1(glob_prnt.io, nparam, "gradf(j) ",
5306  dummy, tempv, 2, 2);
5307  }
5308  continue;
5309  }
5310  tempv = ob[i].grad;
5311  sbout2(glob_prnt.io, nparam, indxob[i], "gradg(j,", ")", tempv);
5312  }
5313  if (ncnstr != 0)
5314  {
5315  for (i = 1; i <= ncnst1; i++)
5316  {
5317  tempv = cs[indxcn[i]].grad;
5318  sbout2(glob_prnt.io, nparam, indxcn[i], "gradg(j,", ")", tempv);
5319  }
5320  if (neqn != 0)
5321  {
5322  sbout1(glob_prnt.io, nparam, "grdpsf(j) ", dummy,
5323  grdpsf, 2, 2);
5324  sbout1(glob_prnt.io, neqn, "P ", dummy,
5325  penp, 2, 2);
5326  }
5327  }
5328  for (i = 1; i <= nparam; i++)
5329  {
5330  tempv = colvec(hess, i, nparam);
5331  sbout2(glob_prnt.io, nparam, i, "hess (j,", ")", tempv);
5332  free_dv(tempv);
5333  }
5334  }
5335 
5336  /*----------------------------------------------------------*
5337  * Main loop of the algorithm *
5338  *----------------------------------------------------------*/
5339 
5340  nstop = 1;
5341  for (;;)
5342  {
5343  out(miter, nparam, nob, nobL, nfsip, nineqn, nn, nineqn, ncnst1,
5344  ncsipl, ncsipn, mesh_pts, param->x, cs, ob, fM, fmax, steps,
5345  sktnom, d0nm, feasb);
5346  if (nstop == 0)
5347  {
5348  if (!feasb)
5349  {
5350  dealloc1(nparam, nrowa, a, hess, hess1, di, d, gm,
5351  grdpsf, penp, bl, bu, clamda, cvec, psmu, span, backup,
5352  iact, iskip, istore);
5353  return;
5354  }
5355  for (i = 1; i <= ncnst1; i++)
5356  cs[i].val = backup[i];
5357  for (i = 1; i <= nob; i++)
5358  ob[i].val = backup[i+ncnst1];
5359  for (i = 1; i <= neqn; i++)
5360  cs[glob_info.nnineq+i].mult = signeq[i] * psmu[i];
5361  dealloc1(nparam, nrowa, a, hess, hess1, di, d, gm,
5362  grdpsf, penp, bl, bu, clamda, cvec, psmu, span, backup,
5363  iact, iskip, istore);
5364  return;
5365  }
5366  if (!feasb && glob_prnt.iprint == 0)
5367  glob_prnt.iter++;
5368  /* Update the SIP constraint set Omega_k */
5369  if ((ncsipl + ncsipn) != 0 || nfsip)
5370  update_omega(nparam, ncsipl, ncsipn, mesh_pts, nineqn, nob, nobL,
5371  nfsip, steps, fmax, cs, ob, param->x, viol,
5372  constr, obj, gradob, gradcn, param->cd, feasb);
5373  /* Compute search direction */
5374  dir(nparam, nob, nobL, nfsip, nineqn, neq, neqn, nn, ncsipl, ncsipn,
5375  ncnst1, feasb, &steps, epskt, epseqn, &sktnom, &scvneq, Ck, &d0nm,
5376  &grdftd, indxob, indxcn, iact, &iskp, iskip, istore, param, di, d,
5377  cs, ob, &fM, &fMp, &fmax, &psf, grdpsf, penp, a, bl, bu, clamda, cvec,
5378  hess, hess1, backup, signeq, viol, obj, constr);
5379  if (nstop == 0 && !glob_log.get_ne_mult)
5380  continue;
5381  glob_log.first = FALSE;
5382  if (!glob_log.update && !glob_log.d0_is0)
5383  {
5384  /* Determine step length */
5385  step1(nparam, nob, nobL, nfsip, nineqn, neq, neqn, nn, ncsipl, ncsipn,
5386  ncnst1, &ncg, &ncf, indxob, indxcn, iact, &iskp, iskip, istore,
5387  feasb, grdftd, ob, &fM, &fMp, &fmax, &psf, penp, &steps, &scvneq,
5388  bu, param->x, di, d, cs, backup, signeq, viol, obj, constr,
5389  param->cd);
5390  if (nstop == 0)
5391  continue;
5392  }
5393  /* Update the Hessian */
5394  hessian(nparam, nob, nfsip, nobL, nineqn, neq, neqn, nn, ncsipn, ncnst1,
5395  nfs, &nstart, feasb, bu, param, ob, fmax, &fM, &fMp, &psf, grdpsf,
5396  penp, cs, gm, indxob, indxcn, bl, clamda, di, hess, d, steps, &nrst,
5397  signeq, span, obj, constr, gradob, gradcn, hess1, cvec, psmu, viol);
5398  if (nstop == 0 || glob_info.mode == 0)
5399  continue;
5400  if (d0nm > dbar)
5401  Ck = DMAX1(0.5e0 * Ck, Cbar);
5402  if (d0nm <= dbar && !glob_log.dlfeas &&
5403  !glob_log.rhol_is1)
5404  Ck = 10.e0 * Ck;
5405  }
5406 }
5407 
5408 /*******************************************************************/
5409 /* Free up memory used by CFSQP1 */
5410 /*******************************************************************/
5411 
5412 #ifdef __STDC__
5413 static void
5414 dealloc1(int nparam, int nrowa, double **a, double **hess, double **hess1,
5415  double *di, double *d, double *gm, double *grdpsf, double *penp,
5416  double *bl, double *bu, double *clamda, double *cvec, double *psmu,
5417  double *span, double *backup, int *iact, int *iskip, int *istore)
5418 #else
5419 static void
5420 dealloc1(nparam, nrowa, a, hess, hess1, di, d, gm, grdpsf, penp, bl, bu, clamda,
5421  cvec, psmu, span, backup, iact, iskip, istore)
5422 int nparam, nrowa;
5423 double **a, **hess, **hess1;
5424 double *di, *d, *gm, *grdpsf, *penp, *bl, *bu, *clamda, *cvec, *psmu, *span,
5425 *backup;
5426 int *iact, *iskip, *istore;
5427 #endif
5428 {
5429  free_dm(a, nrowa);
5430  free_dm(hess, nparam);
5431  free_dm(hess1, nparam + 1);
5432  free_dv(di);
5433  free_dv(d);
5434  free_dv(gm);
5435  free_dv(grdpsf);
5436  free_dv(penp);
5437  free_dv(bl);
5438  free_dv(bu);
5439  free_dv(clamda);
5440  free_dv(cvec);
5441  free_dv(psmu);
5442  free_dv(span);
5443  free_dv(backup);
5444  free_iv(iact);
5445  free_iv(iskip);
5446  free_iv(istore);
5447 }
5448 /************************************************************/
5449 /* CFSQP - Check the input data */
5450 /************************************************************/
5451 
5452 
5453 #ifdef __STDC__
5454 static void
5455 check(int nparam, int nf, int nfsip, int *Linfty, int nineq,
5456  int nnl, int neq, int neqn, int ncsipl, int ncsipn, int mode,
5457  int *modem, double eps, double bigbnd, struct _parameter *param)
5458 #else
5459 static void
5460 check(nparam, nf, nfsip, Linfty, nineq, nnl, neq, neqn, ncsipl, ncsipn,
5461  mode, modem, eps, bigbnd, param)
5462 int nparam, nf, nfsip, nineq, nnl, neq, neqn, ncsipl, ncsipn, mode, *modem,
5463 *Linfty;
5464 double bigbnd, eps;
5465 struct _parameter *param;
5466 #endif
5468  int i;
5469  double bli, bui;
5470 
5471  if (nparam <= 0)
5472  error("nparam should be positive! ",
5473  &glob_prnt.info);
5474  if (nf < 0)
5475  error("nf should not be negative! ",
5476  &glob_prnt.info);
5477  if (nineq < 0)
5478  error("nineq should not be negative! ",
5479  &glob_prnt.info);
5480  if (nineq >= 0 && nnl >= 0 && nineq < nnl)
5481  error("nineq should be no smaller then nnl! ",
5482  &glob_prnt.info);
5483  if (neqn < 0)
5484  error("neqn should not be negative! ",
5485  &glob_prnt.info);
5486  if (neq < neqn)
5487  error("neq should not be smaller then neqn ",
5488  &glob_prnt.info);
5489  if (nf < nfsip)
5490  error("nf should not be smaller then nfsip ",
5491  &glob_prnt.info);
5492  if (nineq < ncsipn + ncsipl)
5493  error("ncsrl+ncsrn should not be larger then nineq",
5494  &glob_prnt.info);
5495  if (nparam <= neq - neqn)
5496  error("Must have nparam > number of linear equalities",
5497  &glob_prnt.info);
5498  if (glob_prnt.iprint < 0 || glob_prnt.iprint > 3)
5499  error("iprint mod 10 should be 0,1,2 or 3! ",
5500  &glob_prnt.info);
5501  if (eps <= glob_grd.epsmac)
5502  {
5503  error("eps should be bigger than epsmac! ",
5504  &glob_prnt.info);
5506  "epsmac = %22.14e which is machine dependent.\n",
5507  glob_grd.epsmac);
5508  }
5509  if (!(mode == 100 || mode == 101 || mode == 110 || mode == 111
5510  || mode == 200 || mode == 201 || mode == 210 || mode == 211))
5511  error("mode is not properly specified! ",
5512  &glob_prnt.info);
5513  if (glob_prnt.info != 0)
5514  {
5516  "Error: Input parameters are not consistent.\n");
5517  return;
5518  }
5519  for (i = 1; i <= nparam; i++)
5520  {
5521  bli = param->bl[i];
5522  bui = param->bu[i];
5523  if (bli > bui)
5524  {
5526  "lower bounds should be smaller than upper bounds\n");
5527  glob_prnt.info = 7;
5528  }
5529  if (glob_prnt.info != 0)
5530  return;
5531  if (bli < (-bigbnd))
5532  param->bl[i] = -bigbnd;
5533  if (bui > bigbnd)
5534  param->bu[i] = bigbnd;
5535  }
5536  if (mode >= 200)
5537  {
5538  i = mode - 200;
5539  glob_info.modec = 2;
5540  }
5541  else
5542  {
5543  i = mode - 100;
5545  }
5546  if (i < 10)
5547  *modem = 0;
5548  else
5549  {
5550  *modem = 1;
5551  i -= 10;
5552  }
5553  if (!i)
5554  *Linfty = FALSE;
5555  else
5556  *Linfty = TRUE;
5557 }
5558 /****************************************************************/
5559 /* CFSQP : Generate a feasible point satisfying simple */
5560 /* bounds and linear constraints. */
5561 /****************************************************************/
5562 
5563 
5564 #ifdef __STDC__
5565 static void
5566 initpt(int nparam, int nnl, int neq, int neqn, int nclin, int nctotl,
5567  int nrowa, struct _parameter *param, struct _constraint *cs,
5568  void(*constr)(int, int, double *, double *, void *),
5569  void(*gradcn)(int, int, double *, double *,
5570  void(*)(int, int, double *, double *, void *), void *))
5571 #else
5572 static void
5573 initpt(nparam, nnl, neq, neqn, nclin, nctotl, nrowa, param, cs,
5574  constr, gradcn)
5575 int nparam, nnl, neq, neqn, nclin, nctotl, nrowa;
5576 struct _constraint *cs;
5577 struct _parameter *param;
5578 void(* constr)(), (* gradcn)();
5579 #endif
5581  int i, j, infoql, mnn, temp1, iout, zero;
5582  double x0i, *atemp, *htemp;
5583  double *x, *bl, *bu, *cvec, *clamda, *bj;
5584  double **a, **hess;
5585 
5586  hess = make_dm(nparam, nparam);
5587  a = make_dm(nrowa, nparam);
5588  x = make_dv(nparam);
5589  bl = make_dv(nctotl);
5590  bu = make_dv(nctotl);
5591  cvec = make_dv(nparam);
5592  clamda = make_dv(nctotl + nparam + 1);
5593  bj = make_dv(nclin);
5594 
5595  glob_prnt.info = 1;
5596  for (i = 1; i <= nclin; i++)
5597  {
5598  glob_grd.valnom = cs[i].val;
5599  j = i + nnl;
5600  if (j <= glob_info.nnineq)
5601  gradcn(nparam, j, (param->x) + 1, cs[i].grad + 1, constr, param->cd);
5602  else
5603  gradcn(nparam, j + neqn, (param->x) + 1, cs[i].grad + 1, constr,
5604  param->cd);
5605  }
5606  for (i = 1; i <= nparam; i++)
5607  {
5608  x0i = param->x[i];
5609  bl[i] = param->bl[i] - x0i;
5610  bu[i] = param->bu[i] - x0i;
5611  cvec[i] = 0.e0;
5612  }
5613  for (i = nclin; i >= 1; i--)
5614  bj[nclin-i+1] = -cs[i].val;
5615  for (i = nclin; i >= 1; i--)
5616  for (j = 1; j <= nparam; j++)
5617  a[nclin-i+1][j] = -cs[i].grad[j];
5618  diagnl(nparam, 1.e0, hess);
5619  nullvc(nparam, x);
5620 
5621  iout = 6;
5622  zero = 0;
5623  mnn = nrowa + 2 * nparam;
5624  iw[1] = 1;
5625  temp1 = neq - neqn;
5626  htemp = convert(hess, nparam, nparam);
5627  atemp = convert(a, nrowa, nparam);
5628 
5629  ql0001_(&nclin, &temp1, &nrowa, &nparam, &nparam, &mnn, (htemp + 1),
5630  (cvec + 1), (atemp + 1), (bj + 1), (bl + 1), (bu + 1), (x + 1), (clamda + 1),
5631  &iout, &infoql, &zero, (w + 1), &lenw, (iw + 1), &leniw,
5632  &glob_grd.epsmac);
5633 
5634  free_dv(htemp);
5635  free_dv(atemp);
5636  if (infoql == 0)
5637  {
5638  for (i = 1; i <= nparam; i++)
5639  param->x[i] = param->x[i] + x[i];
5640  x_is_new = TRUE;
5641  for (i = 1; i <= nclin; i++)
5642  {
5643  j = i + nnl;
5644  if (j <= glob_info.nnineq)
5645  constr(nparam, j, (param->x) + 1,
5646  &(cs[i].val), param->cd);
5647  else
5648  constr(nparam, j + neqn, (param->x) + 1, &(cs[i].val), param->cd);
5649  }
5650  glob_prnt.info = 0;
5651  }
5652  if (glob_prnt.info == 1 && glob_prnt.iprint != 0)
5653  {
5655  "\n Error: No feasible point is found for the");
5656  fprintf(glob_prnt.io, " linear constraints.\n");
5657  }
5658  free_dm(a, nrowa);
5659  free_dm(hess, nparam);
5660  free_dv(x);
5661  free_dv(bl);
5662  free_dv(bu);
5663  free_dv(cvec);
5664  free_dv(clamda);
5665  free_dv(bj);
5666  return;
5667 }
5668 /****************************************************************/
5669 /* CFSQP : Update the SIP "active" objective and constraint */
5670 /* sets Omega_k and Xi_k. */
5671 /****************************************************************/
5672 
5673 
5674 #ifdef __STDC__
5675 static void
5676 update_omega(int nparam, int ncsipl, int ncsipn, int *mesh_pts,
5677  int nineqn, int nob, int nobL, int nfsip, double steps,
5678  double fmax, struct _constraint *cs, struct _objective *ob,
5679  double *x, struct _violation *viol,
5680  void(*constr)(int, int, double *, double *, void *),
5681  void(*obj)(int, int, double *, double *, void *),
5682  void(*gradob)(int, int, double *, double *,
5683  void(*)(int, int, double *, double *, void *), void *),
5684  void(*gradcn)(int, int, double *, double *,
5685  void(*)(int, int, double *, double *, void *), void *),
5686  void *cd, int feasb)
5687 #else
5688 static void
5689 update_omega(nparam, ncsipl, ncsipn, mesh_pts, nineqn, nob, nobL, nfsip,
5690  steps, fmax, cs, ob, x, viol, constr, obj, gradob, gradcn, cd, feasb)
5692 double *x, steps, fmax;
5693 struct _constraint *cs;
5694 struct _objective *ob;
5695 struct _violation *viol;
5696 void(* constr)();
5697 void(* obj)();
5698 void(* gradob)();
5699 void(* gradcn)();
5700 void *cd;
5701 #endif
5703  int i, j, i_max, index, offset, nineq, display;
5704  double epsilon, g_max, fprev, fnow, fnext, fmult;
5705 
5706  epsilon = 1.e0;
5708  nineq = glob_info.nnineq;
5710  display = FALSE;
5711  else
5712  display = TRUE;
5713  /* Clear previous constraint sets */
5714  for (i = 1; i <= ncsipl; i++)
5715  cs[nineq-ncsipl+i].act_sip = FALSE;
5716  for (i = 1; i <= ncsipn; i++)
5717  cs[nineqn-ncsipn+i].act_sip = FALSE;
5718  /* Clear previous objective sets */
5719  for (i = nob - nfsip + 1; i <= nob; i++)
5720  ob[i].act_sip = FALSE;
5721 
5722  /*--------------------------------------------------*/
5723  /* Update Constraint Sets Omega_k */
5724  /*--------------------------------------------------*/
5725 
5726  if (ncsipn != 0)
5727  {
5728  offset = nineqn - ncsipn;
5729  for (i = 1; i <= glob_info.ncsipn; i++)
5730  {
5731  for (j = 1; j <= mesh_pts[glob_info.nfsip+i]; j++)
5732  {
5733  offset++;
5734  if (j == 1)
5735  {
5736  if (cs[offset].val >= -epsilon &&
5737  cs[offset].val >= cs[offset+1].val)
5738  {
5739  cs[offset].act_sip = TRUE;
5741  if (cs[offset].mult == 0.e0 && !glob_log.first)
5742  {
5743  glob_grd.valnom = cs[offset].val;
5744  gradcn(nparam, offset, x + 1, cs[offset].grad + 1, constr,
5745  cd);
5746  }
5747  continue;
5748  }
5749  }
5750  else if (j == mesh_pts[glob_info.nfsip+i])
5751  {
5752  if (cs[offset].val >= -epsilon &&
5753  cs[offset].val > cs[offset-1].val)
5754  {
5755  cs[offset].act_sip = TRUE;
5757  if (cs[offset].mult == 0.e0 && !glob_log.first)
5758  {
5759  glob_grd.valnom = cs[offset].val;
5760  gradcn(nparam, offset, x + 1, cs[offset].grad + 1, constr,
5761  cd);
5762  }
5763  continue;
5764  }
5765  }
5766  else
5767  {
5768  if (cs[offset].val >= -epsilon && cs[offset].val >
5769  cs[offset-1].val && cs[offset].val >=
5770  cs[offset+1].val)
5771  {
5772  cs[offset].act_sip = TRUE;
5774  if (cs[offset].mult == 0.e0 && !glob_log.first)
5775  {
5776  glob_grd.valnom = cs[offset].val;
5777  gradcn(nparam, offset, x + 1, cs[offset].grad + 1, constr,
5778  cd);
5779  }
5780  continue;
5781  }
5782  }
5783  if (cs[offset].val >= -glob_grd.epsmac)
5784  {
5785  cs[offset].act_sip = TRUE;
5787  if (cs[offset].mult == 0.e0 && !glob_log.first)
5788  {
5789  glob_grd.valnom = cs[offset].val;
5790  gradcn(nparam, offset, x + 1, cs[offset].grad + 1, constr, cd);
5791  }
5792  continue;
5793  }
5794  if (cs[offset].mult > 0.e0)
5795  {
5796  cs[offset].act_sip = TRUE;
5798  }
5799  /* Add if binding for d1 */
5800  if (cs[offset].d1bind)
5801  {
5802  cs[offset].act_sip = TRUE;
5804  if (cs[offset].mult == 0.e0 && !glob_log.first)
5805  {
5806  glob_grd.valnom = cs[offset].val;
5807  gradcn(nparam, offset, x + 1, cs[offset].grad + 1, constr, cd);
5808  }
5809  }
5810 
5811  }
5812  }
5813  }
5814  if (ncsipl != 0)
5815  {
5816  /* Don't need to get gradients */
5817  offset = nineq - ncsipl;
5818  for (i = 1; i <= glob_info.ncsipl; i++)
5819  {
5820  if (feasb)
5821  index = glob_info.nfsip + glob_info.ncsipn + i;
5822  else
5823  index = glob_info.ncsipn + i;
5824  for (j = 1; j <= mesh_pts[index]; j++)
5825  {
5826  offset++;
5827  if (j == 1)
5828  {
5829  if (cs[offset].val >= -epsilon &&
5830  cs[offset].val >= cs[offset+1].val)
5831  {
5832  cs[offset].act_sip = TRUE;
5834  continue;
5835  }
5836  }
5837  else
5838  if (j == mesh_pts[index])
5839  {
5840  if (cs[offset].val >= -epsilon &&
5841  cs[offset].val > cs[offset-1].val)
5842  {
5843  cs[offset].act_sip = TRUE;
5845  continue;
5846  }
5847  }
5848  else
5849  {
5850  if (cs[offset].val >= -epsilon && cs[offset].val >
5851  cs[offset-1].val && cs[offset].val >=
5852  cs[offset+1].val)
5853  {
5854  cs[offset].act_sip = TRUE;
5856  continue;
5857  }
5858  }
5859  if (cs[offset].val >= -glob_grd.epsmac ||
5860  cs[offset].mult > 0.e0 || cs[offset].d1bind)
5861  {
5862  cs[offset].act_sip = TRUE;
5864  }
5865  }
5866  }
5867  }
5868  /* Include some extra points during 1st iteration */
5869  /* (gradients are already evaluated for first iteration) */
5870  /* Current heuristics: maximizers and end-points. */
5872  {
5873  if (feasb)
5874  {
5875  offset = nineqn - ncsipn;
5876  for (i = 1; i <= glob_info.ncsipn; i++)
5877  {
5878  i_max = ++offset;
5879  g_max = cs[i_max].val;
5880  if (!cs[i_max].act_sip)
5881  { /* add first point */
5882  cs[i_max].act_sip = TRUE;
5884  }
5885  for (j = 2;j <= mesh_pts[glob_info.nfsip+i];j++)
5886  {
5887  offset++;
5888  if (cs[offset].val > g_max)
5889  {
5890  i_max = offset;
5891  g_max = cs[i_max].val;
5892  }
5893  }
5894  if (!cs[i_max].act_sip)
5895  {
5896  cs[i_max].act_sip = TRUE;
5898  }
5899  if (!cs[offset].act_sip)
5900  { /* add last point */
5901  cs[offset].act_sip = TRUE;
5903  }
5904  }
5905  }
5906  offset = nineq - ncsipl;
5907  for (i = 1; i <= glob_info.ncsipl; i++)
5908  {
5909  i_max = ++offset;
5910  g_max = cs[i_max].val;
5911  if (!cs[i_max].act_sip)
5912  { /* add first point */
5913  cs[i_max].act_sip = TRUE;
5915  }
5916  if (feasb)
5917  index = glob_info.nfsip + glob_info.ncsipn + i;
5918  else
5919  index = glob_info.ncsipn + i;
5920  for (j = 2;j <= mesh_pts[index]; j++)
5921  {
5922  offset++;
5923  if (cs[offset].val > g_max)
5924  {
5925  i_max = offset;
5926  g_max = cs[i_max].val;
5927  }
5928  }
5929  if (!cs[i_max].act_sip)
5930  {
5931  cs[i_max].act_sip = TRUE;
5933  }
5934  if (!cs[offset].act_sip)
5935  { /* add last point */
5936  cs[offset].act_sip = TRUE;
5938  }
5939  }
5940  }
5941 
5942  /* If necessary, append xi_bar */
5943  if (steps < 1.e0 && viol->type == CONSTR)
5944  {
5945  i = viol->index;
5946  if (!cs[i].act_sip)
5947  {
5948  cs[i].act_sip = TRUE;
5950  }
5951  }
5952  if (glob_prnt.iprint >= 2 && display)
5953  fprintf(glob_prnt.io, " |Xi_k| for g %26d\n",
5955 
5956  for (i = 1; i <= ncsipl; i++)
5957  cs[nineq-ncsipl+i].d1bind = FALSE;
5958  for (i = 1; i <= ncsipn; i++)
5959  cs[nineqn-ncsipn+i].d1bind = FALSE;
5960 
5961  /*---------------------------------------------------------*/
5962  /* Update Objective Set Omega_k */
5963  /*---------------------------------------------------------*/
5964 
5965  if (nfsip)
5966  {
5967  offset = nob - nfsip;
5968  if (feasb)
5969  index = glob_info.nfsip;
5970  else
5971  index = glob_info.ncsipn;
5972  for (i = 1; i <= index; i++)
5973  {
5974  for (j = 1; j <= mesh_pts[i]; j++)
5975  {
5976  offset++;
5977  if (nobL > nob)
5978  {
5979  fnow = fabs(ob[offset].val);
5980  fmult = DMAX1(fabs(ob[offset].mult),
5981  fabs(ob[offset].mult_L));
5982  }
5983  else
5984  {
5985  fnow = ob[offset].val;
5986  fmult = ob[offset].mult;
5987  }
5988  if (j == 1)
5989  {
5990  if (nobL > nob)
5991  fnext = fabs(ob[offset+1].val);
5992  else
5993  fnext = ob[offset+1].val;
5994  if ((fnow >= fmax - epsilon) && fnow >= fnext)
5995  {
5996  ob[offset].act_sip = TRUE;
5998  if (fmult == 0.e0 && !glob_log.first)
5999  {
6000  glob_grd.valnom = ob[offset].val;
6001  if (feasb)
6002  gradob(nparam, offset, x + 1,
6003  ob[offset].grad + 1, obj, cd);
6004  else
6005  gradcn(nparam, offset, x + 1, ob[offset].grad + 1,
6006  constr, cd);
6007  }
6008  continue;
6009  }
6010  }
6011  else if (j == mesh_pts[i])
6012  {
6013  if (nobL > nob)
6014  fprev = fabs(ob[offset-1].val);
6015  else
6016  fprev = ob[offset-1].val;
6017  if ((fnow >= fmax - epsilon) && fnow > fprev)
6018  {
6019  ob[offset].act_sip = TRUE;
6021  if (fmult == 0.e0 && !glob_log.first)
6022  {
6023  glob_grd.valnom = ob[offset].val;
6024  if (feasb)
6025  gradob(nparam, offset, x + 1,
6026  ob[offset].grad + 1, obj, cd);
6027  else
6028  gradcn(nparam, offset, x + 1, ob[offset].grad + 1,
6029  constr, cd);
6030  }
6031  continue;
6032  }
6033  }
6034  else
6035  {
6036  if (nobL > nob)
6037  {
6038  fprev = fabs(ob[offset-1].val);
6039  fnext = fabs(ob[offset+1].val);
6040  }
6041  else
6042  {
6043  fprev = ob[offset-1].val;
6044  fnext = ob[offset+1].val;
6045  }
6046  if ((fnow >= fmax - epsilon) && fnow > fprev &&
6047  fnow >= fnext)
6048  {
6049  ob[offset].act_sip = TRUE;
6051  if (fmult == 0.e0 && !glob_log.first)
6052  {
6053  glob_grd.valnom = ob[offset].val;
6054  if (feasb)
6055  gradob(nparam, offset, x + 1,
6056  ob[offset].grad + 1, obj, cd);
6057  else
6058  gradcn(nparam, offset, x + 1, ob[offset].grad + 1,
6059  constr, cd);
6060  }
6061  continue;
6062  }
6063  }
6064  if (fnow >= fmax - glob_grd.epsmac && !ob[offset].act_sip)
6065  {
6066  ob[offset].act_sip = TRUE;
6068  if (fmult == 0.e0 && !glob_log.first)
6069  {
6070  glob_grd.valnom = ob[offset].val;
6071  if (feasb)
6072  gradob(nparam, offset, x + 1,
6073  ob[offset].grad + 1, obj, cd);
6074  else
6075  gradcn(nparam, offset, x + 1, ob[offset].grad + 1,
6076  constr, cd);
6077  }
6078  continue;
6079  }
6080  if (fmult != 0.e0 && !ob[offset].act_sip)
6081  {
6082  ob[offset].act_sip = TRUE;
6084  continue;
6085  }
6086  }
6087  }
6088  /* Addition of objectives for first iteration. */
6089  /* Current heuristics: maximizers and end-points */
6090  if (glob_log.first)
6091  {
6092  offset = nob - nfsip;
6093  if (feasb)
6094  index = glob_info.nfsip;
6095  else
6096  index = glob_info.ncsipn;
6097  for (i = 1; i <= index; i++)
6098  {
6099  i_max = ++offset;
6100  if (nobL == nob)
6101  g_max = ob[i_max].val;
6102  else
6103  g_max = fabs(ob[i_max].val);
6104  if (!ob[i_max].act_sip)
6105  { /* add first point */
6106  ob[i_max].act_sip = TRUE;
6108  }
6109  for (j = 2;j <= mesh_pts[i];j++)
6110  {
6111  offset++;
6112  if (nobL == nob)
6113  fnow = ob[offset].val;
6114  else
6115  fnow = fabs(ob[offset].val);
6116  if (fnow > g_max)
6117  {
6118  i_max = offset;
6119  g_max = fnow;
6120  }
6121  }
6122  if (!ob[i_max].act_sip)
6123  {
6124  ob[i_max].act_sip = TRUE;
6126  }
6127  if (!ob[offset].act_sip)
6128  { /* add last point */
6129  ob[offset].act_sip = TRUE;
6131  }
6132  }
6133  }
6134 
6135  /* If necessary, append omega_bar */
6136  if (steps < 1.e0 && viol->type == OBJECT)
6137  {
6138  i = viol->index;
6139  if (!ob[i].act_sip)
6140  {
6141  ob[i].act_sip = TRUE;
6143  }
6144  }
6145  if (glob_prnt.iprint >= 2 && display)
6146  fprintf(glob_prnt.io, " |Omega_k| for f %26d\n",
6148  }
6149  viol->type = NONE;
6150  viol->index = 0;
6151  return;
6152 }
6153 /*******************************************************************/
6154 /* CFSQP : Computation of the search direction */
6155 /*******************************************************************/
6156 
6157 
6158 #ifdef __STDC__
6159 static void
6160 dqp(int, int, int, int, int, int, int, int, int, int, int, int, int,
6161  int, int, int *, struct _parameter *, double *, int,
6162  struct _objective *, double, double *, struct _constraint *,
6163  double **, double *, double *, double *, double *,
6164  double **, double **, double *, double, int);
6165 static void
6166 di1(int, int, int, int, int, int, int, int, int, int, int, int, int *,
6167  int, struct _parameter *, double *, struct _objective *,
6168  double, double *, struct _constraint *, double *,
6169  double *, double *, double *, double **, double *, double);
6170 #else
6171 static void dqp();
6172 static void di1();
6173 #endif
6174 
6175 #ifdef __STDC__
6176 static void
6177 dir(int nparam, int nob, int nobL, int nfsip, int nineqn, int neq, int neqn,
6178  int nn, int ncsipl, int ncsipn, int ncnstr,
6179  int feasb, double *steps, double epskt, double epseqn,
6180  double *sktnom, double *scvneq, double Ck, double *d0nm,
6181  double *grdftd, int *indxob, int *indxcn, int *iact, int *iskp,
6182  int *iskip, int *istore, struct _parameter *param, double *di,
6183  double *d, struct _constraint *cs, struct _objective *ob,
6184  double *fM, double *fMp, double *fmax, double *psf, double *grdpsf,
6185  double *penp, double **a, double *bl, double *bu, double *clamda,
6186  double *cvec, double **hess, double **hess1,
6187  double *backup, double *signeq, struct _violation *viol,
6188  void(*obj)(int, int, double *, double *, void *),
6189  void(*constr)(int, int, double *, double *, void *))
6190 #else
6191 static void
6192 dir(nparam, nob, nobL, nfsip, nineqn, neq, neqn, nn, ncsipl, ncsipn, ncnstr,
6193  feasb, steps, epskt, epseqn, sktnom, scvneq, Ck, d0nm,
6194  grdftd, indxob, indxcn, iact, iskp, iskip, istore, param, di, d, cs, ob,
6195  fM, fMp, fmax, psf, grdpsf, penp, a, bl, bu, clamda, cvec, hess, hess1,
6196  backup, signeq, viol, obj, constr)
6197 int nparam, nob, nobL, nfsip, nineqn, neq, neqn, nn, ncsipl, ncsipn, ncnstr,
6198 *iskp, feasb;
6199 int *indxob, *indxcn, *iact, *iskip, *istore;
6200 double *steps, epskt, epseqn, *sktnom, Ck, *d0nm, *grdftd, *fM, *fMp,
6201 *fmax, *psf, *scvneq;
6202 double *di, *d, *grdpsf, *penp, **a, *bl, *bu, *clamda, *cvec, **hess,
6203 **hess1, *backup, *signeq;
6204 struct _constraint *cs;
6205 struct _objective *ob;
6206 struct _parameter *param;
6207 struct _violation *viol;
6208 void(* obj)(), (* constr)();
6209 #endif
6211  int i, j, k, kk, ncg, ncf, nqprm0, nclin0, nctot0, infoqp, nqprm1, ncl,
6212  nclin1=0, ncc, nff, nrowa0, nrowa1, ninq, nobb, nobbL,
6213  nncn, ltem1, ltem2, display, need_d1;
6214  double fmxl, vv, dx, dmx, dnm1, dnm, v0, v1, vk=0., temp1, temp2, theta,
6216  sign, *adummy, dnmtil, *tempv;
6217 
6218  ncg = ncf = *iskp = 0;
6222  thrshd = tolfea;
6223  adummy = make_dv(1);
6224  adummy[1] = 0.e0;
6225  dummy = 0.e0;
6226  temp1 = temp2 = 0.e0;
6228  display = FALSE;
6229  else
6230  display = TRUE;
6231  need_d1 = TRUE;
6232 
6233  if (nobL <= 1)
6234  {
6235  nqprm0 = nparam;
6236  nclin0 = ncnstr;
6237  }
6238  else
6239  {
6240  nqprm0 = nparam + 1;
6241  nclin0 = ncnstr + nobL;
6242  }
6243  nctot0 = nqprm0 + nclin0;
6244  vv = 0.e0;
6245  nrowa0 = DMAX1(nclin0, 1);
6246  for (i = 1; i <= ncnstr; i++)
6247  {
6248  if (feasb)
6249  {
6250  if (i > nineqn && i <= glob_info.nnineq)
6251  iskip[glob_info.nnineq+2-i] = i;
6252  iw[i] = i;
6253  }
6254  else
6255  {
6256  if (i <= ncl)
6257  iskip[ncl+2-i] = nineqn + i;
6258  if (i <= ncl)
6259  iw[i] = nineqn + i;
6260  if (i > ncl)
6261  iw[i] = nineqn + neqn + i;
6262  }
6263  }
6264  for (i = 1; i <= nob; i++)
6265  iw[ncnstr+i] = i;
6266  nullvc(nparam, cvec);
6268  dqp(nparam, nqprm0, nob, nobL, nfsip, nineqn, neq, neqn, nn, ncsipl, ncsipn,
6269  ncnstr, nctot0, nrowa0, nineqn, &infoqp, param, di, feasb, ob,
6270  *fmax, grdpsf, cs, a, cvec, bl, bu, clamda, hess, hess1, di, vv, 0);
6271  if (infoqp != 0)
6272  {
6273  glob_prnt.info = 5;
6274  if (!feasb)
6275  glob_prnt.info = 2;
6276  nstop = 0;
6277  free_dv(adummy);
6278  return;
6279  }
6280  /*-------------------------------------------------------------*/
6281  /* Reorder indexes of constraints & objectives */
6282  /*-------------------------------------------------------------*/
6283  if (nn > 1)
6284  {
6285  j = 1;
6286  k = nn;
6287  for (i = nn; i >= 1; i--)
6288  {
6289  if (fuscmp(cs[indxcn[i]].mult, thrshd))
6290  {
6291  iact[j] = indxcn[i];
6292  j++;
6293  }
6294  else
6295  {
6296  iact[k] = indxcn[i];
6297  k--;
6298  }
6299  }
6300  }
6301  if (nobL > 1)
6302  {
6303  j = nn + 1;
6304  k = nn + nob;
6305  for (i = nob; i >= 1; i--)
6306  {
6307  kk = nqprm0 + ncnstr;
6308  ltem1 = fuscmp(ob[i].mult, thrshd);
6309  ltem2 = (nobL != nob) && (fuscmp(ob[i].mult_L, thrshd));
6310  if (ltem1 || ltem2)
6311  {
6312  iact[j] = i;
6313  j++;
6314  }
6315  else
6316  {
6317  iact[k] = i;
6318  k--;
6319  }
6320  }
6321  }
6322  if (nob > 0)
6323  vv = ob[iact[nn+1]].val;
6324  *d0nm = sqrt(scaprd(nparam, di, di));
6325  if (glob_log.first && nclin0 == 0)
6326  {
6327  dx = sqrt(scaprd(nparam, param->x, param->x));
6328  dmx = DMAX1(dx, 1.e0);
6329  if (*d0nm > dmx)
6330  {
6331  for (i = 1; i <= nparam; i++)
6332  di[i] = di[i] * dmx / (*d0nm);
6333  *d0nm = dmx;
6334  }
6335  }
6336  matrvc(nparam, nparam, hess, di, w);
6337  if (nn == 0)
6338  *grdftd = -scaprd(nparam, w, di);
6339  *sktnom = sqrt(scaprd(nparam, w, w));
6340  if (((*d0nm <= epskt) || ((gLgeps > 0.e0) && (*sktnom <= gLgeps))) &&
6341  (neqn == 0 || *scvneq <= epseqn))
6342  {
6343  /* We are finished! */
6344  nstop = 0;
6345  if (feasb && glob_log.first && neqn != 0)
6346  {
6347  /* Finished, but still need to estimate nonlinear equality
6348  constraint multipliers */
6350  glob_log.d0_is0 = TRUE;
6351  }
6352  if (!feasb)
6353  glob_prnt.info = 2;
6354  free_dv(adummy);
6355  if (glob_prnt.iprint < 3 || !display)
6356  return;
6357  if (nobL <= 1)
6358  nff = 1;
6359  if (nobL > 1)
6360  nff = 2;
6361  sbout1(glob_prnt.io, nparam, "multipliers for x ", dummy,
6362  param->mult, 2, 2);
6363  if (ncnstr != 0)
6364  {
6365  fprintf(glob_prnt.io, "\t\t\t %s\t %22.14e\n",
6366  " for g ", cs[1].mult);
6367  for (j = 2; j <= ncnstr; j++)
6368  fprintf(glob_prnt.io, " \t\t\t\t\t\t %22.14e\n", cs[j].mult);
6369  }
6370  if (nobL > 1)
6371  {
6372  fprintf(glob_prnt.io, "\t\t\t %s\t %22.14e\n",
6373  " for f ", ob[1].mult);
6374  for (j = 2; j <= nob; j++)
6375  fprintf(glob_prnt.io, " \t\t\t\t\t\t %22.14e\n", ob[j].mult);
6376  }
6377  return;
6378  }
6379  if (glob_prnt.iprint >= 3 && display)
6380  {
6381  sbout1(glob_prnt.io, nparam, "d0 ", dummy, di, 2, 2);
6382  sbout1(glob_prnt.io, 0, "d0norm ", *d0nm, adummy, 1, 2);
6383  sbout1(glob_prnt.io, 0, "ktnorm ", *sktnom, adummy, 1, 2);
6384  }
6385  if (neqn != 0 && *d0nm <= DMIN1(0.5e0*epskt, (0.1e-1)*glob_grd.rteps)
6386  && *scvneq > epseqn)
6387  {
6388  /* d0 is "zero", but equality constraints not satisfied */
6389  glob_log.d0_is0 = TRUE;
6390  return;
6391  }
6392  /*--------------------------------------------------------------*/
6393  /* Single objective without nonlinear constraints requires */
6394  /* no d1 and dtilde; multi-objectives without nonlinear */
6395  /* constraints requires no d1. */
6396  /*--------------------------------------------------------------*/
6397  if (nn != 0)
6398  *grdftd = slope(nob, nobL, neqn, nparam, feasb, ob, grdpsf,
6399  di, d, *fmax, dummy, 0, adummy, 0);
6400 
6401  if (nn == 0 && nobL <= 1)
6402  {
6403  for (i = 1; i <= nparam; i++)
6404  d[i] = 0.e0;
6405  dnmtil = 0.e0;
6406  free_dv(adummy);
6407  return;
6408  }
6409  if (nn == 0)
6410  {
6411  dnm = *d0nm;
6412  rho = 0.e0;
6413  rhog = 0.e0;
6414  goto L310;
6415  }
6416  /*-------------------------------------------------------------*/
6417  /* compute modified first order direction d1 */
6418  /*-------------------------------------------------------------*/
6419 
6420  /* First check that it is necessary */
6421  if (glob_info.mode == 1)
6422  {
6423  vk = DMIN1(Ck * (*d0nm) * (*d0nm), *d0nm);
6424  need_d1 = FALSE;
6425  for (i = 1; i <= nn; i++)
6426  {
6427  tempv = cs[indxcn[i]].grad;
6428  grdgd0 = scaprd(nparam, tempv, di);
6429  temp1 = vk + cs[indxcn[i]].val + grdgd0;
6430  if (temp1 > 0.e0)
6431  {
6432  need_d1 = TRUE;
6433  break;
6434  }
6435  }
6436  }
6437  if (need_d1)
6438  {
6439  nqprm1 = nparam + 1;
6440  if (glob_info.mode == 0)
6441  nclin1 = ncnstr + DMAX1(nobL, 1);
6442  if (glob_info.mode == 1)
6443  nclin1 = ncnstr;
6444  nrowa1 = DMAX1(nclin1, 1);
6445  ninq = glob_info.nnineq;
6446  di1(nparam, nqprm1, nob, nobL, nfsip, nineqn, neq, neqn, ncnstr,
6447  ncsipl, ncsipn, nrowa1, &infoqp, glob_info.mode,
6448  param, di, ob, *fmax, grdpsf, cs, cvec, bl, bu, clamda,
6449  hess1, d, *steps);
6450  if (infoqp != 0)
6451  {
6452  glob_prnt.info = 6;
6453  if (!feasb)
6454  glob_prnt.info = 2;
6455  nstop = 0;
6456  free_dv(adummy);
6457  return;
6458  }
6459  dnm1 = sqrt(scaprd(nparam, d, d));
6460  if (glob_prnt.iprint >= 3 && display)
6461  {
6462  sbout1(glob_prnt.io, nparam, "d1 ", dummy, d, 2, 2);
6463  sbout1(glob_prnt.io, 0, "d1norm ", dnm1, adummy, 1, 2);
6464  }
6465  }
6466  else
6467  {
6468  dnm1 = 0.e0;
6469  for (i = 1; i <= nparam; i++)
6470  d[i] = 0.e0;
6471  }
6472  if (glob_info.mode != 1)
6473  {
6474  v0 = pow(*d0nm, 2.1);
6475  v1 = DMAX1(0.5e0, pow(dnm1, 2.5));
6476  rho = v0 / (v0 + v1);
6477  rhog = rho;
6478  }
6479  else
6480  {
6481  rhol = 0.e0;
6482  if (need_d1)
6483  {
6484  for (i = 1; i <= nn; i++)
6485  {
6486  tempv = cs[indxcn[i]].grad;
6487  grdgd0 = scaprd(nparam, tempv, di);
6488  grdgd1 = scaprd(nparam, tempv, d);
6489  temp1 = vk + cs[indxcn[i]].val + grdgd0;
6490  temp2 = grdgd1 - grdgd0;
6491  if (temp1 <= 0.e0)
6492  continue;
6493  if (fabs(temp2) < glob_grd.epsmac)
6494  {
6495  rhol = 1.e0;
6497  break;
6498  }
6499  rhol = DMAX1(rhol, -temp1 / temp2);
6500  if (temp2 < 0.e0 && rhol < 1.e0)
6501  continue;
6502  rhol = 1.e0;
6504  break;
6505  }
6506  }
6507  theta = 0.2e0;
6508  if (rhol == 0.e0)
6509  {
6510  rhog = rho = 0.e0;
6511  dnm = *d0nm;
6512  goto L310;
6513  }
6514  if (nobL > 1)
6515  {
6516  rhog = slope(nob, nobL, neqn, nparam, feasb, ob, grdpsf,
6517  di, d, *fmax, theta, glob_info.mode, adummy, 0);
6518  rhog = DMIN1(rhol, rhog);
6519  }
6520  else
6521  {
6522  grdfd0 = *grdftd;
6523  if (nob == 1)
6524  grdfd1 = scaprd(nparam, ob[1].grad, d);
6525  else
6526  grdfd1 = 0.e0;
6527  grdfd1 = grdfd1 - scaprd(nparam, grdpsf, d);
6528  temp1 = grdfd1 - grdfd0;
6529  temp2 = (theta - 1.e0) * grdfd0 / temp1;
6530  if (temp1 <= 0.e0)
6531  rhog = rhol;
6532  else
6533  rhog = DMIN1(rhol, temp2);
6534  }
6535  rho = rhog;
6536  if (*steps == 1.e0 && rhol < 0.5e0)
6537  rho = rhol;
6538  }
6539  for (i = 1; i <= nparam; i++)
6540  {
6541  if (rho != rhog)
6542  cvec[i] = di[i];
6543  di[i] = (1.e0 - rho) * di[i] + rho * d[i];
6544  }
6545  dnm = sqrt(scaprd(nparam, di, di));
6546  if (!(glob_prnt.iprint < 3 || glob_info.mode == 1 || nn == 0) && display)
6547  {
6548  sbout1(glob_prnt.io, 0, "rho ", rho, adummy, 1, 2);
6549  sbout1(glob_prnt.io, nparam, "d ", dummy, di, 2, 2);
6550  sbout1(glob_prnt.io, 0, "dnorm ", dnm, adummy, 1, 2);
6551  }
6552 L310:
6553  for (i = 1; i <= nob; i++)
6554  bl[i] = ob[i].val;
6555  if (rho != 1.e0)
6556  {
6557  if (!(glob_prnt.iprint != 3 || glob_info.mode == 0 || nn == 0)
6558  && display)
6559  {
6560  sbout1(glob_prnt.io, 0, "Ck ", Ck, adummy, 1, 2);
6561  sbout1(glob_prnt.io, 0, "rhol ", rho, adummy, 1, 2);
6562  sbout1(glob_prnt.io, nparam, "dl ", dummy, di, 2, 2);
6563  sbout1(glob_prnt.io, 0, "dlnorm ", dnm, adummy, 1, 2);
6564  }
6565  if (glob_info.mode != 0)
6566  {
6567  glob_log.local = TRUE;
6568  step1(nparam, nob, nobL, nfsip, nineqn, neq, neqn, nn, ncsipl, ncsipn,
6569  ncnstr, &ncg, &ncf, indxob, indxcn, iact, iskp, iskip, istore,
6570  feasb, *grdftd, ob, fM, fMp, fmax, psf, penp, steps, scvneq, bu,
6571  param->x, di, d, cs, backup, signeq, viol, obj, constr, param->cd);
6572  if (!glob_log.update)
6573  nstop = 1;
6574  else
6575  {
6576  free_dv(adummy);
6577  return;
6578  }
6579  glob_log.local = FALSE;
6580  if (rho != rhog && nn != 0)
6581  for (i = 1; i <= nparam; i++)
6582  di[i] = (1 - rhog) * cvec[i] + rhog * d[i];
6583  dnm = sqrt(scaprd(nparam, di, di));
6584  }
6585  }
6586  if (!(glob_prnt.iprint < 3 || glob_info.mode == 0 || nn == 0) &&
6587  display)
6588  {
6589  sbout1(glob_prnt.io, 0, "rhog ", rhog, adummy, 1, 2);
6590  sbout1(glob_prnt.io, nparam, "dg ", dummy, di, 2, 2);
6591  sbout1(glob_prnt.io, 0, "dgnorm ", dnm, adummy, 1, 2);
6592  }
6593  if (rho != 0.e0)
6594  *grdftd = slope(nob, nobL, neqn, nparam, feasb, ob,
6595  grdpsf, di, d, *fmax, theta, 0, bl, 1);
6596  if (glob_info.mode != 1 || rho != rhog)
6597  for (i = 1; i <= nparam; i++)
6598  bu[i] = param->x[i] + di[i];
6599  x_is_new = TRUE;
6600  if (rho != rhog)
6601  ncg = 0;
6602  ncc = ncg + 1;
6603  fmxl = -bgbnd;
6604  ninq = nncn = ncg;
6605  j = 0;
6606  /*--------------------------------------------------------------*/
6607  /* iskip[1]-iskip[iskp] store the indexes of linear inequality*/
6608  /* constraints that are not to be used to compute d~ */
6609  /* iskip[nnineq-nineqn+1]-iskip[nnineq-ncn+1-iskp] store */
6610  /* those that are to be used to compute d~ */
6611  /*--------------------------------------------------------------*/
6612  for (i = ncc; i <= ncnstr; i++)
6613  {
6614  if (i <= nn)
6615  kk = iact[i];
6616  else
6617  kk = indxcn[i];
6618  if (kk > nineqn && kk <= glob_info.nnineq)
6619  {
6620  iskip[ncl+1-j] = kk;
6621  j++;
6622  }
6623  if (kk <= glob_info.nnineq)
6624  {
6625  tempv = cs[kk].grad;
6626  temp1 = dnm * sqrt(scaprd(nparam, tempv, tempv));
6627  temp2 = cs[kk].mult;
6628  }
6629  if (temp2 != 0.e0 || cs[kk].val >= (-0.2e0*temp1) ||
6630  kk > glob_info.nnineq)
6631  {
6632  ninq++;
6633  iw[ninq] = kk;
6634  if (feasb && kk <= nineqn)
6635  istore[kk] = 1;
6636  constr(nparam, kk, bu + 1, &(cs[kk].val), param->cd);
6637  if (!feasb || (feasb && (kk > glob_info.nnineq + neqn)))
6638  continue;
6639  if (kk <= nineqn)
6640  nncn = ninq;
6641  fmxl = DMAX1(fmxl, cs[kk].val);
6642  if (feasb && (kk <= nineqn || (kk > glob_info.nnineq
6643  && kk <= (glob_info.nnineq + neqn))))
6644  glob_info.ncallg++;
6645  if (fabs(fmxl) > bgbnd)
6646  {
6647  for (i = 1; i <= nparam; i++)
6648  d[i] = 0.e0;
6649  dnmtil = 0.e0;
6650  nstop = 1;
6651  free_dv(adummy);
6652  return;
6653  }
6654  continue;
6655  }
6656  if (kk <= nineqn)
6657  continue;
6658  (*iskp)++;
6659  iskip[*iskp] = kk;
6660  j--;
6661  }
6662  if ((neqn != 0) && (feasb))
6663  resign(nparam, neqn, psf, grdpsf, penp, cs, signeq, 10, 20);
6664  ninq -= neq;
6665  /* if (!feasb) ninq+=neqn; BUG??? */
6666  if (ncg != 0)
6667  for (i = 1; i <= ncg; i++)
6668  {
6669  iw[i] = iact[i];
6670  istore[iact[i]] = 1;
6671  fmxl = DMAX1(fmxl, cs[iact[i]].val);
6672  if (fabs(fmxl) > bgbnd)
6673  {
6674  for (i = 1; i <= nparam; i++)
6675  d[i] = 0.e0;
6676  dnmtil = 0.e0;
6677  nstop = 1;
6678  free_dv(adummy);
6679  return;
6680  }
6681  }
6682  if (nobL <= 1)
6683  {
6684  iw[1+ninq+neq] = 1;
6685  nobb = nob;
6686  goto L1110;
6687  }
6688  if (rho != rhog)
6689  ncf = 0;
6690  nff = ncf + 1;
6691  nobb = ncf;
6692  sign = 1.e0;
6693  fmxl = -bgbnd;
6694  if (ob[iact[nn+1]].mult < 0.e0)
6695  sign = -1.e0;
6696  for (i = nff; i <= nob; i++)
6697  {
6698  kk = iact[nn+i];
6699  if (!feasb)
6700  kk = iact[i];
6701  if (feasb)
6702  k = nn + 1;
6703  if (!feasb)
6704  k = 1;
6705  for (j = 1; j <= nparam; j++)
6706  w[nparam+j] = sign * ob[iact[k]].grad[j] - ob[kk].grad[j];
6707  temp1 = fabs(ob[kk].val - sign * vv);
6708  temp2 = dnm * sqrt(scaprd(nparam, &w[nparam], &w[nparam]));
6709  if (temp1 != 0.e0 && temp2 != 0.e0)
6710  {
6711  temp1 = temp1 / temp2;
6712  temp2 = ob[kk].mult;
6713  if (temp2 == 0.e0 && temp1 > 0.2e0)
6714  continue;
6715  }
6716  nobb++;
6717  iw[nobb+ninq+neq] = kk;
6718  if (feasb)
6719  istore[nineqn+kk] = 1;
6720  else
6721  istore[kk] = 1;
6722  if (!feasb)
6723  {
6724  constr(nparam, indxob[kk], bu + 1, &(ob[kk].val), param->cd);
6725  glob_info.ncallg++;
6726  }
6727  else
6728  {
6729  obj(nparam, kk, bu + 1, &(ob[kk].val), param->cd);
6730  glob_info.ncallf++;
6731  if (nobL != nob)
6732  fmxl = DMAX1(fmxl, -ob[kk].val);
6733  }
6734  fmxl = DMAX1(fmxl, ob[kk].val);
6735  if (fabs(fmxl) > bgbnd)
6736  {
6737  for (i = 1; i <= nparam; i++)
6738  d[i] = 0.e0;
6739  dnmtil = 0.e0;
6740  nstop = 1;
6741  free_dv(adummy);
6742  return;
6743  }
6744  }
6745  if (ncf != 0)
6746  {
6747  for (i = 1; i <= ncf; i++)
6748  {
6749  iw[ninq+neq+i] = iact[i+nn];
6750  istore[nineqn+iact[i+nn]] = 1;
6751  fmxl = DMAX1(fmxl, ob[iact[i+nn]].val);
6752  if (nobL != nob)
6753  fmxl = DMAX1(fmxl, -ob[iact[i+nn]].val);
6754  if (fabs(fmxl) > bgbnd)
6755  {
6756  for (i = 1; i <= nparam; i++)
6757  d[i] = 0.e0;
6758  dnmtil = 0.e0;
6759  nstop = 1;
6760  free_dv(adummy);
6761  return;
6762  }
6763  }
6764  }
6765  L1110:
6766  matrvc(nparam, nparam, hess, di, cvec);
6767  vv = -DMIN1(0.01e0 * dnm, pow(dnm, 2.5));
6768  /*--------------------------------------------------------------*/
6769  /* compute a correction dtilde to d=(1-rho)d0+rho*d1 */
6770  /*--------------------------------------------------------------*/
6771  if (nobL != nob)
6772  nobbL = 2 * nobb;
6773  if (nobL == nob)
6774  nobbL = nobb;
6775  if (nobbL <= 1)
6776  {
6777  nqprm0 = nparam;
6778  nclin0 = ninq + neq;
6779  }
6780  else
6781  {
6782  nqprm0 = nparam + 1;
6783  nclin0 = ninq + neq + nobbL;
6784  }
6785  nctot0 = nqprm0 + nclin0;
6786  nrowa0 = DMAX1(nclin0, 1);
6787  i = ninq + neq;
6788  nstop = 1;
6789  dqp(nparam, nqprm0, nobb, nobbL, nfsip, nncn, neq, neqn, nn, ncsipl, ncsipn, i,
6790  nctot0, nrowa0, nineqn, &infoqp, param, di, feasb, ob, fmxl,
6791  grdpsf, cs, a, cvec, bl, bu, clamda, hess, hess1, d, vv, 1);
6792  dnmtil = sqrt(scaprd(nparam, d, d));
6793  if (infoqp != 0 || dnmtil > dnm)
6794  {
6795  for (i = 1; i <= nparam; i++)
6796  d[i] = 0.e0;
6797  dnmtil = 0.e0;
6798  nstop = 1;
6799  free_dv(adummy);
6800  return;
6801  }
6802  if (dnmtil != 0.e0)
6803  for (i = 1; i <= nineqn + nob; i++)
6804  istore[i] = 0;
6805  if (glob_prnt.iprint < 3 || !display)
6806  {
6807  free_dv(adummy);
6808  return;
6809  }
6810  sbout1(glob_prnt.io, nparam, "dtilde ", dummy, d, 2, 2);
6811  sbout1(glob_prnt.io, 0, "dtnorm ", dnmtil, adummy, 1, 2);
6812  free_dv(adummy);
6813  return;
6814 }
6815 
6816 /*******************************************************************/
6817 /* job=0: compute d0 */
6818 /* job=1: compute d~ */
6819 /*******************************************************************/
6820 #ifdef __STDC__
6821 static void
6822 dqp(int nparam, int nqpram, int nob, int nobL, int nfsip, int nineqn,
6823  int neq, int neqn, int nn, int ncsipl, int ncsipn, int ncnstr,
6824  int nctotl, int nrowa, int nineqn_tot, int *infoqp,
6825  struct _parameter *param, double *di, int feasb, struct _objective *ob,
6826  double fmax, double *grdpsf, struct _constraint *cs,
6827  double **a, double *cvec, double *bl, double *bu, double *clamda,
6828  double **hess, double **hess1, double *x,
6829  double vv, int job)
6830 #else
6831 static void
6832 dqp(nparam, nqpram, nob, nobL, nfsip, nineqn, neq, neqn, nn, ncsipl, ncsipn,
6833  ncnstr, nctotl, nrowa, nineqn_tot, infoqp, param, di, feasb, ob,
6834  fmax, grdpsf, cs, a, cvec, bl, bu, clamda, hess, hess1, x, vv, job)
6836 ncnstr, nctotl, nrowa, nineqn_tot, *infoqp, job, feasb;
6837 double fmax, vv;
6838 double *di, *grdpsf, **a, *cvec, *bl, *bu, *clamda, **hess, **hess1, *x;
6839 struct _constraint *cs;
6840 struct _objective *ob;
6841 struct _parameter *param;
6842 #endif
6843 {
6844  int i, ii, j, jj, ij, k, iout, mnn, nqnp, zero, temp1, temp2, ncnstr_used,
6845  numf_used=0;
6846  int *iw_hold;
6847  double x0i, xdi=0., *bj, *htemp, *atemp;
6848 
6849  iout = 6;
6850  bj = make_dv(nrowa);
6851  iw_hold = make_iv(nrowa);
6852  for (i = 1; i <= nparam; i++)
6853  {
6854  x0i = param->x[i];
6855  if (job == 1)
6856  xdi = di[i];
6857  if (job == 0)
6858  xdi = 0.e0;
6859  bl[i] = param->bl[i] - x0i - xdi;
6860  bu[i] = param->bu[i] - x0i - xdi;
6861  cvec[i] = cvec[i] - grdpsf[i];
6862  }
6863  if (nobL > 1)
6864  {
6865  bl[nqpram] = -bgbnd;
6866  bu[nqpram] = bgbnd;
6867  }
6868  ii = ncnstr - nn;
6869  /*---------------------------------------------------------------*/
6870  /* constraints are assigned to a in reverse order */
6871  /*---------------------------------------------------------------*/
6872  k = 0;
6873  for (i = 1; i <= ncnstr; i++)
6874  {
6875  jj = iw[ncnstr+1-i];
6876  if ((jj > glob_info.nnineq) || (jj <= nineqn_tot - ncsipn) ||
6877  ((jj > nineqn_tot) && (jj <= glob_info.nnineq - ncsipl)) ||
6878  cs[jj].act_sip)
6879  {
6880  k++;
6881  x0i = vv;
6882  if (i <= (neq - neqn) || (i > neq && i <= (ncnstr - nineqn)))
6883  x0i = 0.e0;
6884  if (!feasb)
6885  x0i = 0.e0;
6886  bj[k] = x0i - cs[jj].val;
6887  for (j = 1; j <= nparam; j++)
6888  a[k][j] = -cs[jj].grad[j];
6889  if (nobL > 1)
6890  a[k][nqpram] = 0.e0;
6891  iw_hold[k] = jj;
6892  }
6893  }
6894  ncnstr_used = k;
6895  /*---------------------------------------------------------------*/
6896  /* Assign objectives for QP */
6897  /*---------------------------------------------------------------*/
6898  if (nobL == 1)
6899  {
6900  for (i = 1; i <= nparam; i++)
6901  cvec[i] = cvec[i] + ob[1].grad[i];
6902  }
6903  else if (nobL > 1)
6904  {
6905  numf_used = nob - nfsip + glob_info.tot_actf_sip;
6906  if (job && nfsip)
6907  { /* compute # objectives used for dtilde */
6908  numf_used = 0;
6909  for (i = 1; i <= nob; i++)
6910  if (ob[iw[ncnstr+i]].act_sip)
6911  numf_used++;
6912  }
6913  for (i = 1; i <= nob; i++)
6914  {
6915  ij = ncnstr + i;
6916  if ((i <= nob - nfsip) || ob[iw[ij]].act_sip)
6917  {
6918  k++;
6919  iw_hold[k] = iw[ij]; /* record which are used */
6920  bj[k] = fmax - ob[iw[ij]].val;
6921  if (nobL > nob)
6922  bj[k+numf_used] = fmax + ob[iw[ij]].val;
6923  for (j = 1; j <= nparam; j++)
6924  {
6925  a[k][j] = -ob[iw[ij]].grad[j];
6926  if (nobL > nob)
6927  a[k+numf_used][j] = ob[iw[ij]].grad[j];
6928  }
6929  a[k][nqpram] = 1.e0;
6930  if (nobL > nob)
6931  a[k+numf_used][nqpram] = 1.e0;
6932  }
6933  }
6934  cvec[nqpram] = 1.e0;
6935  if (nobL > nob)
6936  k = k + numf_used; /* k=# rows for a */
6937  } /* =# constraints for QP */
6938  matrcp(nparam, hess, nparam + 1, hess1);
6939  nullvc(nqpram, x);
6940 
6941  iw[1] = 1;
6942  zero = 0;
6943  temp1 = neq - neqn;
6944  temp2 = nparam + 1;
6945  mnn = k + 2 * nqpram;
6946  htemp = convert(hess1, nparam + 1, nparam + 1);
6947  atemp = convert(a, nrowa, nqpram);
6948 
6949  ql0001_(&k, &temp1, &nrowa, &nqpram, &temp2, &mnn, (htemp + 1),
6950  (cvec + 1), (atemp + 1), (bj + 1), (bl + 1), (bu + 1), (x + 1),
6951  (clamda + 1), &iout, infoqp, &zero, (w + 1), &lenw, (iw + 1), &leniw,
6952  &glob_grd.epsmac);
6953 
6954  free_dv(htemp);
6955  free_dv(atemp);
6956  if (*infoqp != 0 || job == 1)
6957  {
6958  free_iv(iw_hold);
6959  free_dv(bj);
6960  return;
6961  }
6962 
6963  /*---------------------------------------------------------------*/
6964  /* Save multipliers from the computation of d0 */
6965  /*---------------------------------------------------------------*/
6966  nullvc(nqpram, param->mult);
6967  if (ncsipl + ncsipn)
6968  for (i = 1; i <= ncnstr; i++)
6969  cs[i].mult = 0.e0;
6970  if (nfsip)
6971  for (i = 1; i <= nob; i++)
6972  {
6973  ob[i].mult = 0.e0;
6974  ob[i].mult_L = 0.e0;
6975  }
6976  for (i = 1; i <= nqpram; i++)
6977  {
6978  ii = k + i;
6979  if (clamda[ii] == 0.e0 && clamda[ii+nqpram] == 0.e0)
6980  continue;
6981  else if (clamda[ii] != 0.e0)
6982  clamda[ii] = -clamda[ii];
6983  else
6984  clamda[ii] = clamda[ii+nqpram];
6985  }
6986  nqnp = nqpram + ncnstr;
6987  for (i = 1; i <= nqpram; i++) /* Simple bounds */
6988  param->mult[i] = clamda[k+i];
6989  if (nctotl > nqnp)
6990  { /* Objectives */
6991  for (i = 1; i <= numf_used; i++)
6992  {
6993  ij = ncnstr_used + i;
6994  if (nobL != nob)
6995  {
6996  ii = k - 2 * numf_used + i;
6997  ob[iw_hold[ij]].mult = clamda[ii] - clamda[ii+numf_used];
6998  ob[iw_hold[ij]].mult_L = clamda[ii+numf_used];
6999  }
7000  else
7001  {
7002  ii = k - numf_used + i;
7003  ob[iw_hold[ij]].mult = clamda[ii];
7004  }
7005  }
7006  }
7007  for (i = 1; i <= ncnstr_used; i++) /* Constraints */
7008  cs[iw_hold[i]].mult = clamda[i];
7009  free_iv(iw_hold);
7010  free_dv(bj);
7011  return;
7012 }
7013 
7014 /****************************************************************/
7015 /* Computation of first order direction d1 */
7016 /****************************************************************/
7017 #ifdef __STDC__
7018 static void
7019 di1(int nparam, int nqpram, int nob, int nobL, int nfsip, int nineqn,
7020  int neq, int neqn, int ncnstr, int ncsipl, int ncsipn,
7021  int nrowa, int *infoqp, int mode, struct _parameter *param,
7022  double *d0, struct _objective *ob, double fmax, double
7023  *grdpsf, struct _constraint *cs, double *cvec, double *bl, double *bu,
7024  double *clamda, double **hess1, double *x, double steps)
7025 #else
7026 static void
7027 di1(nparam, nqpram, nob, nobL, nfsip, nineqn, neq, neqn, ncnstr, ncsipl,
7028  ncsipn, nrowa, infoqp, mode, param, d0, ob, fmax, grdpsf, cs,
7029  cvec, bl, bu, clamda, hess1, x, steps)
7030 int nparam, nqpram, nob, nobL, nfsip, nineqn, neq, neqn, ncnstr,
7031 nrowa, *infoqp, mode, ncsipl, ncsipn;
7032 double fmax, steps;
7033 double *d0, *grdpsf, *cvec, *bl, *bu, *clamda, **hess1, *x;
7034 struct _constraint *cs;
7035 struct _objective *ob;
7036 struct _parameter *param;
7037 #endif
7039  int i, k, ii, jj, iout, j, mnn, zero, temp1, temp3, ncnstr_used, numf_used=0;
7040  int *iw_hold;
7041  double x0i, eta, *atemp, *htemp, **a, *bj;
7042 
7043  if ((ncsipl + ncsipn) != 0)
7044  nrowa = nrowa - (ncsipl + ncsipn) + glob_info.tot_actg_sip;
7045  if (nfsip)
7046  {
7047  if (nobL > nob)
7048  nrowa = nrowa - 2 * nfsip + 2 * glob_info.tot_actf_sip;
7049  else
7050  nrowa = nrowa - nfsip + glob_info.tot_actf_sip;
7051  }
7052  nrowa = DMAX1(nrowa, 1);
7053  a = make_dm(nrowa, nqpram);
7054  bj = make_dv(nrowa);
7055  iw_hold = make_iv(nrowa);
7056  iout = 6;
7057  if (mode == 0)
7058  eta = 0.1e0;
7059  if (mode == 1)
7060  eta = 3.e0;
7061  for (i = 1; i <= nparam; i++)
7062  {
7063  x0i = param->x[i];
7064  bl[i] = param->bl[i] - x0i;
7065  bu[i] = param->bu[i] - x0i;
7066  if (mode == 0)
7067  cvec[i] = -eta * d0[i];
7068  if (mode == 1)
7069  cvec[i] = 0.e0;
7070  }
7071  bl[nqpram] = -bgbnd;
7072  bu[nqpram] = bgbnd;
7073  cvec[nqpram] = 1.e0;
7074  ii = ncnstr - nineqn;
7075  k = 0;
7076  for (i = 1; i <= ncnstr; i++)
7077  {
7078  jj = ncnstr + 1 - i;
7079  if ((jj > glob_info.nnineq) || (jj <= nineqn - ncsipn) ||
7080  ((jj > nineqn) && (jj <= glob_info.nnineq - ncsipl)) ||
7081  cs[jj].act_sip)
7082  {
7083  k++;
7084  bj[k] = -cs[jj].val;
7085  for (j = 1; j <= nparam; j++)
7086  a[k][j] = -cs[jj].grad[j];
7087  a[k][nqpram] = 0.e0;
7088  if ((i > (neq - neqn) && i <= neq) || i > ii)
7089  a[k][nqpram] = 1.e0;
7090  iw_hold[k] = jj;
7091  }
7092  }
7093  ncnstr_used = k;
7094 
7095  if (mode != 1)
7096  {
7097  numf_used = nob - nfsip + glob_info.tot_actf_sip;
7098  for (i = 1; i <= nob; i++)
7099  {
7100  if ((i <= nob - nfsip) || ob[i].act_sip)
7101  {
7102  k++;
7103  bj[k] = fmax - ob[i].val;
7104  for (j = 1; j <= nparam; j++)
7105  {
7106  a[k][j] = -ob[i].grad[j] + grdpsf[j];
7107  if (nobL > nob)
7108  a[k+numf_used][j] = ob[i].grad[j] + grdpsf[j];
7109  }
7110  a[k][nqpram] = 1.e0;
7111  if (nobL > nob)
7112  a[k+numf_used][nqpram] = 1.e0;
7113  }
7114  }
7115  if (nob == 0)
7116  {
7117  k++;
7118  bj[k] = fmax;
7119  for (j = 1; j <= nparam; j++)
7120  a[k][j] = grdpsf[j];
7121  a[k][nqpram] = 1.e0;
7122  }
7123  }
7124  diagnl(nqpram, eta, hess1);
7125  nullvc(nqpram, x);
7126  hess1[nqpram][nqpram] = 0.e0;
7127 
7128  iw[1] = 1;
7129  zero = 0;
7130  temp1 = neq - neqn;
7131  if (nobL > nob)
7132  temp3 = k + numf_used;
7133  else
7134  temp3 = k;
7135  mnn = temp3 + 2 * nqpram;
7136  htemp = convert(hess1, nparam + 1, nparam + 1);
7137  atemp = convert(a, nrowa, nqpram);
7138 
7139  ql0001_(&temp3, &temp1, &nrowa, &nqpram, &nqpram, &mnn, (htemp + 1),
7140  (cvec + 1), (atemp + 1), (bj + 1), (bl + 1), (bu + 1), (x + 1),
7141  (clamda + 1), &iout, infoqp, &zero, (w + 1), &lenw, (iw + 1), &leniw,
7142  &glob_grd.epsmac);
7143 
7144  free_dv(htemp);
7145  free_dv(atemp);
7146  free_dm(a, nrowa);
7147  free_dv(bj);
7148  /* Determine binding constraints */
7149  if (ncsipl + ncsipn)
7150  {
7151  for (i = 1; i <= ncnstr_used; i++)
7152  if (clamda[i] > 0.e0)
7153  cs[iw_hold[i]].d1bind = TRUE;
7154  }
7155  free_iv(iw_hold);
7156  return;
7157 }
7158 /*****************************************************************/
7159 /* CFSQP : Armijo or nonmonotone line search, with some */
7160 /* ad hoc strategies to decrease the number of */
7161 /* function evaluations as much as possible. */
7162 /*****************************************************************/
7163 
7164 
7165 #ifdef __STDC__
7166 static void
7167 step1(int nparam, int nob, int nobL, int nfsip, int nineqn, int neq, int neqn,
7168  int nn, int ncsipl, int ncsipn, int ncnstr, int *ncg, int *ncf,
7169  int *indxob, int *indxcn, int *iact, int *iskp, int *iskip,
7170  int *istore, int feasb, double grdftd, struct _objective *ob,
7171  double *fM, double *fMp, double *fmax, double *psf, double *penp,
7172  double *steps, double *scvneq, double *xnew, double *x, double *di,
7173  double *d, struct _constraint *cs, double *backup, double *signeq,
7174  struct _violation *sip_viol,
7175  void(*obj)(int, int, double *, double *, void *),
7176  void(*constr)(int, int, double *, double *, void *), void *cd)
7177 #else
7178 static void
7179 step1(nparam, nob, nobL, nfsip, nineqn, neq, neqn, nn, ncsipl, ncsipn, ncnstr,
7180  ncg, ncf, indxob, indxcn, iact, iskp, iskip, istore, feasb, grdftd, ob,
7181  fM, fMp, fmax, psf, penp, steps, scvneq, xnew, x, di, d, cs, backup,
7182  signeq, sip_viol, obj, constr, cd)
7183 int nparam, nob, nobL, nfsip, nineqn, neq, neqn, nn, ncsipl, ncsipn, ncnstr,
7184 *ncg, *ncf, feasb, *iskp;
7185 int *indxob, *indxcn, *iact, *iskip, *istore;
7186 double grdftd, *fM, *fMp, *fmax, *steps, *scvneq, *psf;
7187 double *xnew, *x, *di, *d, *penp, *backup, *signeq;
7188 struct _constraint *cs;
7189 struct _objective *ob;
7190 struct _violation *sip_viol;
7191 void(* obj)(), (* constr)();
7192 void *cd;
7193 #endif
7195  int i, ii, ij, jj, itry, ikeep, j, job, nlin, mnm, ltem1, ltem2, reform,
7196  fbind, cdone, fdone, eqdone, display, sipldone;
7197  double prod1, prod, dummy, fmax1=0., tolfe, ostep, temp, **adummy, fii;
7198 
7200  itry = ii = jj = 1;
7201  ostep = *steps = 1.e0;
7202  fbind = cdone = fdone = eqdone = FALSE;
7203  dummy = 0.e0;
7204  sipldone = (ncsipl == 0);
7205  if (glob_log.local)
7206  glob_log.dlfeas = FALSE;
7207  ikeep = nlin - *iskp;
7208  prod1 = (0.1e0) * grdftd; /* alpha = 0.1e0 */
7209  tolfe = 0.e0; /* feasibility tolerance */
7210  adummy = make_dm(1, 1);
7211  adummy[1][1] = 0.e0;
7213  display = FALSE;
7214  else
7215  display = TRUE;
7216  if (glob_prnt.iprint >= 3 && display)
7217  sbout1(glob_prnt.io, 0, "directional deriv ", grdftd, *(adummy + 1),
7218  1, 2);
7219  w[1] = *fM;
7220  for (;;)
7221  {
7222  reform = TRUE;
7223  if (glob_prnt.iprint >= 3 && display)
7224  fprintf(glob_prnt.io, "\t\t\t trial number %22d\n",
7225  itry);
7226  prod = prod1 * (*steps);
7227  if (!feasb || (nobL > 1))
7228  prod = prod + tolfe;
7229  for (i = 1; i <= nparam; i++)
7230  {
7231  if (glob_log.local)
7232  xnew[i] = x[i] + (*steps) * di[i];
7233  else
7234  xnew[i] = x[i] + (*steps) * di[i] + d[i] * (*steps) * (*steps);
7235  }
7236  x_is_new = TRUE;
7237  if (glob_prnt.iprint >= 3 && display)
7238  {
7239  sbout1(glob_prnt.io, 0, "trial step ", *steps,
7240  *(adummy + 1), 1, 2);
7241  sbout1(glob_prnt.io, nparam, "trial point ",
7242  dummy, xnew, 2, 2);
7243  }
7244 
7245  /* Generate an upper bound step size using the linear constraints
7246  not used in the computation of dtilde */
7247  if (*iskp != 0)
7248  {
7249  ostep = *steps;
7250  for (i = ii; i <= *iskp; i++)
7251  {
7252  ij = iskip[i];
7253  constr(nparam, ij, xnew + 1, &(cs[ij].val), cd);
7254  if (glob_prnt.iprint >= 3 && display)
7255  {
7256  if (i == 1)
7258  "\t\t\t trial constraints %d \t %22.14e\n", ij,
7259  cs[ij].val);
7260  if (i != 1)
7262  "\t\t\t\t\t %d \t %22.14e\n", ij, cs[ij].val);
7263  }
7264  if (cs[ij].val <= tolfe)
7265  continue;
7266  ii = i;
7267  if (ncsipl && ii > glob_info.nnineq - ncsipl)
7268  {
7269  sip_viol->type = CONSTR;
7270  sip_viol->index = ij;
7271  }
7272  else
7273  {
7274  sip_viol->type = NONE; /* non-SIP constraint violated */
7275  sip_viol->index = 0;
7276  }
7277  goto L1120;
7278  }
7279  *iskp = 0;
7280  }
7281 
7282  /* Refine the upper bound using the linear SI constraints not
7283  in Omega_k */
7284  if (!sipldone)
7285  {
7286  for (i = jj; i <= ncsipl; i++)
7287  {
7288  ij = glob_info.nnineq - ncsipl + i;
7289  if (cs[ij].act_sip || element(iskip, nlin - ikeep, ij))
7290  continue;
7291  constr(nparam, ij, xnew + 1, &(cs[ij].val), cd);
7292  if (glob_prnt.iprint >= 3 && display)
7293  {
7294  if (i == 1)
7296  "\t\t\t trial constraints %d \t %22.14e\n", ij,
7297  cs[ij].val);
7298  if (i != 1)
7300  "\t\t\t\t\t %d \t %22.14e\n", ij, cs[ij].val);
7301  }
7302  if (cs[ij].val <= tolfe)
7303  continue;
7304  jj = i;
7305  sip_viol->type = CONSTR;
7306  sip_viol->index = ij;
7307  goto L1120;
7308  }
7309  sipldone = TRUE;
7310  }
7311  if (nn == 0)
7312  goto L310;
7313 
7314  /* Check nonlinear constraints */
7315  if (!glob_log.local && fbind)
7316  goto L315;
7317  do
7318  {
7319  for (i = 1; i <= nn; i++)
7320  {
7321  *ncg = i;
7322  ii = iact[i];
7323  ij = glob_info.nnineq + neqn;
7324  if (!((ii <= glob_info.nnineq && istore[ii] == 1) ||
7325  (ii > glob_info.nnineq && ii <= ij && eqdone)))
7326  {
7327  temp = 1.e0;
7328  if (ii > glob_info.nnineq && ii <= ij)
7329  temp = signeq[ii-glob_info.nnineq];
7330  constr(nparam, ii, xnew + 1, &(cs[ii].val), cd);
7331  cs[ii].val *= temp;
7332  glob_info.ncallg++;
7333  }
7334  if (glob_prnt.iprint >= 3 && display)
7335  {
7336  if (i == 1 && ikeep == nlin)
7338  "\t\t\t trial constraints %d \t %22.14e\n", ii,
7339  cs[ii].val);
7340  if (i != 1 || ikeep != nlin)
7342  "\t\t\t\t\t %d \t %22.14e\n", ii, cs[ii].val);
7343  }
7344  if (!(glob_log.local || cs[ii].val <= tolfe))
7345  {
7346  shift(nn, ii, iact);
7347  if (ncsipn && ii > nineqn - ncsipn)
7348  {
7349  sip_viol->type = CONSTR;
7350  sip_viol->index = ii;
7351  }
7352  else
7353  {
7354  sip_viol->type = NONE; /* non-SIP constraint violated */
7355  sip_viol->index = 0;
7356  }
7357  goto L1110;
7358  }
7359  if (glob_log.local && cs[ii].val > tolfe)
7360  {
7361  if (ncsipn && ii > nineqn - ncsipn)
7362  {
7363  sip_viol->type = CONSTR;
7364  sip_viol->index = ii;
7365  }
7366  else
7367  {
7368  sip_viol->type = NONE; /* non-SIP constraint violated */
7369  sip_viol->index = 0;
7370  }
7371  goto L1500;
7372  }
7373  }
7374 L310:
7375  cdone = eqdone = TRUE;
7376  if (glob_log.local)
7377  glob_log.dlfeas = TRUE; /* dl is feasible */
7378 L315:
7379  if (fdone)
7380  break;
7381  if (nob > 0)
7382  fmax1 = -bgbnd;
7383  else
7384  fmax1 = 0.e0;
7385  for (i = 0; i <= nob; i++)
7386  {
7387  if (nob != 0 && i == 0)
7388  continue;
7389  *ncf = i;
7390  ii = iact[nn+i];
7391  if (feasb)
7392  {
7393  if (!(eqdone || neqn == 0))
7394  {
7395  for (j = 1; j <= neqn; j++)
7396  constr(nparam, glob_info.nnineq + j, xnew + 1,
7397  &(cs[glob_info.nnineq+j].val), cd);
7398  glob_info.ncallg += neqn;
7399  }
7400  if (neqn != 0)
7401  {
7402  if (eqdone)
7403  job = 20;
7404  if (!eqdone)
7405  job = 10;
7406  resign(nparam, neqn, psf, *(adummy + 1), penp, cs, signeq,
7407  job, 10);
7408  }
7409  if (istore[nineqn+ii] != 1 && i != 0)
7410  {
7411  obj(nparam, ii, xnew + 1, &(ob[ii].val), cd);
7412  glob_info.ncallf++;
7413  }
7414  if (i == 0)
7415  fii = 0.e0;
7416  else
7417  fii = ob[ii].val;
7418  if (i == 0 && glob_prnt.iprint >= 3 && display)
7420  "\t\t\t trial penalty term \t %22.14e\n", -*psf);
7421  if (i == 1 && glob_prnt.iprint >= 3 && display)
7423  "\t\t\t trial objectives %d \t %22.14e\n",
7424  ii, fii - *psf);
7425  if (i > 1 && glob_prnt.iprint >= 3 && display)
7427  "\t\t\t\t\t %d \t %22.14e\n", ii, fii - *psf);
7428  }
7429  else
7430  {
7431  if (istore[ii] != 1)
7432  {
7433  constr(nparam, indxob[ii], xnew + 1, &(ob[ii].val), cd);
7434  glob_info.ncallg++;
7435  }
7436  if (ob[ii].val > tolfe)
7437  reform = FALSE;
7438  if (i == 1 && glob_prnt.iprint > 2 && display)
7440  "\t\t\t trial objectives %d \t %22.14e\n",
7441  indxob[ii], ob[ii].val);
7442  if (i != 1 && glob_prnt.iprint > 2 && display)
7444  "\t\t\t\t\t %d \t %22.14e\n", indxob[ii],
7445  ob[ii].val);
7446  fii = ob[ii].val;
7447  }
7448  fmax1 = DMAX1(fmax1, fii);
7449  if (nobL != nob)
7450  fmax1 = DMAX1(fmax1, -fii);
7451  if (!feasb && reform)
7452  continue;
7453  if (!glob_log.local)
7454  {
7455  if ((fii - *psf) > (*fMp + prod))
7456  {
7457  fbind = TRUE;
7458  shift(nob, ii, &iact[nn]);
7459  if (nfsip && ii > nob - nfsip)
7460  {
7461  sip_viol->type = OBJECT;
7462  sip_viol->index = ii;
7463  }
7464  else
7465  {
7466  sip_viol->type = NONE;
7467  sip_viol->index = 0;
7468  }
7469  goto L1110;
7470  }
7471  if (nobL == nob || (-fii - *psf) <= (*fMp + prod))
7472  continue;
7473  fbind = TRUE;
7474  shift(nob, ii, &iact[nn]);
7475  if (nfsip && ii > nob - nfsip)
7476  {
7477  sip_viol->type = OBJECT;
7478  sip_viol->index = ii;
7479  }
7480  else
7481  {
7482  sip_viol->type = NONE;
7483  sip_viol->index = 0;
7484  }
7485  goto L1110;
7486  }
7487  ltem1 = (fii - *psf) > (*fMp + prod);
7488  ltem2 = (nobL != nob) && ((-fii - *psf) > (*fMp + prod));
7489  if (ltem1 || ltem2)
7490  goto L1500;
7491  }
7492  fbind = FALSE;
7493  fdone = eqdone = TRUE;
7494  }
7495  while (!cdone);
7496  if (ostep == *steps)
7497  mnm = ikeep + neq - neqn;
7498  if (ostep != *steps)
7499  mnm = ncnstr - nn;
7500  for (i = 1; i <= mnm; i++)
7501  {
7502  ii = indxcn[i+nn];
7503  if (ikeep != nlin && ostep == *steps)
7504  {
7505  if (i <= ikeep)
7506  ii = iskip[nlin+2-i];
7507  else
7508  ii = indxcn[nn+i-ikeep+nlin];
7509  }
7510  constr(nparam, ii, xnew + 1, &(cs[ii].val), cd);
7511  }
7512  *scvneq = 0.e0;
7513  for (i = 1; i <= ncnstr; i++)
7514  {
7515  if (i > glob_info.nnineq && i <= (glob_info.nnineq + neqn))
7516  *scvneq = *scvneq - cs[i].val;
7517  backup[i] = cs[i].val;
7518  }
7519  for (i = 1; i <= nob; i++)
7520  backup[i+ncnstr] = ob[i].val;
7521  if (!feasb && reform)
7522  {
7523  for (i = 1; i <= nparam; i++)
7524  x[i] = xnew[i];
7525  nstop = 0;
7526  goto L1500;
7527  }
7528  if (glob_log.local)
7529  *ncg = ncnstr;
7530  if (glob_log.local)
7531  glob_log.update = TRUE;
7532  *fM = fmax1;
7533  *fMp = fmax1 - *psf;
7534  *fmax = fmax1;
7535  for (i = 1; i <= nn; i++)
7536  iact[i] = indxcn[i];
7537  for (i = 1; i <= nob; i++)
7538  iact[nn+i] = i;
7539  goto L1500;
7540  L1110:
7541  cdone = fdone = eqdone = reform = FALSE;
7542  L1120:
7543  itry++;
7544  if (glob_info.modec == 2)
7545  fbind = FALSE;
7546  if (*steps >= 1.e0)
7547  for (i = 1; i <= nob + nineqn; i++)
7548  istore[i] = 0;
7549  *steps = *steps * 0.5e0;
7550  if (*steps < glob_grd.epsmac)
7551  break;
7552  }
7553  glob_prnt.info = 4;
7554  nstop = 0;
7555  L1500:
7556  free_dm(adummy, 1);
7557  if (*steps < 1.e0)
7558  return;
7559  for (i = 1; i <= nob + nineqn; i++)
7560  istore[i] = 0;
7561  return;
7562 }
7563 /******************************************************************/
7564 /* CFSQP : Update the Hessian matrix using BFGS formula with */
7565 /* Powell's modification. */
7566 /******************************************************************/
7567 
7568 
7569 #ifdef __STDC__
7570 static void
7571 hessian(int nparam, int nob, int nfsip, int nobL, int nineqn, int neq,
7572  int neqn, int nn, int ncsipn, int ncnstr, int nfs, int *nstart,
7573  int feasb, double *xnew, struct _parameter *param,
7574  struct _objective *ob, double fmax, double *fM, double *fMp,
7575  double *psf, double *grdpsf, double *penp, struct _constraint *cs,
7576  double *gm, int *indxob, int *indxcn, double *delta, double *eta,
7577  double *gamma, double **hess, double *hd, double steps, int *nrst,
7578  double *signeq, double *span,
7579  void(*obj)(int, int, double *, double *, void *),
7580  void(*constr)(int, int, double *, double *, void *),
7581  void(*gradob)(int, int, double *, double *,
7582  void(*)(int, int, double *, double *, void *), void *),
7583  void(*gradcn)(int, int, double *, double *,
7584  void(*)(int, int, double *, double *, void *), void *),
7585  double **phess, double *psb, double *psmu,
7586  struct _violation *sip_viol)
7587 #else
7588 static void
7589 hessian(nparam, nob, nfsip, nobL, nineqn, neq, neqn, nn, ncsipn, ncnstr,
7590  nfs, nstart, feasb, xnew, param, ob, fmax, fM, fMp, psf, grdpsf, penp,
7591  cs, gm, indxob, indxcn, delta, eta, gamma, hess, hd, steps, nrst, signeq,
7592  span, obj, constr, gradob, gradcn, phess, psb, psmu, sip_viol)
7593 int nparam, nob, nobL, nineqn, neq, neqn, nn, nfsip, ncsipn, ncnstr,
7594 nfs, *nstart, feasb, *nrst;
7595 int *indxob, *indxcn;
7596 double steps, *psf, fmax, *fM, *fMp;
7597 double *xnew, *grdpsf, *penp, *gm, *delta, *eta, *gamma,
7598 **hess, *hd, *signeq, *span, **phess, *psb, *psmu;
7599 struct _constraint *cs;
7600 struct _objective *ob;
7601 struct _parameter *param;
7602 struct _violation *sip_viol;
7603 void(* obj)(), (* constr)(), (* gradob)(), (* gradcn)();
7604 #endif
7606  int i, j, k, ifail, np, mnm, done, display;
7608  double *tempv;
7609 
7610  /* Check to see whether user-accessible stopping criterion
7611  is satisfied. The check of gLgeps is made just after
7612  computing d0 */
7613 
7615  {
7616  if (feasb && nstop && !neqn)
7617  if ((fabs(w[1] - fmax) <= objeps) ||
7618  (fabs(w[1] - fmax) <= objrep*fabs(w[1])))
7619  nstop = 0;
7620  if (!nstop)
7621  {
7622  for (i = 1; i <= nparam; i++)
7623  param->x[i] = xnew[i];
7624  x_is_new = TRUE;
7625  return;
7626  }
7627  }
7628 
7629  delta_s = glob_grd.rteps; /* SIP */
7631  display = FALSE;
7632  else
7633  display = TRUE;
7634  psfnew = 0.e0;
7636  done = FALSE;
7637  dummy = 0.e0;
7638  nullvc(nparam, delta);
7639  nullvc(nparam, eta);
7640  for (j = 1; j <= 2; j++)
7641  {
7642  nullvc(nparam, gamma);
7643  if (nobL > 1)
7644  {
7645  for (i = 1; i <= nparam; i++)
7646  {
7647  hd[i] = 0.e0;
7648  for (k = 1; k <= nob; k++)
7649  hd[i] = hd[i] + ob[k].grad[i] * ob[k].mult;
7650  }
7651  }
7652  if (feasb)
7653  {
7654  if (nineqn != 0)
7655  {
7656  for (i = 1; i <= nparam; i++)
7657  {
7658  gamma[i] = 0.e0;
7659  for (k = 1; k <= nineqn; k++)
7660  gamma[i] = gamma[i] + cs[k].grad[i] * cs[k].mult;
7661  }
7662  }
7663  if (neqn != 0)
7664  {
7665  for (i = 1; i <= nparam; i++)
7666  {
7667  eta[i] = 0.e0;
7668  for (k = 1; k <= neqn; k++)
7669  eta[i] = eta[i] + cs[glob_info.nnineq+k].grad[i] *
7670  cs[glob_info.nnineq+k].mult;
7671  }
7672  }
7673  }
7674  for (i = 1; i <= nparam; i++)
7675  {
7676  if (nobL > 1)
7677  {
7678  if (done)
7679  psb[i] = hd[i] + param->mult[i] + gamma[i];
7680  gamma[i] = gamma[i] + hd[i] - grdpsf[i] + eta[i];
7681  }
7682  else if (nobL == 1)
7683  {
7684  if (done)
7685  psb[i] = ob[1].grad[i] + param->mult[i] + gamma[i];
7686  gamma[i] = gamma[i] + ob[1].grad[i] - grdpsf[i] + eta[i];
7687  }
7688  else if (nobL == 0)
7689  {
7690  if (done)
7691  psb[i] = param->mult[i] + gamma[i];
7692  gamma[i] = gamma[i] - grdpsf[i] + eta[i];
7693  }
7694  if (!done)
7695  delta[i] = gamma[i];
7696  }
7697  if (!done && !glob_log.d0_is0)
7698  {
7699  if (nn != 0)
7700  {
7701  for (i = 1; i <= nn; i++)
7702  {
7703  if ((feasb) && (i > nineqn))
7704  signgj = signeq[i-nineqn];
7705  if ((!feasb) || (i <= nineqn))
7706  signgj = 1.e0;
7707  if ((feasb) && (ncsipn) && (i > nineqn - ncsipn) &&
7708  (cs[indxcn[i]].mult == 0.e0))
7709  continue;
7710  glob_grd.valnom = cs[indxcn[i]].val * signgj;
7711  gradcn(nparam, indxcn[i], xnew + 1, cs[indxcn[i]].grad + 1,
7712  constr, param->cd);
7713  }
7714  resign(nparam, neqn, psf, grdpsf, penp, cs, signeq, 11, 11);
7715  }
7716  for (i = 1; i <= nob; i++)
7717  {
7718  glob_grd.valnom = ob[i].val;
7719  if ((i <= nob - nfsip) || (i > nob - nfsip &&
7720  ((ob[i].mult != 0.e0) || (ob[i].mult_L != 0.e0))))
7721  {
7722  if (feasb)
7723  gradob(nparam, i, xnew + 1, ob[i].grad + 1, obj, param->cd);
7724  else
7725  gradcn(nparam, indxob[i], xnew + 1, ob[i].grad + 1,
7726  constr, param->cd);
7727  }
7728  }
7729  done = TRUE;
7730  }
7731  if (glob_log.d0_is0)
7732  done = TRUE;
7733  }
7734  if (!glob_log.d0_is0)
7735  {
7736  if (!(feasb && steps < delta_s && ((sip_viol->type == OBJECT &&
7737  !ob[sip_viol->index].act_sip) || (sip_viol->type == CONSTR &&
7738  !cs[sip_viol->index].act_sip))))
7739  {
7740  if (*nrst < (5*nparam) || steps > 0.1e0)
7741  {
7742  (*nrst)++;
7743  for (i = 1; i <= nparam; i++)
7744  {
7745  gamma[i] = gamma[i] - delta[i];
7746  delta[i] = xnew[i] - param->x[i];
7747  }
7748  matrvc(nparam, nparam, hess, delta, hd);
7749  dhd = scaprd(nparam, delta, hd);
7750  if (sqrt(scaprd(nparam, delta, delta)) <= glob_grd.epsmac)
7751  {
7752  /* xnew too close to x!! */
7753  nstop = 0;
7754  glob_prnt.info = 8;
7755  return;
7756  }
7757  gammd = scaprd(nparam, delta, gamma);
7758  if (gammd >= (0.2e0*dhd))
7759  theta = 1.e0;
7760  else
7761  theta = 0.8e0 * dhd / (dhd - gammd);
7762  for (i = 1; i <= nparam; i++)
7763  eta[i] = hd[i] * (1.e0 - theta) + theta * gamma[i];
7764  etad = theta * gammd + (1.e0 - theta) * dhd;
7765  for (i = 1; i <= nparam; i++)
7766  {
7767  for (j = i; j <= nparam; j++)
7768  {
7769  hess[i][j] = hess[i][j] - hd[i] * hd[j] / dhd +
7770  eta[i] * eta[j] / etad;
7771  hess[j][i] = hess[i][j];
7772  }
7773  }
7774  }
7775  else
7776  {
7777  *nrst = 0;
7778  diagnl(nparam, 1.e0, hess);
7779  }
7780  }
7781  for (i = 1; i <= nparam; i++)
7782  param->x[i] = xnew[i];
7783  x_is_new = TRUE;
7784  }
7785  if (neqn != 0 && (feasb))
7786  {
7787  i = glob_info.nnineq - nineqn;
7788  if (i != 0)
7789  {
7790  for (j = 1; j <= nparam; j++)
7791  {
7792  gamma[j] = 0.e0;
7793  for (k = 1; k <= i; k++)
7794  gamma[j] = gamma[j] + cs[k+nineqn].grad[j] *
7795  cs[nineqn+k].mult;
7796  }
7797  for (i = 1; i <= nparam; i++)
7798  psb[i] = psb[i] + gamma[i];
7799  }
7800  i = neq - neqn;
7801  if (i != 0)
7802  {
7803  for (j = 1; j <= nparam; j++)
7804  {
7805  gamma[j] = 0.e0;
7806  for (k = 1; k <= i; k++)
7807  gamma[j] = gamma[j] + cs[k+neqn+glob_info.nnineq].grad[j] *
7808  cs[glob_info.nnineq+neqn+k].mult;
7809  }
7810  for (i = 1; i <= nparam; i++)
7811  psb[i] = psb[i] + gamma[i];
7812  }
7813  /* Update penalty parameters for nonlinear equality constraints */
7814  estlam(nparam, neqn, &ifail, bgbnd, phess, delta, eta,
7815  gamma, cs, psb, hd, xnew, psmu);
7816  if (glob_log.get_ne_mult)
7817  return;
7818  for (i = 1; i <= neqn; i++)
7819  {
7820  if (ifail != 0 || glob_log.d0_is0)
7821  penp[i] = 2.e0 * penp[i];
7822  else
7823  {
7824  etad = psmu[i] + penp[i];
7825  if (etad < 1.e0)
7826  penp[i] = DMAX1((1.e0 - psmu[i]), (2.e0 * penp[i]));
7827  }
7828  if (penp[i] > bgbnd)
7829  {
7830  nstop = 0;
7831  glob_prnt.info = 9;
7832  return;
7833  }
7834  }
7835  resign(nparam, neqn, psf, grdpsf, penp, cs, signeq, 20, 12);
7836  *fMp = *fM - *psf;
7837  }
7838  if (nfs != 0)
7839  {
7840  (*nstart)++;
7841  np = indexs(*nstart, nfs);
7842  span[np] = fmax;
7843  for (i = 1; i <= neqn; i++)
7844  gm[(np-1)*neqn+i] = cs[glob_info.nnineq+i].val;
7845  if (neqn != 0)
7846  {
7847  psfnew = 0.e0;
7848  for (i = 1; i <= neqn; i++)
7849  psfnew = psfnew + gm[i]*penp[i];
7850  }
7851  *fM = span[1];
7852  *fMp = span[1] - psfnew;
7853  mnm = DMIN1(*nstart, nfs);
7854  for (i = 2; i <= mnm; i++)
7855  {
7856  if (neqn != 0)
7857  {
7858  psfnew = 0.e0;
7859  for (j = 1; j <= neqn; j++)
7860  psfnew = psfnew + gm[(i-1)*neqn +j]*penp[j];
7861  }
7862  *fM = DMAX1(*fM, span[i]);
7863  *fMp = DMAX1(*fMp, span[i] - psfnew);
7864  }
7865  }
7866  if (glob_prnt.iprint < 3 || !display)
7867  return;
7868  for (i = 1; i <= nob; i++)
7869  {
7870  if (!feasb)
7871  {
7872  sbout2(glob_prnt.io, nparam, indxob[i], "gradg(j,",
7873  ")", ob[i].grad);
7874  continue;
7875  }
7876  if (nob > 1)
7877  sbout2(glob_prnt.io, nparam, i, "gradf(j,", ")",
7878  ob[i].grad);
7879  if (nob == 1)
7880  sbout1(glob_prnt.io, nparam, "gradf(j) ",
7881  dummy, ob[1].grad, 2, 2);
7882  }
7883  if (ncnstr != 0)
7884  {
7885  for (i = 1; i <= ncnstr; i++)
7886  {
7887  tempv = cs[indxcn[i]].grad;
7888  sbout2(glob_prnt.io, nparam, indxcn[i], "gradg(j,", ")", tempv);
7889  }
7890  if (neqn != 0)
7891  {
7892  sbout1(glob_prnt.io, nparam, "grdpsf(j) ",
7893  dummy, grdpsf, 2, 2);
7894  sbout1(glob_prnt.io, neqn, "P ", dummy,
7895  penp, 2, 2);
7896  sbout1(glob_prnt.io, neqn, "psmu ", dummy,
7897  psmu, 2, 2);
7898  }
7899  }
7900  sbout1(glob_prnt.io, nparam, "multipliers for x ", dummy,
7901  param->mult, 2, 2);
7902  if (ncnstr != 0)
7903  {
7904  fprintf(glob_prnt.io, "\t\t\t %s\t %22.14e\n",
7905  " for g ", cs[1].mult);
7906  for (j = 2; j <= ncnstr; j++)
7907  fprintf(glob_prnt.io, " \t\t\t\t\t\t %22.14e\n", cs[j].mult);
7908  }
7909  if (nobL > 1)
7910  {
7911  fprintf(glob_prnt.io, "\t\t\t %s\t %22.14e\n",
7912  " for f ", ob[1].mult);
7913  for (j = 2; j <= nob; j++)
7914  fprintf(glob_prnt.io, " \t\t\t\t\t\t %22.14e\n", ob[j].mult);
7915  }
7916  for (i = 1; i <= nparam; i++)
7917  {
7918  tempv = colvec(hess, i, nparam);
7919  sbout2(glob_prnt.io, nparam, i, "hess (j,", ")", tempv);
7920  free_dv(tempv);
7921  }
7922  return;
7923 }
7924 /**************************************************************/
7925 /* CFSQP : Output */
7926 /**************************************************************/
7927 
7928 
7929 #ifdef __STDC__
7930 static void
7931 out(int miter, int nparam, int nob, int nobL, int nfsip, int ncn,
7932  int nn, int nineqn, int ncnstr, int ncsipl, int ncsipn,
7933  int *mesh_pts, double *x, struct _constraint *cs,
7934  struct _objective *ob, double fM, double fmax,
7935  double steps, double sktnom, double d0norm, int feasb)
7936 #else
7937 static void
7938 out(miter, nparam, nob, nobL, nfsip, ncn, nn, nineqn, ncnstr, ncsipl, ncsipn,
7939  mesh_pts, x, cs, ob, fM, fmax, steps, sktnom, d0norm, feasb)
7940 int miter, nparam, nob, nobL, nfsip, ncn, nn, ncnstr, feasb,
7941 ncsipl, ncsipn, nineqn, *mesh_pts;
7942 double fM, fmax, steps, sktnom, d0norm;
7943 double *x;
7944 struct _constraint *cs;
7945 struct _objective *ob;
7946 #endif
7948  int i, j, index, display, offset;
7949  double SNECV, dummy, *adummy, gmax;
7950 
7951  adummy = make_dv(1);
7952  adummy[1] = 0.e0;
7953  dummy = 0.e0;
7954  if (glob_prnt.iter >= miter && nstop != 0)
7955  {
7956  glob_prnt.info = 3;
7957  nstop = 0;
7958  if (glob_prnt.iprint == 0)
7959  goto L9000;
7960  }
7961  if (glob_prnt.iprint == 0 && glob_prnt.iter < miter)
7962  {
7963  glob_prnt.iter++;
7964  goto L9000;
7965  }
7966  if ((glob_prnt.info > 0 && glob_prnt.info < 3) || glob_prnt.info == 7)
7967  goto L120;
7968  if (glob_prnt.iprint == 1 && nstop != 0)
7969  {
7970  glob_prnt.iter++;
7971  if (glob_prnt.initvl == 0)
7972  goto L9000;
7973  if (feasb && nob > 0)
7974  {
7975  fprintf(glob_prnt.io, " objectives\n");
7976  for (i = 1; i <= nob - nfsip; i++)
7977  {
7978  if (nob == nobL)
7979  fprintf(glob_prnt.io, " \t\t\t %22.14e\n", ob[i].val);
7980  else
7981  fprintf(glob_prnt.io, " \t\t\t %22.14e\n", fabs(ob[i].val));
7982  }
7983  if (nfsip)
7984  {
7985  offset = nob - nfsip;
7986  for (i = 1; i <= glob_info.nfsip; i++)
7987  {
7988  if (nob == nobL)
7989  gmax = ob[++offset].val;
7990  else
7991  gmax = fabs(ob[++offset].val);
7992  for (j = 2; j <= mesh_pts[i]; j++)
7993  {
7994  offset++;
7995  if (nob == nobL && ob[offset].val > gmax)
7996  gmax = ob[offset].val;
7997  else if (nob != nobL && fabs(ob[offset].val) > gmax)
7998  gmax = fabs(ob[offset].val);
7999  }
8000  fprintf(glob_prnt.io, " \t\t\t %22.14e\n", gmax);
8001  }
8002  }
8003  }
8004  if (glob_info.mode == 1 && glob_prnt.iter > 1 && feasb)
8005  sbout1(glob_prnt.io, 0, "objective max4 ", fM, adummy, 1, 1);
8006  if (nob > 1)
8007  sbout1(glob_prnt.io, 0, "objmax ", fmax, adummy, 1, 1);
8008  if (ncnstr == 0)
8009  fprintf(glob_prnt.io, "\n");
8010  else
8011  {
8012  fprintf(glob_prnt.io, " constraints\n");
8013  for (i = 1; i <= nineqn - ncsipn; i++)
8014  fprintf(glob_prnt.io, " \t\t\t %22.14e\n", cs[i].val);
8015  if (ncsipn)
8016  {
8017  offset = nineqn - ncsipn;
8018  for (i = 1; i <= glob_info.ncsipn; i++)
8019  {
8020  gmax = cs[++offset].val;
8021  for (j = 2; j <= mesh_pts[glob_info.nfsip+i]; j++)
8022  {
8023  offset++;
8024  if (cs[offset].val > gmax)
8025  gmax = cs[offset].val;
8026  }
8027  fprintf(glob_prnt.io, " \t\t\t %22.14e\n", gmax);
8028  }
8029  }
8030  for (i = nineqn + 1; i <= glob_info.nnineq - ncsipl; i++)
8031  fprintf(glob_prnt.io, " \t\t\t %22.14e\n", cs[i].val);
8032  if (ncsipl)
8033  {
8034  offset = glob_info.nnineq - ncsipl;
8035  for (i = 1; i <= glob_info.ncsipl; i++)
8036  {
8037  gmax = cs[++offset].val;
8038  if (feasb)
8039  index = glob_info.nfsip + glob_info.ncsipn + i;
8040  else
8041  index = glob_info.ncsipn + i;
8042  for (j = 2; j <= mesh_pts[index]; j++)
8043  {
8044  offset++;
8045  if (cs[offset].val > gmax)
8046  gmax = cs[offset].val;
8047  }
8048  fprintf(glob_prnt.io, " \t\t\t %22.14e\n", gmax);
8049  }
8050  }
8051  for (i = glob_info.nnineq + 1; i <= ncnstr; i++)
8052  fprintf(glob_prnt.io, " \t\t\t %22.14e\n", cs[i].val);
8053  }
8054  if (ncnstr != 0)
8055  fprintf(glob_prnt.io, "\n");
8056  goto L9000;
8057  }
8058  if (glob_prnt.iprint == 1 && nstop == 0)
8059  fprintf(glob_prnt.io, " iteration %26d\n",
8060  glob_prnt.iter);
8061  if (glob_prnt.iprint <= 2 && nstop == 0)
8062  fprintf(glob_prnt.io, " inform %26d\n",
8063  glob_prnt.info);
8064  if (glob_prnt.iprint == 1 && nstop == 0 && (ncsipl + ncsipn) != 0)
8065  fprintf(glob_prnt.io, " |Xi_k| %26d\n",
8067  if (glob_prnt.iprint == 1 && nstop == 0 && nfsip != 0)
8068  fprintf(glob_prnt.io, " |Omega_k| %26d\n",
8070  glob_prnt.iter++;
8071  if (!((glob_prnt.iter) % glob_prnt.iter_mod))
8072  display = TRUE;
8073  else
8074  display = (nstop == 0);
8075  if (glob_prnt.iter_mod != 1 && display)
8076  fprintf(glob_prnt.io, "\n iteration %26d\n",
8077  glob_prnt.iter - 1);
8078  if (glob_prnt.initvl == 0 && display)
8079  sbout1(glob_prnt.io, nparam, "x ", dummy, x, 2, 1);
8080  if (display)
8081  {
8082  if (nob > 0)
8083  {
8084  fprintf(glob_prnt.io, " objectives\n");
8085  for (i = 1; i <= nob - nfsip; i++)
8086  {
8087  if (nob == nobL)
8088  fprintf(glob_prnt.io, " \t\t\t %22.14e\n", ob[i].val);
8089  else
8090  fprintf(glob_prnt.io, " \t\t\t %22.14e\n",
8091  fabs(ob[i].val));
8092  }
8093  }
8094  if (nfsip)
8095  {
8096  offset = nob - nfsip;
8097  if (feasb)
8098  index = glob_info.nfsip;
8099  else
8100  index = glob_info.ncsipn;
8101  for (i = 1; i <= index; i++)
8102  {
8103  if (nob == nobL)
8104  gmax = ob[++offset].val;
8105  else
8106  gmax = fabs(ob[++offset].val);
8107  for (j = 2; j <= mesh_pts[i]; j++)
8108  {
8109  offset++;
8110  if (nob == nobL && ob[offset].val > gmax)
8111  gmax = ob[offset].val;
8112  else if (nob != nobL && fabs(ob[offset].val) > gmax)
8113  gmax = fabs(ob[offset].val);
8114  }
8115  fprintf(glob_prnt.io, " \t\t\t %22.14e\n", gmax);
8116  }
8117  }
8118  }
8119  if (glob_info.mode == 1 && glob_prnt.iter > 1 && display)
8120  sbout1(glob_prnt.io, 0, "objective max4 ", fM, adummy, 1, 1);
8121  if (nob > 1 && display)
8122  sbout1(glob_prnt.io, 0, "objmax ", fmax, adummy, 1, 1);
8123  if (ncnstr != 0 && display)
8124  {
8125  fprintf(glob_prnt.io, " constraints\n");
8126  for (i = 1; i <= nineqn - ncsipn; i++)
8127  fprintf(glob_prnt.io, " \t\t\t %22.14e\n", cs[i].val);
8128  if (ncsipn)
8129  {
8130  offset = nineqn - ncsipn;
8131  for (i = 1; i <= glob_info.ncsipn; i++)
8132  {
8133  gmax = cs[++offset].val;
8134  for (j = 2; j <= mesh_pts[glob_info.nfsip+i]; j++)
8135  {
8136  offset++;
8137  if (cs[offset].val > gmax)
8138  gmax = cs[offset].val;
8139  }
8140  fprintf(glob_prnt.io, " \t\t\t %22.14e\n", gmax);
8141  }
8142  }
8143  for (i = nineqn + 1; i <= glob_info.nnineq - ncsipl; i++)
8144  fprintf(glob_prnt.io, " \t\t\t %22.14e\n", cs[i].val);
8145  if (ncsipl)
8146  {
8147  offset = glob_info.nnineq - ncsipl;
8148  for (i = 1; i <= glob_info.ncsipl; i++)
8149  {
8150  gmax = cs[++offset].val;
8151  if (feasb)
8152  index = glob_info.nfsip + glob_info.ncsipn + i;
8153  else
8154  index = glob_info.ncsipn + i;
8155  for (j = 2; j <= mesh_pts[index];
8156  j++)
8157  {
8158  offset++;
8159  if (cs[offset].val > gmax)
8160  gmax = cs[offset].val;
8161  }
8162  fprintf(glob_prnt.io, " \t\t\t %22.14e\n", gmax);
8163  }
8164  }
8165  for (i = glob_info.nnineq + 1; i <= ncnstr; i++)
8166  fprintf(glob_prnt.io, " \t\t\t %22.14e\n", cs[i].val);
8167  if (feasb)
8168  {
8169  SNECV = 0.e0;
8170  for (i = glob_info.nnineq + 1; i <= glob_info.nnineq + nn - nineqn; i++)
8171  SNECV = SNECV + fabs(cs[i].val);
8172  if (glob_prnt.initvl == 0 && (nn - nineqn) != 0)
8173  sbout1(glob_prnt.io, 0, "SNECV ",
8174  SNECV, adummy, 1, 1);
8175  }
8176  }
8177  if (glob_prnt.iter <= 1 && display)
8178  {
8179  fprintf(glob_prnt.io, " \n");
8180  fprintf(glob_prnt.io, " iteration %26d\n",
8181  glob_prnt.iter);
8182  goto L9000;
8183  }
8184  if (glob_prnt.iprint >= 2 && glob_prnt.initvl == 0 && display)
8185  sbout1(glob_prnt.io, 0, "step ", steps, adummy, 1, 1);
8186  if (glob_prnt.initvl == 0 && display &&
8187  (nstop == 0 || glob_prnt.info != 0 || glob_prnt.iprint == 2))
8188  {
8189  sbout1(glob_prnt.io, 0, "d0norm ", d0norm, adummy, 1, 1);
8190  sbout1(glob_prnt.io, 0, "ktnorm ", sktnom, adummy, 1, 1);
8191  }
8192  if (glob_prnt.initvl == 0 && feasb && display)
8193  fprintf(glob_prnt.io, " ncallf %26d\n",
8194  glob_info.ncallf);
8195  if (glob_prnt.initvl == 0 && (nn != 0 || !feasb) && display)
8196  fprintf(glob_prnt.io, " ncallg %26d\n",
8197  glob_info.ncallg);
8198  if (glob_prnt.iprint >= 3 && glob_prnt.iter_mod != 1 && nstop != 0
8199  && !(glob_prnt.iter % glob_prnt.iter_mod))
8201  "\n The following was calculated during iteration %5d:\n",
8202  glob_prnt.iter);
8203  if (nstop != 0 && (glob_prnt.iter_mod == 1))
8204  fprintf(glob_prnt.io, "\n iteration %26d\n",
8205  glob_prnt.iter);
8206 L120:
8207  if (nstop != 0 || glob_prnt.iprint == 0)
8208  goto L9000;
8209  fprintf(glob_prnt.io, "\n");
8210  if (glob_prnt.iprint >= 3)
8211  fprintf(glob_prnt.io, " inform %26d\n",
8212  glob_prnt.info);
8213  if (glob_prnt.info == 0)
8215  "\nNormal termination: You have obtained a solution !!\n");
8216  if (glob_prnt.info == 0 && sktnom > 0.1e0)
8218  "Warning: Norm of Kuhn-Tucker vector is large !!\n");
8219  if (glob_prnt.info == 3)
8220  {
8222  "\nWarning: Maximum iterations have been reached before\n");
8223  fprintf(glob_prnt.io, "obtaining a solution !!\n\n");
8224  }
8225  if (glob_prnt.info == 4)
8226  {
8228  "\nError : Step size has been smaller than the computed\n");
8229  fprintf(glob_prnt.io, "machine precision !!\n\n");
8230  }
8231  if (glob_prnt.info == 5)
8233  "\nError: Failure in constructing d0 !!\n\n");
8234  if (glob_prnt.info == 6)
8236  "\nError: Failure in constructing d1 !!\n\n");
8237  if (glob_prnt.info == 8)
8238  {
8240  "\nError: The new iterate is numerically equivalent to the\n");
8242  "previous iterate, though the stopping criterion is not \n");
8243  fprintf(glob_prnt.io, "satisfied\n");
8244  }
8245  if (glob_prnt.info == 9)
8246  {
8248  "\nError: Could not satisfy nonlinear equality constraints -\n");
8249  fprintf(glob_prnt.io, " Penalty parameter too large\n");
8250  }
8251  fprintf(glob_prnt.io, "\n");
8252 L9000:
8253  free_dv(adummy);
8254  glob_prnt.initvl = 0;
8255  return;
8256 }
8257 /*************************************************************/
8258 /* CFSQP : Computation of gradients of objective */
8259 /* functions by forward finite differences */
8260 /*************************************************************/
8261 
8262 
8263 #ifdef __STDC__
8264 void grobfd(int nparam, int j, double *x, double *gradf,
8265  void(*obj)(int, int, double *, double *, void *), void *cd)
8266 #else
8267 void grobfd(nparam, j, x, gradf, obj, cd)
8268 int nparam, j;
8269 double *x, *gradf;
8270 void(*obj)();
8271 void *cd;
8272 #endif
8273 {
8274  int i;
8275  double xi, delta;
8276 
8277  for (i = 0; i <= nparam - 1; i++)
8278  {
8279  xi = x[i];
8280  delta = DMAX1(glob_grd.udelta,
8281  glob_grd.rteps * DMAX1(1.e0, fabs(xi)));
8282  if (xi < 0.e0)
8283  delta = -delta;
8284  if (!(glob_prnt.ipd == 1 || j != 1 || glob_prnt.iprint < 3))
8285  {
8286  /* formats are not set yet... */
8287  if (i == 0)
8288  fprintf(glob_prnt.io, "\tdelta(i)\t %22.14f\n", delta);
8289  if (i != 0)
8290  fprintf(glob_prnt.io, "\t\t\t %22.14f\n", delta);
8291  }
8292  x[i] = xi + delta;
8293  x_is_new = TRUE;
8294  (*obj)(nparam, j, x, &gradf[i], cd);
8295  gradf[i] = (gradf[i] - glob_grd.valnom) / delta;
8296  x[i] = xi;
8297  x_is_new = TRUE;
8298  }
8299  return;
8300 }
8301 
8302 /***********************************************************/
8303 /* CFSQP : Computation of gradients of constraint */
8304 /* functions by forward finite differences */
8305 /***********************************************************/
8306 
8307 #ifdef __STDC__
8308 void grcnfd(int nparam, int j, double *x, double *gradg,
8309  void(*constr)(int, int, double *, double *, void *), void *cd)
8310 #else
8311 void grcnfd(nparam, j, x, gradg, constr, cd)
8312 int nparam, j;
8313 double *x, *gradg;
8314 void(*constr)();
8315 void *cd;
8316 #endif
8317 {
8318  int i;
8319  double xi, delta;
8320 
8321  for (i = 0; i <= nparam - 1; i++)
8322  {
8323  xi = x[i];
8324  delta = DMAX1(glob_grd.udelta,
8325  glob_grd.rteps * DMAX1(1.e0, fabs(xi)));
8326  if (xi < 0.e0)
8327  delta = -delta;
8328  if (!(j != 1 || glob_prnt.iprint < 3))
8329  {
8330  /* formats are not set yet... */
8331  if (i == 0)
8332  fprintf(glob_prnt.io, "\tdelta(i)\t %22.14f\n", delta);
8333  if (i != 0)
8334  fprintf(glob_prnt.io, "\t\t\t %22.14f\n", delta);
8335  glob_prnt.ipd = 1;
8336  }
8337  x[i] = xi + delta;
8338  x_is_new = TRUE;
8339  (*constr)(nparam, j, x, &gradg[i], cd);
8340  gradg[i] = (gradg[i] - glob_grd.valnom) / delta;
8341  x[i] = xi;
8342  x_is_new = TRUE;
8343  }
8344  return;
8345 }
8346 /************************************************************/
8347 /* Utility functions used by CFSQP - */
8348 /* Available functions: */
8349 /* diagnl error estlam */
8350 /* colvec scaprd small */
8351 /* fool matrvc matrcp */
8352 /* nullvc resign sbout1 */
8353 /* sbout2 shift slope */
8354 /* fuscmp indexs element */
8355 /************************************************************/
8356 
8357 
8358 #ifdef __STDC__
8359 static void fool(double, double, double *);
8360 #else
8361 static void fool();
8362 #endif
8363 
8364 /************************************************************/
8365 /* Set a=diag*I, a diagonal matrix */
8366 /************************************************************/
8367 
8368 #ifdef __STDC__
8369 static void diagnl(int nrowa, double diag, double **a)
8370 #else
8371 static void diagnl(nrowa, diag, a)
8372 int nrowa;
8373 double **a, diag;
8374 #endif
8375 {
8376  int i, j;
8377 
8378  for (i = 1; i <= nrowa; i++)
8379  {
8380  for (j = i; j <= nrowa; j++)
8381  {
8382  a[i][j] = 0.e0;
8383  a[j][i] = 0.e0;
8384  }
8385  a[i][i] = diag;
8386  }
8387  return;
8388 }
8389 
8390 /***********************************************************/
8391 /* Display error messages */
8392 /***********************************************************/
8393 
8394 #ifdef __STDC__
8395 static void error(const char string[], int *inform)
8396 #else
8397 static void error(string, inform)
8398 const char string[];
8399 int *inform;
8400 #endif
8401 {
8402  if (glob_prnt.iprint > 0)
8403  fprintf(stderr, "%s\n", string);
8404  *inform = 7;
8405  return;
8406 }
8407 
8408 /***********************************************************/
8409 /* Compute an estimate of multipliers for updating */
8410 /* penalty parameter (nonlinear equality constraints) */
8411 /***********************************************************/
8412 
8413 #ifdef __STDC__
8414 static void
8415 estlam(int nparam, int neqn, int *ifail, double bigbnd, double **hess,
8416  double *cvec, double *a, double *b, struct _constraint *cs,
8417  double *psb, double *bl, double *bu, double *x)
8418 #else
8419 static void
8420 estlam(nparam, neqn, ifail, bigbnd, hess, cvec, a, b, cs, psb, bl, bu, x)
8421 int nparam, neqn, *ifail;
8422 double bigbnd, **hess, *cvec, *a, *b, *psb, *bl, *bu, *x;
8423 struct _constraint *cs;
8424 #endif
8426  int i, j, zero, one, lwar2, mnn, iout;
8427  double *ctemp;
8428 
8429  for (i = 1; i <= neqn; i++)
8430  {
8431  bl[i] = (-bigbnd);
8432  bu[i] = bigbnd;
8433  cvec[i] = scaprd(nparam, cs[i+glob_info.nnineq].grad, psb);
8434  x[i] = 0.e0;
8435  for (j = i; j <= neqn; j++)
8436  {
8437  hess[i][j] = scaprd(nparam, cs[i+glob_info.nnineq].grad,
8438  cs[j+glob_info.nnineq].grad);
8439  hess[j][i] = hess[i][j];
8440  }
8441  }
8442  zero = 0;
8443  one = 1;
8444  iw[1] = 1;
8445  mnn = 2 * neqn;
8446  ctemp = convert(hess, neqn, neqn);
8447  lwar2 = lenw - 1;
8448  iout = 6;
8449 
8450  ql0001_(&zero, &zero, &one, &neqn, &neqn, &mnn, (ctemp + 1), (cvec + 1),
8451  (a + 1), (b + 1), (bl + 1), (bu + 1), (x + 1), (w + 1), &iout, ifail,
8452  &zero, (w + 3), &lwar2, (iw + 1), &leniw, &glob_grd.epsmac);
8453 
8454  free_dv(ctemp);
8455  return;
8456 }
8457 
8458 /**************************************************************/
8459 /* Extract a column vector from a matrix */
8460 /**************************************************************/
8461 
8462 #ifdef __STDC__
8463 static double *colvec(double **a, int col, int nrows)
8464 #else
8465 static double *colvec(a, col, nrows)
8466 double **a;
8467 int col, nrows;
8468 #endif
8469 {
8470  double *temp;
8471  int i;
8472 
8473  temp = make_dv(nrows);
8474  for (i = 1;i <= nrows;i++)
8475  temp[i] = a[i][col];
8476  return temp;
8477 }
8478 
8479 /************************************************************/
8480 /* Compute the scalar product z=x'y */
8481 /************************************************************/
8482 
8483 #ifdef __STDC__
8484 static double scaprd(int n, double *x, double *y)
8485 #else
8486 static double scaprd(n, x, y)
8487 double *x, *y;
8488 int n;
8489 #endif
8491  int i;
8492  double z;
8493 
8494  z = 0.e0;
8495  for (i = 1;i <= n;i++)
8496  z = z + x[i] * y[i];
8497  return z;
8498 }
8499 
8500 /***********************************************************/
8501 /* Used by smallNumber() */
8502 /***********************************************************/
8503 
8504 #ifdef __STDC__
8505 static void fool(double x, double y, double *z)
8506 #else
8507 static void fool(x, y, z)
8508 double x, y, *z;
8509 #endif
8510 {
8511  *z = x * y + y;
8512  return;
8513 }
8514 
8515 /**********************************************************/
8516 /* Computes the machine precision */
8517 /**********************************************************/
8518 
8519 static double smallNumber()
8520 {
8521  double one, two, z, tsmall;
8522 
8523  one = 1.e0;
8524  two = 2.e0;
8525  tsmall = one;
8526  do
8527  {
8528  tsmall = tsmall / two;
8529  fool(tsmall, one, &z);
8530  }
8531  while (z > 1.e0);
8532  return tsmall*two*two;
8533 }
8534 
8535 /**********************************************************/
8536 /* Compares value with threshold to see if exceeds */
8537 /**********************************************************/
8538 
8539 #ifdef __STDC__
8540 static int fuscmp(double val, double thrshd)
8541 #else
8542 static int fuscmp(val, thrshd)
8543 double val, thrshd;
8544 #endif
8545 {
8546  int temp;
8547 
8548  if (fabs(val) <= thrshd)
8549  temp = FALSE;
8550  else
8551  temp = TRUE;
8552  return temp;
8553 }
8554 
8555 /**********************************************************/
8556 /* Find the residue of i with respect to nfs */
8557 /**********************************************************/
8558 
8559 #ifdef __STDC__
8560 static int indexs(int i, int nfs)
8561 #else
8562 static int indexs(i, nfs)
8563 int i, nfs;
8564 #endif
8565 {
8566  int mm = i;
8567 
8568  while (mm > nfs)
8569  mm -= nfs;
8570  return mm;
8571 }
8572 
8573 /*********************************************************/
8574 /* Copies matrix a to matrix b */
8575 /*********************************************************/
8576 
8577 #ifdef __STDC__
8578 static void matrcp(int ndima, double **a, int ndimb, double **b)
8579 #else
8580 static void matrcp(ndima, a, ndimb, b)
8581 double **a, **b;
8583 #endif
8584 {
8585  int i, j;
8586 
8587  for (i = 1; i <= ndima; i++)
8588  for (j = 1; j <= ndima; j++)
8589  b[i][j] = a[i][j];
8590  if (ndimb <= ndima)
8591  return;
8592  for (i = 1; i <= ndimb; i++)
8593  {
8594  b[ndimb][i] = 0.e0;
8595  b[i][ndimb] = 0.e0;
8596  }
8597  return;
8598 }
8599 
8600 /*******************************************************/
8601 /* Computes y=ax */
8602 /*******************************************************/
8603 
8604 #ifdef __STDC__
8605 static void matrvc(int la, int na, double **a, double *x, double *y)
8606 #else
8607 static void matrvc(la, na, a, x, y)
8608 double **a, *x, *y;
8609 int la, na;
8610 #endif
8611 {
8612  int i, j;
8613  double yi;
8614 
8615  for (i = 1; i <= la; i++)
8616  {
8617  yi = 0.e0;
8618  for (j = 1; j <= na; j++)
8619  yi = yi + a[i][j] * x[j];
8620  y[i] = yi;
8621  }
8622  return;
8623 }
8624 
8625 /******************************************************/
8626 /* Set x=0 */
8627 /******************************************************/
8628 
8629 #ifdef __STDC__
8630 static void nullvc(int nparam, double *x)
8631 #else
8632 static void nullvc(nparam, x)
8633 int nparam;
8634 double *x;
8635 #endif
8636 {
8637  int i;
8638 
8639  for (i = 1; i <= nparam; i++)
8640  x[i] = 0.e0;
8641  return;
8642 }
8643 
8644 /*********************************************************/
8645 /* job1=10: g*signeq, job1=11: gradg*signeq, */
8646 /* job1=12: job1=10&11 */
8647 /* job1=20: do not change sign */
8648 /* job2=10: psf, job2=11: grdpsf, */
8649 /* job2=12: job2=10&11 */
8650 /* job2=20: do not change sign */
8651 /*********************************************************/
8652 
8653 #ifdef __STDC__
8654 static void
8655 resign(int n, int neqn, double *psf, double *grdpsf, double *penp,
8656  struct _constraint *cs, double *signeq, int job1, int job2)
8657 #else
8658 static void
8659 resign(n, neqn, psf, grdpsf, penp, cs, signeq, job1, job2)
8660 int job1, job2, n, neqn;
8661 double *psf, *grdpsf, *penp, *signeq;
8662 struct _constraint *cs;
8663 #endif
8664 {
8665  int i, j, nineq;
8666 
8667  nineq = glob_info.nnineq;
8668  if (job2 == 10 || job2 == 12)
8669  *psf = 0.e0;
8670  for (i = 1; i <= neqn; i++)
8671  {
8672  if (job1 == 10 || job1 == 12)
8673  cs[i+nineq].val =
8674  signeq[i] * cs[i+nineq].val;
8675  if (job2 == 10 || job2 == 12)
8676  *psf = *psf + cs[i+nineq].val * penp[i];
8677  if (job1 == 10 || job1 == 20)
8678  continue;
8679  for (j = 1; j <= n; j++)
8680  cs[i+nineq].grad[j] = cs[i+nineq].grad[j] * signeq[i];
8681  }
8682  if (job2 == 10 || job2 == 20)
8683  return;
8684  nullvc(n, grdpsf);
8685  for (i = 1; i <= n; i++)
8686  for (j = 1; j <= neqn; j++)
8687  grdpsf[i] = grdpsf[i] + cs[j+nineq].grad[i] * penp[j];
8688  return;
8689 }
8690 
8691 /**********************************************************/
8692 /* Write output to file */
8693 /**********************************************************/
8694 
8695 #ifdef __STDC__
8696 static void
8697 sbout1(FILE *io, int n, const char *s1, double z, double *z1, int job, int level)
8698 #else
8699 static void sbout1(io, n, s1, z, z1, job, level)
8700 FILE *io;
8701 int n, job, level;
8702 double z, *z1;
8703 const char *s1;
8704 #endif
8705 {
8706  int j;
8707 
8708  if (job != 2)
8709  {
8710  if (level == 1)
8711  fprintf(io, " %s\t %22.14e\n", s1, z);
8712  if (level == 2)
8713  fprintf(io, "\t\t\t %s\t %22.14e\n", s1, z);
8714  return;
8715  }
8716  if (n == 0)
8717  return;
8718  if (level == 1)
8719  fprintf(io, " %s\t %22.14e\n", s1, z1[1]);
8720  if (level == 2)
8721  fprintf(io, "\t\t\t %s\t %22.14e\n", s1, z1[1]);
8722  for (j = 2; j <= n; j++)
8723  {
8724  if (level == 1)
8725  fprintf(io, " \t\t\t %22.14e\n", z1[j]);
8726  if (level == 2)
8727  fprintf(io, " \t\t\t\t\t\t %22.14e\n", z1[j]);
8728  }
8729  return;
8730 }
8731 
8732 /*********************************************************/
8733 /* Write output to file */
8734 /*********************************************************/
8735 
8736 #ifdef __STDC__
8737 static void
8738 sbout2(FILE *io, int n, int i, const char *s1, const char *s2, double *z)
8739 #else
8740 static void sbout2(io, n, i, s1, s2, z)
8741 FILE *io;
8742 int n, i;
8743 double *z;
8744 const char *s1, *s2;
8745 #endif
8746 {
8747  int j;
8748 
8749  fprintf(io, "\t\t\t %8s %5d %1s\t %22.14e\n", s1, i, s2, z[1]);
8750  for (j = 2; j <= n; j++)
8751  fprintf(io, "\t\t\t\t\t\t %22.14e\n", z[j]);
8752  return;
8753 }
8754 
8755 /*********************************************************/
8756 /* Extract ii from iact and push in front */
8757 /*********************************************************/
8758 
8759 #ifdef __STDC__
8760 static void shift(int n, int ii, int *iact)
8761 #else
8762 static void shift(n, ii, iact)
8763 int n, ii, *iact;
8764 #endif
8765 {
8766  int j, k;
8767 
8768  if (ii == iact[1])
8769  return;
8770  for (j = 1; j <= n; j++)
8771  {
8772  if (ii != iact[j])
8773  continue;
8774  for (k = j; k >= 2; k--)
8775  iact[k] = iact[k-1];
8776  break;
8777  }
8778  if (n != 0)
8779  iact[1] = ii;
8780  return;
8781 }
8782 
8783 /****************************************************************/
8784 /* job=0 : Compute the generalized gradient of the minimax */
8785 /* job=1 : Compute rhog in mode = 1 */
8786 /****************************************************************/
8787 
8788 #ifdef __STDC__
8789 static double
8790 slope(int nob, int nobL, int neqn, int nparam, int feasb,
8791  struct _objective *ob, double *grdpsf, double *x, double *y,
8792  double fmax, double theta, int job, double *prev, int old)
8793 #else
8794 static double
8795 slope(nob, nobL, neqn, nparam, feasb, ob, grdpsf, x, y, fmax, theta, job,
8796  prev, old)
8797 int nob, nobL, neqn, nparam, job, feasb, old;
8798 double fmax, theta;
8799 double *grdpsf, *x, *y, * prev;
8800 struct _objective *ob;
8801 #endif
8802 {
8803  int i;
8804  double slope1, rhs, rhog, grdftx, grdfty, diff, grpstx, grpsty;
8805  double tslope;
8806 
8807  tslope = -bgbnd;
8808  if (feasb && nob == 0)
8809  tslope = 0.e0;
8810  if (neqn == 0 || !feasb)
8811  {
8812  grpstx = 0.e0;
8813  grpsty = 0.e0;
8814  }
8815  else
8816  {
8817  grpstx = scaprd(nparam, grdpsf, x);
8818  grpsty = scaprd(nparam, grdpsf, y);
8819  }
8820  for (i = 1; i <= nob; i++)
8821  {
8822  if (old)
8823  slope1 = prev[i] + scaprd(nparam, ob[i].grad, x);
8824  else
8825  slope1 = ob[i].val + scaprd(nparam, ob[i].grad, x);
8826  tslope = DMAX1(tslope, slope1);
8827  if (nobL != nob)
8828  tslope = DMAX1(tslope, -slope1);
8829  }
8830  tslope = tslope - fmax - grpstx;
8831  if (job == 0)
8832  return tslope;
8833  rhs = theta * tslope + fmax;
8834  rhog = 1.e0;
8835  for (i = 1; i <= nob; i++)
8836  {
8837  grdftx = scaprd(nparam, ob[i].grad, x) - grpstx;
8838  grdfty = scaprd(nparam, ob[i].grad, y) - grpsty;
8839  diff = grdfty - grdftx;
8840  if (diff <= 0.e0)
8841  continue;
8842  rhog = DMIN1(rhog, (rhs - ob[i].val - grdftx) / diff);
8843  if (nobL != nob)
8844  rhog = DMIN1(rhog, -(rhs + ob[i].val + grdftx) / diff);
8845  }
8846  tslope = rhog;
8847  return tslope;
8848 }
8849 
8850 /************************************************************/
8851 /* Determine whether index is in set */
8852 /************************************************************/
8853 
8854 #ifdef __STDC__
8855 static int element(int *set, int length, int index)
8856 #else
8857 static int element(set, length, index)
8858 int *set;
8859 int length, index;
8860 #endif
8861 {
8862  int i, temp;
8863 
8864  temp = 0;
8865  for (i = 1; i <= length; i++)
8866  {
8867  if (set[i] == 0)
8868  break;
8869  if (set[i] == index)
8870  {
8871  temp = 1;
8872  return temp;
8873  }
8874  }
8875  return temp;
8876 }
8877 /*************************************************************/
8878 /* Memory allocation utilities for CFSQP */
8879 /* */
8880 /* All vectors and matrices are intended to */
8881 /* be subscripted from 1 to n, NOT 0 to n-1. */
8882 /* The addreses returned assume this convention. */
8883 /*************************************************************/
8884 
8885 
8886 /*************************************************************/
8887 /* Create double precision vector */
8888 /*************************************************************/
8889 
8890 #ifdef __STDC__
8891 static double *
8892 make_dv(int len)
8893 #else
8894 static double *
8895 make_dv(len)
8896 int len;
8897 #endif
8898 {
8899  double *v;
8900 
8901  if (!len)
8902  len = 1;
8903  v = (double *)calloc(len, sizeof(double));
8904  if (!v)
8905  {
8906  fprintf(stderr, "Run-time error in make_dv");
8907  exit(1);
8908  }
8909  return --v;
8910 }
8911 
8912 /*************************************************************/
8913 /* Create integer vector */
8914 /*************************************************************/
8915 
8916 #ifdef __STDC__
8917 static int *
8918 make_iv(int len)
8919 #else
8920 static int *
8921 make_iv(len)
8922 int len;
8923 #endif
8924 {
8925  int *v;
8926 
8927  if (!len)
8928  len = 1;
8929  v = (int *)calloc(len, sizeof(int));
8930  if (!v)
8931  {
8932  fprintf(stderr, "Run-time error in make_iv");
8933  exit(1);
8934  }
8935  return --v;
8936 }
8937 
8938 /*************************************************************/
8939 /* Create a double precision matrix */
8940 /*************************************************************/
8941 
8942 #ifdef __STDC__
8943 static double **
8944 make_dm(int rows, int cols)
8945 #else
8946 static double **
8947 make_dm(rows, cols)
8948 int rows, cols;
8949 #endif
8950 {
8951  double **temp;
8952  int i;
8953 
8954  if (rows == 0)
8955  rows = 1;
8956  if (cols == 0)
8957  cols = 1;
8958  temp = (double **)calloc(rows, sizeof(double *));
8959  if (!temp)
8960  {
8961  fprintf(stderr, "Run-time error in make_dm");
8962  exit(1);
8963  }
8964  temp--;
8965  for (i = 1; i <= rows; i++)
8966  {
8967  temp[i] = (double *)calloc(cols, sizeof(double));
8968  if (!temp[i])
8969  {
8970  fprintf(stderr, "Run-time error in make_dm");
8971  exit(1);
8972  }
8973  temp[i]--;
8974  }
8975  return temp;
8976 }
8977 
8978 /*************************************************************/
8979 /* Free a double precision vector */
8980 /*************************************************************/
8981 
8982 #ifdef __STDC__
8983 static void
8984 free_dv(double *v)
8985 #else
8986 static void
8987 free_dv(v)
8988 double *v;
8989 #endif
8990 {
8991  free((char *)(v + 1));
8992 }
8993 
8994 /*************************************************************/
8995 /* Free an integer vector */
8996 /*************************************************************/
8997 
8998 #ifdef __STDC__
8999 static void
9000 free_iv(int *v)
9001 #else
9002 static void
9003 free_iv(v)
9004 int *v;
9005 #endif
9006 {
9007  free((char *)(v + 1));
9008 }
9009 
9010 /*************************************************************/
9011 /* Free a double precision matrix */
9012 /*************************************************************/
9013 
9014 #ifdef __STDC__
9015 static void
9016 free_dm(double **m, int rows)
9017 #else
9018 static void
9019 free_dm(m, rows)
9020 double **m;
9021 int rows;
9022 #endif
9023 {
9024  int i;
9025 
9026  if (!rows)
9027  rows = 1;
9028  for (i = 1; i <= rows; i++)
9029  free((char *)(m[i] + 1));
9030  free((char *)(m + 1));
9031 }
9032 
9033 /*************************************************************/
9034 /* Converts matrix a into a form that can easily be */
9035 /* passed to a FORTRAN subroutine. */
9036 /*************************************************************/
9037 
9038 #ifdef __STDC__
9039 static double *
9040 convert(double **a, int m, int n)
9041 #else
9042 static double *
9043 convert(a, m, n)
9044 double **a;
9045 int m, n;
9046 #endif
9047 {
9048  double *temp;
9049  int i, j;
9050 
9051  temp = make_dv(m * n);
9052 
9053  for (i = 1; i <= n; i++) /* loop through columns */
9054  for (j = 1; j <= m; j++) /* loop through row */
9055  temp[(m*(i-1)+j)] = a[j][i];
9056 
9057  return temp;
9058 }
9059 
9060 
9061 // Wavelets ----------------------------------------------------------------
9062 
9063 void wtn(double a[], unsigned long nn[], int ndim, int isign,
9064  void(*wtstep)(double [], unsigned long, int))
9065 {
9066  unsigned long i1, i2, i3, k, n, nnew, nprev = 1, nt, ntot = 1;
9067  int idim;
9068 
9069  for (idim = 1;idim <= ndim;idim++)
9070  ntot *= nn[idim];
9071  std::vector<double> buffer(ntot);
9072  auto *wksp= buffer.data()-1;
9073  for (idim = 1;idim <= ndim;idim++)
9074  {
9075  n = nn[idim];
9076  nnew = n * nprev;
9077  if (n > 4)
9078  {
9079  for (i2 = 0;i2 < ntot;i2 += nnew)
9080  {
9081  for (i1 = 1;i1 <= nprev;i1++)
9082  {
9083  for (i3 = i1 + i2, k = 1;k <= n;++k, i3 += nprev)
9084  wksp[k] = a[i3];
9085  if (isign >= 0)
9086  {
9087  for (nt = n;nt >= 4;nt >>= 1)
9088  (*wtstep)(wksp, nt, isign);
9089  }
9090  else
9091  {
9092  for (nt = 4;nt <= n;nt <<= 1)
9093  (*wtstep)(wksp, nt, isign);
9094  }
9095 
9096  for (i3 = i1 + i2, k = 1;k <= n;++k, i3 += nprev)
9097  a[i3] = wksp[k];
9098  }
9099  }
9100  }
9101  nprev = nnew;
9102  }
9103 }
9104 
9105 typedef struct
9106 {
9107  unsigned int ncof, ioff, joff;
9108  double *cc, *cr;
9109 }
9110 wavefilt;
9111 
9112 wavefilt wfilt;
9113 
9114 void pwtset(int n)
9115 {
9116  int k;
9117  float sig = -1.0;
9118  static double c2[3] =
9119  {
9120  0.0, 0.707106781186547, 0.707106781186547
9121  };
9122  static double c4[5] =
9123  {
9124  0.0, 0.4829629131445341, 0.8365163037378079,
9125  0.2241438680420134, -0.1294095225512604
9126  };
9127  static double c12[13] =
9128  {
9129  0.0, 0.111540743350, 0.494623890398, 0.751133908021,
9130  0.315250351709, -0.226264693965, -0.129766867567,
9131  0.097501605587, 0.027522865530, -0.031582039318,
9132  0.000553842201, 0.004777257511, -0.001077301085
9133  };
9134  static double c20[21] =
9135  {
9136  0.0, 0.026670057901, 0.188176800078, 0.527201188932,
9137  0.688459039454, 0.281172343661, -0.249846424327,
9138  -0.195946274377, 0.127369340336, 0.093057364604,
9139  -0.071394147166, -0.029457536822, 0.033212674059,
9140  0.003606553567, -0.010733175483, 0.001395351747,
9141  0.001992405295, -0.000685856695, -0.000116466855,
9142  0.000093588670, -0.000013264203
9143  };
9144  static double c2r[2], c4r[5], c12r[13], c20r[21];
9145 
9146  wfilt.ncof = n;
9147  if (n == 2)
9148  {
9149  wfilt.cc = c2;
9150  wfilt.cr = c2r;
9151  }
9152  else if (n == 4)
9153  {
9154  wfilt.cc = c4;
9155  wfilt.cr = c4r;
9156  }
9157  else if (n == 12)
9158  {
9159  wfilt.cc = c12;
9160  wfilt.cr = c12r;
9161  }
9162  else if (n == 20)
9163  {
9164  wfilt.cc = c20;
9165  wfilt.cr = c20r;
9166  }
9167  else
9168  nrerror("unimplemented value n in pwtset");
9169  for (k = 1;k <= n;k++)
9170  {
9171  wfilt.cr[wfilt.ncof+1-k] = sig * wfilt.cc[k];
9172  sig = -sig;
9173  }
9174  wfilt.ioff = wfilt.joff = -(n >> 1);
9175 }
9176 
9177 void pwt(double a[], unsigned long n, int isign)
9178 {
9179  double ai, ai1;
9180  unsigned long i, ii, jf, jr, k, n1, ni, nj, nh, nmod;
9181 
9182  if (n < 4)
9183  return;
9184  std::vector<double> buffer(n, 0.0);
9185  auto *wksp= buffer.data()-1;
9186  nmod = wfilt.ncof * n;
9187  n1 = n - 1;
9188  nh = n >> 1;
9189  if (isign >= 0)
9190  {
9191  for (ii = 1, i = 1;i <= n;i += 2, ii++)
9192  {
9193  ni = i + nmod + wfilt.ioff;
9194  nj = i + nmod + wfilt.joff;
9195  double &aux1=wksp[ii];
9196  double &aux2=wksp[ii+nh];
9197  unsigned long kmax=4*(wfilt.ncof/4);
9198  // Loop unrolling (every 4 coefficients)
9199  for (k = 1;k <= kmax;k+=4)
9200  {
9201  unsigned long k_1=k+1;
9202  unsigned long k_2=k+2;
9203  unsigned long k_3=k+3;
9204  jf = n1 & (ni + k);
9205  jr = n1 & (nj + k);
9206  aux1 += wfilt.cc[k] * a[jf+1];
9207  aux2 += wfilt.cr[k] * a[jr+1];
9208  unsigned long jf_1 = n1 & (ni + k_1);
9209  unsigned long jr_1 = n1 & (nj + k_1);
9210  aux1 += wfilt.cc[k_1] * a[jf_1+1];
9211  aux2 += wfilt.cr[k_1] * a[jr_1+1];
9212  unsigned long jf_2 = n1 & (ni + k_2);
9213  unsigned long jr_2 = n1 & (nj + k_2);
9214  aux1 += wfilt.cc[k_2] * a[jf_2+1];
9215  aux2 += wfilt.cr[k_2] * a[jr_2+1];
9216  unsigned long jf_3 = n1 & (ni + k_3);
9217  unsigned long jr_3 = n1 & (nj + k_3);
9218  aux1 += wfilt.cc[k_3] * a[jf_3+1];
9219  aux2 += wfilt.cr[k_3] * a[jr_3+1];
9220  }
9221  // The rest of coefficients
9222  for (k = kmax+1;k <= wfilt.ncof;++k)
9223  {
9224  jf = n1 & (ni + k);
9225  jr = n1 & (nj + k);
9226  aux1 += wfilt.cc[k] * a[jf+1];
9227  aux2 += wfilt.cr[k] * a[jr+1];
9228  }
9229  }
9230  }
9231  else
9232  {
9233  for (ii = 1, i = 1;i <= n;i += 2, ii++)
9234  {
9235  ai = a[ii];
9236  ai1 = a[ii+nh];
9237  ni = i + nmod + wfilt.ioff;
9238  nj = i + nmod + wfilt.joff;
9239  for (k = 1;k <= wfilt.ncof;k++)
9240  {
9241  jf = (n1 & (ni + k)) + 1;
9242  jr = (n1 & (nj + k)) + 1;
9243  wksp[jf] += wfilt.cc[k] * ai;
9244  wksp[jr] += wfilt.cr[k] * ai1;
9245  }
9246  }
9247  }
9248  memcpy(&a[1],&wksp[1],n*sizeof(double));
9249 }
9250 
9251 /* Gamma function ---------------------------------------------------------- */
9252 #define ITMAX 100
9253 #define EPS 3.0e-7
9254 
9255 void gser(double *gamser, double a, double x, double *gln)
9256 {
9257  int n;
9258  double sum, del, ap;
9259 
9260  *gln = gammln(a);
9261  if (x <= 0.0)
9262  {
9263  if (x < 0.0)
9264  nrerror("x less than 0 in routine gser");
9265  *gamser = 0.0;
9266  return;
9267  }
9268  else
9269  {
9270  ap = a;
9271  del = sum = 1.0 / a;
9272  for (n = 1;n <= ITMAX;n++)
9273  {
9274  ++ap;
9275  del *= x / ap;
9276  sum += del;
9277  if (fabs(del) < fabs(sum)*EPS)
9278  {
9279  *gamser = sum * exp(-x + a * log(x) - (*gln));
9280  return;
9281  }
9282  }
9283  nrerror("a too large, ITMAX too small in routine gser");
9284  return;
9285  }
9286 }
9287 #undef ITMAX
9288 #undef EPS
9289 
9290 #define ITMAX 100
9291 #define EPS 3.0e-7
9292 #define FPMIN 1.0e-30
9293 
9294 void gcf(double *gammcf, double a, double x, double *gln)
9295 {
9296  int i;
9297  double an, b, c, d, del, h;
9298 
9299  *gln = gammln(a);
9300  b = x + 1.0 - a;
9301  c = 1.0 / FPMIN;
9302  d = 1.0 / b;
9303  h = d;
9304  for (i = 1;i <= ITMAX;i++)
9305  {
9306  an = -i * (i - a);
9307  b += 2.0;
9308  d = an * d + b;
9309  if (fabs(d) < FPMIN)
9310  d = FPMIN;
9311  c = b + an / c;
9312  if (fabs(c) < FPMIN)
9313  c = FPMIN;
9314  d = 1.0 / d;
9315  del = d * c;
9316  h *= del;
9317  if (fabs(del - 1.0) < EPS)
9318  break;
9319  }
9320  if (i > ITMAX)
9321  nrerror("a too large, ITMAX too small in gcf");
9322  *gammcf = exp(-x + a * log(x) - (*gln)) * h;
9323 }
9324 #undef ITMAX
9325 #undef EPS
9326 #undef FPMIN
9327 
9328 double gammp(double a, double x)
9329 {
9330  double gamser, gammcf, gln;
9331 
9332  if (x < 0.0 || a <= 0.0)
9333  nrerror("Invalid arguments in routine gammp");
9334  if (x < (a + 1.0))
9335  {
9336  gser(&gamser, a, x, &gln);
9337  return gamser;
9338  }
9339  else
9340  {
9341  gcf(&gammcf, a, x, &gln);
9342  return 1.0 -gammcf;
9343  }
9344 }
9345 
9346 /* Solving linear equation systems via Cholesky ---------------------------- */
9347 void choldc(double *a, int n, double *p)
9348 {
9349  int i, j, k;
9350  double sum;
9351 
9352  for (i = 1;i <= n;i++)
9353  {
9354  for (j = i;j <= n;j++)
9355  {
9356  for (sum = a[i*n+j], k = i - 1;k >= 1;k--)
9357  sum -= a[i*n+k] * a[j*n+k];
9358  if (i == j)
9359  {
9360  if (sum <= 0.0)
9361  nrerror("choldc failed");
9362  p[i] = sqrt(sum);
9363  }
9364  else
9365  a[j*n+i] = sum / p[i];
9366  }
9367  }
9368 }
9369 
9370 void cholsl(double *a, int n, double *p, double *b, double *x)
9371 {
9372  int i, k;
9373  double sum;
9374 
9375  for (i = 1;i <= n;i++)
9376  {
9377  for (sum = b[i], k = i - 1;k >= 1;k--)
9378  sum -= a[i*n+k] * x[k];
9379  x[i] = sum / p[i];
9380  }
9381  for (i = n;i >= 1;i--)
9382  {
9383  for (sum = x[i], k = i + 1;k <= n;k++)
9384  sum -= a[k*n+i] * x[k];
9385  x[i] = sum / p[i];
9386  }
9387 }
9388 
9389 /* Polynomial interpolation ------------------------------------------------ */
9390 void polint(double *xa, double *ya, int n, double x, double &y, double &dy)
9391 {
9392  int i, m, ns = 1;
9393  double den, dif, dift, ho, hp, w;
9394  dif = fabs(x - xa[1]);
9395  std::vector<double> buffer(2*n);
9396  auto *c= buffer.data()-1;
9397  auto *d= c + n;
9398  for (i = 1;i <= n;i++)
9399  {
9400  if ((dift = fabs(x - xa[i])) < dif)
9401  {
9402  ns = i;
9403  dif = dift;
9404  }
9405  c[i] = ya[i];
9406  d[i] = ya[i];
9407  }
9408  y = ya[ns--];
9409  for (m = 1;m < n;m++)
9410  {
9411  for (i = 1;i <= n - m;i++)
9412  {
9413  ho = xa[i] - x;
9414  hp = xa[i+m] - x;
9415  w = c[i+1] - d[i];
9416  if ((den = ho - hp) == 0.0)
9417  {
9418  nrerror("error in routine polint\n");
9419  }
9420  den = w / den;
9421  d[i] = hp * den;
9422  c[i] = ho * den;
9423  }
9424  y += (dy = (2 * ns < (n - m) ? c[ns+1] : d[ns--]));
9425  }
9426 }
doublereal d__3
double bli
goto L570
double grdftd
void cholsl(double *a, int n, double *p, double *b, double *x)
doublereal d__1
#define GOLD
int * mesh_pts1
else display
double xi
int nrows
double bessi0(double x)
int ql0001_(m, me, mmax, n, nmax, mnn, c, d, a, b, xl, xu, x, u, iout, ifail, iprint, war, lwar, iwar, liwar, eps1) integer *m
int * nmax
double gmax
int ql0002_()
double * bj
void svbksb(double *u, double *w, double *v, int m, int n, double *b, double *x)
#define XMIPP_MAX(x, y)
Definition: xmipp_macros.h:193
VOID(* C_fp)()
free_dv(w)
goto L740
struct Tglob_info glob_info
glob_info ncsipl
double doublereal
void mnbrak(double *ax, double *bx, double *cx, double *fa, double *fb, double *fc, double(*func)(double *, void *), void *prm, int ncom, double *pcom, double *xicom)
#define cmache_1
#define DMAX1(a, b)
doublereal * war
double bessi1(double x)
double dhd
double fmxl
VOID H_f
double betai(double a, double b, double x)
#define CONSTR
void nineq
#define IC2
glob_log d0_is0
short int shortint
double * psb
ftnint * inrecl
int * mmax
glob_info ncsipn
void wtn(double a[], unsigned long nn[], int ndim, int isign, void(*wtstep)(double [], unsigned long, int))
integer(* I_fp)()
goto L549
struct _violation * sip_viol
double * gm
#define ZEPS
goto L930
double grdgd0
void grobfd()
void ksone(double data[], int n, double(*func)(double), double *d, double *prob)
#define MAXIT
double sign
double probks(double alam)
doublereal * c
doublereal * g
double * bl
double d0nm
goto L775
#define MAX(a, b)
void * cd
#define EPS
void svdcmp(double *U, int Lines, int Columns, double *W, double *V)
double rho
double eta
doublereal * xl
double ostep
doublereal * grad
double brent(double ax, double bx, double cx, double(*func)(double *, void *), void *prm, double tol, double *xmin, int ncom, double *pcom, double *xicom)
VOID Z_f
void sqrt(Image< double > &op)
double tolfea
#define TOL
double x0i
#define FALSE_
HBITMAP buffer
Definition: svm-toy.cpp:37
static double * y
glob_grd rteps
void(*)(*)(*) gradob()
float del
glob_log rhol_is1
double * grdpsf
int ndima
sbout1(glob_prnt.io, nparam, "multipliers for x ", dummy, param->mult, 2, 2)
double Cbar
diagnl(nqpram, eta, hess1)
#define TRUE_
void choldc(double *a, int n, double *p)
else temp3
double * tempv
static void nparam
goto L640
int * iskip
int nnlsWght(int N, int M, double *A, double *b, double *weight)
doublereal * w
double betacf(double a, double b, double x)
doublereal * xu
double udelta
void nrerror(const char error_text[])
ftnint * innum
void nfsr
double gLgeps
void * mesh_pts
void(*)(*)(*)(*) gradcn()
ftnint * innamed
double epseqn
void gcf(double *gammcf, double a, double x, double *gln)
int * istore
char * address
#define M3
glob_prnt iter
dealloc(nineq, neq, signeq, indxcn, indxob, cs, param)
static void nnl
double fmax1
cmache_1 eps
double * atemp
integer * liwar
shortlogical(* K_fp)()
double * gamma
#define XMIN
void _nnls_g1(double a, double b, double *cterm, double *sterm, double *sig)
long Long
free_iv(iw)
doublereal(*)(* E_fp)()
i<=ncnstr;i++) cs[i].mult=0.e0;if(nfsip) for(i=1;i<=nob;i++) { ob[i].mult=0.e0;ob[i].mult_L=0.e0;} for(i=1;i<=nqpram;i++) { ii=k+i;if(clamda[ii]==0.e0 &&clamda[ii+nqpram]==0.e0) continue;else if(clamda[ii] !=0.e0) clamda[ii]=-clamda[ii];else clamda[ii]=clamda[ii+nqpram];} nqnp=nqpram+ncnstr;for(i=1;i<=nqpram;i++) param-> mult[i]
double * di
double gi
integer * iprint
long ftnlen
void nineqn
doublereal * x
matrvc(nparam, nparam, hess, di, w)
static void * iskp
double chebev(double a, double b, double c[], int m, double x)
#define i
nullvc(nparam, grdpsf)
double bui
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
matrcp(nparam, hess, nparam+1, hess1)
double epskt
double fMp
doublereal * d
return mm
double ** hess
#define F1DIM(x, f)
double dmx
#define SQR(a)
double theta
double temp2
float cfsqpreal
double * bu
#define RM2
double vv
goto L440
cfsqp1(miter, nparam, nob, nobL, nfsip1, nineqn, neq, neqn, ncsipl1, ncsipn1, mesh_pts1, ncnstr, nctotl, nrowa, feasb, epskt, epseqn, indxob, indxcn, param, cs, ob, signeq, obj, constr, gradob, gradcn)
#define cl(i, j)
glob_log first
double fnow
void miter
#define M2
doublereal * b
double dnm1
void nf
double psf
int Linfty
goto L860
int ntot
#define M1
double ** phess
void linmin(double *p, double *xi, int n, double &fret, double(*func)(double *, void *), void *prm)
double * htemp
long flag
double v1
void log(Image< double > &op)
struct _constraint * cs
double SNECV
double delta_s
double bigbnd
double * lambda
void cfsqp(nparam, nf, nfsr, nineqn, nineq, neqn, neq, ncsrl, ncsrn, mesh_pts, mode, iprint, miter, inform, bigbnd, eps, epseqn, udelta, bl, bu, x, f, g, lambda, obj, constr, gradob, gradcn, cd) int nparam
struct Tglob_prnt glob_prnt
double signgj
integer * iact
if(fabs(c[*nmax+ *nmax *c_dim1])==0.e0)
viol index
viol type
double prod
glob_log local
double * gradg
static void nqpram
int in
double * f
doublereal(* D_fp)()
int integer
double bessi1_5(double x)
#define NRSIGN(a, b)
double * cvec
goto L170
double * penp
#define OBJECT
double fmult
double thrshd
double fii
integer * iwar
void indexx(int n, double arrin[], int indx[])
double prod1
long ftnint
double dnm
#define FALSE
int * indxcn
void ncsrn
double * ctemp
Vardesc ** vars
goto L910
double sktnom
double * signeq
void neqn
double dx
double scvneq
long int logical
#define RM1
double gammd
double vk
void beschb(double x, double *gam1, double *gam2, double *gampl, double *gammi)
#define ITMAX
static void * ncf
double psfnew
glob_prnt io
free((char *) ob)
void powell(double *p, double *xi, int n, double ftol, int &iter, double &fret, double(*func)(double *, void *), void *prm, bool show)
void polint(double *xa, double *ya, int n, double x, double &y, double &dy)
double z
__host__ __device__ float length(float2 v)
glob_prnt ipd
double * psmu
ftnint * inopen
double gasdev(int *idum)
int feasbl
void ncsrl
void mode
goto L880
double dummy
double gammp(double a, double x)
#define GLIMIT
for(j=1;j<=i__1;++j)
#define SHFT(a, b, c, d)
double * gradf
double etad
#define SVDMAXITER
glob_info tot_actf_sip
goto L800
int ni
void sort(struct DCEL_T *dcel)
Definition: sorting.cpp:18
#define NUSE2
void bessjy(double x, double xnu, double *rj, double *ry, double *rjp, double *ryp)
double fprev
int * me
double * d0
double tolfe
doublereal * vsmall
#define j
int leniw
struct _violation _viol
double steps
#define IA2
double bessj1_5(double x)
VOID(* Z_fp)()
struct _parameter _param
#define DMIN1(a, b)
ftnint * innrec
double bessi2_5(double x)
double g_max
struct _parameter * param
int * meq
int ndimb
goto L70
glob_info nfsip
glob_log get_ne_mult
static void ncn
cfsqpcomplex cc
#define len
double * hd
double tdev(double nu, int *idum)
double bgbnd
void error(char *s)
Definition: tools.cpp:107
double bessj3_5(double x)
doublereal d__2
logical(* L_fp)()
int(* S_fp)()
struct Tglob_log glob_log
doublereal * eps1
shortint(* J_fp)()
double grdfd1
integer * iout
int * indxob
double objeps
#define FPMIN
double grdgd1
int nnls(double *a, int m, int n, double *b, double *x, double *rnorm, double *wp, double *zzp, int *indexp)
doublecomplex z
#define TINY
void pwtset(int n)
#define IA3
int * mnn
double ran1(int *idum)
void neq
int nstop
void(*)(*) constr()
free_dm(hess, nparam)
int lenw
#define NUSE1
doublereal E_f
glob_prnt iter_mod
#define IC1
goto L710
struct _objective * ob
double fnext
int feasb
glob_prnt initvl
int prnt
#define min(a, b)
double fM
#define TRUE
dqp(nparam, nqprm0, nob, nobL, nfsip, nineqn, neq, neqn, nn, ncsipl, ncsipn, ncnstr, nctot0, nrowa0, nineqn, &infoqp, param, di, feasb, ob, *fmax, grdpsf, cs, a, cvec, bl, bu, clamda, hess, hess1, di, vv, 0)
#define IC3
void * inform
int * iw_hold
static void nctotl
static void * modem
doublereal d__4
cfsqpreal(* R_fp)()
#define SIGN(a, b)
ncallg glob_info ncallg
doublereal * u
double rhol
doublereal eps
struct Tglob_grd glob_grd
double * clamda
void gser(double *gamser, double a, double x, double *gln)
fprintf(glob_prnt.io, "\)
void(* obj)()
double * adummy
glob_info ncallf
double bessi3_5(double x)
ProgClassifyCL2D * prm
double bessi0_5(double x)
integer * ifail
struct _violation * viol
int idum
goto L550
int _nnls_h12(int mode, int lpivot, int l1, int m, double *u, int u_dim1, double *up, double *cm, int ice, int icv, int ncv)
glob_info modec
double bessi2(double x)
double d0norm
double objrep
integer * lwar
VOID(* H_fp)()
#define PI
Definition: tools.h:43
double dbar
struct Tcmache cmache_
int x_is_new
double dnmtil
double v0
double ** hess1
double * span
size_t fact(int num)
double epsilon
#define NONE
double bessj0(double x)
void pwt(double a[], unsigned long n, int isign)
#define VOID
VOID C_f
#define CGOLD
double fmax
#define abs(x)
double Pythag(double a, double b)
short int shortlogical
int * n
doublereal * a
double bessi3(double x)
#define IA1
double Ck
double gammln(double xx)
int ir
ql0001_ & zero(ctemp+1),(cvec+1),(a+1),(b+1),(bl+1),(bu+1),(x+1),(w+1), &iout, ifail, &zero,(w+3), &lwar2,(iw+1), &leniw, &glob_grd.epsmac
double * xnew
double bessi4(double x)
void grcnfd()
glob_grd epsmac
double rhog
double temp1
double grdfd0
#define max(a, b)
double * delta
double * backup
goto L770
static void nobL
check(nparam, nf, nfsr, &Linfty, nineq, nineqn, neq, neqn, ncsrl, ncsrn, mode, &modem, eps, bgbnd, param)