ocra-recipes
Doxygen documentation for the ocra-recipes repository
OFSQP.cpp
Go to the documentation of this file.
1 #include "ocra/optim/OFSQP.h"
2 #include "ocra/optim/ObjQLD.h"
3 #include <algorithm> //for min and max
4 #include <assert.h>
5 
6 namespace ocra
7 {
9  :x_is_new(true), glob_grd(0x0), glob_prnt(0x0)
10  {
11  }
12 
13  void OFSQPProblem::gradob(int nparam,int j,double *x,double *gradf,void *cd)
14  {
15  assert(glob_grd != 0x0 && glob_prnt != 0x0 && "this default implementation is made so far to be called within fsqp routine only");
16 
17  int i;
18  double xi,delta;
19 
20  for (i=0; i<=nparam-1; i++) {
21  xi=x[i];
22  delta=std::max(glob_grd->udelta,
23  glob_grd->rteps*std::max(1.e0,fabs(xi)));
24  if (xi<0.e0) delta=-delta;
25  if (!(glob_prnt->ipd==1 || j != 1 || glob_prnt->iprint<3)) {
26  /* formats are not set yet... */
27  if (i==0) fprintf(glob_prnt->io,"\tdelta(i)\t %22.14f\n",delta);
28  if (i!=0) fprintf(glob_prnt->io,"\t\t\t %22.14f\n",delta);
29  }
30  x[i]=xi+delta;
31  invalidateX();
32  obj(nparam,j,x,&gradf[i],cd);
33  gradf[i]=(gradf[i]-glob_grd->valnom)/delta;
34  x[i]=xi;
35  invalidateX();
36  }
37  return;
38  }
39 
40 
41  void OFSQPProblem::gradcn(int nparam,int j,double *x,double *gradg,void *cd)
42  {
43  assert(glob_grd != 0x0 && glob_prnt != 0x0 && "this default implementation is made so far to be called within fsqp routine only");
44 
45  int i;
46  double xi,delta;
47 
48  for (i=0; i<=nparam-1; i++) {
49  xi=x[i];
50  delta=std::max(glob_grd->udelta,
51  glob_grd->rteps*std::max(1.e0,fabs(xi)));
52  if (xi<0.e0) delta=-delta;
53  if (!(j != 1 || glob_prnt->iprint<3)) {
54  /* formats are not set yet... */
55  if (i==0) fprintf(glob_prnt->io,"\tdelta(i)\t %22.14f\n",delta);
56  if (i!=0) fprintf(glob_prnt->io,"\t\t\t %22.14f\n",delta);
57  glob_prnt->ipd=1;
58  }
59  x[i]=xi+delta;
60  invalidateX();
61  constr(nparam,j,x,&gradg[i],cd);
62  gradg[i]=(gradg[i]-glob_grd->valnom)/delta;
63  x[i]=xi;
64  invalidateX();
65  }
66  return;
67  }
68 
70  {
71  x_is_new = true;
72  }
73 
75  {
76  x_is_new = false;
77  }
78 
80  {
81  return x_is_new;
82  }
83 
85  {
86  glob_grd = &grd;
87  glob_prnt = &prnt;
88  }
89 
91  {
92  glob_grd = 0x0;
93  glob_prnt = 0x0;
94  }
95 
96 
97  OFSQP::OFSQP(void)
98  : cfsqp_version("CFSQP 2.5d")
99  {
100  //this variables needs to be initialized for optimized version
101  objeps = 0;
102  objrep = 0;
103  gLgeps = 0;
104  nstop = 0;
105  }
106 
107 
109  {
110  }
111 
112 
113  void
114  OFSQP::cfsqp(int nparam,int nf,int nfsr,int nineqn,int nineq,int neqn,
115  int neq,int ncsrl,int ncsrn,int *mesh_pts,
116  int mode,int iprint,int miter,int *inform,double bigbnd,
117  double eps,double epseqn,double udelta,double *bl,double *bu,
118  double *x,double *f,double *g,double *lambda, OFSQPProblem& problem, void *cd)
119 
120  /*---------------------------------------------------------------------
121  * Brief specification of various arrays and parameters in the calling
122  * sequence. See manual for a more detailed description.
123  *
124  * nparam : number of variables
125  * nf : number of objective functions (count each set of sequentially
126  * related objective functions once)
127  * nfsr : number of sets of sequentially related objectives (possibly
128  * zero)
129  * nineqn : number of nonlinear inequality constraints
130  * nineq : total number of inequality constraints
131  * neqn : number of nonlinear equality constraints
132  * neq : total number of equality constraints
133  * ncsrl : number of sets of linear sequentially related inequality
134  * constraints
135  * ncsrn : number of sets of nonlinear sequentially related inequality
136  * constraints
137  * mesh_pts : array of integers giving the number of actual objectives/
138  * constraints in each sequentially related objective or
139  * constraint set. The order is as follows:
140  * (i) objective sets, (ii) nonlinear constraint sets,
141  * (iii) linear constraint sets. If one or no sequentially
142  * related constraint or objectives sets are present, the
143  * user may simply pass the address of an integer variable
144  * containing the appropriate number (possibly zero).
145  * mode : mode=CBA specifies job options as described below:
146  * A = 0 : ordinary minimax problems
147  * = 1 : ordinary minimax problems with each individual
148  * function replaced by its absolute value, ie,
149  * an L_infty problem
150  * B = 0 : monotone decrease of objective function
151  * after each iteration
152  * = 1 : monotone decrease of objective function after
153  * at most four iterations
154  * C = 1 : default operation.
155  * = 2 : requires that constraints always be evaluated
156  * before objectives during the line search.
157  * iprint : print level indicator with the following options-
158  * iprint=0: no normal output, only error information
159  * (this option is imposed during phase 1)
160  * iprint=1: a final printout at a local solution
161  * iprint=2: a brief printout at the end of each iteration
162  * iprint=3: detailed infomation is printed out at the end
163  * of each iteration (for debugging purposes)
164  * For iprint=2 or 3, the information may be printed at
165  * iterations that are multiples of 10, instead of every
166  * iteration. This may be done by adding the desired number
167  * of iterations to skip printing to the desired iprint value
168  * as specified above. e.g., sending iprint=23 would give
169  * the iprint=3 information once every 20 iterations.
170  * miter : maximum number of iterations allowed by the user to solve
171  * the problem
172  * inform : status report at the end of execution
173  * inform= 0:normal termination
174  * inform= 1:no feasible point found for linear constraints
175  * inform= 2:no feasible point found for nonlinear constraints
176  * inform= 3:no solution has been found in miter iterations
177  * inform= 4:stepsize smaller than machine precision before
178  * a successful new iterate is found
179  * inform= 5:failure in attempting to construct d0
180  * inform= 6:failure in attempting to construct d1
181  * inform= 7:inconsistent input data
182  * inform= 8:new iterate essentially identical to previous
183  * iterate, though stopping criterion not satisfied.
184  * inform= 9:penalty parameter too large, unable to satisfy
185  * nonlinear equality constraint
186  * bigbnd : plus infinity
187  * eps : stopping criterion. Execution stopped when the norm of the
188  * Newton direction vector is smaller than eps
189  * epseqn : tolerance of the violation of nonlinear equality constraints
190  * allowed by the user at an optimal solution
191  * udelta : perturbation size in computing gradients by finite
192  * difference. The actual perturbation is determined by
193  * sign(x_i) X max{udelta, rteps X max{1, |x_i|}} for each
194  * component of x, where rteps is the square root of machine
195  * precision.
196  * bl : array of dimension nparam,containing lower bound of x
197  * bu : array of dimension nparam,containing upper bound of x
198  * x : array of dimension nparam,containing initial guess in input
199  * and final iterate at the end of execution
200  * f : array of dimension sufficient enough to hold the value of
201  * all regular objective functions and the value of all
202  * members of the sequentially related objective sets.
203  * (dimension must be at least 1)
204  * g : array of dimension sufficient enough to hold the value of
205  * all regular constraint functions and the value of all
206  * members of the sequentially related constraint sets.
207  * (dimension must be at least 1)
208  * lambda : array of dimension nparam+dim(f)+dim(g), containing
209  * Lagrange multiplier values at x in output. (A concerns the
210  * mode, see above). The first nparam positions contain the
211  * multipliers associated with the simple bounds, the next
212  * dim(g) positions contain the multipliers associated with
213  * the constraints. The final dim(f) positions contain the
214  * multipliers associated with the objective functions. The
215  * multipliers are in the order they were specified in the
216  * user-defined objective and constraint functions.
217  * obj : Pointer to function that returns the value of objective
218  * functions, one upon each call
219  * constr : Pointer to function that returns the value of constraints
220  * one upon each call
221  * gradob : Pointer to function that computes gradients of f,
222  * alternatively it can be replaced by grobfd to compute
223  * finite difference approximations
224  * gradcn : Pointer to function that computes gradients of g,
225  * alternatively it can be replaced by grcnfd to compute
226  * finite difference approximations
227  * cd : Void pointer that may be used by the user for the passing of
228  * "client data" (untouched by CFSQP)
229  *
230  *----------------------------------------------------------------------
231  *
232  *
233  * CFSQP Version 2.5d
234  *
235  * Craig Lawrence, Jian L. Zhou
236  * and Andre Tits
237  * Institute for Systems Research
238  * and
239  * Electrical Engineering Department
240  * University of Maryland
241  * College Park, Md 20742
242  *
243  * February, 1998
244  *
245  *
246  * The purpose of CFSQP is to solve general nonlinear constrained
247  * minimax optimization problems of the form
248  *
249  * (A=0 in mode) minimize max_i f_i(x) for i=1,...,n_f
250  * or
251  * (A=1 in mode) minimize max_j |f_i(x)| for i=1,...,n_f
252  * s.t. bl <= x <= bu
253  * g_j(x) <= 0, for j=1,...,nineqn
254  * A_1 x - B_1 <= 0
255  *
256  * h_i(x) = 0, for i=1,...,neqn
257  * A_2 x - B_2 = 0
258  *
259  * CFSQP is also able to efficiently handle problems with large sets of
260  * sequentially related objectives or constraints, see the manual for
261  * details.
262  *
263  *
264  * Conditions for External Use
265  * ===========================
266  *
267  * 1. The CFSQP routines may not be distributed to third parties.
268  * Interested parties shall contact AEM Design directly.
269  * 2. If modifications are performed on the routines, these
270  * modifications shall be communicated to AEM Design. The
271  * modified routines will remain the sole property of the authors.
272  * 3. Due acknowledgment shall be made of the use of the CFSQP
273  * routines in research reports or publications. Whenever
274  * such reports are released for public access, a copy shall
275  * be forwarded to AEM Design.
276  * 4. The CFSQP routines may only be used for research and
277  * development, unless it has been agreed otherwise with AEM
278  * Design in writing.
279  *
280  * Copyright (c) 1993-1998 by Craig T. Lawrence, Jian L. Zhou, and
281  * Andre L. Tits
282  * All Rights Reserved.
283  *
284  *
285  * Enquiries should be directed to:
286  *
287  * AEM Design
288  * 3754 LaVista Rd., Suite 250
289  * Tucker, GA 30084
290  * U. S. A.
291  *
292  * Phone : 678-990-1121
293  * Fax : 678-990-1122
294  * E-mail: info@aemdesign.com
295  *
296  * References:
297  * [1] E. Panier and A. Tits, `On Combining Feasibility, Descent and
298  * Superlinear Convergence In Inequality Constrained Optimization',
299  * Mathematical Programming, Vol. 59(1993), 261-276.
300  * [2] J. F. Bonnans, E. Panier, A. Tits and J. Zhou, `Avoiding the
301  * Maratos Effect by Means of a Nonmonotone Line search: II.
302  * Inequality Problems - Feasible Iterates', SIAM Journal on
303  * Numerical Analysis, Vol. 29, No. 4, 1992, pp. 1187-1202.
304  * [3] J.L. Zhou and A. Tits, `Nonmonotone Line Search for Minimax
305  * Problems', Journal of Optimization Theory and Applications,
306  * Vol. 76, No. 3, 1993, pp. 455-476.
307  * [4] C.T. Lawrence, J.L. Zhou and A. Tits, `User's Guide for CFSQP
308  * Version 2.5: A C Code for Solving (Large Scale) Constrained
309  * Nonlinear (Minimax) Optimization Problems, Generating Iterates
310  * Satisfying All Inequality Constraints,' Institute for
311  * Systems Research, University of Maryland,Technical Report
312  * TR-94-16r1, College Park, MD 20742, 1997.
313  * [5] C.T. Lawrence and A.L. Tits, `Nonlinear Equality Constraints
314  * in Feasible Sequential Quadratic Programming,' Optimization
315  * Methods and Software, Vol. 6, March, 1996, pp. 265-282.
316  * [6] J.L. Zhou and A.L. Tits, `An SQP Algorithm for Finely
317  * Discretized Continuous Minimax Problems and Other Minimax
318  * Problems With Many Objective Functions,' SIAM Journal on
319  * Optimization, Vol. 6, No. 2, May, 1996, pp. 461--487.
320  * [7] C. T. Lawrence and A. L. Tits, `Feasible Sequential Quadratic
321  * Programming for Finely Discretized Problems from SIP,'
322  * To appear in R. Reemtsen, J.-J. Ruckmann (eds.): Semi-Infinite
323  * Programming, in the series Nonconcex Optimization and its
324  * Applications. Kluwer Academic Publishers, 1998.
325  *
326  ***********************************************************************
327  */
328  {
329  pb = &problem;
330  pb->invalidateX();
331  pb->setFSQPstruct(glob_grd, glob_prnt);
332 
333  int i,ipp,j,ncnstr,nclin,nctotl,nob,nobL,modem,nn,
334  nppram,nrowa,ncsipl1,ncsipn1,nfsip1;
335  bool feasbl,feasb,prnt,Linfty;
336  int *indxob,*indxcn,*mesh_pts1;
337  double *signeq;
338  double xi,gi,gmax,dummy,epskt;
339  struct _constraint *cs; /* pointer to array of constraints */
340  struct _objective *ob; /* pointer to array of objectives */
341  struct _parameter *param; /* pointer to parameter structure */
342  struct _parameter _param;
343 
344  /* Make adjustments to parameters for SIP constraints */
345  glob_info.tot_actf_sip = glob_info.tot_actg_sip = 0;
346  mesh_pts=mesh_pts-1;
347  glob_info.nfsip=nfsr;
348  glob_info.ncsipl=ncsrl;
349  glob_info.ncsipn=ncsrn;
350  nf=nf-nfsr;
351  nfsip1=nfsr;
352  nfsr=0;
353  for (i=1; i<=nfsip1; i++)
354  nfsr=nfsr+mesh_pts[i];
355  nf=nf+nfsr;
356  nineqn=nineqn-ncsrn;
357  nineq=nineq-ncsrl-ncsrn;
358  ncsipl1=ncsrl;
359  ncsipn1=ncsrn;
360  ncsrl=0;
361  ncsrn=0;
362  if (ncsipn1)
363  for (i=1; i<=ncsipn1; i++)
364  ncsrn=ncsrn+mesh_pts[nfsip1+i];
365  if (ncsipl1)
366  for (i=1; i<=ncsipl1; i++)
367  ncsrl=ncsrl+mesh_pts[nfsip1+ncsipn1+i];
368  nineqn=nineqn+ncsrn;
369  nineq=nineq+ncsrn+ncsrl;
370  /* Create array of constraint structures */
371  cs=(struct _constraint *)calloc(nineq+neq+1,
372  sizeof(struct _constraint));
373  for (i=1; i<=nineq+neq; i++) {
374  cs[i].grad=make_dv(nparam);
375  cs[i].act_sip=false;
376  cs[i].d1bind=false;
377  }
378  /* Create parameter structure */
379  _param.x=make_dv(nparam+1);
380  _param.bl=make_dv(nparam);
381  _param.bu=make_dv(nparam);
382  _param.mult=make_dv(nparam+1);
383  param=&_param;
384 
385  /* Initialize, compute the machine precision, etc. */
386  bl=bl-1; bu=bu-1; x=x-1;
387  for (i=1; i<=nparam; i++) {
388  param->x[i]=x[i];
389  param->bl[i]=bl[i];
390  param->bu[i]=bu[i];
391  }
392  param->cd=cd; /* Initialize client data */
393  dummy=0.e0;
394  f=f-1; g=g-1; lambda=lambda-1;
395  glob_prnt.iter=0;
396  nstop=1;
397  nn=nineqn+neqn;
398  glob_grd.epsmac=small();
399  tolfea=glob_grd.epsmac*1.e2;
400  bgbnd=bigbnd;
401  glob_grd.rteps=sqrt(glob_grd.epsmac);
402  glob_grd.udelta=udelta;
403  glob_log.rhol_is1=false;
404  glob_log.get_ne_mult=false;
405  signeq=make_dv(neqn);
406 
407  nob=0;
408  gmax=-bgbnd;
409  glob_prnt.info=0;
410  glob_prnt.iprint=iprint%10;
411  ipp=iprint;
412  glob_prnt.iter_mod=std::max(iprint-iprint%10,1);
413  glob_prnt.io=stdout;
414  ncnstr=nineq+neq;
415  glob_info.nnineq=nineq;
416  if (glob_prnt.iprint>0) {
417  fprintf(glob_prnt.io,
418  "\n\n CFSQP Version 2.5d (Released February 1998) \n");
419  fprintf(glob_prnt.io,
420  " Copyright (c) 1993 --- 1998 \n");
421  fprintf(glob_prnt.io,
422  " C.T. Lawrence, J.L. Zhou \n");
423  fprintf(glob_prnt.io,
424  " and A.L. Tits \n");
425  fprintf(glob_prnt.io,
426  " All Rights Reserved \n\n");
427  }
428  /*-----------------------------------------------------*/
429  /* Check the input data */
430  /*-----------------------------------------------------*/
431  check(nparam,nf,nfsr,&Linfty,nineq,nineqn,neq,neqn,
432  ncsrl,ncsrn,mode,&modem,eps,bgbnd,param);
433  if (glob_prnt.info==7) {
434  *inform=glob_prnt.info;
435  pb->resetFSQPstruct();
436  return;
437  }
438 
439  maxit=std::max(std::max(miter,10*std::max(nparam,ncnstr)),1000);
440  feasb=true;
441  feasbl=true;
442  prnt=false;
443  nppram=nparam+1;
444 
445  /*-----------------------------------------------------*/
446  /* Check whether x is within bounds */
447  /*-----------------------------------------------------*/
448  for (i=1; i<=nparam; i++) {
449  xi=param->x[i];
450  if (param->bl[i]<=xi && param->bu[i]>=xi) continue;
451  feasbl=false;
452  break;
453  }
454  nclin=ncnstr-nn;
455  /*-----------------------------------------------------*/
456  /* Check whether linear constraints are feasbile */
457  /*-----------------------------------------------------*/
458  if (nclin!=0) {
459  for (i=1; i<=nclin; i++) {
460  j=i+nineqn;
461  if (j<=nineq) {
462  pb->constr(nparam,j,(param->x)+1,&gi,param->cd);
463  if (gi>glob_grd.epsmac) feasbl=false;
464  } else {
465  pb->constr(nparam,j+neqn,(param->x)+1,&gi,param->cd);
466  if (fabs(gi)>glob_grd.epsmac) feasbl=false;
467  }
468  cs[j].val=gi;
469  }
470  }
471  /*-------------------------------------------------------*/
472  /* Generate a new point if infeasible */
473  /*-------------------------------------------------------*/
474  if (!feasbl) {
475  if (glob_prnt.iprint>0) {
476  fprintf(glob_prnt.io,
477  " The given initial point is infeasible for inequality\n");
478  fprintf(glob_prnt.io,
479  " constraints and linear equality constraints:\n");
480  sbout1(glob_prnt.io,nparam," ",dummy,
481  param->x,2,1);
482  prnt=true;
483  }
484  nctotl=nparam+nclin;
485  lenw=2*nparam*nparam+10*nparam+2*nctotl+1;
486  leniw=std::max(2*nparam+2*nctotl+3,2*nclin+2*nparam+6);
487  /*-----------------------------------------------------*/
488  /* Attempt to generate a point satisfying all linear */
489  /* constraints. */
490  /*-----------------------------------------------------*/
491  nrowa=std::max(nclin,1);
492  iw=make_iv(leniw);
493  w=make_dv(lenw);
494  initpt(nparam,nineqn,neq,neqn,nclin,nctotl,nrowa,param,
495  &cs[nineqn]);
496  free_iv(iw);
497  free_dv(w);
498  if (glob_prnt.info!=0) {
499  *inform=glob_prnt.info;
500  pb->resetFSQPstruct();
501  return;
502  }
503  }
504  indxob=make_iv(std::max(nineq+neq,nf));
505  indxcn=make_iv(nineq+neq);
506 L510:
507  if (glob_prnt.info!=-1) {
508  for (i=1; i<=nineqn; i++) {
509  pb->constr(nparam,i,(param->x)+1,&(cs[i].val),param->cd);
510  if (cs[i].val>0.e0) feasb=false;
511  }
512  glob_info.ncallg=nineqn;
513  if (!feasb) {
514  /* Create array of objective structures for Phase 1 */
515  ob=(struct _objective *)calloc(nineqn+1,
516  sizeof(struct _objective));
517  for (i=1; i<=nineqn; i++) {
518  ob[i].grad=make_dv(nparam);
519  ob[i].act_sip=false;
520  }
521  for (i=1; i<=nineqn; i++) {
522  nob++;
523  indxob[nob]=i;
524  ob[nob].val=cs[i].val;
525  gmax=std::max(gmax,ob[nob].val);
526  }
527  for (i=1; i<=nineq-nineqn; i++)
528  indxcn[i]=nineqn+i;
529  for (i=1; i<=neq-neqn; i++)
530  indxcn[i+nineq-nineqn]=nineq+neqn+i;
531  goto L605;
532  }
533  }
534 
535  /* Create array of objective structures for Phase 2 and */
536  /* initialize. */
537  ob=(struct _objective *)calloc(nf+1,sizeof(struct _objective));
538  for (i=1; i<=nf; i++) {
539  ob[i].grad=make_dv(nparam);
540  ob[i].act_sip=false;
541  }
542  for (i=1; i<=nineqn; i++) {
543  indxcn[i]=i;
544  }
545  for (i=1; i<=neq-neqn; i++)
546  cs[i+nineq+neqn].val=cs[i+nineq].val;
547  for (i=1; i<=neqn; i++) {
548  j=i+nineq;
549  pb->constr(nparam,j,(param->x)+1,&(cs[j].val),param->cd);
550  indxcn[nineqn+i]=j;
551  }
552  for (i=1; i<=nineq-nineqn; i++)
553  indxcn[i+nn]=nineqn+i;
554  for (i=1; i<=neq-neqn; i++)
555  indxcn[i+nineq+neqn]=nineq+neqn+i;
556  glob_info.ncallg+=neqn;
557 
558 L605:
559  if (glob_prnt.iprint>0 && feasb && !prnt) {
560  fprintf(glob_prnt.io,
561  "The given initial point is feasible for inequality\n");
562  fprintf(glob_prnt.io,
563  " constraints and linear equality constraints:\n");
564  sbout1(glob_prnt.io,nparam," ",dummy,
565  param->x,2,1);
566  prnt=true;
567  }
568  if (nob==0) {
569  if (glob_prnt.iprint>0) {
570  if (glob_prnt.info!=0) {
571  fprintf(glob_prnt.io,
572  "To generate a feasible point for nonlinear inequality\n");
573  fprintf(glob_prnt.io,
574  "constraints and linear equality constraints, ");
575  fprintf(glob_prnt.io,"ncallg = %10d\n",glob_info.ncallg);
576  if (ipp==0)
577  fprintf(glob_prnt.io," iteration %26d\n",
578  glob_prnt.iter);
579  if (ipp>0)
580  fprintf(glob_prnt.io," iteration %26d\n",
581  glob_prnt.iter-1);
582  if (ipp==0) glob_prnt.iter++;
583  }
584  if (feasb && !feasbl) {
585  fprintf(glob_prnt.io,
586  "Starting from the generated point feasible for\n");
587  fprintf(glob_prnt.io,
588  "inequality constraints and linear equality constraints:\n");
589  sbout1(glob_prnt.io,nparam," ",
590  dummy,param->x,2,1);
591 
592  }
593  if (glob_prnt.info!=0 || !prnt || !feasb) {
594  fprintf(glob_prnt.io,
595  "Starting from the generated point feasible for\n");
596  fprintf(glob_prnt.io,
597  "inequality constraints and linear equality constraints:\n");
598  sbout1(glob_prnt.io,nparam," ",
599  dummy,param->x,2,1);
600  }
601  }
602  feasb=true;
603  feasbl=true;
604  }
605  if (ipp>0 && !feasb && !prnt) {
606  fprintf(glob_prnt.io,
607  " The given initial point is infeasible for inequality\n");
608  fprintf(glob_prnt.io,
609  " constraints and linear equality constraints:\n");
610  sbout1(glob_prnt.io,nparam," ",dummy,
611  param->x,2,1);
612  prnt=true;
613  }
614  if (nob==0) nob=1;
615  if (feasb) {
616  nob=nf;
617  glob_prnt.info=0;
618  glob_prnt.iprint=iprint%10;
619  ipp=iprint;
620  glob_prnt.iter_mod=std::max(iprint-iprint%10,1);
621  glob_info.mode=modem;
622  epskt=eps;
623  if (Linfty) nobL=2*nob;
624  else nobL=nob;
625  if (nob!=0 || neqn!=0) goto L910;
626  fprintf(glob_prnt.io,
627  "current feasible iterate with no objective specified\n");
628  *inform=glob_prnt.info;
629  for (i=1; i<=nineq+neq; i++)
630  g[i]=cs[i].val;
631  dealloc(nineq,neq,signeq,indxcn,indxob,cs,param);
632  free((char *) ob);
633  pb->resetFSQPstruct();
634  return;
635  }
636  ipp=0;
637  glob_info.mode=0;
638  nobL=nob;
639  glob_prnt.info=-1;
640  epskt=1.e-10;
641 L910:
642  nctotl=nppram+ncnstr+std::max(nobL,1);
643  leniw=2*(ncnstr+std::max(nobL,1))+2*nppram+6;
644  lenw=2*nppram*nppram+10*nppram+6*(ncnstr+std::max(nobL,1)+1);
645  glob_info.M=4;
646  if (modem==1 && nn==0) glob_info.M=3;
647 
648  param->x[nparam+1]=gmax;
649  if (feasb) {
650  for (i=1; i<=neqn; i++) {
651  if (cs[i+nineq].val>0.e0) signeq[i]=-1.e0;
652  else signeq[i]=1.e0;
653  }
654  }
655  if (!feasb) {
656  ncsipl1=ncsrl;
657  ncsipn1=0;
658  nfsip1=ncsrn;
659  mesh_pts1=&mesh_pts[glob_info.nfsip];
660  } else {
661  ncsipl1=ncsrl;
662  ncsipn1=ncsrn;
663  nfsip1=nfsr;
664  mesh_pts1=mesh_pts;
665  }
666  /*---------------------------------------------------------------*/
667  /* either attempt to generate a point satisfying all */
668  /* constraints or try to solve the original problem */
669  /*---------------------------------------------------------------*/
670  nrowa=std::max(ncnstr+std::max(nobL,1),1);
671  w=make_dv(lenw);
672  iw=make_iv(leniw);
673 
674  cfsqp1(miter,nparam,nob,nobL,nfsip1,nineqn,neq,neqn,ncsipl1,ncsipn1,
675  mesh_pts1,ncnstr,nctotl,nrowa,feasb,epskt,epseqn,indxob,
676  indxcn,param,cs,ob,signeq);
677 
678  free_iv(iw);
679  free_dv(w);
680  if (glob_prnt.info==-1) { /* Successful phase 1 termination */
681  for (i=1; i<=nob; i++)
682  cs[i].val=ob[i].val;
683  nob=0;
684  for (i=1; i<=nineqn; i++)
685  free_dv(ob[i].grad);
686  free((char *) ob);
687  goto L510;
688  }
689  if (glob_prnt.info!=0) {
690  if (feasb) {
691  for (i=1; i<=nparam; i++)
692  x[i]=param->x[i];
693  for (i=1; i<=nineq+neq; i++)
694  g[i]=cs[i].val;
695  *inform=glob_prnt.info;
696  dealloc(nineq,neq,signeq,indxcn,indxob,cs,param);
697  for (i=1; i<=nf; i++) {
698  f[i]=ob[i].val;
699  free_dv(ob[i].grad);
700  }
701  free((char *) ob);
702  pb->resetFSQPstruct();
703  return;
704  }
705  glob_prnt.info=2;
706  fprintf(glob_prnt.io,
707  "Error: No feasible point is found for nonlinear inequality\n");
708  fprintf(glob_prnt.io,
709  "constraints and linear equality constraints\n");
710  *inform=glob_prnt.info;
711  dealloc(nineq,neq,signeq,indxcn,indxob,cs,param);
712  for (i=1; i<=nineqn; i++)
713  free_dv(ob[i].grad);
714  free((char *) ob);
715  pb->resetFSQPstruct();
716  return;
717  }
718  /* Successful phase 2 termination */
719  *inform=glob_prnt.info;
720  for (i=1; i<=nparam; i++) {
721  x[i]=param->x[i];
722  lambda[i]=param->mult[i];
723  }
724  for (i=1; i<=nineq+neq; i++) {
725  g[i]=cs[i].val;
726  lambda[i+nparam]=cs[i].mult;
727  }
728  for (i=1; i<=nf; i++) {
729  f[i]=ob[i].val;
730  lambda[i+nparam+nineq+neq]=ob[i].mult;
731  free_dv(ob[i].grad);
732  }
733  /* If just one objective, set multiplier=1 */
734  if (nf==1) lambda[1+nparam+nineq+neq]=1.e0;
735  free((char *) ob);
736  dealloc(nineq,neq,signeq,indxcn,indxob,cs,param);
737  pb->resetFSQPstruct();
738  return;
739  }
740 
741 
742  /***************************************************************/
743  /* Free allocated memory */
744  /***************************************************************/
745 
746 
747  void
748  OFSQP::dealloc(int nineq,int neq,double *signeq,int *indxob,
749  int *indxcn,struct _constraint *cs,struct _parameter *param)
750  {
751  int i;
752 
753  free_dv(param->x);
754  free_dv(param->bl);
755  free_dv(param->bu);
756  free_dv(param->mult);
757  free_dv(signeq);
758  free_iv(indxob);
759  free_iv(indxcn);
760  for (i=1; i<=nineq+neq; i++)
761  free_dv(cs[i].grad);
762  free((char *) cs);
763  }
764 
765 
766  void
767  OFSQP::cfsqp1(int miter,int nparam,int nob,int nobL,int nfsip,int nineqn,
768  int neq,int neqn,int ncsipl,int ncsipn,int *mesh_pts,int ncnstr,
769  int nctotl,int nrowa,int feasb,double epskt,double epseqn,
770  int *indxob,int *indxcn,struct _parameter *param,
771  struct _constraint *cs, struct _objective *ob,double *signeq)
772  {
773  int i,iskp,nfs,ncf,ncg,nn,nstart,nrst,ncnst1;
774  int *iact,*iskip,*istore;
775  double Cbar,Ck,dbar,fmax,fM,fMp,steps,d0nm,dummy,
776  sktnom,scvneq,grdftd,psf;
777  double *di,*d,*gm,*grdpsf,*penp,*bl,*bu,*clamda,
778  *cvec,*psmu,*span,*backup;
779  double **hess,**hess1,**a;
780  double *tempv;
781  struct _violation *viol;
782  struct _violation _viol;
783 
784  /* Allocate memory */
785 
786  hess=make_dm(nparam,nparam);
787  hess1=make_dm(nparam+1,nparam+1);
788  a=make_dm(nrowa,nparam+2);
789  di=make_dv(nparam+1);
790  d=make_dv(nparam+1);
791  gm=make_dv(4*neqn);
792  grdpsf=make_dv(nparam);
793  penp=make_dv(neqn);
794  bl=make_dv(nctotl);
795  bu=make_dv(nctotl);
796  clamda=make_dv(nctotl+nparam+1);
797  cvec=make_dv(nparam+1);
798  psmu=make_dv(neqn);
799  span=make_dv(4);
800  backup=make_dv(nob+ncnstr);
801  iact=make_iv(nob+nineqn+neqn);
802  iskip=make_iv(glob_info.nnineq+1);
803  istore=make_iv(nineqn+nob);
804 
805  viol=&_viol;
806  viol->index=0;
807  viol->type=NONE;
808 
809  glob_prnt.initvl=1;
810  glob_log.first=true;
811  nrst=glob_prnt.ipd=0;
812  dummy=0.e0;
813  scvneq=0.e0;
814  steps=0.e0;
815  sktnom=0.e0;
816  d0nm=0.e0;
817  if (glob_prnt.iter==0) diagnl(nparam,1.e0,hess);
818  if (feasb) {
819  glob_log.first=true;
820  if (glob_prnt.iter>0) glob_prnt.iter--;
821  if (glob_prnt.iter!=0) diagnl(nparam,1.e0,hess);
822  }
823  Ck=Cbar=1.e-2;
824  dbar=5.e0;
825  nstart=1;
826  glob_info.ncallf=0;
827  nstop=1;
828  nfs=0;
829  if (glob_info.mode!=0)
830  nfs=glob_info.M;
831  if (feasb) {
832  nn=nineqn+neqn;
833  ncnst1=ncnstr;
834  } else {
835  nn=0;
836  ncnst1=ncnstr-nineqn-neqn;
837  }
838  scvneq=0.e0;
839  for (i=1; i<=ncnst1; i++) {
840  glob_grd.valnom=cs[indxcn[i]].val;
841  backup[i]=glob_grd.valnom;
842  if (feasb && i>nineqn && i<=nn) {
843  gm[i-nineqn]=glob_grd.valnom*signeq[i-nineqn];
844  scvneq=scvneq+fabs(glob_grd.valnom);
845  }
846  if (feasb && i<=nn) {
847  iact[i]=indxcn[i];
848  if (i<=nineqn) istore[i]=0;
849  if (i>nineqn) penp[i-nineqn]=2.e0;
850  }
851  pb->gradcn(nparam,indxcn[i],(param->x)+1,(cs[indxcn[i]].grad)+1,param->cd);
852  }
853  nullvc(nparam,grdpsf);
854  psf=0.e0;
855  if (feasb && neqn!=0)
856  resign(nparam,neqn,&psf,grdpsf,penp,cs,signeq,12,12);
857  fmax=-bgbnd;
858  for (i=1; i<=nob; i++) {
859  if (!feasb) {
860  glob_grd.valnom=ob[i].val;
861  iact[i]=i;
862  istore[i]=0;
863  pb->gradcn(nparam,indxob[i],(param->x)+1,(ob[i].grad)+1,param->cd);
864  } else {
865  iact[nn+i]=i;
866  istore[nineqn+i]=0;
867  pb->obj(nparam,i,(param->x)+1,&(ob[i].val),param->cd);
868  glob_grd.valnom=ob[i].val;
869  backup[i+ncnst1]=glob_grd.valnom;
870  pb->gradob(nparam,i,(param->x)+1,(ob[i].grad)+1,param->cd);
871  glob_info.ncallf++;
872  if (nobL!=nob) fmax=std::max(fmax,-ob[i].val);
873  }
874  fmax=std::max(fmax,ob[i].val);
875  }
876  if (feasb && nob==0) fmax=0.e0;
877  fM=fmax;
878  fMp=fmax-psf;
879  span[1]=fM;
880 
881  if (glob_prnt.iprint>=3 && glob_log.first) {
882  for (i=1; i<=nob; i++) {
883  if (feasb) {
884  if (nob>1) {
885  tempv=ob[i].grad;
886  sbout2(glob_prnt.io,nparam,i,"gradf(j,",")",tempv);
887  }
888  if (nob==1) {
889  tempv=ob[1].grad;
890  sbout1(glob_prnt.io,nparam,"gradf(j) ",
891  dummy,tempv,2,2);
892  }
893  continue;
894  }
895  tempv=ob[i].grad;
896  sbout2(glob_prnt.io,nparam,indxob[i],"gradg(j,",")",tempv);
897  }
898  if (ncnstr!=0) {
899  for (i=1; i<=ncnst1; i++) {
900  tempv=cs[indxcn[i]].grad;
901  sbout2(glob_prnt.io,nparam,indxcn[i],"gradg(j,",")",tempv);
902  }
903  if (neqn!=0) {
904  sbout1(glob_prnt.io,nparam,"grdpsf(j) ",dummy,
905  grdpsf,2,2);
906  sbout1(glob_prnt.io,neqn,"P ",dummy,
907  penp,2,2);
908  }
909  }
910  for (i=1; i<=nparam; i++) {
911  tempv=colvec(hess,i,nparam);
912  sbout2(glob_prnt.io,nparam,i,"hess (j,",")",tempv);
913  free_dv(tempv);
914  }
915  }
916 
917  /*----------------------------------------------------------*
918  * Main loop of the algorithm *
919  *----------------------------------------------------------*/
920 
921  nstop=1;
922  for (;;) {
923  out(miter,nparam,nob,nobL,nfsip,nineqn,nn,nineqn,ncnst1,
924  ncsipl,ncsipn,mesh_pts,param->x,cs,ob,fM,fmax,steps,
925  sktnom,d0nm,feasb);
926  if (nstop==0) {
927  if (!feasb) {
928  dealloc1(nparam,nrowa,a,hess,hess1,di,d,gm,
929  grdpsf,penp,bl,bu,clamda,cvec,psmu,span,backup,
930  iact,iskip,istore);
931  return;
932  }
933  for (i=1; i<=ncnst1; i++) cs[i].val=backup[i];
934  for (i=1; i<=nob; i++) ob[i].val=backup[i+ncnst1];
935  for (i=1; i<=neqn; i++)
936  cs[glob_info.nnineq+i].mult = signeq[i]*psmu[i];
937  dealloc1(nparam,nrowa,a,hess,hess1,di,d,gm,
938  grdpsf,penp,bl,bu,clamda,cvec,psmu,span,backup,
939  iact,iskip,istore);
940  return;
941  }
942  if (!feasb && glob_prnt.iprint==0) glob_prnt.iter++;
943  /* Update the SIP constraint set Omega_k */
944  if ((ncsipl+ncsipn)!=0 || nfsip)
945  update_omega(nparam,ncsipl,ncsipn,mesh_pts,nineqn,nob,nobL,
946  nfsip,steps,fmax,cs,ob,param->x,viol,param->cd,feasb);
947  /* Compute search direction */
948  dir(nparam,nob,nobL,nfsip,nineqn,neq,neqn,nn,ncsipl,ncsipn,
949  ncnst1,feasb,&steps,epskt,epseqn,&sktnom,&scvneq,Ck,&d0nm,
950  &grdftd,indxob,indxcn,iact,&iskp,iskip,istore,param,di,d,
951  cs,ob,&fM,&fMp,&fmax,&psf,grdpsf,penp,a,bl,bu,clamda,cvec,
952  hess,hess1,backup,signeq,viol);
953  if (nstop==0 && !glob_log.get_ne_mult) continue;
954  glob_log.first=false;
955  if (!glob_log.update && !glob_log.d0_is0) {
956  /* Determine step length */
957  step1(nparam,nob,nobL,nfsip,nineqn,neq,neqn,nn,ncsipl,ncsipn,
958  ncnst1,&ncg,&ncf,indxob,indxcn,iact,&iskp,iskip,istore,
959  feasb,grdftd,ob,&fM,&fMp,&fmax,&psf,penp,&steps,&scvneq,
960  bu,param->x,di,d,cs,backup,signeq,viol,param->cd);
961  if (nstop==0) continue;
962  }
963  /* Update the Hessian */
964  hessian(nparam,nob,nfsip,nobL,nineqn,neq,neqn,nn,ncsipn,ncnst1,
965  nfs,&nstart,feasb,bu,param,ob,fmax,&fM,&fMp,&psf,grdpsf,
966  penp,cs,gm,indxob,indxcn,bl,clamda,di,hess,d,steps,&nrst,
967  signeq,span,hess1,cvec,psmu,viol);
968  if (nstop==0 || glob_info.mode==0) continue;
969  if (d0nm>dbar) Ck=std::max(0.5e0*Ck,Cbar);
970  if (d0nm<=dbar && glob_log.dlfeas) Ck=Ck;
971  if (d0nm<=dbar && !glob_log.dlfeas &&
972  !glob_log.rhol_is1) Ck=10.e0*Ck;
973  }
974  }
975 
976  /*******************************************************************/
977  /* Free up memory used by CFSQP1 */
978  /*******************************************************************/
979 
980  void
981  OFSQP::dealloc1(int nparam,int nrowa,double **a,double **hess,double **hess1,
982  double *di,double *d,double *gm,double *grdpsf,double *penp,
983  double *bl,double *bu,double *clamda,double *cvec,double *psmu,
984  double *span,double *backup,int *iact,int *iskip,int *istore)
985  {
986  free_dm(a,nrowa);
987  free_dm(hess,nparam);
988  free_dm(hess1,nparam+1);
989  free_dv(di);
990  free_dv(d);
991  free_dv(gm);
992  free_dv(grdpsf);
993  free_dv(penp);
994  free_dv(bl);
995  free_dv(bu);
996  free_dv(clamda);
997  free_dv(cvec);
998  free_dv(psmu);
999  free_dv(span);
1000  free_dv(backup);
1001  free_iv(iact);
1002  free_iv(iskip);
1003  free_iv(istore);
1004  }
1005 
1006 
1007  /************************************************************/
1008  /* CFSQP - Check the input data */
1009  /************************************************************/
1010 
1011  void
1012  OFSQP::check(int nparam,int nf,int nfsip,bool *Linfty,int nineq,
1013  int nnl,int neq,int neqn,int ncsipl,int ncsipn,int mode,
1014  int *modem,double eps,double bigbnd,struct _parameter *param)
1015  {
1016  int i;
1017  double bli,bui;
1018 
1019  if (nparam<=0)
1020  error("nparam should be positive! ",
1021  &glob_prnt.info);
1022  if (nf<0)
1023  error("nf should not be negative! ",
1024  &glob_prnt.info);
1025  if (nineq<0)
1026  error("nineq should not be negative! ",
1027  &glob_prnt.info);
1028  if (nineq>=0 && nnl>=0 && nineq<nnl)
1029  error("nineq should be no smaller than nnl! ",
1030  &glob_prnt.info);
1031  if (neqn<0)
1032  error("neqn should not be negative! ",
1033  &glob_prnt.info);
1034  if (neq<neqn)
1035  error("neq should not be smaller than neqn ",
1036  &glob_prnt.info);
1037  if (nf<nfsip)
1038  error("nf should not be smaller than nfsip ",
1039  &glob_prnt.info);
1040  if (nineq<ncsipn+ncsipl)
1041  error("ncsrl+ncsrn should not be larger than nineq",
1042  &glob_prnt.info);
1043  if (nparam<=neq-neqn)
1044  error("Must have nparam > number of linear equalities",
1045  &glob_prnt.info);
1046  if (glob_prnt.iprint<0 || glob_prnt.iprint>3)
1047  error("iprint mod 10 should be 0,1,2 or 3! ",
1048  &glob_prnt.info);
1049  if (eps<=glob_grd.epsmac) {
1050  error("eps should be bigger than epsmac! ",
1051  &glob_prnt.info);
1052  fprintf(glob_prnt.io,
1053  "epsmac = %22.14e which is machine dependent.\n",
1054  glob_grd.epsmac);
1055  }
1056  if (!(mode==100 || mode==101 || mode==110 || mode==111
1057  || mode==200 || mode==201 || mode==210 || mode==211))
1058  error("mode is not properly specified! ",
1059  &glob_prnt.info);
1060  if (glob_prnt.info!=0) {
1061  fprintf(glob_prnt.io,
1062  "Error: Input parameters are not consistent.\n");
1063  return;
1064  }
1065  for (i=1; i<=nparam; i++) {
1066  bli=param->bl[i];
1067  bui=param->bu[i];
1068  if (bli>bui) {
1069  fprintf(glob_prnt.io,
1070  "lower bounds should be smaller than upper bounds\n");
1071  glob_prnt.info=7;
1072  }
1073  if (glob_prnt.info!=0) return;
1074  if (bli<(-bigbnd)) param->bl[i]=-bigbnd;
1075  if (bui>bigbnd) param->bu[i]=bigbnd;
1076  }
1077  if (mode >= 200) {
1078  i=mode-200;
1079  glob_info.modec=2;
1080  } else {
1081  i=mode-100;
1082  glob_info.modec=1;
1083  }
1084  if (i<10) *modem=0;
1085  else {
1086  *modem=1;
1087  i-=10;
1088  }
1089  if (!i) *Linfty=false;
1090  else *Linfty=true;
1091  }
1092 
1093  /****************************************************************/
1094  /* CFSQP : Generate a feasible point satisfying simple */
1095  /* bounds and linear constraints. */
1096  /****************************************************************/
1097 
1098  void
1099  OFSQP::initpt(int nparam,int nnl,int neq,int neqn,int nclin,int nctotl,
1100  int nrowa,struct _parameter *param,struct _constraint *cs)
1101  {
1102  int i,j,infoql,mnn,temp1,iout,zero;
1103  double x0i,*atemp,*htemp;
1104  double *x,*bl,*bu,*cvec,*clamda,*bj;
1105  double **a,**hess;
1106 
1107  hess=make_dm(nparam,nparam);
1108  a=make_dm(nrowa,nparam);
1109  x=make_dv(nparam);
1110  bl=make_dv(nctotl);
1111  bu=make_dv(nctotl);
1112  cvec=make_dv(nparam);
1113  clamda=make_dv(nctotl+nparam+1);
1114  bj=make_dv(nclin);
1115 
1116  glob_prnt.info=1;
1117  for (i=1; i<=nclin; i++) {
1118  glob_grd.valnom=cs[i].val;
1119  j=i+nnl;
1120  if (j<=glob_info.nnineq)
1121  pb->gradcn(nparam,j,(param->x)+1,cs[i].grad+1,param->cd);
1122  else pb->gradcn(nparam,j+neqn,(param->x)+1,cs[i].grad+1,param->cd);
1123  }
1124  for (i=1; i<=nparam; i++) {
1125  x0i=param->x[i];
1126  bl[i]=param->bl[i]-x0i;
1127  bu[i]=param->bu[i]-x0i;
1128  cvec[i]=0.e0;
1129  }
1130  for (i=nclin; i>=1; i--)
1131  bj[nclin-i+1]=-cs[i].val;
1132  for (i=nclin; i>=1; i--)
1133  for (j=1; j<=nparam; j++)
1134  a[nclin-i+1][j]=-cs[i].grad[j];
1135  diagnl(nparam,1.e0,hess);
1136  nullvc(nparam,x);
1137 
1138  iout=6;
1139  zero=0;
1140  mnn=nrowa+2*nparam;
1141  iw[1]=1;
1142  temp1=neq-neqn;
1143  htemp=convert(hess,nparam,nparam);
1144  atemp=convert(a,nrowa,nparam);
1145 
1146  ObjQLD::ql0001_(&nclin,&temp1,&nrowa,&nparam,&nparam,&mnn,(htemp+1),
1147  (cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1),
1148  &iout,&infoql,&zero,(w+1),&lenw,(iw+1),&leniw,
1149  &glob_grd.epsmac);
1150 
1151  free_dv(htemp);
1152  free_dv(atemp);
1153  if (infoql==0) {
1154  for (i=1; i<=nparam; i++)
1155  param->x[i]=param->x[i]+x[i];
1156  pb->invalidateX();
1157  for (i=1; i<=nclin; i++) {
1158  j=i+nnl;
1159  if (j<=glob_info.nnineq) pb->constr(nparam,j,(param->x)+1,
1160  &(cs[i].val),param->cd);
1161  else pb->constr(nparam,j+neqn,(param->x)+1,&(cs[i].val),param->cd);
1162  }
1163  glob_prnt.info=0;
1164  }
1165  if (glob_prnt.info==1 && glob_prnt.iprint!=0) {
1166  fprintf(glob_prnt.io,
1167  "\n Error: No feasible point is found for the");
1168  fprintf(glob_prnt.io," linear constraints.\n");
1169  }
1170  free_dm(a,nrowa);
1171  free_dm(hess,nparam);
1172  free_dv(x);
1173  free_dv(bl);
1174  free_dv(bu);
1175  free_dv(cvec);
1176  free_dv(clamda);
1177  free_dv(bj);
1178  return;
1179  }
1180 
1181  /****************************************************************/
1182  /* CFSQP : Update the SIP "active" objective and constraint */
1183  /* sets Omega_k and Xi_k. */
1184  /****************************************************************/
1185 
1186  void
1187  OFSQP::update_omega(int nparam,int ncsipl,int ncsipn,int *mesh_pts,
1188  int nineqn,int nob,int nobL,int nfsip,double steps,
1189  double fmax,struct _constraint *cs,struct _objective *ob,
1190  double *x,struct _violation *viol,void *cd,int feasb)
1191  {
1192  int i,j,i_max,index,offset,nineq;
1193  bool display;
1194  double epsilon,g_max,fprev,fnow,fnext,fmult;
1195 
1196  epsilon=1.e0;
1197  glob_info.tot_actf_sip=glob_info.tot_actg_sip=0;
1198  nineq=glob_info.nnineq;
1199  if (glob_prnt.iter%glob_prnt.iter_mod) display=false;
1200  else display=true;
1201  /* Clear previous constraint sets */
1202  for (i=1; i<=ncsipl; i++)
1203  cs[nineq-ncsipl+i].act_sip=false;
1204  for (i=1; i<=ncsipn; i++)
1205  cs[nineqn-ncsipn+i].act_sip=false;
1206  /* Clear previous objective sets */
1207  for (i=nob-nfsip+1; i<=nob; i++)
1208  ob[i].act_sip=false;
1209 
1210  /*--------------------------------------------------*/
1211  /* Update Constraint Sets Omega_k */
1212  /*--------------------------------------------------*/
1213 
1214  if (ncsipn != 0) {
1215  offset=nineqn-ncsipn;
1216  for (i=1; i<=glob_info.ncsipn; i++) {
1217  for (j=1; j<=mesh_pts[glob_info.nfsip+i]; j++) {
1218  offset++;
1219  if (j==1) {
1220  if (cs[offset].val >= -epsilon &&
1221  cs[offset].val>=cs[offset+1].val) {
1222  cs[offset].act_sip=true;
1223  glob_info.tot_actg_sip++;
1224  if (cs[offset].mult==0.e0 && !glob_log.first) {
1225  glob_grd.valnom=cs[offset].val;
1226  pb->gradcn(nparam,offset,x+1,cs[offset].grad+1,cd);
1227  }
1228  continue;
1229  }
1230  } else if (j==mesh_pts[glob_info.nfsip+i]) {
1231  if (cs[offset].val >= -epsilon &&
1232  cs[offset].val>cs[offset-1].val) {
1233  cs[offset].act_sip=true;
1234  glob_info.tot_actg_sip++;
1235  if (cs[offset].mult==0.e0 && !glob_log.first) {
1236  glob_grd.valnom=cs[offset].val;
1237  pb->gradcn(nparam,offset,x+1,cs[offset].grad+1,cd);
1238  }
1239  continue;
1240  }
1241  } else {
1242  if (cs[offset].val >= -epsilon && cs[offset].val >
1243  cs[offset-1].val && cs[offset].val >=
1244  cs[offset+1].val) {
1245  cs[offset].act_sip=true;
1246  glob_info.tot_actg_sip++;
1247  if (cs[offset].mult==0.e0 && !glob_log.first) {
1248  glob_grd.valnom=cs[offset].val;
1249  pb->gradcn(nparam,offset,x+1,cs[offset].grad+1,cd);
1250  }
1251  continue;
1252  }
1253  }
1254  if (cs[offset].val >= -glob_grd.epsmac) {
1255  cs[offset].act_sip=true;
1256  glob_info.tot_actg_sip++;
1257  if (cs[offset].mult==0.e0 && !glob_log.first) {
1258  glob_grd.valnom=cs[offset].val;
1259  pb->gradcn(nparam,offset,x+1,cs[offset].grad+1,cd);
1260  }
1261  continue;
1262  }
1263  if (cs[offset].mult>0.e0) {
1264  cs[offset].act_sip=true;
1265  glob_info.tot_actg_sip++;
1266  }
1267  /* Add if binding for d1 */
1268  if (cs[offset].d1bind) {
1269  cs[offset].act_sip=true;
1270  glob_info.tot_actg_sip++;
1271  if (cs[offset].mult==0.e0 && !glob_log.first) {
1272  glob_grd.valnom=cs[offset].val;
1273  pb->gradcn(nparam,offset,x+1,cs[offset].grad+1,cd);
1274  }
1275  }
1276 
1277  }
1278  }
1279  }
1280  if (ncsipl != 0) {
1281  /* Don't need to get gradients */
1282  offset=nineq-ncsipl;
1283  for (i=1; i<=glob_info.ncsipl; i++) {
1284  if (feasb) index=glob_info.nfsip+glob_info.ncsipn+i;
1285  else index=glob_info.ncsipn+i;
1286  for (j=1; j<=mesh_pts[index]; j++) {
1287  offset++;
1288  if (j==1) {
1289  if (cs[offset].val >= -epsilon &&
1290  cs[offset].val>=cs[offset+1].val) {
1291  cs[offset].act_sip=true;
1292  glob_info.tot_actg_sip++;
1293  continue;
1294  }
1295  } else
1296  if (j==mesh_pts[index]) {
1297  if (cs[offset].val >= -epsilon &&
1298  cs[offset].val>cs[offset-1].val) {
1299  cs[offset].act_sip=true;
1300  glob_info.tot_actg_sip++;
1301  continue;
1302  }
1303  } else {
1304  if (cs[offset].val >= -epsilon && cs[offset].val >
1305  cs[offset-1].val && cs[offset].val >=
1306  cs[offset+1].val) {
1307  cs[offset].act_sip=true;
1308  glob_info.tot_actg_sip++;
1309  continue;
1310  }
1311  }
1312  if (cs[offset].val >= -glob_grd.epsmac ||
1313  cs[offset].mult>0.e0 || cs[offset].d1bind) {
1314  cs[offset].act_sip=true;
1315  glob_info.tot_actg_sip++;
1316  }
1317  }
1318  }
1319  }
1320  /* Include some extra points during 1st iteration */
1321  /* (gradients are already evaluated for first iteration) */
1322  /* Current heuristics: maximizers and end-points. */
1323  if (glob_log.first) {
1324  if (feasb) {
1325  offset=nineqn-ncsipn;
1326  for (i=1; i<=glob_info.ncsipn; i++) {
1327  i_max= ++offset;
1328  g_max=cs[i_max].val;
1329  if (!cs[i_max].act_sip) { /* add first point */
1330  cs[i_max].act_sip=true;
1331  glob_info.tot_actg_sip++;
1332  }
1333  for (j=2;j<=mesh_pts[glob_info.nfsip+i];j++) {
1334  offset++;
1335  if (cs[offset].val>g_max) {
1336  i_max=offset;
1337  g_max=cs[i_max].val;
1338  }
1339  }
1340  if (!cs[i_max].act_sip) {
1341  cs[i_max].act_sip=true;
1342  glob_info.tot_actg_sip++;
1343  }
1344  if (!cs[offset].act_sip) { /* add last point */
1345  cs[offset].act_sip=true;
1346  glob_info.tot_actg_sip++;
1347  }
1348  }
1349  }
1350  offset=nineq-ncsipl;
1351  for (i=1; i<=glob_info.ncsipl; i++) {
1352  i_max= ++offset;
1353  g_max=cs[i_max].val;
1354  if (!cs[i_max].act_sip) { /* add first point */
1355  cs[i_max].act_sip=true;
1356  glob_info.tot_actg_sip++;
1357  }
1358  if (feasb) index=glob_info.nfsip+glob_info.ncsipn+i;
1359  else index=glob_info.ncsipn+i;
1360  for (j=2;j<=mesh_pts[index]; j++) {
1361  offset++;
1362  if (cs[offset].val>g_max) {
1363  i_max=offset;
1364  g_max=cs[i_max].val;
1365  }
1366  }
1367  if (!cs[i_max].act_sip) {
1368  cs[i_max].act_sip=true;
1369  glob_info.tot_actg_sip++;
1370  }
1371  if (!cs[offset].act_sip) { /* add last point */
1372  cs[offset].act_sip=true;
1373  glob_info.tot_actg_sip++;
1374  }
1375  }
1376  }
1377 
1378  /* If necessary, append xi_bar */
1379  if (steps<1.e0 && viol->type==CONSTR) {
1380  i=viol->index;
1381  if (!cs[i].act_sip) {
1382  cs[i].act_sip=true;
1383  glob_info.tot_actg_sip++;
1384  }
1385  }
1386  if (glob_prnt.iprint>=2 && display)
1387  fprintf(glob_prnt.io," |Xi_k| for g %26d\n",
1388  glob_info.tot_actg_sip);
1389 
1390  for (i=1; i<=ncsipl; i++)
1391  cs[nineq-ncsipl+i].d1bind=false;
1392  for (i=1; i<=ncsipn; i++)
1393  cs[nineqn-ncsipn+i].d1bind=false;
1394 
1395  /*---------------------------------------------------------*/
1396  /* Update Objective Set Omega_k */
1397  /*---------------------------------------------------------*/
1398 
1399  if (nfsip) {
1400  offset=nob-nfsip;
1401  if (feasb) index=glob_info.nfsip;
1402  else index=glob_info.ncsipn;
1403  for (i=1; i<=index; i++) {
1404  for (j=1; j<=mesh_pts[i]; j++) {
1405  offset++;
1406  if (nobL>nob) {
1407  fnow=fabs(ob[offset].val);
1408  fmult=std::max(fabs(ob[offset].mult),
1409  fabs(ob[offset].mult_L));
1410  } else {
1411  fnow=ob[offset].val;
1412  fmult=ob[offset].mult;
1413  }
1414  if (j==1) {
1415  if (nobL>nob) fnext=fabs(ob[offset+1].val);
1416  else fnext=ob[offset+1].val;
1417  if ((fnow>=fmax-epsilon)&& fnow>=fnext) {
1418  ob[offset].act_sip=true;
1419  glob_info.tot_actf_sip++;
1420  if (fmult==0.e0 && !glob_log.first) {
1421  glob_grd.valnom=ob[offset].val;
1422  if (feasb) pb->gradob(nparam,offset,x+1,ob[offset].grad+1,cd);
1423  else pb->gradcn(nparam,offset,x+1,ob[offset].grad+1,cd);
1424  }
1425  continue;
1426  }
1427  } else if (j==mesh_pts[i]) {
1428  if (nobL>nob) fprev=fabs(ob[offset-1].val);
1429  else fprev=ob[offset-1].val;
1430  if ((fnow>=fmax-epsilon)&& fnow>fprev) {
1431  ob[offset].act_sip=true;
1432  glob_info.tot_actf_sip++;
1433  if (fmult==0.e0 && !glob_log.first) {
1434  glob_grd.valnom=ob[offset].val;
1435  if (feasb) pb->gradob(nparam,offset,x+1,ob[offset].grad+1,cd);
1436  else pb->gradcn(nparam,offset,x+1,ob[offset].grad+1,cd);
1437  }
1438  continue;
1439  }
1440  } else {
1441  if (nobL>nob) {
1442  fprev=fabs(ob[offset-1].val);
1443  fnext=fabs(ob[offset+1].val);
1444  } else {
1445  fprev=ob[offset-1].val;
1446  fnext=ob[offset+1].val;
1447  }
1448  if ((fnow>=fmax-epsilon)&& fnow>fprev &&
1449  fnow>=fnext) {
1450  ob[offset].act_sip=true;
1451  glob_info.tot_actf_sip++;
1452  if (fmult==0.e0 && !glob_log.first) {
1453  glob_grd.valnom=ob[offset].val;
1454  if (feasb) pb->gradob(nparam,offset,x+1,
1455  ob[offset].grad+1,cd);
1456  else pb->gradcn(nparam,offset,x+1,ob[offset].grad+1,cd);
1457  }
1458  continue;
1459  }
1460  }
1461  if (fnow>= fmax-glob_grd.epsmac && !ob[offset].act_sip) {
1462  ob[offset].act_sip=true;
1463  glob_info.tot_actf_sip++;
1464  if (fmult==0.e0 && !glob_log.first) {
1465  glob_grd.valnom=ob[offset].val;
1466  if (feasb) pb->gradob(nparam,offset,x+1,
1467  ob[offset].grad+1,cd);
1468  else pb->gradcn(nparam,offset,x+1,ob[offset].grad+1,cd);
1469  }
1470  continue;
1471  }
1472  if (fmult!=0.e0 && !ob[offset].act_sip) {
1473  ob[offset].act_sip=true;
1474  glob_info.tot_actf_sip++;
1475  continue;
1476  }
1477  }
1478  }
1479  /* Addition of objectives for first iteration. */
1480  /* Current heuristics: maximizers and end-points */
1481  if (glob_log.first) {
1482  offset=nob-nfsip;
1483  if (feasb) index=glob_info.nfsip;
1484  else index=glob_info.ncsipn;
1485  for (i=1; i<=index; i++) {
1486  i_max= ++offset;
1487  if (nobL==nob) g_max=ob[i_max].val;
1488  else g_max=fabs(ob[i_max].val);
1489  if (!ob[i_max].act_sip) { /* add first point */
1490  ob[i_max].act_sip=true;
1491  glob_info.tot_actf_sip++;
1492  }
1493  for (j=2;j<=mesh_pts[i];j++) {
1494  offset++;
1495  if (nobL==nob) fnow=ob[offset].val;
1496  else fnow=fabs(ob[offset].val);
1497  if (fnow>g_max) {
1498  i_max=offset;
1499  g_max=fnow;
1500  }
1501  }
1502  if (!ob[i_max].act_sip) {
1503  ob[i_max].act_sip=true;
1504  glob_info.tot_actf_sip++;
1505  }
1506  if (!ob[offset].act_sip) { /* add last point */
1507  ob[offset].act_sip=true;
1508  glob_info.tot_actf_sip++;
1509  }
1510  }
1511  }
1512 
1513  /* If necessary, append omega_bar */
1514  if (steps<1.e0 && viol->type==OBJECT) {
1515  i=viol->index;
1516  if (!ob[i].act_sip) {
1517  ob[i].act_sip=true;
1518  glob_info.tot_actf_sip++;
1519  }
1520  }
1521  if (glob_prnt.iprint>=2 && display)
1522  fprintf(glob_prnt.io," |Omega_k| for f %26d\n",
1523  glob_info.tot_actf_sip);
1524  }
1525  viol->type=NONE;
1526  viol->index=0;
1527  return;
1528  }
1529 
1530 
1531  /*******************************************************************/
1532  /* CFSQP : Computation of the search direction */
1533  /*******************************************************************/
1534 
1535 
1536  void
1537  OFSQP::dir(int nparam,int nob,int nobL,int nfsip,int nineqn,int neq,int neqn,
1538  int nn,int ncsipl,int ncsipn,int ncnstr,
1539  int feasb,double *steps,double epskt,double epseqn,
1540  double *sktnom,double *scvneq,double Ck,double *d0nm,
1541  double *grdftd,int *indxob,int *indxcn,int *iact,int *iskp,
1542  int *iskip,int *istore,struct _parameter *param,double *di,
1543  double *d,struct _constraint *cs,struct _objective *ob,
1544  double *fM,double *fMp,double *fmax,double *psf,double *grdpsf,
1545  double *penp,double **a,double *bl,double *bu,double *clamda,
1546  double *cvec,double **hess,double **hess1,
1547  double *backup,double *signeq,struct _violation *viol)
1548  {
1549  int i,j,k,kk,ncg,ncf,nqprm0,nclin0,nctot0,infoqp,nqprm1,ncl,
1550  nclin1,ncc,nff,nrowa0,nrowa1,ninq,nobb,nobbL,
1551  nncn,ltem1,ltem2;
1552  bool display,need_d1;
1553  double fmxl,vv,dx,dmx,dnm1,dnm,v0,v1,vk,temp1,temp2,theta,
1554  rhol,rhog,rho,grdfd0,grdfd1,dummy,grdgd0,grdgd1,thrshd,
1555  sign,*adummy,dnmtil,*tempv;
1556 
1557  theta = 0; //AE: initialization to avoid VS crash in debug for mode B=0
1558 
1559  ncg=ncf=*iskp=0;
1560  ncl=glob_info.nnineq-nineqn;
1561  glob_log.local=glob_log.update=false;
1562  glob_log.rhol_is1=false;
1563  thrshd=tolfea;
1564  adummy=make_dv(1);
1565  adummy[1]=0.e0;
1566  dummy=0.e0;
1567  temp1=temp2=0.e0;
1568  if (glob_prnt.iter%glob_prnt.iter_mod) display=false;
1569  else display=true;
1570  need_d1=true;
1571 
1572  if (nobL<=1) {
1573  nqprm0=nparam;
1574  nclin0=ncnstr;
1575  } else {
1576  nqprm0=nparam+1;
1577  nclin0=ncnstr+nobL;
1578  }
1579  nctot0=nqprm0+nclin0;
1580  vv=0.e0;
1581  nrowa0=std::max(nclin0,1);
1582  for (i=1; i<=ncnstr; i++) {
1583  if (feasb) {
1584  if (i>nineqn && i<=glob_info.nnineq)
1585  iskip[glob_info.nnineq+2-i]=i;
1586  iw[i]=i;
1587  } else {
1588  if (i<=ncl) iskip[ncl+2-i]=nineqn+i;
1589  if (i<=ncl) iw[i]=nineqn+i;
1590  if (i>ncl) iw[i]=nineqn+neqn+i;
1591  }
1592  }
1593  for (i=1; i<=nob; i++)
1594  iw[ncnstr+i]=i;
1595  nullvc(nparam, cvec);
1596  glob_log.d0_is0=false;
1597  dqp(nparam,nqprm0,nob,nobL,nfsip,nineqn,neq,neqn,nn,ncsipl,ncsipn,
1598  ncnstr,nctot0,nrowa0,nineqn,&infoqp,param,di,feasb,ob,
1599  *fmax,grdpsf,cs,a,cvec,bl,bu,clamda,hess,hess1,di,vv,0);
1600  if (infoqp!=0) {
1601  glob_prnt.info=5;
1602  if (!feasb) glob_prnt.info=2;
1603  nstop=0;
1604  free_dv(adummy);
1605  return;
1606  }
1607  /*-------------------------------------------------------------*/
1608  /* Reorder indexes of constraints & objectives */
1609  /*-------------------------------------------------------------*/
1610  if (nn>1) {
1611  j=1;
1612  k=nn;
1613  for (i=nn; i>=1; i--) {
1614  if (fuscmp(cs[indxcn[i]].mult,thrshd)) {
1615  iact[j]=indxcn[i];
1616  j++;
1617  } else {
1618  iact[k]=indxcn[i];
1619  k--;
1620  }
1621  }
1622  }
1623  if (nobL>1) {
1624  j=nn+1;
1625  k=nn+nob;
1626  for (i=nob; i>=1; i--) {
1627  kk=nqprm0+ncnstr;
1628  ltem1=fuscmp(ob[i].mult,thrshd);
1629  ltem2=(nobL!=nob) && (fuscmp(ob[i].mult_L,thrshd));
1630  if (ltem1 || ltem2) {
1631  iact[j]=i;
1632  j++;
1633  } else {
1634  iact[k]=i;
1635  k--;
1636  }
1637  }
1638  }
1639  if (nob>0) vv=ob[iact[nn+1]].val;
1640  *d0nm=sqrt(scaprd(nparam,di,di));
1641  if (glob_log.first && nclin0==0) {
1642  dx=sqrt(scaprd(nparam,param->x,param->x));
1643  dmx=std::max(dx,1.e0);
1644  if (*d0nm>dmx) {
1645  for (i=1; i<=nparam; i++)
1646  di[i]=di[i]*dmx/(*d0nm);
1647  *d0nm=dmx;
1648  }
1649  }
1650  matrvc(nparam,nparam,hess,di,w);
1651  if (nn==0) *grdftd = -scaprd(nparam,w,di);
1652  *sktnom=sqrt(scaprd(nparam,w,w));
1653  if (((*d0nm<=epskt)||((gLgeps>0.e0)&&(*sktnom<=gLgeps)))&&
1654  (neqn==0 || *scvneq<=epseqn)) {
1655  /* We are finished! */
1656  nstop=0;
1657  if (feasb && glob_log.first && neqn!=0) {
1658  /* Finished, but still need to estimate nonlinear equality
1659  constraint multipliers */
1660  glob_log.get_ne_mult = true;
1661  glob_log.d0_is0 = true;
1662  }
1663  if (!feasb) glob_prnt.info=2;
1664  free_dv(adummy);
1665  if (glob_prnt.iprint<3 || !display) return;
1666  if (nobL<=1) nff=1;
1667  if (nobL>1) nff=2;
1668  sbout1(glob_prnt.io,nparam,"multipliers for x ",dummy,
1669  param->mult,2,2);
1670  if (ncnstr!=0) {
1671  fprintf(glob_prnt.io,"\t\t\t %s\t %22.14e\n",
1672  " for g ",cs[1].mult);
1673  for (j=2; j<=ncnstr; j++)
1674  fprintf(glob_prnt.io," \t\t\t\t\t\t %22.14e\n",cs[j].mult);
1675  }
1676  if (nobL>1) {
1677  fprintf(glob_prnt.io,"\t\t\t %s\t %22.14e\n",
1678  " for f ",ob[1].mult);
1679  for (j=2; j<=nob; j++)
1680  fprintf(glob_prnt.io," \t\t\t\t\t\t %22.14e\n",ob[j].mult);
1681  }
1682  return;
1683  }
1684  if (glob_prnt.iprint>=3 && display) {
1685  sbout1(glob_prnt.io,nparam,"d0 ",dummy,di,2,2);
1686  sbout1(glob_prnt.io,0,"d0norm ",*d0nm,adummy,1,2);
1687  sbout1(glob_prnt.io,0,"ktnorm ",*sktnom,adummy,1,2);
1688  }
1689  if (neqn!=0 && *d0nm<=std::min(0.5e0*epskt,(0.1e-1)*glob_grd.rteps)
1690  && *scvneq>epseqn) {
1691  /* d0 is "zero", but equality constraints not satisfied */
1692  glob_log.d0_is0 = true;
1693  return;
1694  }
1695  /*--------------------------------------------------------------*/
1696  /* Single objective without nonlinear constraints requires */
1697  /* no d1 and dtilde; multi-objectives without nonlinear */
1698  /* constraints requires no d1. */
1699  /*--------------------------------------------------------------*/
1700  if (nn!=0) *grdftd=slope(nob,nobL,neqn,nparam,feasb,ob,grdpsf,
1701  di,d,*fmax,dummy,0,adummy,0);
1702 
1703  if (nn==0 && nobL<=1) {
1704  for (i=1; i<=nparam; i++) d[i]=0.e0;
1705  dnmtil=0.e0;
1706  free_dv(adummy);
1707  return;
1708  }
1709  if (nn==0) {
1710  dnm=*d0nm;
1711  rho=0.e0;
1712  rhog=0.e0;
1713  goto L310;
1714  }
1715  /*-------------------------------------------------------------*/
1716  /* compute modified first order direction d1 */
1717  /*-------------------------------------------------------------*/
1718 
1719  /* First check that it is necessary */
1720  if (glob_info.mode==1) {
1721  vk=std::min(Ck*(*d0nm)*(*d0nm),*d0nm);
1722  need_d1=false;
1723  for (i=1; i<=nn; i++) {
1724  tempv=cs[indxcn[i]].grad;
1725  grdgd0=scaprd(nparam,tempv,di);
1726  temp1=vk+cs[indxcn[i]].val+grdgd0;
1727  if (temp1>0.e0) {
1728  need_d1=true;
1729  break;
1730  }
1731  }
1732  }
1733  if (need_d1) {
1734  nqprm1=nparam+1;
1735  if (glob_info.mode==0) nclin1=ncnstr+std::max(nobL,1);
1736  if (glob_info.mode==1) nclin1=ncnstr;
1737  nrowa1=std::max(nclin1,1);
1738  ninq=glob_info.nnineq;
1739  di1(nparam,nqprm1,nob,nobL,nfsip,nineqn,neq,neqn,ncnstr,
1740  ncsipl,ncsipn,nrowa1,&infoqp,glob_info.mode,
1741  param,di,ob,*fmax,grdpsf,cs,cvec,bl,bu,clamda,
1742  hess1,d,*steps);
1743  if (infoqp!=0) {
1744  glob_prnt.info=6;
1745  if (!feasb) glob_prnt.info=2;
1746  nstop=0;
1747  free_dv(adummy);
1748  return;
1749  }
1750  dnm1=sqrt(scaprd(nparam,d,d));
1751  if (glob_prnt.iprint>=3 && display) {
1752  sbout1(glob_prnt.io,nparam,"d1 ",dummy,d,2,2);
1753  sbout1(glob_prnt.io,0,"d1norm ",dnm1,adummy,1,2);
1754  }
1755  } else {
1756  dnm1=0.e0;
1757  for (i=1; i<=nparam; i++) d[i]=0.e0;
1758  }
1759  if (glob_info.mode!=1) {
1760  v0=pow(*d0nm,2.1);
1761  v1=std::max(0.5e0,pow(dnm1,2.5));
1762  rho=v0/(v0+v1);
1763  rhog=rho;
1764  } else {
1765  rhol=0.e0;
1766  if (need_d1) {
1767  for (i=1; i<=nn; i++) {
1768  tempv=cs[indxcn[i]].grad;
1769  grdgd0=scaprd(nparam,tempv,di);
1770  grdgd1=scaprd(nparam,tempv,d);
1771  temp1=vk+cs[indxcn[i]].val+grdgd0;
1772  temp2=grdgd1-grdgd0;
1773  if (temp1<=0.e0) continue;
1774  if (fabs(temp2)<glob_grd.epsmac) {
1775  rhol=1.e0;
1776  glob_log.rhol_is1=true;
1777  break;
1778  }
1779  rhol=std::max(rhol,-temp1/temp2);
1780  if (temp2<0.e0 && rhol<1.e0) continue;
1781  rhol=1.e0;
1782  glob_log.rhol_is1=true;
1783  break;
1784  }
1785  }
1786  theta=0.2e0;
1787  if (rhol==0.e0) {
1788  rhog=rho=0.e0;
1789  dnm=*d0nm;
1790  goto L310;
1791  }
1792  if (nobL>1) {
1793  rhog=slope(nob,nobL,neqn,nparam,feasb,ob,grdpsf,
1794  di,d,*fmax,theta,glob_info.mode,adummy,0);
1795  rhog=std::min(rhol,rhog);
1796  } else {
1797  grdfd0= *grdftd;
1798  if (nob==1) grdfd1=scaprd(nparam,ob[1].grad,d);
1799  else grdfd1=0.e0;
1800  grdfd1=grdfd1-scaprd(nparam,grdpsf,d);
1801  temp1=grdfd1-grdfd0;
1802  temp2=(theta-1.e0)*grdfd0/temp1;
1803  if(temp1<=0.e0) rhog=rhol;
1804  else rhog=std::min(rhol,temp2);
1805  }
1806  rho=rhog;
1807  if (*steps==1.e0 && rhol<0.5e0) rho=rhol;
1808  }
1809  for (i=1; i<=nparam; i++) {
1810  if (rho!=rhog) cvec[i]=di[i];
1811  di[i]=(1.e0-rho)*di[i]+rho*d[i];
1812  }
1813  dnm=sqrt(scaprd(nparam,di,di));
1814  if (!(glob_prnt.iprint<3 || glob_info.mode==1 || nn==0)&&display) {
1815  sbout1(glob_prnt.io,0,"rho ",rho,adummy,1,2);
1816  sbout1(glob_prnt.io,nparam,"d ",dummy,di,2,2);
1817  sbout1(glob_prnt.io,0,"dnorm ",dnm,adummy,1,2);
1818  }
1819 L310:
1820  for (i=1; i<=nob; i++) bl[i]=ob[i].val;
1821  if (rho!=1.e0) {
1822  if (!(glob_prnt.iprint!=3 || glob_info.mode==0 || nn==0)
1823  && display) {
1824  sbout1(glob_prnt.io,0,"Ck ",Ck,adummy,1,2);
1825  sbout1(glob_prnt.io,0,"rhol ",rho,adummy,1,2);
1826  sbout1(glob_prnt.io,nparam,"dl ",dummy,di,2,2);
1827  sbout1(glob_prnt.io,0,"dlnorm ",dnm,adummy,1,2);
1828  }
1829  if (glob_info.mode!=0) {
1830  glob_log.local=true;
1831  step1(nparam,nob,nobL,nfsip,nineqn,neq,neqn,nn,ncsipl,ncsipn,
1832  ncnstr,&ncg,&ncf,indxob,indxcn,iact,iskp,iskip,istore,
1833  feasb,*grdftd,ob,fM,fMp,fmax,psf,penp,steps,scvneq,bu,
1834  param->x,di,d,cs,backup,signeq,viol,param->cd);
1835  if (!glob_log.update) nstop=1;
1836  else {
1837  free_dv(adummy);
1838  return;
1839  }
1840  glob_log.local=false;
1841  if (rho!=rhog && nn!=0)
1842  for (i=1; i<=nparam; i++)
1843  di[i]=(1-rhog)*cvec[i]+rhog*d[i];
1844  dnm=sqrt(scaprd(nparam,di,di));
1845  }
1846  }
1847  if (!(glob_prnt.iprint<3 || glob_info.mode==0 || nn==0) &&
1848  display) {
1849  sbout1(glob_prnt.io,0,"rhog ",rhog,adummy,1,2);
1850  sbout1(glob_prnt.io,nparam,"dg ",dummy,di,2,2);
1851  sbout1(glob_prnt.io,0,"dgnorm ",dnm,adummy,1,2);
1852  }
1853  if (rho !=0.e0) *grdftd=slope(nob,nobL,neqn,nparam,feasb,ob,
1854  grdpsf,di,d,*fmax,theta,0,bl,1);
1855  if (glob_info.mode!=1 || rho!=rhog)
1856  for (i=1; i<=nparam; i++)
1857  bu[i]=param->x[i]+di[i];
1858  pb->invalidateX();
1859  if (rho!=rhog) ncg=0;
1860  ncc=ncg+1;
1861  fmxl=-bgbnd;
1862  ninq=nncn=ncg;
1863  j=0;
1864  /*--------------------------------------------------------------*/
1865  /* iskip[1]-iskip[iskp] store the indexes of linear inequality*/
1866  /* constraints that are not to be used to compute d~ */
1867  /* iskip[nnineq-nineqn+1]-iskip[nnineq-ncn+1-iskp] store */
1868  /* those that are to be used to compute d~ */
1869  /*--------------------------------------------------------------*/
1870  for (i=ncc; i<=ncnstr; i++) {
1871  if (i<=nn) kk=iact[i];
1872  else kk=indxcn[i];
1873  if (kk>nineqn && kk<=glob_info.nnineq) {
1874  iskip[ncl+1-j]=kk;
1875  j++;
1876  }
1877  if (kk<=glob_info.nnineq) {
1878  tempv=cs[kk].grad;
1879  temp1=dnm*sqrt(scaprd(nparam,tempv,tempv));
1880  temp2=cs[kk].mult;
1881  }
1882  if (temp2!=0.e0 || cs[kk].val >= (-0.2e0*temp1) ||
1883  kk>glob_info.nnineq) {
1884  ninq++;
1885  iw[ninq]=kk;
1886  if (feasb && kk<=nineqn) istore[kk]=1;
1887  pb->constr(nparam,kk,bu+1,&(cs[kk].val),param->cd);
1888  if (!feasb || (feasb && (kk>glob_info.nnineq+neqn))) continue;
1889  if (kk<=nineqn) nncn=ninq;
1890  fmxl=std::max(fmxl,cs[kk].val);
1891  if (feasb &&(kk<=nineqn || (kk>glob_info.nnineq
1892  && kk<=(glob_info.nnineq+neqn)))) glob_info.ncallg++;
1893  if (fabs(fmxl)>bgbnd) {
1894  for (i=1; i<=nparam; i++) d[i]=0.e0;
1895  dnmtil=0.e0;
1896  nstop=1;
1897  free_dv(adummy);
1898  return;
1899  }
1900  continue;
1901  }
1902  if (kk<=nineqn) continue;
1903  (*iskp)++;
1904  iskip[*iskp]=kk;
1905  j--;
1906  }
1907  if ((neqn!=0)&&(feasb))
1908  resign(nparam,neqn,psf,grdpsf,penp,cs,signeq,10,20);
1909  ninq-=neq;
1910  /* if (!feasb) ninq+=neqn; BUG??? */
1911  if (ncg!=0) for (i=1; i<=ncg; i++) {
1912  iw[i]=iact[i];
1913  if (iact[i]<=nineqn) istore[iact[i]]=1;
1914  fmxl=std::max(fmxl,cs[iact[i]].val);
1915  if (fabs(fmxl)>bgbnd) {
1916  for (i=1; i<=nparam; i++) d[i]=0.e0;
1917  dnmtil=0.e0;
1918  nstop=1;
1919  free_dv(adummy);
1920  return;
1921  }
1922  }
1923  if (nobL<=1) {
1924  iw[1+ninq+neq]=1;
1925  nobb=nob;
1926  goto L1110;
1927  }
1928  if (rho!=rhog) ncf=0;
1929  nff=ncf+1;
1930  nobb=ncf;
1931  sign=1.e0;
1932  fmxl=-bgbnd;
1933  if (ob[iact[nn+1]].mult<0.e0) sign=-1.e0;
1934  for (i=nff; i<=nob; i++) {
1935  kk=iact[nn+i];
1936  if (!feasb) kk=iact[i];
1937  if (feasb) k=nn+1;
1938  if (!feasb) k=1;
1939  for (j=1; j<=nparam; j++)
1940  w[nparam+j]=sign*ob[iact[k]].grad[j]-ob[kk].grad[j];
1941  temp1=fabs(ob[kk].val-sign*vv);
1942  temp2=dnm*sqrt(scaprd(nparam,&w[nparam],&w[nparam]));
1943  if (temp1!=0.e0 && temp2!=0.e0) {
1944  temp1=temp1/temp2;
1945  temp2=ob[kk].mult;
1946  if (temp2==0.e0 && temp1>0.2e0) continue;
1947  }
1948  nobb++;
1949  iw[nobb+ninq+neq]=kk;
1950  if (feasb) istore[nineqn+kk]=1;
1951  else istore[kk]=1;
1952  if (!feasb) {
1953  pb->constr(nparam,indxob[kk],bu+1,&(ob[kk].val),param->cd);
1954  glob_info.ncallg++;
1955  } else {
1956  pb->obj(nparam,kk,bu+1,&(ob[kk].val),param->cd);
1957  glob_info.ncallf++;
1958  if (nobL!=nob) fmxl=std::max(fmxl, -ob[kk].val);
1959  }
1960  fmxl=std::max(fmxl,ob[kk].val);
1961  if (fabs(fmxl)>bgbnd) {
1962  for (i=1; i<=nparam; i++) d[i]=0.e0;
1963  dnmtil=0.e0;
1964  nstop=1;
1965  free_dv(adummy);
1966  return;
1967  }
1968  }
1969  if (ncf != 0) {
1970  for (i=1; i<=ncf; i++) {
1971  iw[ninq+neq+i]=iact[i+nn];
1972  istore[nineqn+iact[i+nn]]=1;
1973  fmxl=std::max(fmxl,ob[iact[i+nn]].val);
1974  if (nobL != nob) fmxl=std::max(fmxl,-ob[iact[i+nn]].val);
1975  if (fabs(fmxl)>bgbnd) {
1976  for (i=1; i<=nparam; i++) d[i]=0.e0;
1977  dnmtil=0.e0;
1978  nstop=1;
1979  free_dv(adummy);
1980  return;
1981  }
1982  }
1983  }
1984 L1110:
1985  matrvc(nparam,nparam,hess,di,cvec);
1986  vv=-std::min(0.01e0*dnm,pow(dnm,2.5));
1987  /*--------------------------------------------------------------*/
1988  /* compute a correction dtilde to d=(1-rho)d0+rho*d1 */
1989  /*--------------------------------------------------------------*/
1990  if (nobL!=nob) nobbL=2*nobb;
1991  if (nobL==nob) nobbL=nobb;
1992  if (nobbL<=1) {
1993  nqprm0=nparam;
1994  nclin0=ninq+neq;
1995  } else {
1996  nqprm0=nparam+1;
1997  nclin0=ninq+neq+nobbL;
1998  }
1999  nctot0=nqprm0+nclin0;
2000  nrowa0=std::max(nclin0,1);
2001  i=ninq+neq;
2002  nstop=1;
2003  dqp(nparam,nqprm0,nobb,nobbL,nfsip,nncn,neq,neqn,nn,ncsipl,ncsipn,i,
2004  nctot0,nrowa0,nineqn,&infoqp,param,di,feasb,ob,fmxl,
2005  grdpsf,cs,a,cvec,bl,bu,clamda,hess,hess1,d,vv,1);
2006  dnmtil=sqrt(scaprd(nparam,d,d));
2007  if (infoqp!=0 || dnmtil>dnm) {
2008  for (i=1; i<=nparam; i++) d[i]=0.e0;
2009  dnmtil=0.e0;
2010  nstop=1;
2011  free_dv(adummy);
2012  return;
2013  }
2014  if (dnmtil!=0.e0)
2015  for (i=1; i<=nineqn+nob; i++)
2016  istore[i]=0;
2017  if (glob_prnt.iprint<3 || !display) {
2018  free_dv(adummy);
2019  return;
2020  }
2021  sbout1(glob_prnt.io,nparam,"dtilde ",dummy,d,2,2);
2022  sbout1(glob_prnt.io,0,"dtnorm ",dnmtil,adummy,1,2);
2023  free_dv(adummy);
2024  return;
2025  }
2026 
2027 
2028  /*******************************************************************/
2029  /* job=0: compute d0 */
2030  /* job=1: compute d~ */
2031  /*******************************************************************/
2032 
2033  void
2034  OFSQP::dqp(int nparam,int nqpram,int nob,int nobL,int nfsip,int nineqn,
2035  int neq,int neqn,int nn,int ncsipl,int ncsipn,int ncnstr,
2036  int nctotl,int nrowa,int nineqn_tot,int *infoqp,
2037  struct _parameter *param,double *di,int feasb,struct _objective *ob,
2038  double fmax,double *grdpsf,struct _constraint *cs,
2039  double **a,double *cvec,double *bl,double *bu,double *clamda,
2040  double **hess,double **hess1,double *x,
2041  double vv,int job)
2042  {
2043  int i,ii,j,jj,ij,k,iout,mnn,nqnp,zero,temp1,temp2,ncnstr_used,
2044  numf_used;
2045  int *iw_hold;
2046  double x0i,xdi,*bj,*htemp,*atemp;
2047 
2048  iout=6;
2049  bj=make_dv(nrowa);
2050  iw_hold=make_iv(nrowa);
2051  for (i=1; i<=nparam; i++) {
2052  x0i=param->x[i];
2053  if (job==1) xdi=di[i];
2054  if (job==0) xdi=0.e0;
2055  bl[i]=param->bl[i]-x0i-xdi;
2056  bu[i]=param->bu[i]-x0i-xdi;
2057  cvec[i]=cvec[i]-grdpsf[i];
2058  }
2059  if (nobL>1) {
2060  bl[nqpram]=-bgbnd;
2061  bu[nqpram]=bgbnd;
2062  }
2063  ii=ncnstr-nn;
2064  /*---------------------------------------------------------------*/
2065  /* constraints are assigned to a in reverse order */
2066  /*---------------------------------------------------------------*/
2067  k=0;
2068  for (i=1; i<=ncnstr; i++) {
2069  jj=iw[ncnstr+1-i];
2070  if ((jj>glob_info.nnineq)||(jj<=nineqn_tot-ncsipn)||
2071  ((jj>nineqn_tot)&&(jj<=glob_info.nnineq-ncsipl))||
2072  cs[jj].act_sip) {
2073  k++;
2074  x0i=vv;
2075  if (i<=(neq-neqn) || (i>neq && i<=(ncnstr-nineqn)))
2076  x0i=0.e0;
2077  if (!feasb) x0i=0.e0;
2078  bj[k]=x0i-cs[jj].val;
2079  for (j=1; j<=nparam; j++)
2080  a[k][j]=-cs[jj].grad[j];
2081  if (nobL>1) a[k][nqpram]=0.e0;
2082  iw_hold[k]=jj;
2083  }
2084  }
2085  ncnstr_used=k;
2086  /*---------------------------------------------------------------*/
2087  /* Assign objectives for QP */
2088  /*---------------------------------------------------------------*/
2089  if (nobL==1) {
2090  for (i=1; i<=nparam; i++)
2091  cvec[i]=cvec[i]+ob[1].grad[i];
2092  } else if (nobL>1) {
2093  numf_used=nob-nfsip+glob_info.tot_actf_sip;
2094  if (job&&nfsip) { /* compute # objectives used for dtilde */
2095  numf_used=0;
2096  for (i=1; i<=nob; i++)
2097  if (ob[iw[ncnstr+i]].act_sip) numf_used++;
2098  }
2099  for (i=1; i<=nob; i++) {
2100  ij=ncnstr+i;
2101  if ((i<=nob-nfsip) || ob[iw[ij]].act_sip) {
2102  k++;
2103  iw_hold[k]=iw[ij]; /* record which are used */
2104  bj[k]=fmax-ob[iw[ij]].val;
2105  if (nobL>nob) bj[k+numf_used]=fmax+ob[iw[ij]].val;
2106  for (j=1; j<=nparam; j++) {
2107  a[k][j]=-ob[iw[ij]].grad[j];
2108  if (nobL>nob) a[k+numf_used][j]=ob[iw[ij]].grad[j];
2109  }
2110  a[k][nqpram]=1.e0;
2111  if (nobL>nob) a[k+numf_used][nqpram]=1.e0;
2112  }
2113  }
2114  cvec[nqpram]=1.e0;
2115  if (nobL>nob) k=k+numf_used; /* k=# rows for a */
2116  } /* =# constraints for QP */
2117  matrcp(nparam,hess,nparam+1,hess1);
2118  nullvc(nqpram,x);
2119 
2120  iw[1]=1;
2121  zero=0;
2122  temp1=neq-neqn;
2123  temp2=nparam+1;
2124  mnn=k+2*nqpram;
2125  htemp=convert(hess1,nparam+1,nparam+1);
2126  atemp=convert(a,nrowa,nqpram);
2127 
2128  ObjQLD::ql0001_(&k,&temp1,&nrowa,&nqpram,&temp2,&mnn,(htemp+1),
2129  (cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),
2130  (clamda+1),&iout,infoqp,&zero,(w+1),&lenw,(iw+1),&leniw,
2131  &glob_grd.epsmac);
2132 
2133  free_dv(htemp);
2134  free_dv(atemp);
2135  if (*infoqp!=0 || job==1) {
2136  free_iv(iw_hold);
2137  free_dv(bj);
2138  return;
2139  }
2140 
2141  /*---------------------------------------------------------------*/
2142  /* Save multipliers from the computation of d0 */
2143  /*---------------------------------------------------------------*/
2144  nullvc(nqpram,param->mult);
2145  if (ncsipl+ncsipn)
2146  for (i=1; i<=ncnstr; i++)
2147  cs[i].mult=0.e0;
2148  if (nfsip)
2149  for (i=1; i<=nob; i++) {
2150  ob[i].mult=0.e0;
2151  ob[i].mult_L=0.e0;
2152  }
2153  for (i=1; i<=nqpram; i++) {
2154  ii=k+i;
2155  if (clamda[ii]==0.e0 && clamda[ii+nqpram]==0.e0) continue;
2156  else if (clamda[ii]!=0.e0) clamda[ii]=-clamda[ii];
2157  else clamda[ii]=clamda[ii+nqpram];
2158  }
2159  nqnp=nqpram+ncnstr;
2160  for (i=1; i<=nqpram; i++) /* Simple bounds */
2161  param->mult[i]=clamda[k+i];
2162  if (nctotl>nqnp) { /* Objectives */
2163  for (i=1; i<=numf_used; i++) {
2164  ij=ncnstr_used+i;
2165  if (nobL!=nob) {
2166  ii=k-2*numf_used+i;
2167  ob[iw_hold[ij]].mult=clamda[ii]-clamda[ii+numf_used];
2168  ob[iw_hold[ij]].mult_L=clamda[ii+numf_used];
2169  } else {
2170  ii=k-numf_used+i;
2171  ob[iw_hold[ij]].mult=clamda[ii];
2172  }
2173  }
2174  }
2175  for (i=1; i<=ncnstr_used; i++) /* Constraints */
2176  cs[iw_hold[i]].mult=clamda[i];
2177  free_iv(iw_hold);
2178  free_dv(bj);
2179  return;
2180  }
2181 
2182 
2183  /****************************************************************/
2184  /* Computation of first order direction d1 */
2185  /****************************************************************/
2186 
2187  void
2188  OFSQP::di1(int nparam,int nqpram,int nob,int nobL,int nfsip,int nineqn,
2189  int neq,int neqn,int ncnstr,int ncsipl,int ncsipn,
2190  int nrowa,int *infoqp,int mode,struct _parameter *param,
2191  double *d0,struct _objective *ob,double fmax,double
2192  *grdpsf,struct _constraint *cs,double *cvec,double *bl,double *bu,
2193  double *clamda,double **hess1,double *x,double steps)
2194  {
2195  int i,k,ii,jj,iout,j,mnn,zero,temp1,temp3,ncnstr_used,numf_used;
2196  int *iw_hold;
2197  double x0i,eta,*atemp,*htemp,**a,*bj;
2198 
2199  if ((ncsipl+ncsipn)!=0)
2200  nrowa=nrowa-(ncsipl+ncsipn)+glob_info.tot_actg_sip;
2201  if (nfsip) {
2202  if (nobL>nob) nrowa=nrowa-2*nfsip+2*glob_info.tot_actf_sip;
2203  else nrowa=nrowa-nfsip+glob_info.tot_actf_sip;
2204  }
2205  nrowa=std::max(nrowa,1);
2206  a=make_dm(nrowa,nqpram);
2207  bj=make_dv(nrowa);
2208  iw_hold=make_iv(nrowa);
2209  iout=6;
2210  if (mode==0) eta=0.1e0;
2211  if (mode==1) eta=3.e0;
2212  for (i=1; i<=nparam; i++) {
2213  x0i=param->x[i];
2214  bl[i]=param->bl[i]-x0i;
2215  bu[i]=param->bu[i]-x0i;
2216  if (mode==0) cvec[i]=-eta*d0[i];
2217  if (mode==1) cvec[i]=0.e0;
2218  }
2219  bl[nqpram]=-bgbnd;
2220  bu[nqpram]=bgbnd;
2221  cvec[nqpram]=1.e0;
2222  ii=ncnstr-nineqn;
2223  k=0;
2224  for (i=1; i<=ncnstr; i++) {
2225  jj=ncnstr+1-i;
2226  if ((jj>glob_info.nnineq)||(jj<=nineqn-ncsipn)||
2227  ((jj>nineqn)&&(jj<=glob_info.nnineq-ncsipl))||
2228  cs[jj].act_sip) {
2229  k++;
2230  bj[k]=-cs[jj].val;
2231  for (j=1; j<=nparam; j++)
2232  a[k][j]=-cs[jj].grad[j];
2233  a[k][nqpram]=0.e0;
2234  if ((i>(neq-neqn) && i<=neq) || i>ii) a[k][nqpram]=1.e0;
2235  iw_hold[k]=jj;
2236  }
2237  }
2238  ncnstr_used=k;
2239 
2240  if (mode!=1) {
2241  numf_used=nob-nfsip+glob_info.tot_actf_sip;
2242  for (i=1; i<=nob; i++) {
2243  if ((i<=nob-nfsip) || ob[i].act_sip) {
2244  k++;
2245  bj[k]=fmax-ob[i].val;
2246  for (j=1; j<=nparam; j++) {
2247  a[k][j]=-ob[i].grad[j]+grdpsf[j];
2248  if (nobL>nob) a[k+numf_used][j]=ob[i].grad[j]+grdpsf[j];
2249  }
2250  a[k][nqpram]=1.e0;
2251  if (nobL>nob) a[k+numf_used][nqpram]=1.e0;
2252  }
2253  }
2254  if (nob==0) {
2255  k++;
2256  bj[k]=fmax;
2257  for (j=1; j<=nparam; j++)
2258  a[k][j]=grdpsf[j];
2259  a[k][nqpram]=1.e0;
2260  }
2261  }
2262  diagnl(nqpram,eta,hess1);
2263  nullvc(nqpram,x);
2264  hess1[nqpram][nqpram]=0.e0;
2265 
2266  iw[1]=1;
2267  zero=0;
2268  temp1=neq-neqn;
2269  if (nobL>nob) temp3=k+numf_used;
2270  else temp3=k;
2271  mnn=temp3+2*nqpram;
2272  htemp=convert(hess1,nparam+1,nparam+1);
2273  atemp=convert(a,nrowa,nqpram);
2274 
2275  ObjQLD::ql0001_(&temp3,&temp1,&nrowa,&nqpram,&nqpram,&mnn,(htemp+1),
2276  (cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),
2277  (clamda+1),&iout,infoqp,&zero,(w+1),&lenw,(iw+1),&leniw,
2278  &glob_grd.epsmac);
2279 
2280  free_dv(htemp);
2281  free_dv(atemp);
2282  free_dm(a,nrowa);
2283  free_dv(bj);
2284  /* Determine binding constraints */
2285  if (ncsipl+ncsipn) {
2286  for (i=1; i<=ncnstr_used; i++)
2287  if (clamda[i]>0.e0) cs[iw_hold[i]].d1bind=true;
2288  }
2289  free_iv(iw_hold);
2290  return;
2291  }
2292 
2293 
2294  /*****************************************************************/
2295  /* CFSQP : Armijo or nonmonotone line search, with some */
2296  /* ad hoc strategies to decrease the number of */
2297  /* function evaluations as much as possible. */
2298  /*****************************************************************/
2299 
2300 
2301  void
2302  OFSQP::step1(int nparam,int nob,int nobL,int nfsip,int nineqn,int neq,int neqn,
2303  int nn,int ncsipl,int ncsipn,int ncnstr,int *ncg,int *ncf,
2304  int *indxob,int *indxcn,int *iact,int *iskp,int *iskip,
2305  int *istore,int feasb,double grdftd,struct _objective *ob,
2306  double *fM,double *fMp,double *fmax,double *psf,double *penp,
2307  double *steps,double *scvneq,double *xnew,double *x,double *di,
2308  double *d,struct _constraint *cs,double *backup,double *signeq,
2309  struct _violation *sip_viol,void *cd)
2310  {
2311  int i,ii,ij,jj,itry,ikeep,j,job,nlin,mnm,ltem1,ltem2;
2312  bool display,fbind,cdone,fdone,eqdone,reform,sipldone;
2313  double prod1,prod,dummy,fmax1,tolfe,ostep,temp,**adummy,fii;
2314 
2315  nlin=glob_info.nnineq-nineqn;
2316  itry=ii=jj=1;
2317  ostep=*steps=1.e0;
2318  fbind=cdone=fdone=eqdone=false;
2319  dummy=0.e0;
2320  sipldone=(ncsipl==0);
2321  if (glob_log.local) glob_log.dlfeas=false;
2322  ikeep=nlin-*iskp;
2323  prod1=(0.1e0)*grdftd; /* alpha = 0.1e0 */
2324  tolfe=0.e0; /* feasibility tolerance */
2325  adummy=make_dm(1,1);
2326  adummy[1][1]=0.e0;
2327  if (glob_prnt.iter%glob_prnt.iter_mod) display=false;
2328  else display=true;
2329  if (glob_prnt.iprint >= 3 && display)
2330  sbout1(glob_prnt.io,0,"directional deriv ",grdftd,*(adummy+1),
2331  1,2);
2332  w[1]=*fM;
2333  for (;;) {
2334  reform=true;
2335  if (glob_prnt.iprint >= 3 && display)
2336  fprintf(glob_prnt.io,"\t\t\t trial number %22d\n",
2337  itry);
2338  prod=prod1*(*steps);
2339  if (!feasb || (nobL > 1)) prod=prod+tolfe;
2340  for (i=1; i<=nparam; i++) {
2341  if (glob_log.local) xnew[i]=x[i]+(*steps)*di[i];
2342  else xnew[i]=x[i]+(*steps)*di[i]+d[i]*(*steps)*(*steps);
2343  }
2344  pb->invalidateX();
2345  if (glob_prnt.iprint >= 3 && display) {
2346  sbout1(glob_prnt.io,0,"trial step ",*steps,
2347  *(adummy+1),1,2);
2348  sbout1(glob_prnt.io,nparam,"trial point ",
2349  dummy,xnew,2,2);
2350  }
2351 
2352  /* Generate an upper bound step size using the linear constraints
2353  not used in the computation of dtilde */
2354  if (*iskp != 0) {
2355  ostep=*steps;
2356  for (i=ii; i<=*iskp; i++) {
2357  ij=iskip[i];
2358  pb->constr(nparam,ij,xnew+1,&(cs[ij].val),cd);
2359  if (glob_prnt.iprint >= 3 && display) {
2360  if (i==1) fprintf(glob_prnt.io,
2361  "\t\t\t trial constraints %d \t %22.14e\n",ij,
2362  cs[ij].val);
2363  if (i!=1) fprintf(glob_prnt.io,
2364  "\t\t\t\t\t %d \t %22.14e\n",ij,cs[ij].val);
2365  }
2366  if (cs[ij].val<=tolfe) continue;
2367  ii=i;
2368  if (ncsipl && ii>glob_info.nnineq-ncsipl) {
2369  sip_viol->type = CONSTR;
2370  sip_viol->index = ij;
2371  } else {
2372  sip_viol->type = NONE; /* non-SIP constraint violated */
2373  sip_viol->index = 0;
2374  }
2375  goto L1120;
2376  }
2377  *iskp=0;
2378  }
2379 
2380  /* Refine the upper bound using the linear SI constraints not
2381  in Omega_k */
2382  if (!sipldone) {
2383  for (i=jj; i<=ncsipl; i++) {
2384  ij=glob_info.nnineq-ncsipl+i;
2385  if (cs[ij].act_sip||element(iskip,nlin-ikeep,ij))
2386  continue;
2387  pb->constr(nparam,ij,xnew+1,&(cs[ij].val),cd);
2388  if (glob_prnt.iprint >= 3 && display) {
2389  if (i==1) fprintf(glob_prnt.io,
2390  "\t\t\t trial constraints %d \t %22.14e\n",ij,
2391  cs[ij].val);
2392  if (i!=1) fprintf(glob_prnt.io,
2393  "\t\t\t\t\t %d \t %22.14e\n",ij,cs[ij].val);
2394  }
2395  if (cs[ij].val<=tolfe) continue;
2396  jj=i;
2397  sip_viol->type=CONSTR;
2398  sip_viol->index=ij;
2399  goto L1120;
2400  }
2401  sipldone=true;
2402  }
2403  if (nn==0) goto L310;
2404 
2405  /* Check nonlinear constraints */
2406  if (!glob_log.local && fbind) goto L315;
2407  do {
2408  for (i=1; i<=nn; i++) {
2409  *ncg=i;
2410  ii=iact[i];
2411  ij=glob_info.nnineq+neqn;
2412  if (!((ii<=nineqn && istore[ii]==1)||
2413  (ii>glob_info.nnineq && ii<=ij && eqdone))) {
2414  temp=1.e0;
2415  if(ii>glob_info.nnineq && ii<=ij)
2416  temp=signeq[ii-glob_info.nnineq];
2417  pb->constr(nparam,ii,xnew+1,&(cs[ii].val),cd);
2418  cs[ii].val *= temp;
2419  glob_info.ncallg++;
2420  }
2421  if (glob_prnt.iprint>=3 && display) {
2422  if (i==1 && ikeep==nlin) fprintf(glob_prnt.io,
2423  "\t\t\t trial constraints %d \t %22.14e\n",ii,
2424  cs[ii].val);
2425  if (i!=1 || ikeep!=nlin) fprintf(glob_prnt.io,
2426  "\t\t\t\t\t %d \t %22.14e\n",ii,cs[ii].val);
2427  }
2428  if (!(glob_log.local || cs[ii].val<=tolfe)) {
2429  shift(nn,ii,iact);
2430  if (ncsipn && ii>nineqn-ncsipn) {
2431  sip_viol->type=CONSTR;
2432  sip_viol->index=ii;
2433  } else {
2434  sip_viol->type=NONE; /* non-SIP constraint violated */
2435  sip_viol->index=0;
2436  }
2437  goto L1110;
2438  }
2439  if (glob_log.local && cs[ii].val>tolfe) {
2440  if (ncsipn && ii>nineqn-ncsipn) {
2441  sip_viol->type=CONSTR;
2442  sip_viol->index=ii;
2443  } else {
2444  sip_viol->type=NONE; /* non-SIP constraint violated */
2445  sip_viol->index=0;
2446  }
2447  goto L1500;
2448  }
2449  }
2450 L310: cdone=eqdone=true;
2451  if (glob_log.local) glob_log.dlfeas=true; /* dl is feasible */
2452 L315: if (fdone) break;
2453  if (nob>0) fmax1=-bgbnd;
2454  else fmax1=0.e0;
2455  for (i=1; i<=nob; i++) { //CHANGE HERE : i=1 instead of i=0, found by Olivier Stasse
2456  if (nob!=0 && i==0) continue;
2457  *ncf=i;
2458  ii=iact[nn+i];
2459  if (feasb) {
2460  if (!(eqdone || neqn==0)) {
2461  for (j=1; j<=neqn; j++)
2462  pb->constr(nparam,glob_info.nnineq+j,xnew+1,
2463  &(cs[glob_info.nnineq+j].val),cd);
2464  glob_info.ncallg+=neqn;
2465  }
2466  if (neqn != 0) {
2467  if (eqdone) job=20;
2468  if (!eqdone) job=10;
2469  resign(nparam,neqn,psf,*(adummy+1),penp,cs,signeq,
2470  job,10);
2471  }
2472  if (istore[nineqn+ii]!=1 && i!=0) {
2473  pb->obj(nparam,ii,xnew+1,&(ob[ii].val),cd);
2474  glob_info.ncallf++;
2475  }
2476  if (i==0) fii=0.e0;
2477  else fii=ob[ii].val;
2478  if (i==0 && glob_prnt.iprint>=3 && display)
2479  fprintf(glob_prnt.io,
2480  "\t\t\t trial penalty term \t %22.14e\n",-*psf);
2481  if (i==1 && glob_prnt.iprint>=3 && display)
2482  fprintf(glob_prnt.io,
2483  "\t\t\t trial objectives %d \t %22.14e\n",
2484  ii,fii-*psf);
2485  if (i>1 && glob_prnt.iprint>=3 && display)
2486  fprintf(glob_prnt.io,
2487  "\t\t\t\t\t %d \t %22.14e\n",ii,fii-*psf);
2488  } else {
2489  if (istore[ii]!=1) {
2490  pb->constr(nparam,indxob[ii],xnew+1,&(ob[ii].val),cd);
2491  glob_info.ncallg++;
2492  }
2493  if (ob[ii].val>tolfe) reform=false;
2494  if (i==1 && glob_prnt.iprint>2 && display)
2495  fprintf(glob_prnt.io,
2496  "\t\t\t trial objectives %d \t %22.14e\n",
2497  indxob[ii],ob[ii].val);
2498  if (i!=1 && glob_prnt.iprint>2 && display)
2499  fprintf(glob_prnt.io,
2500  "\t\t\t\t\t %d \t %22.14e\n",indxob[ii],
2501  ob[ii].val);
2502  fii=ob[ii].val;
2503  }
2504  fmax1=std::max(fmax1,fii);
2505  if (nobL!=nob) fmax1=std::max(fmax1,-fii);
2506  if (!feasb && reform) continue;
2507  if (!glob_log.local) {
2508  if ((fii-*psf)>(*fMp+prod)) {
2509  fbind=true;
2510  shift(nob,ii,&iact[nn]);
2511  if (nfsip && ii>nob-nfsip) {
2512  sip_viol->type=OBJECT;
2513  sip_viol->index=ii;
2514  } else {
2515  sip_viol->type=NONE;
2516  sip_viol->index=0;
2517  }
2518  goto L1110;
2519  }
2520  if (nobL==nob || (-fii-*psf)<=(*fMp+prod))
2521  continue;
2522  fbind=true;
2523  shift(nob,ii,&iact[nn]);
2524  if (nfsip && ii>nob-nfsip) {
2525  sip_viol->type=OBJECT;
2526  sip_viol->index=ii;
2527  } else {
2528  sip_viol->type=NONE;
2529  sip_viol->index=0;
2530  }
2531  goto L1110;
2532  }
2533  ltem1=(fii-*psf)>(*fMp+prod);
2534  ltem2=(nobL!=nob)&&((-fii-*psf)>(*fMp+prod));
2535  if (ltem1 || ltem2) goto L1500;
2536  }
2537  fbind=false;
2538  fdone=eqdone=true;
2539  } while (!cdone);
2540  if (ostep==*steps) mnm=ikeep+neq-neqn;
2541  if (ostep!=*steps) mnm=ncnstr-nn;
2542  for (i=1; i<=mnm; i++) {
2543  ii=indxcn[i+nn];
2544  if (ikeep!=nlin && ostep==*steps) {
2545  if (i<= ikeep) ii=iskip[nlin+2-i];
2546  else ii=indxcn[nn+i-ikeep+nlin];
2547  }
2548  pb->constr(nparam,ii,xnew+1,&(cs[ii].val),cd);
2549  }
2550  *scvneq=0.e0;
2551  for (i=1; i<=ncnstr; i++) {
2552  if (i>glob_info.nnineq && i<=(glob_info.nnineq+neqn))
2553  *scvneq=*scvneq-cs[i].val;
2554  backup[i]=cs[i].val;
2555  }
2556  for (i=1; i<=nob; i++)
2557  backup[i+ncnstr]=ob[i].val;
2558  if (!feasb && reform) {
2559  for (i=1; i<=nparam; i++)
2560  x[i]=xnew[i];
2561  nstop=0;
2562  goto L1500;
2563  }
2564  if (glob_log.local) *ncg=ncnstr;
2565  if (glob_log.local) glob_log.update=true;
2566  *fM=fmax1;
2567  *fMp=fmax1-*psf;
2568  *fmax=fmax1;
2569  for (i=1; i<=nn; i++)
2570  iact[i]=indxcn[i];
2571  for (i=1; i<=nob; i++)
2572  iact[nn+i]=i;
2573  goto L1500;
2574 L1110:
2575  cdone=fdone=eqdone=reform=false;
2576 L1120:
2577  itry++;
2578  if (glob_info.modec==2) fbind=false;
2579  if (*steps >= 1.e0)
2580  for (i=1; i<=nob+nineqn; i++)
2581  istore[i]=0;
2582  *steps=*steps*0.5e0;
2583  if (*steps<glob_grd.epsmac) break;
2584  }
2585  glob_prnt.info=4;
2586  nstop=0;
2587 L1500:
2588  free_dm(adummy,1);
2589  if (*steps<1.e0) return;
2590  for (i=1; i<=nob+nineqn; i++)
2591  istore[i]=0;
2592  return;
2593  }
2594 
2595 
2596 
2597  /******************************************************************/
2598  /* CFSQP : Update the Hessian matrix using BFGS formula with */
2599  /* Powell's modification. */
2600  /******************************************************************/
2601 
2602  void
2603  OFSQP::hessian(int nparam,int nob,int nfsip,int nobL,int nineqn,int neq,
2604  int neqn,int nn,int ncsipn,int ncnstr,int nfs,int *nstart,
2605  int feasb,double *xnew,struct _parameter *param,
2606  struct _objective *ob,double fmax,double *fM,double *fMp,
2607  double *psf,double *grdpsf,double *penp,struct _constraint *cs,
2608  double *gm,int *indxob,int *indxcn,double *delta,double *eta,
2609  double *gamma,double **hess,double *hd,double steps,int *nrst,
2610  double *signeq,double *span,
2611  double **phess,double *psb,double *psmu,
2612  struct _violation *sip_viol)
2613  {
2614  int i,j,k,ifail,np,mnm;
2615  bool display,done;
2616  double dhd,gammd,etad,dummy,theta,signgj,psfnew,delta_s;
2617  double *tempv;
2618 
2619  /* Check to see whether user-accessible stopping criterion
2620  is satisfied. The check of gLgeps is made just after
2621  computing d0 */
2622 
2623  if (!glob_log.get_ne_mult) {
2624  if (feasb && nstop && !neqn)
2625  if ((fabs(w[1]-fmax) <= objeps) ||
2626  (fabs(w[1]-fmax) <= objrep*fabs(w[1]))) nstop=0;
2627  if (!nstop) {
2628  for (i=1; i<= nparam; i++)
2629  param->x[i]=xnew[i];
2630  pb->invalidateX();
2631  return;
2632  }
2633  }
2634 
2635  delta_s=glob_grd.rteps; /* SIP */
2636  if (glob_prnt.iter%glob_prnt.iter_mod) display=false;
2637  else display=true;
2638  psfnew=0.e0;
2639  glob_prnt.ipd=0;
2640  done=false;
2641  dummy=0.e0;
2642  nullvc(nparam,delta);
2643  nullvc(nparam,eta);
2644  for (j=1; j<=2; j++) {
2645  nullvc(nparam, gamma);
2646  if (nobL>1) {
2647  for (i=1; i<=nparam; i++) {
2648  hd[i]=0.e0;
2649  for (k=1; k<=nob; k++)
2650  hd[i]=hd[i]+ob[k].grad[i]*ob[k].mult;
2651  }
2652  }
2653  if (feasb) {
2654  if (nineqn != 0) {
2655  for (i=1; i<=nparam; i++) {
2656  gamma[i]=0.e0;
2657  for (k=1; k<=nineqn; k++)
2658  gamma[i]=gamma[i]+cs[k].grad[i]*cs[k].mult;
2659  }
2660  }
2661  if (neqn != 0) {
2662  for (i=1; i<=nparam; i++) {
2663  eta[i]=0.e0;
2664  for (k=1; k<=neqn; k++)
2665  eta[i]=eta[i]+cs[glob_info.nnineq+k].grad[i]*
2666  cs[glob_info.nnineq+k].mult;
2667  }
2668  }
2669  }
2670  for (i=1; i<=nparam; i++) {
2671  if (nobL>1) {
2672  if (done) psb[i]=hd[i]+param->mult[i]+gamma[i];
2673  gamma[i]=gamma[i]+hd[i]-grdpsf[i]+eta[i];
2674  } else if (nobL==1) {
2675  if (done) psb[i]=ob[1].grad[i]+param->mult[i]+gamma[i];
2676  gamma[i]=gamma[i]+ob[1].grad[i]-grdpsf[i]+eta[i];
2677  } else if (nobL==0) {
2678  if (done) psb[i]=param->mult[i]+gamma[i];
2679  gamma[i]=gamma[i]-grdpsf[i]+eta[i];
2680  }
2681  if (!done) delta[i]=gamma[i];
2682  }
2683  if (!done && !glob_log.d0_is0) {
2684  if (nn != 0) {
2685  for (i=1; i<=nn; i++) {
2686  if ((feasb) && (i>nineqn)) signgj=signeq[i-nineqn];
2687  if ((!feasb) || (i<=nineqn)) signgj=1.e0;
2688  if ((feasb) && (ncsipn) && (i>nineqn-ncsipn) &&
2689  (cs[indxcn[i]].mult==0.e0)) continue;
2690  glob_grd.valnom=cs[indxcn[i]].val*signgj;
2691  pb->gradcn(nparam,indxcn[i],xnew+1,cs[indxcn[i]].grad+1,param->cd);
2692  }
2693  resign(nparam,neqn,psf,grdpsf,penp,cs,signeq,11,11);
2694  }
2695  for (i=1; i<=nob; i++) {
2696  glob_grd.valnom=ob[i].val;
2697  if ((i<=nob-nfsip)||(i>nob-nfsip &&
2698  ((ob[i].mult !=0.e0)||(ob[i].mult_L !=0.e0)))) {
2699  if (feasb)
2700  pb->gradob(nparam,i,xnew+1,ob[i].grad+1,param->cd);
2701  else pb->gradcn(nparam,indxob[i],xnew+1,ob[i].grad+1,param->cd);
2702  }
2703  }
2704  done=true;
2705  }
2706  if (glob_log.d0_is0) done=true;
2707  }
2708  if (!glob_log.d0_is0) {
2709  if (!(feasb && steps<delta_s && ((sip_viol->type==OBJECT &&
2710  !ob[sip_viol->index].act_sip)||(sip_viol->type==CONSTR &&
2711  !cs[sip_viol->index].act_sip)))) {
2712  if (*nrst<(5*nparam) || steps>0.1e0) {
2713  (*nrst)++;
2714  for (i=1; i<=nparam; i++) {
2715  gamma[i]=gamma[i]-delta[i];
2716  delta[i]=xnew[i]-param->x[i];
2717  }
2718  matrvc(nparam,nparam,hess,delta,hd);
2719  dhd=scaprd(nparam,delta,hd);
2720  if (sqrt(scaprd(nparam,delta,delta)) <= glob_grd.epsmac) {
2721  /* xnew too close to x!! */
2722  nstop=0;
2723  glob_prnt.info=8;
2724  return;
2725  }
2726  gammd=scaprd(nparam,delta,gamma);
2727  if (gammd >= (0.2e0*dhd)) theta=1.e0;
2728  else theta=0.8e0*dhd/(dhd-gammd);
2729  for (i=1; i<=nparam; i++)
2730  eta[i]=hd[i]*(1.e0-theta)+theta*gamma[i];
2731  etad=theta*gammd+(1.e0-theta)*dhd;
2732  for (i=1; i<=nparam; i++) {
2733  for (j=i; j<=nparam; j++) {
2734  hess[i][j]=hess[i][j] - hd[i]*hd[j]/dhd +
2735  eta[i]*eta[j]/etad;
2736  hess[j][i]=hess[i][j];
2737  }
2738  }
2739  } else {
2740  *nrst=0;
2741  diagnl(nparam,1.e0,hess);
2742  }
2743  }
2744  for (i=1; i<=nparam; i++)
2745  param->x[i]=xnew[i];
2746  pb->invalidateX();
2747  }
2748  if (neqn!=0 && (feasb)) {
2749  i=glob_info.nnineq-nineqn;
2750  if (i!=0) {
2751  for (j=1; j<=nparam; j++) {
2752  gamma[j]=0.e0;
2753  for (k=1; k<=i; k++)
2754  gamma[j]=gamma[j]+cs[k+nineqn].grad[j]*
2755  cs[nineqn+k].mult;
2756  }
2757  for (i=1; i<=nparam; i++)
2758  psb[i]=psb[i]+gamma[i];
2759  }
2760  i=neq-neqn;
2761  if (i!=0) {
2762  for (j=1; j<=nparam; j++) {
2763  gamma[j]=0.e0;
2764  for (k=1; k<=i; k++)
2765  gamma[j]=gamma[j]+cs[k+neqn+glob_info.nnineq].grad[j]*
2766  cs[glob_info.nnineq+neqn+k].mult;
2767  }
2768  for (i=1; i<=nparam; i++)
2769  psb[i]=psb[i]+gamma[i];
2770  }
2771  /* Update penalty parameters for nonlinear equality constraints */
2772  estlam(nparam,neqn,&ifail,bgbnd,phess,delta,eta,
2773  gamma,cs,psb,hd,xnew,psmu);
2774  if (glob_log.get_ne_mult) return;
2775  for (i=1; i<=neqn; i++) {
2776  if (ifail != 0 || glob_log.d0_is0) penp[i]=2.e0*penp[i];
2777  else {
2778  etad=psmu[i]+penp[i];
2779  if (etad < 1.e0)
2780  penp[i]=std::max((1.e0-psmu[i]),(2.e0*penp[i]));
2781  }
2782  if (penp[i] > bgbnd) {
2783  nstop=0;
2784  glob_prnt.info=9;
2785  return;
2786  }
2787  }
2788  resign(nparam,neqn,psf,grdpsf,penp,cs,signeq,20,12);
2789  *fMp=*fM-*psf;
2790  }
2791  if (nfs != 0) {
2792  (*nstart)++;
2793  np=indexs(*nstart,nfs);
2794  span[np]=fmax;
2795  for (i=1; i<=neqn; i++)
2796  gm[(np-1)*neqn+i]=cs[glob_info.nnineq+i].val;
2797  if (neqn != 0) {
2798  psfnew=0.e0;
2799  for (i=1; i<=neqn; i++)
2800  psfnew=psfnew+gm[i]*penp[i];
2801  }
2802  *fM=span[1];
2803  *fMp=span[1]-psfnew;
2804  mnm=std::min(*nstart,nfs);
2805  for (i=2; i<=mnm; i++) {
2806  if (neqn != 0) {
2807  psfnew=0.e0;
2808  for (j=1; j<=neqn; j++)
2809  psfnew=psfnew+gm[(i-1)*neqn +j]*penp[j];
2810  }
2811  *fM=std::max(*fM, span[i]);
2812  *fMp=std::max(*fMp,span[i]-psfnew);
2813  }
2814  }
2815  if (glob_prnt.iprint < 3 || !display) return;
2816  for (i=1; i<=nob; i++) {
2817  if (!feasb) {
2818  sbout2(glob_prnt.io,nparam,indxob[i],"gradg(j,",
2819  ")",ob[i].grad);
2820  continue;
2821  }
2822  if (nob>1) sbout2(glob_prnt.io,nparam,i,"gradf(j,",")",
2823  ob[i].grad);
2824  if (nob==1) sbout1(glob_prnt.io,nparam,"gradf(j) ",
2825  dummy,ob[1].grad,2,2);
2826  }
2827  if (ncnstr != 0) {
2828  for (i=1; i<=ncnstr; i++) {
2829  tempv=cs[indxcn[i]].grad;
2830  sbout2(glob_prnt.io,nparam,indxcn[i],"gradg(j,",")",tempv);
2831  }
2832  if (neqn != 0) {
2833  sbout1(glob_prnt.io,nparam,"grdpsf(j) ",
2834  dummy,grdpsf,2,2);
2835  sbout1(glob_prnt.io,neqn,"P ",dummy,
2836  penp,2,2);
2837  sbout1(glob_prnt.io,neqn,"psmu ",dummy,
2838  psmu,2,2);
2839  }
2840  }
2841  sbout1(glob_prnt.io,nparam,"multipliers for x ",dummy,
2842  param->mult,2,2);
2843  if (ncnstr != 0) {
2844  fprintf(glob_prnt.io,"\t\t\t %s\t %22.14e\n",
2845  " for g ",cs[1].mult);
2846  for (j=2; j<=ncnstr; j++)
2847  fprintf(glob_prnt.io," \t\t\t\t\t\t %22.14e\n",cs[j].mult);
2848  }
2849  if (nobL > 1) {
2850  fprintf(glob_prnt.io,"\t\t\t %s\t %22.14e\n",
2851  " for f ",ob[1].mult);
2852  for (j=2; j<=nob; j++)
2853  fprintf(glob_prnt.io," \t\t\t\t\t\t %22.14e\n",ob[j].mult);
2854  }
2855  for (i=1; i<=nparam; i++) {
2856  tempv=colvec(hess,i,nparam);
2857  sbout2(glob_prnt.io,nparam,i,"hess (j,",")",tempv);
2858  free_dv(tempv);
2859  }
2860  return;
2861  }
2862 
2863 
2864  /**************************************************************/
2865  /* CFSQP : Output */
2866  /**************************************************************/
2867 
2868 
2869  void
2870  OFSQP::out(int miter,int nparam,int nob,int nobL,int nfsip,int ncn,
2871  int nn,int nineqn,int ncnstr,int ncsipl,int ncsipn,
2872  int *mesh_pts,double *x,struct _constraint *cs,
2873  struct _objective *ob,double fM,double fmax,
2874  double steps,double sktnom,double d0norm,int feasb)
2875  {
2876  int i,j,index,offset;
2877  bool display;
2878  double SNECV,dummy,*adummy,gmax;
2879 
2880  adummy=make_dv(1);
2881  adummy[1]=0.e0;
2882  dummy=0.e0;
2883  if (glob_prnt.iter>=miter && nstop != 0) {
2884  glob_prnt.info=3;
2885  nstop=0;
2886  if (glob_prnt.iprint==0) goto L9000;
2887  }
2888  if (glob_prnt.iprint==0 && glob_prnt.iter<miter) {
2889  glob_prnt.iter++;
2890  goto L9000;
2891  }
2892  if ((glob_prnt.info>0 && glob_prnt.info<3) || glob_prnt.info==7)
2893  goto L120;
2894  if (glob_prnt.iprint==1 && nstop!=0) {
2895  glob_prnt.iter++;
2896  if (glob_prnt.initvl==0) goto L9000;
2897  if (feasb && nob>0) {
2898  fprintf(glob_prnt.io," objectives\n");
2899  for (i=1; i<=nob-nfsip; i++) {
2900  if (nob==nobL)
2901  fprintf(glob_prnt.io," \t\t\t %22.14e\n",ob[i].val);
2902  else
2903  fprintf(glob_prnt.io," \t\t\t %22.14e\n",fabs(ob[i].val));
2904  }
2905  if (nfsip) {
2906  offset=nob-nfsip;
2907  for (i=1; i<=glob_info.nfsip; i++) {
2908  if (nob==nobL) gmax=ob[++offset].val;
2909  else gmax=fabs(ob[++offset].val);
2910  for (j=2; j<=mesh_pts[i]; j++) {
2911  offset++;
2912  if (nob==nobL && ob[offset].val>gmax)
2913  gmax=ob[offset].val;
2914  else if (nob!=nobL && fabs(ob[offset].val)>gmax)
2915  gmax=fabs(ob[offset].val);
2916  }
2917  fprintf(glob_prnt.io," \t\t\t %22.14e\n",gmax);
2918  }
2919  }
2920  }
2921  if (glob_info.mode==1 && glob_prnt.iter>1 && feasb)
2922  sbout1(glob_prnt.io,0,"objective max4 ",fM,adummy,1,1);
2923  if (nob>1)
2924  sbout1(glob_prnt.io,0,"objmax ",fmax,adummy,1,1);
2925  if (ncnstr==0) fprintf(glob_prnt.io,"\n");
2926  else {
2927  fprintf(glob_prnt.io," constraints\n");
2928  for (i=1; i<=nineqn-ncsipn; i++)
2929  fprintf(glob_prnt.io," \t\t\t %22.14e\n",cs[i].val);
2930  if (ncsipn) {
2931  offset=nineqn-ncsipn;
2932  for (i=1; i<=glob_info.ncsipn; i++) {
2933  gmax=cs[++offset].val;
2934  for (j=2; j<=mesh_pts[glob_info.nfsip+i]; j++) {
2935  offset++;
2936  if (cs[offset].val>gmax) gmax=cs[offset].val;
2937  }
2938  fprintf(glob_prnt.io," \t\t\t %22.14e\n",gmax);
2939  }
2940  }
2941  for (i=nineqn+1; i<=glob_info.nnineq-ncsipl; i++)
2942  fprintf(glob_prnt.io," \t\t\t %22.14e\n",cs[i].val);
2943  if (ncsipl) {
2944  offset=glob_info.nnineq-ncsipl;
2945  for (i=1; i<=glob_info.ncsipl; i++) {
2946  gmax=cs[++offset].val;
2947  if (feasb) index=glob_info.nfsip+glob_info.ncsipn+i;
2948  else index=glob_info.ncsipn+i;
2949  for (j=2; j<=mesh_pts[index]; j++) {
2950  offset++;
2951  if (cs[offset].val>gmax) gmax=cs[offset].val;
2952  }
2953  fprintf(glob_prnt.io," \t\t\t %22.14e\n",gmax);
2954  }
2955  }
2956  for (i=glob_info.nnineq+1; i<=ncnstr; i++)
2957  fprintf(glob_prnt.io," \t\t\t %22.14e\n",cs[i].val);
2958  }
2959  if (ncnstr!=0) fprintf(glob_prnt.io,"\n");
2960  goto L9000;
2961  }
2962  if (glob_prnt.iprint==1 && nstop==0)
2963  fprintf(glob_prnt.io," iteration %26d\n",
2964  glob_prnt.iter);
2965  if (glob_prnt.iprint<=2 && nstop==0)
2966  fprintf(glob_prnt.io," inform %26d\n",
2967  glob_prnt.info);
2968  if (glob_prnt.iprint==1 && nstop==0 && (ncsipl+ncsipn)!=0)
2969  fprintf(glob_prnt.io," |Xi_k| %26d\n",
2970  glob_info.tot_actg_sip);
2971  if (glob_prnt.iprint==1 && nstop==0 && nfsip!=0)
2972  fprintf(glob_prnt.io," |Omega_k| %26d\n",
2973  glob_info.tot_actf_sip);
2974  glob_prnt.iter++;
2975  if (!((glob_prnt.iter)%glob_prnt.iter_mod)) display=true;
2976  else display=(nstop==0);
2977  if (glob_prnt.iter_mod!=1 && display)
2978  fprintf(glob_prnt.io,"\n iteration %26d\n",
2979  glob_prnt.iter-1);
2980  if (glob_prnt.initvl==0 && display)
2981  sbout1(glob_prnt.io,nparam,"x ",dummy,x,2,1);
2982  if (display) {
2983  if (nob>0) {
2984  fprintf(glob_prnt.io," objectives\n");
2985  for (i=1; i<=nob-nfsip; i++) {
2986  if (nob==nobL)
2987  fprintf(glob_prnt.io," \t\t\t %22.14e\n",ob[i].val);
2988  else
2989  fprintf(glob_prnt.io," \t\t\t %22.14e\n",
2990  fabs(ob[i].val));
2991  }
2992  }
2993  if (nfsip) {
2994  offset=nob-nfsip;
2995  if (feasb) index=glob_info.nfsip;
2996  else index=glob_info.ncsipn;
2997  for (i=1; i<=index; i++) {
2998  if (nob==nobL) gmax=ob[++offset].val;
2999  else gmax=fabs(ob[++offset].val);
3000  for (j=2; j<=mesh_pts[i]; j++) {
3001  offset++;
3002  if (nob==nobL && ob[offset].val>gmax)
3003  gmax=ob[offset].val;
3004  else if (nob!=nobL && fabs(ob[offset].val)>gmax)
3005  gmax=fabs(ob[offset].val);
3006  }
3007  fprintf(glob_prnt.io," \t\t\t %22.14e\n",gmax);
3008  }
3009  }
3010  }
3011  if (glob_info.mode==1 && glob_prnt.iter>1 && display)
3012  sbout1(glob_prnt.io,0,"objective max4 ",fM,adummy,1,1);
3013  if (nob>1 && display)
3014  sbout1(glob_prnt.io,0,"objmax ",fmax,adummy,1,1);
3015  if (ncnstr != 0 && display ) {
3016  fprintf(glob_prnt.io," constraints\n");
3017  for (i=1; i<=nineqn-ncsipn; i++)
3018  fprintf(glob_prnt.io," \t\t\t %22.14e\n",cs[i].val);
3019  if (ncsipn) {
3020  offset=nineqn-ncsipn;
3021  for (i=1; i<=glob_info.ncsipn; i++) {
3022  gmax=cs[++offset].val;
3023  for (j=2; j<=mesh_pts[glob_info.nfsip+i]; j++) {
3024  offset++;
3025  if (cs[offset].val>gmax) gmax=cs[offset].val;
3026  }
3027  fprintf(glob_prnt.io," \t\t\t %22.14e\n",gmax);
3028  }
3029  }
3030  for (i=nineqn+1; i<=glob_info.nnineq-ncsipl; i++)
3031  fprintf(glob_prnt.io," \t\t\t %22.14e\n",cs[i].val);
3032  if (ncsipl) {
3033  offset=glob_info.nnineq-ncsipl;
3034  for (i=1; i<=glob_info.ncsipl; i++) {
3035  gmax=cs[++offset].val;
3036  if (feasb) index=glob_info.nfsip+glob_info.ncsipn+i;
3037  else index=glob_info.ncsipn+i;
3038  for (j=2; j<=mesh_pts[index];
3039  j++) {
3040  offset++;
3041  if (cs[offset].val>gmax) gmax=cs[offset].val;
3042  }
3043  fprintf(glob_prnt.io," \t\t\t %22.14e\n",gmax);
3044  }
3045  }
3046  for (i=glob_info.nnineq+1; i<=ncnstr; i++)
3047  fprintf(glob_prnt.io," \t\t\t %22.14e\n",cs[i].val);
3048  if (feasb) {
3049  SNECV=0.e0;
3050  for (i=glob_info.nnineq+1; i<=glob_info.nnineq+nn-nineqn; i++)
3051  SNECV=SNECV+fabs(cs[i].val);
3052  if (glob_prnt.initvl==0 && (nn-nineqn)!=0)
3053  sbout1(glob_prnt.io,0,"SNECV ",
3054  SNECV,adummy,1,1);
3055  }
3056  }
3057  if (glob_prnt.iter<=1 && display) {
3058  fprintf(glob_prnt.io," \n");
3059  fprintf(glob_prnt.io," iteration %26d\n",
3060  glob_prnt.iter);
3061  goto L9000;
3062  }
3063  if (glob_prnt.iprint>=2 && glob_prnt.initvl==0 && display)
3064  sbout1(glob_prnt.io,0,"step ",steps,adummy,1,1);
3065  if (glob_prnt.initvl==0 && display &&
3066  (nstop==0 || glob_prnt.info!=0 || glob_prnt.iprint==2)) {
3067  sbout1(glob_prnt.io,0,"d0norm ",d0norm,adummy,1,1);
3068  sbout1(glob_prnt.io,0,"ktnorm ",sktnom,adummy,1,1);
3069  }
3070  if (glob_prnt.initvl==0 && feasb && display)
3071  fprintf(glob_prnt.io," ncallf %26d\n",
3072  glob_info.ncallf);
3073  if (glob_prnt.initvl==0 && (nn!=0 || !feasb) && display)
3074  fprintf(glob_prnt.io," ncallg %26d\n",
3075  glob_info.ncallg);
3076  if (glob_prnt.iprint>=3 && glob_prnt.iter_mod!=1 && nstop!=0
3077  && !(glob_prnt.iter%glob_prnt.iter_mod))
3078  fprintf(glob_prnt.io,
3079  "\n The following was calculated during iteration %5d:\n",
3080  glob_prnt.iter);
3081  if (nstop != 0 && (glob_prnt.iter_mod==1))
3082  fprintf(glob_prnt.io,"\n iteration %26d\n",
3083  glob_prnt.iter);
3084 L120:
3085  if (nstop!=0 || glob_prnt.iprint==0) goto L9000;
3086  fprintf(glob_prnt.io,"\n");
3087  if (glob_prnt.iprint>=3)
3088  fprintf(glob_prnt.io," inform %26d\n",
3089  glob_prnt.info);
3090  if (glob_prnt.info==0) fprintf(glob_prnt.io,
3091  "\nNormal termination: You have obtained a solution !!\n");
3092  if (glob_prnt.info==0 && sktnom>0.1e0) fprintf(glob_prnt.io,
3093  "Warning: Norm of Kuhn-Tucker vector is large !!\n");
3094  if (glob_prnt.info==3) {
3095  fprintf(glob_prnt.io,
3096  "\nWarning: Maximum iterations have been reached before\n");
3097  fprintf(glob_prnt.io,"obtaining a solution !!\n\n");
3098  }
3099  if (glob_prnt.info==4) {
3100  fprintf(glob_prnt.io,
3101  "\nError : Step size has been smaller than the computed\n");
3102  fprintf(glob_prnt.io,"machine precision !!\n\n");
3103  }
3104  if (glob_prnt.info==5) fprintf(glob_prnt.io,
3105  "\nError: Failure in constructing d0 !!\n\n");
3106  if (glob_prnt.info==6) fprintf(glob_prnt.io,
3107  "\nError: Failure in constructing d1 !!\n\n");
3108  if (glob_prnt.info==8) {
3109  fprintf(glob_prnt.io,
3110  "\nError: The new iterate is numerically equivalent to the\n");
3111  fprintf(glob_prnt.io,
3112  "previous iterate, though the stopping criterion is not \n");
3113  fprintf(glob_prnt.io,"satisfied\n");
3114  }
3115  if (glob_prnt.info==9) {
3116  fprintf(glob_prnt.io,
3117  "\nError: Could not satisfy nonlinear equality constraints -\n");
3118  fprintf(glob_prnt.io," Penalty parameter too large\n");
3119  }
3120  fprintf(glob_prnt.io,"\n");
3121 L9000:
3122  free_dv(adummy);
3123  glob_prnt.initvl=0;
3124  return;
3125  }
3126 
3127 
3128  /************************************************************/
3129  /* Utility functions used by CFSQP - */
3130  /* Available functions: */
3131  /* diagnl error estlam */
3132  /* colvec scaprd small */
3133  /* fool matrvc matrcp */
3134  /* nullvc resign sbout1 */
3135  /* sbout2 shift slope */
3136  /* fuscmp indexs element */
3137  /************************************************************/
3138 
3139  /************************************************************/
3140  /* Set a=diag*I, a diagonal matrix */
3141  /************************************************************/
3142 
3143 
3144  void OFSQP::diagnl(int nrowa,double diag,double **a)
3145  {
3146  int i,j;
3147 
3148  for (i=1; i<=nrowa; i++) {
3149  for (j=i; j<=nrowa; j++) {
3150  a[i][j]=0.e0;
3151  a[j][i]=0.e0;
3152  }
3153  a[i][i]=diag;
3154  }
3155  return;
3156  }
3157 
3158  /***********************************************************/
3159  /* Display error messages */
3160  /***********************************************************/
3161 
3162 
3163  void OFSQP::error(const char string[],int *inform)
3164  {
3165  if (glob_prnt.iprint>0)
3166  fprintf(stderr,"%s\n",string);
3167  *inform=7;
3168  return;
3169  }
3170 
3171 
3172  /***********************************************************/
3173  /* Compute an estimate of multipliers for updating */
3174  /* penalty parameter (nonlinear equality constraints) */
3175  /***********************************************************/
3176 
3177 
3178  void
3179  OFSQP::estlam(int nparam,int neqn,int *ifail,double bigbnd,double **hess,
3180  double *cvec,double *a,double *b,struct _constraint *cs,
3181  double *psb,double *bl,double *bu,double *x)
3182  {
3183  int i,j,zero,one,lwar2,mnn,iout;
3184  double *ctemp;
3185 
3186  for (i=1; i<=neqn; i++) {
3187  bl[i]= (-bigbnd);
3188  bu[i]= bigbnd;
3189  cvec[i]=scaprd(nparam,cs[i+glob_info.nnineq].grad,psb);
3190  x[i]= 0.e0;
3191  for (j=i; j<=neqn; j++) {
3192  hess[i][j]=scaprd(nparam,cs[i+glob_info.nnineq].grad,
3193  cs[j+glob_info.nnineq].grad);
3194  hess[j][i]=hess[i][j];
3195  }
3196  }
3197  zero=0;
3198  one=1;
3199  iw[1]=1;
3200  mnn=2*neqn;
3201  ctemp=convert(hess,neqn,neqn);
3202  lwar2=lenw-1;
3203  iout=6;
3204 
3205  ObjQLD::ql0001_(&zero,&zero,&one,&neqn,&neqn,&mnn,(ctemp+1),(cvec+1),
3206  (a+1),(b+1),(bl+1),(bu+1),(x+1),(w+1),&iout,ifail,
3207  &zero,(w+3),&lwar2,(iw+1),&leniw,&glob_grd.epsmac);
3208 
3209  free_dv(ctemp);
3210  return;
3211  }
3212 
3213 
3214  /**************************************************************/
3215  /* Extract a column vector from a matrix */
3216  /**************************************************************/
3217 
3218 
3219  double *OFSQP::colvec(double **a,int col,int nrows)
3220  {
3221  double *temp;
3222  int i;
3223 
3224  temp=make_dv(nrows);
3225  for (i=1;i<=nrows;i++)
3226  temp[i]=a[i][col];
3227  return temp;
3228  }
3229 
3230 
3231  /************************************************************/
3232  /* Compute the scalar product z=x'y */
3233  /************************************************************/
3234 
3235 
3236  double OFSQP::scaprd(int n,double *x,double *y)
3237  {
3238  int i;
3239  double z;
3240 
3241  z=0.e0;
3242  for (i=1;i<=n;i++)
3243  z=z+x[i]*y[i];
3244  return z;
3245  }
3246 
3247 
3248  /***********************************************************/
3249  /* Used by small() */
3250  /***********************************************************/
3251 
3252 
3253  void OFSQP::fool(double x,double y,double *z)
3254  {
3255  *z=x*y+y;
3256  return;
3257  }
3258 
3259 
3260  /**********************************************************/
3261  /* Computes the machine precision */
3262  /**********************************************************/
3263 
3264 
3265  double OFSQP::small()
3266  {
3267  double one,two,z,tsmall;
3268 
3269  one=1.e0;
3270  two=2.e0;
3271  tsmall=one;
3272  do {
3273  tsmall=tsmall/two;
3274  fool(tsmall,one,&z);
3275  } while (z>1.e0);
3276  return tsmall*two*two;
3277  }
3278 
3279 
3280  /**********************************************************/
3281  /* Compares value with threshold to see if exceeds */
3282  /**********************************************************/
3283 
3284 
3285  bool OFSQP::fuscmp(double val,double thrshd)
3286  {
3287  bool temp;
3288 
3289  if (fabs(val)<=thrshd) temp=false;
3290  else temp=true;
3291  return temp;
3292  }
3293 
3294 
3295  /**********************************************************/
3296  /* Find the residue of i with respect to nfs */
3297  /**********************************************************/
3298 
3299 
3300  int OFSQP::indexs(int i,int nfs)
3301  {
3302  int mm=i;
3303 
3304  while (mm>nfs) mm -= nfs;
3305  return mm;
3306  }
3307 
3308 
3309  /*********************************************************/
3310  /* Copies matrix a to matrix b */
3311  /*********************************************************/
3312 
3313 
3314  void OFSQP::matrcp(int ndima,double **a,int ndimb,double **b)
3315  {
3316  int i,j;
3317 
3318  for (i=1; i<=ndima; i++)
3319  for (j=1; j<=ndima; j++)
3320  b[i][j]=a[i][j];
3321  if (ndimb<=ndima) return;
3322  for (i=1; i<=ndimb; i++) {
3323  b[ndimb][i]=0.e0;
3324  b[i][ndimb]=0.e0;
3325  }
3326  return;
3327  }
3328 
3329  /*******************************************************/
3330  /* Computes y=ax */
3331  /*******************************************************/
3332 
3333 
3334  void OFSQP::matrvc(int la,int na,double **a,double *x,double *y)
3335  {
3336  int i,j;
3337  double yi;
3338 
3339  for (i=1; i<=la; i++) {
3340  yi=0.e0;
3341  for (j=1; j<=na; j++)
3342  yi=yi + a[i][j]*x[j];
3343  y[i]=yi;
3344  }
3345  return;
3346  }
3347 
3348  /******************************************************/
3349  /* Set x=0 */
3350  /******************************************************/
3351 
3352 
3353  void OFSQP::nullvc(int nparam,double *x)
3354  {
3355  int i;
3356 
3357  for (i=1; i<=nparam; i++)
3358  x[i]=0.e0;
3359  return;
3360  }
3361 
3362  /*********************************************************/
3363  /* job1=10: g*signeq, job1=11: gradg*signeq, */
3364  /* job1=12: job1=10&11 */
3365  /* job1=20: do not change sign */
3366  /* job2=10: psf, job2=11: grdpsf, */
3367  /* job2=12: job2=10&11 */
3368  /* job2=20: do not change sign */
3369  /*********************************************************/
3370 
3371 
3372  void
3373  OFSQP::resign(int n,int neqn,double *psf,double *grdpsf,double *penp,
3374  struct _constraint *cs,double *signeq,int job1,int job2)
3375  {
3376  int i,j,nineq;
3377 
3378  nineq=glob_info.nnineq;
3379  if (job2==10 || job2==12) *psf=0.e0;
3380  for (i=1; i<=neqn; i++) {
3381  if (job1==10 || job1==12) cs[i+nineq].val=
3382  signeq[i]*cs[i+nineq].val;
3383  if (job2==10 || job2==12) *psf=*psf+cs[i+nineq].val*penp[i];
3384  if (job1==10 || job1==20) continue;
3385  for (j=1; j<=n; j++)
3386  cs[i+nineq].grad[j]=cs[i+nineq].grad[j]*signeq[i];
3387  }
3388  if (job2==10 || job2==20) return;
3389  nullvc(n,grdpsf);
3390  for (i=1; i<=n; i++)
3391  for (j=1; j<=neqn; j++)
3392  grdpsf[i]=grdpsf[i]+cs[j+nineq].grad[i]*penp[j];
3393  return;
3394  }
3395 
3396  /**********************************************************/
3397  /* Write output to file */
3398  /**********************************************************/
3399 
3400 
3401  void
3402  OFSQP::sbout1(FILE *io,int n,const char *s1,double z,double *z1,int job,int level)
3403  {
3404  int j;
3405 
3406  if (job != 2) {
3407  if (level == 1) fprintf(io," %s\t %22.14e\n",s1,z);
3408  if (level == 2) fprintf(io,"\t\t\t %s\t %22.14e\n",s1,z);
3409  return;
3410  }
3411  if (n==0) return;
3412  if (level == 1) fprintf(io," %s\t %22.14e\n",s1,z1[1]);
3413  if (level == 2) fprintf(io,"\t\t\t %s\t %22.14e\n",s1,z1[1]);
3414  for (j=2; j<=n; j++) {
3415  if (level == 1) fprintf(io," \t\t\t %22.14e\n",z1[j]);
3416  if (level == 2) fprintf(io," \t\t\t\t\t\t %22.14e\n",z1[j]);
3417  }
3418  return;
3419  }
3420 
3421  /*********************************************************/
3422  /* Write output to file */
3423  /*********************************************************/
3424 
3425 
3426  void
3427  OFSQP::sbout2(FILE *io,int n,int i,const char *s1,const char *s2,double *z)
3428  {
3429  int j;
3430 
3431  fprintf(io,"\t\t\t %8s %5d %1s\t %22.14e\n",s1,i,s2,z[1]);
3432  for (j=2; j<=n; j++)
3433  fprintf(io,"\t\t\t\t\t\t %22.14e\n",z[j]);
3434  return;
3435  }
3436 
3437 
3438  /*********************************************************/
3439  /* Extract ii from iact and push in front */
3440  /*********************************************************/
3441 
3442 
3443  void OFSQP::shift(int n,int ii,int *iact)
3444  {
3445  int j,k;
3446 
3447  if (ii == iact[1]) return;
3448  for (j=1; j<=n; j++) {
3449  if (ii != iact[j]) continue;
3450  for (k=j; k>=2; k--)
3451  iact[k]=iact[k-1];
3452  break;
3453  }
3454  if (n!=0) iact[1]=ii;
3455  return;
3456  }
3457 
3458  /****************************************************************/
3459  /* job=0 : Compute the generalized gradient of the minimax */
3460  /* job=1 : Compute rhog in mode = 1 */
3461  /****************************************************************/
3462 
3463 
3464  double
3465  OFSQP::slope(int nob,int nobL,int neqn,int nparam,int feasb,
3466  struct _objective *ob,double *grdpsf,double *x,double *y,
3467  double fmax,double theta,int job,double *prev,int old)
3468  {
3469  int i;
3470  double slope1,rhs,rhog,grdftx,grdfty,diff,grpstx,grpsty;
3471  double tslope;
3472 
3473  tslope=-bgbnd;
3474  if (feasb && nob==0) tslope=0.e0;
3475  if (neqn==0 || !feasb) {
3476  grpstx=0.e0;
3477  grpsty=0.e0;
3478  } else {
3479  grpstx=scaprd(nparam,grdpsf,x);
3480  grpsty=scaprd(nparam,grdpsf,y);
3481  }
3482  for (i=1; i<=nob; i++) {
3483  if (old) slope1=prev[i]+scaprd(nparam,ob[i].grad,x);
3484  else slope1=ob[i].val+scaprd(nparam,ob[i].grad,x);
3485  tslope=std::max(tslope,slope1);
3486  if (nobL != nob) tslope=std::max(tslope,-slope1);
3487  }
3488  tslope=tslope-fmax-grpstx;
3489  if (job == 0) return tslope;
3490  rhs=theta*tslope+fmax;
3491  rhog=1.e0;
3492  for (i=1; i<=nob; i++) {
3493  grdftx=scaprd(nparam,ob[i].grad,x)-grpstx;
3494  grdfty=scaprd(nparam,ob[i].grad,y)-grpsty;
3495  diff=grdfty-grdftx;
3496  if (diff <= 0.e0) continue;
3497  rhog=std::min(rhog,(rhs-ob[i].val-grdftx)/diff);
3498  if (nobL != nob) rhog=std::min(rhog,-(rhs+ob[i].val+grdftx)/diff);
3499  }
3500  tslope=rhog;
3501  return tslope;
3502  }
3503 
3504  /************************************************************/
3505  /* Determine whether index is in set */
3506  /************************************************************/
3507 
3508 
3509  bool OFSQP::element(int *set,int length,int index)
3510  {
3511  int i;
3512  bool temp;
3513 
3514  temp=false;
3515  for (i=1; i<=length; i++) {
3516  if (set[i]==0) break;
3517  if (set[i]==index) {
3518  temp=true;
3519  return temp;
3520  }
3521  }
3522  return temp;
3523  }
3524 
3525 
3526 
3527 
3528  /*************************************************************/
3529  /* Memory allocation utilities for CFSQP */
3530  /* */
3531  /* All vectors and matrices are intended to */
3532  /* be subscripted from 1 to n, NOT 0 to n-1. */
3533  /* The addreses returned assume this convention. */
3534  /*************************************************************/
3535 
3536  /*************************************************************/
3537  /* Create double precision vector */
3538  /*************************************************************/
3539 
3540 
3541  double *
3542  OFSQP::make_dv(int len)
3543  {
3544  double *v;
3545 
3546  if (!len) len=1;
3547  v=(double *)calloc(len,sizeof(double));
3548  if (!v) {
3549  fprintf(stderr,"Run-time error in make_dv");
3550  exit(1);
3551  }
3552  return --v;
3553  }
3554 
3555  /*************************************************************/
3556  /* Create integer vector */
3557  /*************************************************************/
3558 
3559 
3560  int *
3561  OFSQP::make_iv(int len)
3562  {
3563  int *v;
3564 
3565  if (!len) len=1;
3566  v=(int *)calloc(len,sizeof(int));
3567  if (!v) {
3568  fprintf(stderr,"Run-time error in make_iv");
3569  exit(1);
3570  }
3571  return --v;
3572  }
3573 
3574  /*************************************************************/
3575  /* Create a double precision matrix */
3576  /*************************************************************/
3577 
3578 
3579  double **
3580  OFSQP::make_dm(int rows, int cols)
3581  {
3582  double **temp;
3583  int i;
3584 
3585  if (rows == 0) rows=1;
3586  if (cols == 0) cols=1;
3587  temp=(double **)calloc(rows,sizeof(double *));
3588  if (!temp) {
3589  fprintf(stderr,"Run-time error in make_dm");
3590  exit(1);
3591  }
3592  temp--;
3593  for (i=1; i<=rows; i++) {
3594  temp[i]=(double *)calloc(cols,sizeof(double));
3595  if (!temp[i]) {
3596  fprintf(stderr,"Run-time error in make_dm");
3597  exit(1);
3598  }
3599  temp[i]--;
3600  }
3601  return temp;
3602  }
3603 
3604  /*************************************************************/
3605  /* Free a double precision vector */
3606  /*************************************************************/
3607 
3608 
3609  void
3610  OFSQP::free_dv(double *v)
3611  {
3612  free((char *) (v+1));
3613  }
3614 
3615  /*************************************************************/
3616  /* Free an integer vector */
3617  /*************************************************************/
3618 
3619 
3620  void
3621  OFSQP::free_iv(int *v)
3622  {
3623  free((char *) (v+1));
3624  }
3625 
3626  /*************************************************************/
3627  /* Free a double precision matrix */
3628  /*************************************************************/
3629 
3630 
3631  void
3632  OFSQP::free_dm(double **m,int rows)
3633  {
3634  int i;
3635 
3636  if (!rows) rows=1;
3637  for (i=1; i<=rows; i++) free((char *) (m[i]+1));
3638  free ((char *) (m+1));
3639  }
3640 
3641  /*************************************************************/
3642  /* Converts matrix a into a form that can easily be */
3643  /* passed to a FORTRAN subroutine. */
3644  /*************************************************************/
3645 
3646 
3647  double *
3648  OFSQP::convert(double **a,int m,int n)
3649  {
3650  double *temp;
3651  int i,j;
3652 
3653  temp = make_dv(m*n);
3654 
3655  for (i=1; i<=n; i++) /* loop thru columns */
3656  for (j=1; j<=m; j++) /* loop thru row */
3657  temp[(m*(i-1)+j)] = a[j][i];
3658 
3659  return temp;
3660  }
3661 
3662 
3663 
3664 
3665 
3666 
3667 
3668  /**********************************************************
3669  * E X A M P L E 1 *
3670  **********************************************************/
3671 
3672  class Ex1Pb : public OFSQPProblem
3673  {
3674 
3675  void obj(int nparam, int j, double* x, double* fj, void* cd)
3676  {
3677  *fj=pow((x[0]+3.e0*x[1]+x[2]),2.e0)+4.e0*pow((x[0]-x[1]),2.e0);
3678  return;
3679  }
3680 
3681  void gradob(int nparam, int j, double* x, double* gradfj, void* cd)
3682  {
3683  double fa,fb;
3684 
3685  fa=2.e0*(x[0]+3.e0*x[1]+x[2]);
3686  fb=8.e0*(x[0]-x[1]);
3687  gradfj[0]=fa+fb;
3688  gradfj[1]=fa*3.e0-fb;
3689  gradfj[2]=fa;
3690  return;
3691  }
3692 
3693  void constr(int nparam, int j, double* x, double* gj, void* cd)
3694  {
3695  switch (j) {
3696  case 1:
3697  *gj=pow(x[0],3.e0)-6.e0*x[1]-4.e0*x[2]+3.e0;
3698  break;
3699  case 2:
3700  *gj=1.e0-x[0]-x[1]-x[2];
3701  break;
3702  }
3703  return;
3704  }
3705 
3706  void gradcn(int nparam, int j, double* x, double* gradgj, void* cd)
3707  {
3708  switch (j) {
3709  case 1:
3710  gradgj[0]=3.e0*x[0]*x[0];
3711  gradgj[1]=-6.e0;
3712  gradgj[2]=-4.e0;
3713  break;
3714  case 2:
3715  gradgj[0]=gradgj[1]=gradgj[2]=-1.e0;
3716  break;
3717  }
3718  return;
3719  }
3720  };
3721 
3723  {
3724  Ex1Pb pb;
3725 
3726  OFSQP solver;
3727  int nparam, nf, nineq, neq, mode, iprint, miter, neqn, nineqn, ncsrl, ncsrn, nfsr, mesh_pts[1], inform;
3728  double bigbnd, eps, epsneq, udelta;
3729  double *x, *bl, *bu, *f, *g, *lambda;
3730 
3731  mode = 110;
3732  iprint = 1;
3733  miter = 500;
3734  bigbnd = 1.e10;
3735  eps = 1.e-8;
3736  epsneq = 0.e0;
3737  udelta = 0.e0;
3738  nparam = 3;
3739  nf = 1;
3740  neqn = 0;
3741  nineqn = 1;
3742  nineq = 1;
3743  neq = 1;
3744  ncsrl = ncsrn = nfsr = mesh_pts[0] = 0;
3745  bl = new double[nparam];
3746  bu = new double[nparam];
3747  x = new double[nparam];
3748  f = new double[nf+1];
3749  g = new double[nineq+neq+1];
3750  lambda = new double[nineq+neq+nf+nparam];
3751 
3752  bl[0] = bl[1] = bl[2] = 0.e0;
3753  bu[0] = bu[1] = bu[2] = bigbnd;
3754 
3755  x[0] = 0.1e0;
3756  x[1] = 0.7e0;
3757  x[2] = 0.2e0;
3758 
3759  solver.cfsqp(nparam, nf, nfsr, nineqn, nineq, neqn, neq, ncsrl, ncsrn, mesh_pts, mode, iprint, miter, &inform, bigbnd, eps,
3760  epsneq, udelta, bl, bu, x, f, g, lambda, pb, 0x0);
3761 
3762  delete bl;
3763  delete bu;
3764  delete x;
3765  delete f;
3766  delete g;
3767  delete lambda;
3768  }
3769 
3770 
3771  /**********************************************************
3772  * E X A M P L E 2 *
3773  **********************************************************/
3774 
3775  class Ex2Pb : public OFSQPProblem
3776  {
3777  void obj(int nparam, int j, double* x, double* fj, void* cd)
3778  {
3779  double pi,theta;
3780  int i;
3781  pi=3.14159265358979e0;
3782  theta=pi*(8.5e0+j*0.5e0)/180.e0;
3783  *fj=0.e0;
3784  for (i=0; i<=5; i++)
3785  *fj=*fj+cos(2.e0*pi*x[i]*sin(theta));
3786  *fj=2.e0*(*fj+cos(2.e0*pi*3.5e0*sin(theta)))/15.e0+1.e0/15.e0;
3787  return;
3788  }
3789 
3790  void constr(int nparam, int j, double* x, double* gj, void* cd)
3791  {
3792  double ss=0.425e0;
3793  switch (j)
3794  {
3795  case 1: *gj=ss-x[0]; break;
3796  case 2: *gj=ss+x[0]-x[1]; break;
3797  case 3: *gj=ss+x[1]-x[2]; break;
3798  case 4: *gj=ss+x[2]-x[3]; break;
3799  case 5: *gj=ss+x[3]-x[4]; break;
3800  case 6: *gj=ss+x[4]-x[5]; break;
3801  case 7: *gj=ss+x[5]-3.5e0; break;
3802  }
3803  return;
3804  }
3805  };
3806 
3808  {
3809  Ex2Pb pb;
3810 
3811  OFSQP solver;
3812  int nparam, nf, nineq, neq, mode, iprint, miter, neqn, nineqn, ncsrl, ncsrn, nfsr, mesh_pts[1], inform;
3813  double bigbnd, eps, epsneq, udelta;
3814  double *x, *bl, *bu, *f, *g, *lambda;
3815 
3816  mode = 111;
3817  iprint = 1;
3818  miter = 500;
3819  bigbnd = 1.e10;
3820  eps = 1.e-8;
3821  epsneq = 0.e0;
3822  udelta = 0.e0;
3823  nparam = 6;
3824  nf = 163;
3825  neqn = 0;
3826  nineqn = 0;
3827  nineq = 7;
3828  neq = 0;
3829  ncsrl = ncsrn = nfsr = mesh_pts[0] = 0;
3830  bl = new double[nparam];
3831  bu = new double[nparam];
3832  x = new double[nparam];
3833  f = new double[nf+1];
3834  g = new double[nineq+neq+1];
3835  lambda = new double[nineq+neq+nf+nparam];
3836 
3837  bl[0] = bl[1] = bl[2] = bl[3] = bl[4] = bl[5] = -bigbnd;
3838  bu[0] = bu[1] = bu[2] = bu[3] = bu[4] = bu[5] = bigbnd;
3839 
3840  x[0] = 0.5e0;
3841  x[1] = 1.0e0;
3842  x[2] = 1.5e0;
3843  x[3] = 2.0e0;
3844  x[4] = 2.5e0;
3845  x[5] = 3.0e0;
3846 
3847  solver.cfsqp(nparam, nf, nfsr, nineqn, nineq, neqn, neq, ncsrl, ncsrn, mesh_pts, mode, iprint, miter, &inform, bigbnd, eps,
3848  epsneq, udelta, bl, bu, x, f, g, lambda, pb, 0x0);
3849 
3850  delete bl;
3851  delete bu;
3852  delete x;
3853  delete f;
3854  delete g;
3855  delete lambda;
3856  }
3857 
3858 
3860  {
3861  Ex2Pb pb;
3862 
3863  OFSQP solver;
3864  int nparam, nf, nineq, neq, mode, iprint, miter, neqn, nineqn, ncsrl, ncsrn, nfsr, mesh_pts[1], inform;
3865  double bigbnd, eps, epsneq, udelta;
3866  double *x, *bl, *bu, *f, *g, *lambda;
3867 
3868  mode = 111;
3869  iprint = 1;
3870  miter = 500;
3871  bigbnd = 1.e10;
3872  eps = 1.e-8;
3873  epsneq = 0.e0;
3874  udelta = 0.e0;
3875  nparam = 6;
3876  nf = 1;
3877  nfsr = 1;
3878  mesh_pts[0] = 163;
3879  neqn = 0;
3880  nineqn = 0;
3881  nineq = 7;
3882  neq = 0;
3883  ncsrl = ncsrn = 0;
3884  bl = new double[nparam];
3885  bu = new double[nparam];
3886  x = new double[nparam];
3887  f = new double[mesh_pts[0]+1];
3888  g = new double[nineq+neq+1];
3889  lambda = new double[nineq+neq+mesh_pts[0]+nparam+1];
3890 
3891  bl[0] = bl[1] = bl[2] = bl[3] = bl[4] = bl[5] = -bigbnd;
3892  bu[0] = bu[1] = bu[2] = bu[3] = bu[4] = bu[5] = bigbnd;
3893 
3894  x[0] = 0.5e0;
3895  x[1] = 1.0e0;
3896  x[2] = 1.5e0;
3897  x[3] = 2.0e0;
3898  x[4] = 2.5e0;
3899  x[5] = 3.0e0;
3900 
3901  solver.cfsqp(nparam, nf, nfsr, nineqn, nineq, neqn, neq, ncsrl, ncsrn, mesh_pts, mode, iprint, miter, &inform, bigbnd, eps,
3902  epsneq, udelta, bl, bu, x, f, g, lambda, pb, 0x0);
3903 
3904  delete bl;
3905  delete bu;
3906  delete x;
3907  delete f;
3908  delete g;
3909  delete lambda;
3910  }
3911 
3912 
3913  /**********************************************************
3914  * E X A M P L E 3 *
3915  **********************************************************/
3916  class Ex3Pb : public OFSQPProblem
3917  {
3918  void obj(int nparam, int j, double* x, double* fj, void* cd)
3919  {
3920  *fj=x[0]*x[3]*(x[0]+x[1]+x[2])+x[2];
3921  return;
3922  }
3923 
3924  void gradob(int nparam, int j, double* x, double* gradfj, void* cd)
3925  {
3926  gradfj[0]=x[3]*(x[0]+x[1]+x[2])+x[0]*x[3];
3927  gradfj[1]=x[0]*x[3];
3928  gradfj[2]=x[0]*x[3]+1.e0;
3929  gradfj[3]=x[0]*(x[0]+x[1]+x[2]);
3930  return;
3931  }
3932 
3933  void constr(int nparam, int j, double* x, double* gj, void* cd)
3934  {
3935  switch (j) {
3936  case 1:
3937  *gj=25.e0-x[0]*x[1]*x[2]*x[3];
3938  break;
3939  case 2:
3940  *gj=x[0]*x[0]+x[1]*x[1]+x[2]*x[2]+x[3]*x[3]-40.e0;
3941  break;
3942  }
3943  return;
3944  }
3945 
3946  void gradcn(int nparam, int j, double* x, double* gradgj, void* cd)
3947  {
3948  switch (j) {
3949  case 1:
3950  gradgj[0]=-x[1]*x[2]*x[3];
3951  gradgj[1]=-x[0]*x[2]*x[3];
3952  gradgj[2]=-x[0]*x[1]*x[3];
3953  gradgj[3]=-x[0]*x[1]*x[2];
3954  break;
3955  case 2:
3956  gradgj[0]=2.e0*x[0];
3957  gradgj[1]=2.e0*x[1];
3958  gradgj[2]=2.e0*x[2];
3959  gradgj[3]=2.e0*x[3];
3960  break;
3961  }
3962  return;
3963  }
3964  };
3965 
3967  {
3968  Ex3Pb pb;
3969 
3970  OFSQP solver;
3971  int nparam, nf, nineq, neq, mode, iprint, miter, neqn, nineqn, ncsrl, ncsrn, nfsr, mesh_pts[1], inform;
3972  double bigbnd, eps, epsneq, udelta;
3973  double *x, *bl, *bu, *f, *g, *lambda;
3974 
3975  mode = 100;
3976  iprint = 1;
3977  miter = 500;
3978  bigbnd = 1.e10;
3979  eps = 1.e-7;
3980  epsneq = 7.e-6;
3981  udelta = 0.e0;
3982  nparam = 4;
3983  nf = 1;
3984  neqn = 1;
3985  nineqn = 1;
3986  nineq = 1;
3987  neq = 1;
3988  ncsrl = ncsrn = nfsr = mesh_pts[0] = 0;
3989  bl = new double[nparam];
3990  bu = new double[nparam];
3991  x = new double[nparam];
3992  f = new double[nf+1];
3993  g = new double[nineq+neq+1];
3994  lambda = new double[nineq+neq+nf+nparam+1];
3995 
3996  bl[0] = bl[1] = bl[2] = bl[3] = 1.e0;
3997  bu[0] = bu[1] = bu[2] = bu[3] = 5.e0;
3998 
3999  x[0] = 1.e0;
4000  x[1] = 5.e0;
4001  x[2] = 5.e0;
4002  x[3] = 1.e0;
4003 
4004  solver.cfsqp(nparam, nf, nfsr, nineqn, nineq, neqn, neq, ncsrl, ncsrn, mesh_pts, mode, iprint, miter, &inform, bigbnd, eps,
4005  epsneq, udelta, bl, bu, x, f, g, lambda, pb, 0x0);
4006 
4007  delete bl;
4008  delete bu;
4009  delete x;
4010  delete f;
4011  delete g;
4012  delete lambda;
4013  }
4014 
4015 
4016  /**********************************************************
4017  * E X A M P L E 4 *
4018  **********************************************************/
4019  class Ex4Pb : public OFSQPProblem
4020  {
4021  void obj(int nparam, int j, double* x, double* fj, void* cd)
4022  {
4023  *fj=x[9];
4024  return;
4025  }
4026 
4027  void gradob(int nparam, int j, double* x, double* gradfj, void* cd)
4028  {
4029  gradfj[0]=0.e0;
4030  gradfj[1]=0.e0;
4031  gradfj[2]=0.e0;
4032  gradfj[3]=0.e0;
4033  gradfj[4]=0.e0;
4034  gradfj[5]=0.e0;
4035  gradfj[6]=0.e0;
4036  gradfj[7]=0.e0;
4037  gradfj[8]=0.e0;
4038  gradfj[9]=1.e0;
4039  return;
4040  }
4041 
4042  void constr(int nparam, int j, double* x, double* gj, void* cd)
4043  {
4044  double t,z,s1,s2;
4045  int k,r;
4046 
4047  r=100;
4048  s1=s2=0.e0;
4049  if (j<=r)
4050  t=3.14159265358979312e0*(j-1)*0.025e0;
4051  else
4052  {
4053  if (j<=2*r)
4054  t=3.14159265358979312e0*(j-1-r)*0.025e0;
4055  else
4056  t=3.14159265358979312e0*(1.2e0+(j-1-2*r)*0.2e0)*0.25e0;
4057  }
4058  for (k=1; k<=9; k++)
4059  {
4060  s1=s1+x[k-1]*cos(k*t);
4061  s2=s2+x[k-1]*sin(k*t);
4062  }
4063  z=s1*s1 + s2*s2;
4064  if (j<=r)
4065  *gj=(1.e0-x[9])*(1.e0-x[9])-z;
4066  else
4067  {
4068  if (j<=2*r)
4069  *gj=z-(1.e0+x[9])*(1.e0+x[9]);
4070  else
4071  *gj=z-x[9]*x[9];
4072  }
4073  return;
4074  }
4075  };
4076 
4078  {
4079  Ex4Pb pb;
4080 
4081  OFSQP solver;
4082  int nparam, nf, nineq, neq, mode, iprint, miter, neqn, nineqn, ncsrl, ncsrn, nfsr, mesh_pts[3], numc, inform;
4083  double bigbnd, eps, epsneq, udelta;
4084  double *x, *bl, *bu, *f, *g, *lambda;
4085 
4086  int r = 100;
4087 
4088  mode = 100;
4089  iprint = 1;
4090  miter = 500;
4091  bigbnd = 1.e10;
4092  eps = 1.e-7;
4093  epsneq = 0.e0;
4094  udelta = 0.e0;
4095  nparam = 10;
4096  nf = 1;
4097  neqn = 0;
4098  nineqn = nineq = ncsrn = 3;
4099  ncsrl = 0;
4100  mesh_pts[0] = mesh_pts[1] = r;
4101  mesh_pts[2] = 3*r/2;
4102  neq = nfsr = 0;
4103  numc = (int)3.5*r;
4104  bl = new double[2*nparam];
4105  bu = new double[2*nparam];
4106  x = new double[2*nparam];
4107  f = new double[2*(nf+1)];
4108  g = new double[2*(numc+1)];
4109  lambda = new double[2*(numc+nf+nparam+1)];
4110 
4111  bl[0] = bl[1] = bl[2] = bl[3] = bl[4] = bl[5] = bl[6] = bl[7] = bl[8] = bl[9] = -bigbnd;
4112  bu[0] = bu[1] = bu[2] = bu[3] = bu[4] = bu[5] = bu[6] = bu[7] = bu[8] = bu[9] = bigbnd;
4113 
4114  x[0] = x[1] = x[2] = x[3] = x[4] = x[5] = x[6] = x[7] = x[8] = 0.1e0;
4115  x[9] = 1.e0;
4116 
4117  solver.cfsqp(nparam, nf, nfsr, nineqn, nineq, neqn, neq, ncsrl, ncsrn, mesh_pts, mode, iprint, miter, &inform, bigbnd, eps,
4118  epsneq, udelta, bl, bu, x, f, g, lambda, pb, 0x0);
4119 
4120  delete bl;
4121  delete bu;
4122  delete x;
4123  delete f;
4124  delete g;
4125  delete lambda;
4126  }
4127 
4128  /**********************************************************
4129  * E X A M P L E 5 *
4130  **********************************************************/
4131  class Ex5Pb : public OFSQPProblem
4132  {
4133  void obj(int nparam, int j, double* x, double* fj, void* cd)
4134  {
4135  *fj=(1.e0/3.e0)*pow(x[0],2.e0)+pow(x[1],2.e0)+0.5e0*x[0];
4136  return;
4137  }
4138 
4139  void gradob(int nparam, int j, double* x, double* gradfj, void* cd)
4140  {
4141  gradfj[0]=(2.e0/3.e0)*x[0]+0.5e0;
4142  gradfj[1]=2.e0*x[1];
4143  return;
4144  }
4145 
4146  void constr(int nparam, int j, double *x, double* gj, void* cd)
4147  {
4148  double y;
4149 
4150  y=(j-1)/100.e0;
4151  *gj=pow((1.e0-pow(y*x[0],2.e0)),2.e0)-x[0]*y*y-pow(x[1],2.e0)
4152  +x[1];
4153  return;
4154  }
4155 
4156  void gradcn(int nparam, int j, double* x, double* gradgj, void* cd)
4157  {
4158  double y;
4159 
4160  y=(j-1)/100.e0;
4161  gradgj[0]=-4.e0*(1.e0-pow(y*x[0],2.e0))*y*y*x[0]-y*y;
4162  gradgj[1]=-2.e0*x[1]+1.e0;
4163  return;
4164  }
4165  };
4166 
4168  {
4169  Ex5Pb pb;
4170 
4171  OFSQP solver;
4172  int nparam, nf, nineq, neq, mode, iprint, miter, neqn, nineqn, ncsrl, ncsrn, nfsr, mesh_pts[1], inform;
4173  double bigbnd, eps, epsneq, udelta;
4174  double *x, *bl, *bu, *f, *g, *lambda;
4175 
4176  mode = 110;
4177  iprint = 1;
4178  miter = 500;
4179  bigbnd = 1.e10;
4180  eps = 1.e-4;
4181  epsneq = 0.e0;
4182  udelta = 0.e0;
4183  nparam = 2;
4184  nf = 1;
4185  neqn = 0;
4186  nineqn = nineq = 1;
4187  ncsrn = 1;
4188  ncsrl = 0;
4189  mesh_pts[0] = 101;
4190  neq = nfsr = 0;
4191  bl = new double[nparam];
4192  bu = new double[nparam];
4193  x = new double[nparam];
4194  f = new double[nf+1];
4195  g = new double[nineq + (mesh_pts[0]-1)*(ncsrl+ncsrn) + neq+1];
4196  lambda = new double[nineq + (mesh_pts[0]-1)*(ncsrl+ncsrn) + neq + nf + nparam];
4197 
4198  bl[0] = bl[1] = -bigbnd;
4199  bu[0] = bu[1] = bigbnd;
4200 
4201  x[0] = -1.e0;
4202  x[1] = -2.e0;
4203 
4204  solver.cfsqp(nparam, nf, nfsr, nineqn, nineq, neqn, neq, ncsrl, ncsrn, mesh_pts, mode, iprint, miter, &inform, bigbnd, eps,
4205  epsneq, udelta, bl, bu, x, f, g, lambda, pb, 0x0);
4206 
4207  delete bl;
4208  delete bu;
4209  delete x;
4210  delete f;
4211  delete g;
4212  delete lambda;
4213  }
4214 
4215 }//ocra
4216 
4217 // cmake:sourcegroup=Solvers
void testOFSQP04()
Definition: OFSQP.cpp:4077
void testOFSQP02a()
Definition: OFSQP.cpp:3807
void resetFSQPstruct()
Definition: OFSQP.cpp:90
virtual void gradob(int nparam, int j, double *x, double *gradfj, void *cd)
Definition: OFSQP.cpp:13
void cfsqp(int nparam, int nf, int nfsr, int nineqn, int nineq, int neqn, int neq, int ncsrl, int ncsrn, int *mesh_pts, int mode, int iprint, int miter, int *inform, double bigbnd, double eps, double epseqn, double udelta, double *bl, double *bu, double *x, double *f, double *g, double *lambda, OFSQPProblem &problem, void *cd)
Definition: OFSQP.cpp:114
void testOFSQP01()
Definition: OFSQP.cpp:3722
void setFSQPstruct(fsqpDetails::Grd &grd, fsqpDetails::Prnt &prnt)
Definition: OFSQP.cpp:84
void invalidateX()
Definition: OFSQP.cpp:69
Optimization-based Robot Controller namespace. a library of classes to write and solve optimization p...
OFSQP(void)
Definition: OFSQP.cpp:97
~OFSQP(void)
Definition: OFSQP.cpp:108
void convert(const LinearConstraint &cstr, const std::vector< int > &mapping, eConstraintOutput type, MatrixBase< Derived > &A, VectorBase1 &b, VectorBase2 &l, double infinity=0.)
void testOFSQP03()
Definition: OFSQP.cpp:3966
virtual void gradcn(int nparam, int j, double *x, double *gradgj, void *cd)
Definition: OFSQP.cpp:41
void testOFSQP02b()
Definition: OFSQP.cpp:3859
Declaration file of the ObjQLD class. This class should be merged with ocra::ObjQLD. It has been created to have a cml-free solver.
virtual void constr(int nparam, int j, double *x, double *gj, void *cd)=0
void validateX()
Definition: OFSQP.cpp:74
void testOFSQP05()
Definition: OFSQP.cpp:4167
virtual void obj(int nparam, int j, double *x, double *fj, void *cd)=0