Scippy

SCIP

Solving Constraint Integer Programs

nlpi_worhp.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2018 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file nlpi_worhp.c
17  * @ingroup NLPIS
18  * @brief Worhp NLP interface
19  * @author Benjamin Mueller
20  * @author Renke Kuhlmann
21  *
22  * @todo So far, Worhp can not handle the case that variables have been fixed before warm-starting. Remove the code in
23  * nlpiChgVarBoundsWorhp when this has changed.
24  */
25 
26 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
27 
28 #include "nlpi/nlpi_worhp.h"
29 #include "nlpi/nlpi.h"
30 #include "nlpi/nlpioracle.h"
31 #include "nlpi/exprinterpret.h"
32 #include "scip/interrupt.h"
33 #include "scip/misc.h"
34 
35 #include <stdio.h>
36 #include <stdlib.h>
37 
38 #include "worhp/worhp.h"
39 
40 #if WORHP_MAJOR < 2 && WORHP_MINOR < 10
41 #error "Require at least Worhp 1.10"
42 #endif
43 
44 #define NLPI_DESC "Worhp interface" /**< description of solver */
45 #define NLPI_PRIORITY_IP 0 /**< priority of NLP solver (Interior Point) */
46 #define NLPI_PRIORITY_SQP -2000 /**< priority of NLP solver (SQP) */
47 
48 #define DEFAULT_VERBLEVEL 0 /**< default verbosity level (0: normal 1: full 2: debug >2: more debug) */
49 #define DEFAULT_SCALEDKKT TRUE /**< default whether KKT conditions are allowed to be scaled in the solver */
50 #define DEFAULT_MAXITER 3000 /**< default iteration limit for Worhp */
51 #define DEFAULT_RANDSEED 107 /**< initial random seed */
52 
53 #define MAXPERTURB 0.01 /**< maximal perturbation of bounds in starting point heuristic */
54 
55 /*
56  * Data structures
57  */
58 
59 struct SCIP_NlpiData
60 {
61  BMS_BLKMEM* blkmem; /**< block memory */
62  SCIP_MESSAGEHDLR* messagehdlr; /**< message handler */
63  SCIP_Real infinity; /**< initial value for infinity */
64  SCIP_Bool useip; /**< should the Interior Point solver of Worhp be used? */
65 };
66 
67 struct SCIP_NlpiProblem
68 {
69  SCIP_NLPIORACLE* oracle; /**< Oracle-helper to store and evaluate NLP */
70  BMS_BLKMEM* blkmem; /**< block memory */
71  SCIP_RANDNUMGEN* randnumgen; /**< random number generator */
72 
73  SCIP_NLPTERMSTAT lasttermstat; /**< termination status from last run */
74  SCIP_NLPSOLSTAT lastsolstat; /**< solution status from last run */
75  SCIP_Real lasttime; /**< time spend in last run */
76  int lastniter; /**< number of iterations in last run */
77 
78  SCIP_Real* lastprimal; /**< primal solution from last run, if available */
79  SCIP_Real* lastdualcons; /**< dual solution from last run, if available */
80  SCIP_Real* lastduallb; /**< dual solution for lower bounds from last run, if available */
81  SCIP_Real* lastdualub; /**< dual solution for upper bounds from last run, if available */
82  int lastprimalsize; /**< size of lastprimal array */
83  int lastdualconssize; /**< size of lastdualcons array */
84  int lastduallbsize; /**< size of lastduallb array */
85  int lastdualubsize; /**< size of lastdualub array */
86 
87  SCIP_Bool firstrun; /**< whether the next NLP solve will be the first one (with the current problem structure) */
88  SCIP_Real* initguess; /**< initial values for primal variables, or NULL if not known */
89 
90  /* Worhp data structures */
91  OptVar* opt; /**< Worhp variables */
92  Workspace* wsp; /**< Worhp working space */
93  Params* par; /**< Worhp parameters */
94  Control* cnt; /**< Worhp control */
95 
96  /* parameters */
97  SCIP_Real feastol; /**< feasibility tolerance for primal variables and slacks */
98  SCIP_Real relobjtol; /**< relative objective tolerance */
99  SCIP_Real lobjlim; /**< lower objective limit (cutoff) */
100  SCIP_Real timelim; /**< NLP time limit */
101  int fromscratch; /**< solver should start from scratch at next call?: 0 no, 1 yes */
102  int verblevel; /**< verbosity level of output of NLP solver to the screen: 0 off, 1 normal, 2 debug, > 2 more debug */
103  int itlim; /**< NLP iteration limit */
104  int fastfail; /**< should the NLP solver stop early if convergence is slow?: 0 no, 1 yes */
105 };
106 
107 /*
108  * Local methods
109  */
110 
111 /** clears the last solution information */
112 static
114  SCIP_NLPIPROBLEM* problem /**< pointer to problem data structure */
115  )
116 {
117  assert(problem != NULL);
118  assert(problem->blkmem != NULL);
119 
120  BMSfreeBlockMemoryArrayNull(problem->blkmem, &(problem->lastprimal), problem->lastprimalsize);
121  BMSfreeBlockMemoryArrayNull(problem->blkmem, &(problem->lastdualcons), problem->lastdualconssize);
122  BMSfreeBlockMemoryArrayNull(problem->blkmem, &(problem->lastduallb), problem->lastduallbsize);
123  BMSfreeBlockMemoryArrayNull(problem->blkmem, &(problem->lastdualub), problem->lastdualubsize);
124 
125  problem->lastprimalsize = 0;
126  problem->lastdualconssize = 0;
127  problem->lastduallbsize = 0;
128  problem->lastdualubsize = 0;
131 }
132 
133 /** evaluate last Worhp run */
134 static
136  SCIP_NLPIPROBLEM* problem /**< pointer to problem data structure */
137  )
138 {
139  int i;
140 
141  assert(problem != NULL);
142  assert(problem->opt != NULL);
143  assert(problem->wsp != NULL);
144  assert(problem->par != NULL);
145  assert(problem->cnt != NULL);
146 
147  switch( problem->cnt->status )
148  {
149  case InitError:
150  {
151  /* initialization error */
152  SCIPdebugMessage("Worhp failed because of initialization error!\n");
153  invalidateSolution(problem);
156  break;
157  }
158 
159  case DataError:
160  {
161  /* data error */
162  SCIPdebugMessage("Worhp failed because of data error!\n");
163  invalidateSolution(problem);
166  break;
167  }
168 
169  case LicenseError:
170  {
171  /* license error */
172  SCIPerrorMessage("Worhp failed because of license error!\n");
173  invalidateSolution(problem);
176  break;
177  }
178 
179  case evalsNaN:
180  {
181  /* evaluation errors */
182  SCIPdebugMessage("Worhp failed because of a NaN value in an evaluation!\n");
183  invalidateSolution(problem);
186  break;
187  }
188 
189  case QPerror:
190  case MinimumStepsize:
191  case TooBig:
192  case LinearSolverFailed:
193  {
194  /* numerical errors during solution of NLP */
195  SCIPdebugMessage("Worhp failed because of a numerical error during optimization!\n");
196  invalidateSolution(problem);
199  break;
200  }
201 
202  case MaxCalls:
203  case MaxIter:
204  {
205  /* maximal number of calls or iteration */
206  SCIPdebugMessage("Worhp failed because maximal number of calls or iterations is reached!\n");
207  invalidateSolution(problem);
210  break;
211  }
212 
213  case Timeout:
214  {
215  /* time limit reached */
216  SCIPdebugMessage("Worhp failed because time limit is reached!\n");
217  invalidateSolution(problem);
220  break;
221  }
222 
223  case DivergingPrimal:
224  case DivergingDual:
225  {
226  /* iterates diverge */
227  SCIPdebugMessage("Worhp failed because of diverging iterates!\n");
228  invalidateSolution(problem);
231  break;
232  }
233 
234  case LocalInfeas:
235  case LocalInfeasOptimal:
236  {
237  /* infeasible stationary point found */
238  SCIPdebugMessage("Worhp failed because of convergence against infeasible stationary point!\n");
239  invalidateSolution(problem);
242  break;
243  }
244 
245  case GlobalInfeas:
246  {
247  /* infeasible stationary point found */
248  SCIPdebugMessage("Worhp failed because of convergence against infeasible stationary point!\n");
249  invalidateSolution(problem);
252  break;
253  }
254 
255  case RegularizationFailed:
256  {
257  /* regularization of Hessian matrix failed */
258  SCIPdebugMessage("Worhp failed because of regularization of Hessian matrix failed!\n");
259  invalidateSolution(problem);
262  break;
263  }
264 
265  case OptimalSolution:
266  {
267  /* everything went fine */
268  SCIPdebugMessage("Worhp terminated successfully at a local optimum!\n");
271  break;
272  }
273 
274  case OptimalSolutionConstantF:
275  {
276  /* feasible point, KKT conditions are not satisfied, and Worhp thinks that there is no objective function */
277  SCIPdebugMessage("Worhp terminated successfully with a feasible point but KKT are not met!\n");
280  break;
281  }
282 
283  case AcceptableSolutionSKKT:
284  case AcceptableSolutionScaled:
285  case AcceptablePreviousScaled:
286  {
287  /* feasible point but KKT conditions are violated in unscaled space */
288  SCIPdebugMessage("Worhp terminated successfully with a feasible point but KKT are violated in unscaled space!\n");
291  break;
292  }
293 
294  case LowPassFilterOptimal:
295  {
296  /* feasible and no further progress */
297  SCIPdebugMessage("Worhp terminated at feasible solution without further progress!\n");
300  break;
301  }
302 
303  case FeasibleSolution:
304  {
305  /* feasible and in feasibility mode, i.e., optimality not required */
306  SCIPdebugMessage("Worhp terminated at feasible solution, optimality was not required!\n");
309  break;
310  }
311 
312  case AcceptableSolution:
313  case AcceptableSolutionConstantF:
314  {
315  /* acceptable solution found, but stopped due to limit or error */
316  SCIPdebugMessage("Worhp terminated at acceptable solution due to limit or error!\n");
319  break;
320  }
321 
322  case AcceptablePrevious:
323  case AcceptablePreviousConstantF:
324  {
325  /* previously acceptable solution was found, but stopped due to limit or error */
326  SCIPdebugMessage("Worhp previously found acceptable solution but terminated due to limit or error!\n");
329  break;
330  }
331 
332  case LowPassFilterAcceptable:
333  {
334  /* acceptable solution found, and no further progress */
335  SCIPdebugMessage("Worhp found acceptable solution but terminated due no further progress!\n");
338  break;
339  }
340 
341  case SearchDirectionZero:
342  case SearchDirectionSmall:
343  {
344  /* acceptable solution found, but search direction is small or zero */
345  SCIPdebugMessage("Worhp found acceptable solution but search direction is small or zero!\n");
348  break;
349  }
350 
351  case FritzJohn:
352  case NotDiffable:
353  case Unbounded:
354  {
355  /* acceptable solution found, but not optimal */
356  SCIPdebugMessage("Worhp found acceptable solution but terminated perhaps due to nondifferentiability, unboundedness or at Fritz John point!\n");
359  break;
360  }
361 
362  default:
363  {
364  SCIPerrorMessage("Worhp returned with unknown solution status %d\n", problem->cnt->status);
367  return SCIP_OKAY;
368  }
369  }
370 
371  /* store solution */
372  if( problem->lastprimal == NULL )
373  {
374  if( problem->opt->m > 0 )
375  {
376  SCIP_ALLOC( BMSduplicateBlockMemoryArray(problem->blkmem, &problem->lastdualcons, problem->opt->Mu, problem->opt->m) );
377  problem->lastdualconssize = problem->opt->m;
378  }
379 
380  if( problem->opt->n > 0 )
381  {
382  SCIP_ALLOC( BMSduplicateBlockMemoryArray(problem->blkmem, &problem->lastprimal, problem->opt->X, problem->opt->n) );
383  problem->lastprimalsize = problem->opt->n;
384 
385  SCIP_ALLOC( BMSallocBlockMemoryArray(problem->blkmem, &problem->lastduallb, problem->opt->n) );
386  problem->lastduallbsize = problem->opt->n;
387 
388  SCIP_ALLOC( BMSallocBlockMemoryArray(problem->blkmem, &problem->lastdualub, problem->opt->n) );
389  problem->lastdualubsize = problem->opt->n;
390  }
391  }
392  else
393  {
394  BMScopyMemoryArray(problem->lastprimal, problem->opt->X, problem->opt->n);
395  BMScopyMemoryArray(problem->lastdualcons, problem->opt->Mu, problem->opt->m);
396  }
397 
398  for( i = 0; i < problem->opt->n; ++i )
399  {
400  if( problem->opt->Lambda[i] <= 0.0 )
401  {
402  problem->lastduallb[i] = -problem->opt->Lambda[i];
403  problem->lastdualub[i] = 0.0;
404  }
405  else
406  {
407  problem->lastduallb[i] = 0.0;
408  problem->lastdualub[i] = problem->opt->Lambda[i];
409  }
410  }
411 
412  assert(problem->lastprimal != NULL || problem->opt->n == 0);
413  assert(problem->lastdualcons != NULL || problem->opt->m == 0);
414  assert(problem->lastduallb != NULL || problem->opt->n == 0);
415  assert(problem->lastdualub != NULL || problem->opt->n == 0);
416 
417  return SCIP_OKAY;
418 }
419 
420 /** evaluates objective function and store the result in the corresponding Worhp data fields */
421 static
423  SCIP_NLPIPROBLEM* problem /**< pointer to problem data structure */
424  )
425 {
426  SCIP_Real objval;
427 
428  assert(problem != NULL);
429  assert(problem->oracle != NULL);
430  assert(problem->blkmem != NULL);
431  assert(problem->opt != NULL);
432  assert(problem->wsp != NULL);
433  assert(problem->opt->n == SCIPnlpiOracleGetNVars(problem->oracle));
434  assert(problem->opt->m == SCIPnlpiOracleGetNConstraints(problem->oracle));
435 
436  SCIP_CALL( SCIPnlpiOracleEvalObjectiveValue(problem->oracle, problem->opt->X, &objval) );
437  problem->opt->F = problem->wsp->ScaleObj * objval;
438 
439 #ifdef SCIP_DEBUG_USERF
440  {
441  int i;
442 
443  printf("userF()\n");
444  for( i = 0; i < problem->opt->n; ++i )
445  printf(" x[%d] = %g\n", i, problem->opt->X[i]);
446  printf(" obj = %g\n", problem->opt->F);
447  }
448 #endif
449 
450  return SCIP_OKAY;
451 }
452 
453 /** evaluates constraints and store the result in the corresponding Worhp data fields */
454 static
456  SCIP_NLPIPROBLEM* problem /**< pointer to problem data structure */
457  )
458 {
459  assert(problem != NULL);
460  assert(problem->oracle != NULL);
461  assert(problem->blkmem != NULL);
462  assert(problem->opt != NULL);
463  assert(problem->wsp != NULL);
464  assert(problem->opt->n == SCIPnlpiOracleGetNVars(problem->oracle));
465  assert(problem->opt->m == SCIPnlpiOracleGetNConstraints(problem->oracle));
466 
467  SCIP_CALL( SCIPnlpiOracleEvalConstraintValues(problem->oracle, problem->opt->X, problem->opt->G) );
468 
469 #ifdef SCIP_DEBUG_USERG
470  {
471  int i;
472 
473  printf("userG()\n");
474  for( i = 0; i < problem->opt->n; ++i )
475  printf(" x[%d] = %g\n", i, problem->opt->X[i]);
476 
477  for( i = 0; i < problem->opt->m; ++i )
478  printf(" cons[%d] = %g\n", i, problem->opt->G[i]);
479  }
480 #endif
481 
482  return SCIP_OKAY;
483 }
484 
485 /** computes objective gradient and store the result in the corresponding Worhp data fields */
486 static
488  SCIP_NLPIPROBLEM* problem /**< pointer to problem data structure */
489  )
490 {
491  SCIP_Real objval;
492 
493  assert(problem != NULL);
494  assert(problem->oracle != NULL);
495  assert(problem->blkmem != NULL);
496  assert(problem->opt != NULL);
497  assert(problem->wsp != NULL);
498  assert(problem->opt->n == SCIPnlpiOracleGetNVars(problem->oracle));
499  assert(problem->opt->m == SCIPnlpiOracleGetNConstraints(problem->oracle));
500 
501  /* TODO this needs to be changed if we store the gradient of the objective function in a sparse format */
502  SCIP_CALL( SCIPnlpiOracleEvalObjectiveGradient(problem->oracle, problem->opt->X, TRUE, &objval,
503  problem->wsp->DF.val) );
504 
505  /* scale gradient if necessary */
506  if( problem->wsp->ScaleObj != 1.0 )
507  {
508  int i;
509  for( i = 0; i < problem->opt->n; ++i )
510  problem->wsp->DF.val[i] *= problem->wsp->ScaleObj;
511  }
512 
513 #ifdef SCIP_DEBUG_USERDF
514  {
515  int i;
516 
517  printf("userDF()\n");
518  for( i = 0; i < problem->opt->n; ++i )
519  printf(" x[%d] = %g\n", i, problem->opt->X[i]);
520 
521  for( i = 0; i < problem->opt->n; ++i )
522  printf(" DF[%d] = %g\n", i, problem->wsp->DF.val[i]);
523  }
524 #endif
525 
526  return SCIP_OKAY;
527 }
528 
529 /** computes jacobian matrix and store the result in the corresponding Worhp data fields */
530 static
532  SCIP_NLPIPROBLEM* problem /**< pointer to problem data structure */
533  )
534 {
535  SCIP_RETCODE retcode;
536  SCIP_Real* jacvals;
537 
538  assert(problem != NULL);
539  assert(problem->oracle != NULL);
540  assert(problem->blkmem != NULL);
541  assert(problem->opt != NULL);
542  assert(problem->wsp != NULL);
543  assert(problem->opt->n == SCIPnlpiOracleGetNVars(problem->oracle));
544  assert(problem->opt->m == SCIPnlpiOracleGetNConstraints(problem->oracle));
545 
546  SCIP_ALLOC( BMSallocBlockMemoryArray(problem->blkmem, &jacvals, problem->wsp->DG.nnz) );
547  retcode = SCIPnlpiOracleEvalJacobian(problem->oracle, problem->opt->X, TRUE, NULL, jacvals);
548 
549  if( retcode == SCIP_OKAY )
550  {
551  int i;
552 
553  /* map values with DG indices */
554  for( i = 0; i < problem->wsp->DG.nnz; ++i )
555  {
556  problem->wsp->DG.val[i] = jacvals[ problem->wsp->DG.perm[i]-1 ];
557  }
558 
559 #ifdef SCIP_DEBUG_USERDG
560  printf("userDG()\n");
561  for( i = 0; i < problem->opt->n; ++i )
562  printf(" x[%d] = %g\n", i, problem->opt->X[i]);
563  for( i = 0; i < problem->wsp->DG.nnz; ++i )
564  printf(" DG[%d] = %g\n", i, problem->wsp->DG.val[i]);
565 #endif
566  }
567 
568  /* free memory */
569  BMSfreeBlockMemoryArray(problem->blkmem, &jacvals, problem->wsp->DG.nnz);
570 
571  return retcode;
572 }
573 
574 /** computes hessian matrix and store the result in the corresponding Worhp data fields */
575 static
577  SCIP_NLPIPROBLEM* problem /**< pointer to problem data structure */
578  )
579 {
580  const int* offset;
581  SCIP_Real* hessianvals;
582  SCIP_RETCODE retcode;
583  int nnonz;
584 
585  assert(problem != NULL);
586  assert(problem->oracle != NULL);
587  assert(problem->blkmem != NULL);
588  assert(problem->opt != NULL);
589  assert(problem->wsp != NULL);
590  assert(problem->opt->n == SCIPnlpiOracleGetNVars(problem->oracle));
591  assert(problem->opt->m == SCIPnlpiOracleGetNConstraints(problem->oracle));
592 
593  /* get nonzero entries in HM of SCIP (excludes unused diagonal entries) */
594  SCIP_CALL( SCIPnlpiOracleGetHessianLagSparsity(problem->oracle, &offset, NULL) );
595  nnonz = offset[problem->opt->n];
596 
597  /* evaluate hessian */
598  SCIP_ALLOC( BMSallocBlockMemoryArray(problem->blkmem, &hessianvals, problem->wsp->HM.nnz) );
599  retcode = SCIPnlpiOracleEvalHessianLag(problem->oracle, problem->opt->X, TRUE, problem->wsp->ScaleObj,
600  problem->opt->Mu, hessianvals);
601 
602  if( retcode == SCIP_OKAY )
603  {
604  int i;
605 
606  assert(problem->wsp->HM.nnz >= nnonz);
607  for( i = 0; i < problem->wsp->HM.nnz; ++i )
608  {
609  /* an entry i with HM.perm[i] - 1 >= nnonz corresponds to an in SCIP non-existing diagonal element */
610  if( problem->wsp->HM.perm[i] - 1 >= nnonz )
611  problem->wsp->HM.val[i] = 0.0;
612  else
613  problem->wsp->HM.val[i] = hessianvals[ problem->wsp->HM.perm[i] - 1 ];
614  }
615 
616 #ifdef SCIP_DEBUG_HM
617  printf("userHM()\n");
618  for( i = 0; i < problem->opt->n; ++i )
619  printf(" x[%d] = %g\n", i, problem->opt->X[i]);
620  for( i = 0; i < problem->wsp->HM.nnz; ++i )
621  printf(" HM[%d] = %g\n", i, problem->wsp->HM.val[i]);
622 #endif
623  }
624 
625  /* free memory */
626  BMSfreeBlockMemoryArray(problem->blkmem, &hessianvals, problem->wsp->HM.nnz);
627 
628  return retcode;
629 }
630 
631 /** Worhp print callback function that does nothing */
632 static void noprint(
633  int mode, /**< the mode */
634  const char s[] /**< a string */
635  )
636 { /*lint --e{715}*/
637 }
638 
639 /** initialize Worhp data */
640 static
642  SCIP_NLPI* nlpi, /**< pointer to NLPI datastructure */
643  SCIP_NLPIPROBLEM* problem /**< pointer to problem data structure */
644  )
645 {
646  Workspace* wsp;
647  Control* cnt;
648  OptVar* opt;
649  Params* par;
650  const SCIP_Real* lbs;
651  const SCIP_Real* ubs;
652  const int* offset;
653  const int* cols;
654  SCIP_NLPIDATA* nlpidata;
655  int i;
656  int j;
657 
658  assert(nlpi != NULL);
659  assert(problem != NULL);
660  assert(problem->cnt != NULL);
661  assert(problem->wsp != NULL);
662  assert(problem->par != NULL);
663  assert(problem->opt != NULL);
664  assert(problem->firstrun);
665 
666  wsp = problem->wsp;
667  cnt = problem->cnt;
668  opt = problem->opt;
669  par = problem->par;
670 
671  nlpidata = SCIPnlpiGetData(nlpi);
672  assert(nlpidata != NULL);
673 
674  /* properly zeros everything */
675  WorhpPreInit(opt, wsp, par, cnt);
676 
677  /* set problem dimensions */
678  opt->n = SCIPnlpiOracleGetNVars(problem->oracle);
679  opt->m = SCIPnlpiOracleGetNConstraints(problem->oracle);
680  SCIPdebugMessage("nvars %d nconss %d\n", opt->n, opt->m);
681 
682  /* assume that objective function is dense; TODO use sparse representation */
683  wsp->DF.nnz = opt->n;
684 
685  /* get number of non-zero entries in Jacobian */
686  SCIP_CALL( SCIPnlpiOracleGetJacobianSparsity(problem->oracle, &offset, NULL) );
687  wsp->DG.nnz = offset[opt->m];
688  SCIPdebugMessage("nnonz jacobian %d\n", wsp->DG.nnz);
689 
690  /* get number of non-zero entries in hessian
691  *
692  * note that Worhp wants to have the full diagonal in ANY case
693  */
694  SCIP_CALL( SCIPnlpiOracleGetHessianLagSparsity(problem->oracle, &offset, &cols) );
695  wsp->HM.nnz = 0;
696 
697  j = offset[0];
698  for( i = 0; i < opt->n; ++i )
699  {
700  /* diagonal element */
701  ++(wsp->HM.nnz);
702 
703  /* strict lower triangle elements */
704  for( ; j < offset[i+1]; ++j )
705  {
706  if( i != cols[j] )
707  {
708  assert(i > cols[j]);
709  ++(wsp->HM.nnz);
710  }
711  }
712  }
713  assert(offset[opt->n] <= wsp->HM.nnz);
714  SCIPdebugMessage("nnonz hessian %d\n", wsp->HM.nnz);
715 
716  /* initialize data in Worhp */
717  WorhpInit(opt, wsp, par, cnt);
718  if (cnt->status != FirstCall)
719  {
720  SCIPerrorMessage("Initialisation failed.\n");
721  return SCIP_ERROR;
722  }
723 
724  /* set variable bounds */
725  lbs = SCIPnlpiOracleGetVarLbs(problem->oracle);
726  ubs = SCIPnlpiOracleGetVarUbs(problem->oracle);
727 
728  BMScopyMemoryArray(opt->XL, lbs, opt->n);
729  BMScopyMemoryArray(opt->XU, ubs, opt->n);
730 
731 #ifdef SCIP_DEBUG
732  for( i = 0; i < opt->n; ++i )
733  {
734  SCIPdebugMessage("bounds %d [%g,%g]\n", i, opt->XL[i], opt->XU[i]);
735  }
736 #endif
737 
738  /* set constraint sides */
739  for( i = 0; i < opt->m; ++i )
740  {
741  opt->GL[i] = SCIPnlpiOracleGetConstraintLhs(problem->oracle, i);
742  opt->GU[i] = SCIPnlpiOracleGetConstraintRhs(problem->oracle, i);
743 
744  /* adjust constraint sides when both are infinite */
745  if( opt->GL[i] <= -nlpidata->infinity && opt->GU[i] >= nlpidata->infinity )
746  {
747  SCIPmessagePrintWarning(nlpidata->messagehdlr, "Lhs and rhs of constraint %d are infinite.\n", i);
748  opt->GL[i] = -nlpidata->infinity / 10.0;
749  opt->GU[i] = nlpidata->infinity / 10.0;
750  }
751 
752  SCIPdebugMessage("sides %d [%g,%g]\n", i, opt->GL[i], opt->GU[i]);
753  }
754 
755  /* set column indices of objective function; note that indices go from 1 to n */
756  /* if( wsp->DF.NeedStructure ) evaluates to FALSE if DF is dense */
757  {
758  SCIPdebugPrintf("column indices of objective function:");
759  for( i = 0; i < opt->n; ++i )
760  {
761  wsp->DF.row[i] = i + 1;
762  SCIPdebugPrintf(" %d", wsp->DF.row[i]);
763  }
764  SCIPdebugPrintf("\n");
765  }
766 
767  /* set column and row indices of non-zero entries in Jacobian matrix */
768  /* if( wsp->DG.NeedStructure ) evaluates to FALSE if DG is dense */
769  {
770  int nnonz;
771 
772  SCIP_CALL( SCIPnlpiOracleGetJacobianSparsity(problem->oracle, &offset, &cols) );
773  assert(offset[opt->m] == wsp->DG.nnz);
774 
775  nnonz = 0;
776  j = offset[0];
777  for( i = 0; i < opt->m; ++i )
778  {
779  for( ; j < offset[i+1]; ++j )
780  {
781  wsp->DG.row[nnonz] = i + 1;
782  wsp->DG.col[nnonz] = cols[j] + 1;
783  ++nnonz;
784  }
785  }
786  assert(nnonz == wsp->DG.nnz);
787 
788  /* sort arrays w.r.t the column-major order */
789  SortWorhpMatrix(&wsp->DG);
790  }
791 
792  /* set column and row indices of non-zero entries in hessian matrix */
793  if( problem->par->UserHM || problem->par->FidifHM || problem->par->BFGSmethod > 1 )
794  {
795  int nnonz;
796  int k;
797 
798  SCIP_CALL( SCIPnlpiOracleGetHessianLagSparsity(problem->oracle, &offset, &cols) );
799  assert(offset[opt->n] <= wsp->HM.nnz);
800 
801  k = offset[opt->n];
802  nnonz = 0;
803  j = offset[0];
804  for( i = 0; i < opt->n; ++i )
805  {
806  SCIP_Bool adddiag = TRUE;
807 
808  for( ; j < offset[i+1]; ++j )
809  {
810  problem->wsp->HM.row[nnonz] = i + 1;
811  problem->wsp->HM.col[nnonz] = cols[j] + 1;
812  ++nnonz;
813 
814  if( i == cols[j] )
815  adddiag = FALSE;
816  }
817 
818  /* Worhp wants to have each diagonal element */
819  if( adddiag )
820  {
821  problem->wsp->HM.row[k] = i + 1;
822  problem->wsp->HM.col[k] = i + 1;
823  ++k;
824  }
825  }
826  assert(nnonz == offset[opt->n]);
827  assert(k == wsp->HM.nnz);
828 
829  /* sort arrays w.r.t the LT column-major order */
830  SortWorhpMatrix(&wsp->HM);
831 
832 #ifdef SCIP_DEBUG
833  SCIPdebugMessage("column and row indices of hessian:\n");
834  for( i = 0; i < wsp->HM.nnz; ++i )
835  {
836  SCIPdebugMessage(" entry %d: (row,col) = (%d,%d)\n", i, wsp->HM.row[i], wsp->HM.col[i]);
837  }
838 #endif
839  }
840 
841  return SCIP_OKAY;
842 }
843 
844 /** update Worhp data */
845 static
847  SCIP_NLPIPROBLEM* problem /**< pointer to problem data structure */
848  )
849 {
850  const SCIP_Real* lbs;
851  const SCIP_Real* ubs;
852  int i;
853 
854  assert(problem != NULL);
855  assert(problem->cnt != NULL);
856  assert(problem->wsp != NULL);
857  assert(problem->par != NULL);
858  assert(problem->opt != NULL);
859  assert(problem->oracle != NULL);
860  assert(problem->opt->n == SCIPnlpiOracleGetNVars(problem->oracle));
861  assert(problem->opt->m == SCIPnlpiOracleGetNConstraints(problem->oracle));
862 
863  WorhpRestart(problem->opt, problem->wsp, problem->par, problem->cnt);
864 
865  /* update variable bounds */
866  lbs = SCIPnlpiOracleGetVarLbs(problem->oracle);
867  ubs = SCIPnlpiOracleGetVarUbs(problem->oracle);
868  for( i = 0; i < problem->opt->n; ++i )
869  {
870  problem->opt->XL[i] = lbs[i];
871  problem->opt->XU[i] = ubs[i];
872  }
873 
874  /* update constraint sides */
875  for( i = 0; i < problem->opt->m; ++i )
876  {
877  problem->opt->GL[i] = SCIPnlpiOracleGetConstraintLhs(problem->oracle, i);
878  problem->opt->GU[i] = SCIPnlpiOracleGetConstraintRhs(problem->oracle, i);
879  }
880 
881  return SCIP_OKAY;
882 }
883 
884 /** frees Worhp data */
885 static
887  SCIP_NLPIPROBLEM* problem /**< pointer to problem data structure */
888  )
889 {
890  assert(problem != NULL);
891  assert(problem->cnt != NULL);
892  assert(problem->wsp != NULL);
893  assert(problem->par != NULL);
894  assert(problem->opt != NULL);
895 
896  if( problem->opt->initialised )
897  WorhpFree(problem->opt, problem->wsp, problem->par, problem->cnt);
898 
899  return SCIP_OKAY;
900 }
901 
902 /*
903  * Callback methods of NLP solver interface
904  */
905 
906 /* TODO: Implement all necessary NLP interface methods. The methods with an #if 0 ... #else #define ... are optional
907  * (currently, all methods are required) */
908 
909 /** copy method of NLP interface (called when SCIP copies plugins)
910  *
911  * input:
912  * - blkmem block memory in target SCIP
913  * - sourcenlpi the NLP interface to copy
914  * - targetnlpi buffer to store pointer to copy of NLP interface
915  */
916 static
917 SCIP_DECL_NLPICOPY( nlpiCopyWorhp )
918 {
919  SCIP_NLPIDATA* sourcedata;
920 
921  assert(sourcenlpi != NULL);
922  assert(targetnlpi != NULL);
923 
924  sourcedata = SCIPnlpiGetData(sourcenlpi);
925  assert(sourcedata != NULL);
926 
927  SCIP_CALL( SCIPcreateNlpSolverWorhp(blkmem, targetnlpi, sourcedata->useip) );
928  assert(*targetnlpi != NULL);
929 
930  SCIP_CALL( SCIPnlpiSetRealPar(*targetnlpi, NULL, SCIP_NLPPAR_INFINITY, sourcedata->infinity) );
931  SCIP_CALL( SCIPnlpiSetMessageHdlr(*targetnlpi, sourcedata->messagehdlr) );
932 
933  return SCIP_OKAY;
934 } /*lint !e715*/
935 
936 /** destructor of NLP interface to free nlpi data
937  *
938  * input:
939  * - nlpi datastructure for solver interface
940  */
941 static
942 SCIP_DECL_NLPIFREE( nlpiFreeWorhp )
943 {
944  SCIP_NLPIDATA* data;
945 
946  assert(nlpi != NULL);
947 
948  data = SCIPnlpiGetData(nlpi);
949  assert(data != NULL);
950  assert(data->blkmem != NULL);
951 
952  BMSfreeBlockMemory(data->blkmem, &data);
953 
954  return SCIP_OKAY;
955 } /*lint !e715*/
956 
957 /** gets pointer for NLP solver
958  *
959  * to do dirty stuff
960  *
961  * input:
962  * - nlpi datastructure for solver interface
963  *
964  * return: void pointer to solver
965  */
966 static
967 SCIP_DECL_NLPIGETSOLVERPOINTER(nlpiGetSolverPointerWorhp)
968 {
969  assert(nlpi != NULL);
970 
971  return NULL;
972 } /*lint !e715*/
973 
974 /** creates a problem instance
975  *
976  * input:
977  * - nlpi datastructure for solver interface
978  * - problem pointer to store the problem data
979  * - name name of problem, can be NULL
980  */
981 static
982 SCIP_DECL_NLPICREATEPROBLEM(nlpiCreateProblemWorhp)
983 {
984  SCIP_NLPIDATA* data;
985 
986  assert(nlpi != NULL);
987  assert(problem != NULL);
988 
989  data = SCIPnlpiGetData(nlpi);
990  assert(data != NULL);
991 
992  SCIP_ALLOC( BMSallocBlockMemory(data->blkmem, problem) );
993  if( *problem == NULL )
994  return SCIP_NOMEMORY;
995 
996  /* initialize problem */
997  BMSclearMemory((*problem));
998  (*problem)->blkmem = data->blkmem;
999  (*problem)->firstrun = TRUE;
1000  SCIP_CALL( SCIPnlpiOracleCreate(data->blkmem, &(*problem)->oracle) );
1001  SCIP_CALL( SCIPnlpiOracleSetInfinity((*problem)->oracle, data->infinity) );
1002  SCIP_CALL( SCIPnlpiOracleSetProblemName((*problem)->oracle, name) );
1003 
1004  /* allocate memory for Worhp data */
1005  SCIP_ALLOC( BMSallocBlockMemory(data->blkmem, &(*problem)->opt) );
1006  SCIP_ALLOC( BMSallocBlockMemory(data->blkmem, &(*problem)->wsp) );
1007  SCIP_ALLOC( BMSallocBlockMemory(data->blkmem, &(*problem)->par) );
1008  SCIP_ALLOC( BMSallocBlockMemory(data->blkmem, &(*problem)->cnt) );
1009  WorhpPreInit((*problem)->opt, (*problem)->wsp, (*problem)->par, (*problem)->cnt);
1010 
1011  /* set default parameters */
1012  (*problem)->feastol = SCIP_DEFAULT_FEASTOL;
1013  (*problem)->relobjtol = SCIP_DEFAULT_FEASTOL;
1014  (*problem)->lobjlim = SCIP_INVALID;
1015  (*problem)->timelim = SCIP_DEFAULT_INFINITY;
1016  (*problem)->fromscratch = 0;
1017  (*problem)->verblevel = DEFAULT_VERBLEVEL;
1018  (*problem)->itlim = DEFAULT_MAXITER;
1019  (*problem)->fastfail = 0;
1020 
1021  /* create random number generator */
1022  SCIP_CALL( SCIPrandomCreate(&(*problem)->randnumgen, (*problem)->blkmem, DEFAULT_RANDSEED) );
1023 
1024  return SCIP_OKAY;
1025 } /*lint !e715*/
1026 
1027 /** free a problem instance
1028  *
1029  * input:
1030  * - nlpi datastructure for solver interface
1031  * - problem pointer where problem data is stored
1032  */
1033 static
1034 SCIP_DECL_NLPIFREEPROBLEM(nlpiFreeProblemWorhp)
1035 {
1036  SCIP_NLPIDATA* data;
1037 
1038  assert(nlpi != NULL);
1039  assert(problem != NULL);
1040  assert(*problem != NULL);
1041 
1042  data = SCIPnlpiGetData(nlpi);
1043  assert(data != NULL);
1044 
1045  if( (*problem)->opt != NULL )
1046  {
1047  /* free memory for last solution information */
1048  invalidateSolution(*problem);
1049 
1050  assert((*problem)->wsp != NULL);
1051  assert((*problem)->par != NULL);
1052  assert((*problem)->cnt != NULL);
1053 
1054  /* free Worhp data */
1055  SCIP_CALL( freeWorhp(*problem) );
1056  BMSfreeBlockMemory(data->blkmem, &(*problem)->cnt);
1057  BMSfreeBlockMemory(data->blkmem, &(*problem)->par);
1058  BMSfreeBlockMemory(data->blkmem, &(*problem)->wsp);
1059  BMSfreeBlockMemory(data->blkmem, &(*problem)->opt);
1060  }
1061 
1062  if( (*problem)->oracle != NULL )
1063  {
1064  SCIP_CALL( SCIPnlpiOracleFree(&(*problem)->oracle) );
1065  }
1066 
1067  SCIPrandomFree(&(*problem)->randnumgen, (*problem)->blkmem);
1068  BMSfreeMemoryArrayNull(&(*problem)->initguess);
1069  BMSfreeBlockMemory(data->blkmem, problem);
1070  *problem = NULL;
1071 
1072  return SCIP_OKAY;
1073 } /*lint !e715*/
1074 
1075 /** gets pointer to solver-internal problem instance
1076  *
1077  * to do dirty stuff
1078  *
1079  * input:
1080  * - nlpi datastructure for solver interface
1081  * - problem datastructure for problem instance
1082  *
1083  * return: void pointer to problem instance
1084  */
1085 static
1086 SCIP_DECL_NLPIGETPROBLEMPOINTER(nlpiGetProblemPointerWorhp)
1087 {
1088  assert(nlpi != NULL);
1089  assert(problem != NULL);
1090 
1091  return NULL;
1092 } /*lint !e715*/
1093 
1094 /** add variables
1095  *
1096  * input:
1097  * - nlpi datastructure for solver interface
1098  * - problem datastructure for problem instance
1099  * - nvars number of variables
1100  * - lbs lower bounds of variables, can be NULL if -infinity
1101  * - ubs upper bounds of variables, can be NULL if +infinity
1102  * - varnames names of variables, can be NULL
1103  */
1104 static
1105 SCIP_DECL_NLPIADDVARS( nlpiAddVarsWorhp )
1106 {
1107  assert(nlpi != NULL);
1108  assert(problem != NULL);
1109  assert(problem->oracle != NULL);
1110 
1111  SCIP_CALL( SCIPnlpiOracleAddVars(problem->oracle, nvars, lbs, ubs, varnames) );
1112 
1113  BMSfreeMemoryArrayNull(&problem->initguess);
1114  invalidateSolution(problem);
1115  problem->firstrun = TRUE;
1116 
1117  return SCIP_OKAY; /*lint !e527*/
1118 } /*lint !e715*/
1119 
1120 
1121 /** add constraints
1122  * quadratic coefficiens: row oriented matrix for each constraint
1123  *
1124  * input:
1125  * - nlpi datastructure for solver interface
1126  * - problem datastructure for problem instance
1127  * - ncons number of added constraints
1128  * - lhss left hand sides of constraints
1129  * - rhss right hand sides of constraints
1130  * - nlininds number of linear coefficients for each constraint
1131  * may be NULL in case of no linear part
1132  * - lininds indices of variables for linear coefficients for each constraint
1133  * may be NULL in case of no linear part
1134  * - linvals values of linear coefficient for each constraint
1135  * may be NULL in case of no linear part
1136  * - nquadrows number of columns in matrix of quadratic part for each constraint
1137  * may be NULL in case of no quadratic part in any constraint
1138  * - quadrowidxs indices of variables for which a quadratic part is specified
1139  * may be NULL in case of no quadratic part in any constraint
1140  * - quadoffsets start index of each rows quadratic coefficients in quadinds[.] and quadvals[.]
1141  * indices are given w.r.t. quadrowidxs., i.e., quadoffsets[.][i] gives the start index of row quadrowidxs[.][i] in quadvals[.]
1142  * quadoffsets[.][nquadrows[.]] gives length of quadinds[.] and quadvals[.]
1143  * entry of array may be NULL in case of no quadratic part
1144  * may be NULL in case of no quadratic part in any constraint
1145  * - quadinds column indices w.r.t. quadrowidxs, i.e., quadrowidxs[quadinds[.][i]] gives the index of the variable corresponding
1146  * to entry i, entry of array may be NULL in case of no quadratic part
1147  * may be NULL in case of no quadratic part in any constraint
1148  * - quadvals coefficient values
1149  * entry of array may be NULL in case of no quadratic part
1150  * may be NULL in case of no quadratic part in any constraint
1151  * - exprvaridxs indices of variables in expression tree, maps variable indices in expression tree to indices in nlp
1152  * entry of array may be NULL in case of no expression tree
1153  * may be NULL in case of no expression tree in any constraint
1154  * - exprtrees expression tree for nonquadratic part of constraints
1155  * entry of array may be NULL in case of no nonquadratic part
1156  * may be NULL in case of no nonquadratic part in any constraint
1157  * - names of constraints, may be NULL or entries may be NULL
1158  */
1159 static
1160 SCIP_DECL_NLPIADDCONSTRAINTS( nlpiAddConstraintsWorhp )
1161 {
1162  assert(nlpi != NULL);
1163  assert(problem != NULL);
1164  assert(problem->oracle != NULL);
1165 
1166  SCIP_CALL( SCIPnlpiOracleAddConstraints(problem->oracle,
1167  ncons, lhss, rhss,
1168  nlininds, lininds, linvals,
1169  nquadelems, quadelems,
1170  exprvaridxs, exprtrees, names) );
1171 
1172  invalidateSolution(problem);
1173  problem->firstrun = TRUE;
1174 
1175  return SCIP_OKAY; /*lint !e527*/
1176 } /*lint !e715*/
1177 
1178 /** sets or overwrites objective, a minimization problem is expected
1179  * May change sparsity pattern.
1180  *
1181  * input:
1182  * - nlpi datastructure for solver interface
1183  * - problem datastructure for problem instance
1184  * - nlins number of linear variables
1185  * - lininds variable indices
1186  * may be NULL in case of no linear part
1187  * - linvals coefficient values
1188  * may be NULL in case of no linear part
1189  * - nquadcols number of columns in matrix of quadratic part
1190  * - quadcols indices of variables for which a quadratic part is specified
1191  * may be NULL in case of no quadratic part
1192  * - quadoffsets start index of each rows quadratic coefficients in quadinds and quadvals
1193  * quadoffsets[.][nquadcols] gives length of quadinds and quadvals
1194  * may be NULL in case of no quadratic part
1195  * - quadinds column indices
1196  * may be NULL in case of no quadratic part
1197  * - quadvals coefficient values
1198  * may be NULL in case of no quadratic part
1199  * - exprvaridxs indices of variables in expression tree, maps variable indices in expression tree to indices in nlp
1200  * may be NULL in case of no expression tree
1201  * - exprtree expression tree for nonquadratic part of objective function
1202  * may be NULL in case of no nonquadratic part
1203  * - constant objective value offset
1204  */
1205 static
1206 SCIP_DECL_NLPISETOBJECTIVE( nlpiSetObjectiveWorhp )
1207 {
1208  assert(nlpi != NULL);
1209  assert(problem != NULL);
1210  assert(problem->oracle != NULL);
1211 
1212  /* We pass the objective gradient in dense form to WORHP, so if the sparsity of that gradient changes, we do not need
1213  * to reset WORHP (firstrun=TRUE). However, if the sparsity of the Hessian matrix of the objective changes, then the
1214  * sparsity pattern of the Hessian of the Lagrangian may change. Thus, reset Worhp if the objective was and/or
1215  * becomes nonlinear, but leave firstrun untouched if it was and stays linear.
1216  */
1217  if( nquadelems > 0 || exprtree != NULL || SCIPnlpiOracleGetConstraintDegree(problem->oracle, -1) > 1 )
1218  problem->firstrun = TRUE;
1219 
1220  SCIP_CALL( SCIPnlpiOracleSetObjective(problem->oracle,
1221  constant, nlins, lininds, linvals,
1222  nquadelems, quadelems,
1223  exprvaridxs, exprtree) );
1224 
1225  invalidateSolution(problem);
1226 
1227  return SCIP_OKAY; /*lint !e527*/
1228 } /*lint !e715*/
1229 
1230 /** change variable bounds
1231  *
1232  * input:
1233  * - nlpi datastructure for solver interface
1234  * - problem datastructure for problem instance
1235  * - nvars number of variables to change bounds
1236  * - indices indices of variables to change bounds
1237  * - lbs new lower bounds
1238  * - ubs new upper bounds
1239  */
1240 static
1241 SCIP_DECL_NLPICHGVARBOUNDS( nlpiChgVarBoundsWorhp )
1242 {
1243 #ifdef SCIP_DISABLED_CODE
1244  const SCIP_Real* oldlbs = SCIPnlpiOracleGetVarLbs(problem->oracle);
1245  const SCIP_Real* oldubs = SCIPnlpiOracleGetVarUbs(problem->oracle);
1246  int i;
1247 #endif
1248 
1249  assert(nlpi != NULL);
1250  assert(problem != NULL);
1251  assert(problem->oracle != NULL);
1252 
1253 #ifdef SCIP_DISABLED_CODE
1254  /* TODO check WORHP version here */
1255  /* So far, Worhp can not handle fixed variables (and fixed variables that have been unfixed) when applying a
1256  * restart. The following code needs to be removed when this has changed.
1257  */
1258  for( i = 0; i < nvars; ++i )
1259  {
1260  int index = indices[i];
1261  SCIPdebugMessage("change bounds of %d from [%g,%g] -> [%g,%g]\n", index, oldlbs[index], oldubs[index],
1262  lbs[i], ubs[i]);
1263 
1264  if( REALABS(lbs[i] - ubs[i]) <= problem->feastol )
1265  problem->firstrun = TRUE;
1266  else
1267  if( REALABS(oldlbs[index] - oldubs[index]) <= problem->feastol )
1268  problem->firstrun = TRUE;
1269  }
1270 #endif
1271 
1272  SCIP_CALL( SCIPnlpiOracleChgVarBounds(problem->oracle, nvars, indices, lbs, ubs) );
1273 
1274  invalidateSolution(problem);
1275 
1276  return SCIP_OKAY; /*lint !e527*/
1277 } /*lint !e715*/
1278 
1279 /** change constraint bounds
1280  *
1281  * input:
1282  * - nlpi datastructure for solver interface
1283  * - problem datastructure for problem instance
1284  * - nconss number of constraints to change sides
1285  * - indices indices of constraints to change sides
1286  * - lhss new left hand sides
1287  * - rhss new right hand sides
1288  */
1289 static
1290 SCIP_DECL_NLPICHGCONSSIDES( nlpiChgConsSidesWorhp )
1291 {
1292  assert(nlpi != NULL);
1293  assert(problem != NULL);
1294  assert(problem->oracle != NULL);
1295 
1296 #ifdef SCIP_DEBUG
1297  {
1298  SCIP_Real oldlhs;
1299  SCIP_Real oldrhs;
1300  int i;
1301 
1302  for( i = 0; i < nconss; ++i )
1303  {
1304  int index = indices[i];
1305  oldlhs = SCIPnlpiOracleGetConstraintLhs(problem->oracle, index);
1306  oldrhs = SCIPnlpiOracleGetConstraintRhs(problem->oracle, index);
1307  SCIPdebugMessage("change constraint side of %d from [%g,%g] -> [%g,%g]\n", index, oldlhs, oldrhs, lhss[i], rhss[i]);
1308  }
1309  }
1310 #endif
1311 
1312  SCIP_CALL( SCIPnlpiOracleChgConsSides(problem->oracle, nconss, indices, lhss, rhss) );
1313 
1314  invalidateSolution(problem);
1315 
1316  return SCIP_OKAY; /*lint !e527*/
1317 } /*lint !e715*/
1318 
1319 /** delete a set of variables
1320  *
1321  * input:
1322  * - nlpi datastructure for solver interface
1323  * - problem datastructure for problem instance
1324  * - dstats deletion status of vars; 1 if var should be deleted, 0 if not
1325  *
1326  * output:
1327  * - dstats new position of var, -1 if var was deleted
1328  */
1329 static
1330 SCIP_DECL_NLPIDELVARSET( nlpiDelVarSetWorhp )
1331 {
1332  assert(nlpi != NULL);
1333  assert(problem != NULL);
1334  assert(problem->oracle != NULL);
1335 
1336  SCIP_CALL( SCIPnlpiOracleDelVarSet(problem->oracle, dstats) );
1337 
1338  BMSfreeMemoryArrayNull(&problem->initguess); // @TODO keep initguess for remaining variables
1339 
1340  invalidateSolution(problem);
1341  problem->firstrun = TRUE;
1342 
1343  return SCIP_OKAY; /*lint !e527*/
1344 } /*lint !e715*/
1345 
1346 /** delete a set of constraints
1347  *
1348  * input:
1349  * - nlpi datastructure for solver interface
1350  * - problem datastructure for problem instance
1351  * - dstats deletion status of rows; 1 if row should be deleted, 0 if not
1352  *
1353  * output:
1354  * - dstats new position of row, -1 if row was deleted
1355  */
1356 static
1357 SCIP_DECL_NLPIDELCONSSET( nlpiDelConstraintSetWorhp )
1358 {
1359  assert(nlpi != NULL);
1360  assert(problem != NULL);
1361  assert(problem->oracle != NULL);
1362 
1363  SCIP_CALL( SCIPnlpiOracleDelConsSet(problem->oracle, dstats) );
1364 
1365  invalidateSolution(problem);
1366  problem->firstrun = TRUE;
1367 
1368  return SCIP_OKAY; /*lint !e527*/
1369 } /*lint !e715*/
1370 
1371 /** changes (or adds) linear coefficients in a constraint or objective
1372  *
1373  * input:
1374  * - nlpi datastructure for solver interface
1375  * - problem datastructure for problem instance
1376  * - idx index of constraint or -1 for objective
1377  * - nvals number of values in linear constraint to change
1378  * - varidxs indices of variables which coefficient to change
1379  * - vals new values for coefficients
1380  */
1381 static
1382 SCIP_DECL_NLPICHGLINEARCOEFS( nlpiChgLinearCoefsWorhp )
1383 {
1384  assert(nlpi != NULL);
1385  assert(problem != NULL);
1386  assert(problem->oracle != NULL);
1387 
1388  SCIP_CALL( SCIPnlpiOracleChgLinearCoefs(problem->oracle, idx, nvals, varidxs, vals) );
1389 
1390  invalidateSolution(problem);
1391  problem->firstrun = TRUE;
1392 
1393  return SCIP_OKAY; /*lint !e527*/
1394 } /*lint !e715*/
1395 
1396 /** changes (or adds) coefficients in the quadratic part of a constraint or objective
1397  *
1398  * input:
1399  * - nlpi datastructure for solver interface
1400  * - problem datastructure for problem instance
1401  * - idx index of constraint or -1 for objective
1402  * - nentries number of entries in quadratic matrix to change
1403  * - rows row indices of entries in quadratic matrix where values should be changed
1404  * - cols column indices of entries in quadratic matrix where values should be changed
1405  * - values new values for entries in quadratic matrix
1406  */
1407 static
1408 SCIP_DECL_NLPICHGQUADCOEFS( nlpiChgQuadraticCoefsWorhp )
1409 {
1410  assert(nlpi != NULL);
1411  assert(problem != NULL);
1412  assert(problem->oracle != NULL);
1413 
1414  SCIP_CALL( SCIPnlpiOracleChgQuadCoefs(problem->oracle, idx, nquadelems, quadelems) );
1415 
1416  invalidateSolution(problem);
1417  problem->firstrun = TRUE;
1418 
1419  return SCIP_OKAY; /*lint !e527*/
1420 } /*lint !e715*/
1421 
1422 /** replaces the expression tree of a constraint or objective
1423  *
1424  * input:
1425  * - nlpi datastructure for solver interface
1426  * - problem datastructure for problem instance
1427  * - idxcons index of constraint or -1 for objective
1428  * - exprvaridxs indices of variables in expression tree, maps variable indices in expression tree to indices in nlp, or NULL
1429  * - exprtree new expression tree for constraint or objective, or NULL to only remove previous tree
1430  */
1431 static
1432 SCIP_DECL_NLPICHGEXPRTREE( nlpiChgExprtreeWorhp )
1433 {
1434  assert(nlpi != NULL);
1435  assert(problem != NULL);
1436  assert(problem->oracle != NULL);
1437 
1438  SCIP_CALL( SCIPnlpiOracleChgExprtree(problem->oracle, idxcons, exprvaridxs, exprtree) );
1439 
1440  invalidateSolution(problem);
1441  problem->firstrun = TRUE;
1442 
1443  return SCIP_OKAY; /*lint !e527*/
1444 } /*lint !e715*/
1445 
1446 /** change one coefficient in the nonlinear part
1447  *
1448  * input:
1449  * - nlpi datastructure for solver interface
1450  * - problem datastructure for problem instance
1451  * - idxcons index of constraint or -1 for objective
1452  * - idxparam index of parameter
1453  * - value new value for nonlinear parameter
1454  *
1455  * return: Error if parameter does not exist
1456  */
1457 static
1458 SCIP_DECL_NLPICHGNONLINCOEF( nlpiChgNonlinCoefWorhp )
1459 {
1460  assert(nlpi != NULL);
1461  assert(problem != NULL);
1462  assert(problem->oracle != NULL);
1463 
1464  SCIP_CALL( SCIPnlpiOracleChgExprParam(problem->oracle, idxcons, idxparam, value) );
1465 
1466  invalidateSolution(problem);
1467 
1468  return SCIP_OKAY; /*lint !e527*/
1469 } /*lint !e715*/
1470 
1471 /** change the constant offset in the objective
1472  *
1473  * input:
1474  * - nlpi datastructure for solver interface
1475  * - problem datastructure for problem instance
1476  * - objconstant new value for objective constant
1477  */
1478 static
1479 SCIP_DECL_NLPICHGOBJCONSTANT( nlpiChgObjConstantWorhp )
1480 {
1481  assert(nlpi != NULL);
1482  assert(problem != NULL);
1483  assert(problem->oracle != NULL);
1484 
1485  SCIP_CALL( SCIPnlpiOracleChgObjConstant(problem->oracle, objconstant) );
1486 
1487  return SCIP_OKAY; /*lint !e527*/
1488 } /*lint !e715*/
1489 
1490 /** sets initial guess for primal variables
1491  *
1492  * input:
1493  * - nlpi datastructure for solver interface
1494  * - problem datastructure for problem instance
1495  * - primalvalues initial primal values for variables, or NULL to clear previous values
1496  * - consdualvalues initial dual values for constraints, or NULL to clear previous values
1497  * - varlbdualvalues initial dual values for variable lower bounds, or NULL to clear previous values
1498  * - varubdualvalues initial dual values for variable upper bounds, or NULL to clear previous values
1499  */
1500 static
1501 SCIP_DECL_NLPISETINITIALGUESS( nlpiSetInitialGuessWorhp )
1502 {
1503  assert(nlpi != NULL);
1504  assert(problem != NULL);
1505  assert(problem->oracle != NULL);
1506 
1507  if( primalvalues != NULL )
1508  {
1509  if( !problem->initguess )
1510  {
1511  if( BMSduplicateMemoryArray(&problem->initguess, primalvalues, SCIPnlpiOracleGetNVars(problem->oracle)) == NULL )
1512  return SCIP_NOMEMORY;
1513  }
1514  else
1515  {
1516  BMScopyMemoryArray(problem->initguess, primalvalues, SCIPnlpiOracleGetNVars(problem->oracle));
1517  }
1518  }
1519  else
1520  {
1521  BMSfreeMemoryArrayNull(&problem->initguess);
1522  }
1523 
1524  return SCIP_OKAY;
1525 } /*lint !e715*/
1526 
1527 /** tries to solve NLP
1528  *
1529  * input:
1530  * - nlpi datastructure for solver interface
1531  * - problem datastructure for problem instance
1532  */
1533 static
1534 SCIP_DECL_NLPISOLVE( nlpiSolveWorhp )
1535 {
1536  SCIP_NLPIDATA* nlpidata = SCIPnlpiGetData(nlpi);
1537  Workspace* wsp = problem->wsp;
1538  Control* cnt = problem->cnt;
1539  OptVar* opt = problem->opt;
1540  Params* par = problem->par;
1541  int status;
1542  int i;
1543 
1544  problem->lastniter = -1;
1545  problem->lasttime = -1.0;
1546 
1547  if( problem->verblevel == 0 )
1548  {
1549  SetWorhpPrint(noprint);
1550  }
1551  else
1552  {
1553  /* TODO this should go to a function that prints to the SCIP message handler
1554  * all this doesn't seem threadsafe at all!
1555  */
1556  SetWorhpPrint(WorhpDefaultPrintFunction);
1557  }
1558 
1559  /* initialize Worhp data if necessary */
1560  if( problem->firstrun )
1561  {
1562  SCIP_CALL( freeWorhp(problem) );
1563  SCIP_CALL( initWorhp(nlpi, problem) );
1564  problem->firstrun = FALSE;
1565  }
1566  else
1567  {
1568  SCIP_CALL( updateWorhp(problem) );
1569  }
1570 
1571  /* set parameters */
1572  InitParams(&status, par);
1573 
1574  if( status != OK )
1575  return SCIP_INVALIDCALL;
1576 
1577  par->Algorithm = nlpidata->useip ? 2 : 1;
1578  par->ScaledKKT = DEFAULT_SCALEDKKT;
1579  par->sKKTOnlyAcceptable = DEFAULT_SCALEDKKT;
1580 
1581  par->Infty = nlpidata->infinity;
1582  par->TolFeas = problem->feastol;
1583  par->TolOpti = problem->relobjtol;
1584  par->TolComp = problem->relobjtol;
1585  par->Timeout = problem->timelim;
1586  par->MaxIter = problem->itlim;
1587  par->NLPprint = problem->verblevel - 1; /* Worhp verbosity levels: -1 = off, 0 = normal, 1 = debug, >1 = more debug */
1588 
1589 #ifdef CHECKFUNVALUES
1590  /* activate gradient and hessian check */
1591  par->CheckValuesDF = TRUE;
1592  par->CheckValuesDG = TRUE;
1593  par->CheckValuesHM = TRUE;
1594 #endif
1595 
1596 #ifdef SCIP_DEBUG
1597  SCIP_CALL( SCIPnlpiOraclePrintProblem(problem->oracle, nlpidata->messagehdlr, NULL) );
1598 #endif
1599 
1600  /* set initial guess (if available) */
1601  if( problem->initguess != NULL )
1602  {
1603  BMScopyMemoryArray(problem->opt->X, problem->initguess, problem->opt->n);
1604  }
1605  else
1606  {
1607  SCIP_Real lb, ub;
1608 
1609  assert(problem->randnumgen != NULL);
1610 
1611  SCIPdebugMessage("Worhp started without intial primal values; make up starting guess by projecting 0 onto variable bounds\n");
1612 
1613  for( i = 0; i < problem->opt->n; ++i )
1614  {
1615  lb = SCIPnlpiOracleGetVarLbs(problem->oracle)[i];
1616  ub = SCIPnlpiOracleGetVarUbs(problem->oracle)[i];
1617 
1618  if( lb > 0.0 )
1619  problem->opt->X[i] = SCIPrandomGetReal(problem->randnumgen, lb, lb + MAXPERTURB*MIN(1.0, ub-lb));
1620  else if( ub < 0.0 )
1621  problem->opt->X[i] = SCIPrandomGetReal(problem->randnumgen, ub - MAXPERTURB*MIN(1.0, ub-lb), ub);
1622  else
1623  problem->opt->X[i] = SCIPrandomGetReal(problem->randnumgen,
1624  MAX(lb, -MAXPERTURB*MIN(1.0, ub-lb)), MIN(ub, MAXPERTURB*MIN(1.0, ub-lb)));
1625  }
1626  }
1627 
1628 #ifdef SCIP_DEBUG
1629  SCIPdebugMessage("start point:\n");
1630  for( i = 0; i < problem->opt->n; ++i )
1631  {
1632  SCIPdebugMessage("x[%d] = %f\n", i, problem->opt->X[i]);
1633  }
1634 #endif
1635 
1636  /*
1637  * Worhp Reverse Communication loop.
1638  * In every iteration poll GetUserAction for the requested action, i.e. one
1639  * of {callWorhp, iterOutput, evalF, evalG, evalDF, evalDG, evalHM, fidif}.
1640  *
1641  * Make sure to reset the requested user action afterwards by calling
1642  * DoneUserAction, except for 'callWorhp' and 'fidif'.
1643  */
1644  while( cnt->status < TerminateSuccess && cnt->status > TerminateError )
1645  {
1646  /*
1647  * Worhp's main routine.
1648  * Do not manually reset callWorhp, this is only done by the FD routines.
1649  */
1650  if( GetUserAction(cnt, callWorhp) )
1651  {
1652  Worhp(opt, wsp, par, cnt);
1653  /* No DoneUserAction! */
1654  }
1655 
1656  /*
1657  * Show iteration output.
1658  * The call to IterationOutput() may be replaced by user-defined code.
1659  */
1660  if( GetUserAction(cnt, iterOutput) )
1661  {
1662  IterationOutput(opt, wsp, par, cnt);
1663  DoneUserAction(cnt, iterOutput);
1664  }
1665 
1666  /*
1667  * Evaluate the objective function.
1668  * The call to UserF may be replaced by user-defined code.
1669  */
1670  if( GetUserAction(cnt, evalF) )
1671  {
1672  if( userF(problem) != SCIP_OKAY )
1673  break;
1674  DoneUserAction(cnt, evalF);
1675  }
1676 
1677  /*
1678  * Evaluate the constraints.
1679  * The call to UserG may be replaced by user-defined code.
1680  */
1681  if( GetUserAction(cnt, evalG) )
1682  {
1683  if( userG(problem) != SCIP_OKAY )
1684  break;
1685  DoneUserAction(cnt, evalG);
1686  }
1687 
1688  /*
1689  * Evaluate the gradient of the objective function.
1690  * The call to UserDF may be replaced by user-defined code.
1691  */
1692  if( GetUserAction(cnt, evalDF) )
1693  {
1694  if( userDF(problem) != SCIP_OKAY )
1695  break;
1696  DoneUserAction(cnt, evalDF);
1697  }
1698 
1699  /*
1700  * Evaluate the Jacobian of the constraints.
1701  * The call to UserDG may be replaced by user-defined code.
1702  */
1703  if( GetUserAction(cnt, evalDG) )
1704  {
1705  if( userDG(problem) != SCIP_OKAY )
1706  break;
1707  DoneUserAction(cnt, evalDG);
1708  }
1709 
1710  /*
1711  * Evaluate the Hessian matrix of the Lagrange function (L = f + mu*g)
1712  * The call to UserHM may be replaced by user-defined code.
1713  */
1714  if( GetUserAction(cnt, evalHM) )
1715  {
1716  if( userHM(problem) != SCIP_OKAY)
1717  break;
1718  DoneUserAction(cnt, evalHM);
1719  }
1720 
1721  /*
1722  * Use finite differences with RC to determine derivatives
1723  * Do not reset fidif, this is done by the FD routine.
1724  */
1725  if( GetUserAction(cnt, fidif) )
1726  {
1727  WorhpFidif(opt, wsp, par, cnt);
1728  /* No DoneUserAction! */
1729  }
1730  }
1731 
1732  /* interpret Worhp result */
1733  if( cnt->status < TerminateSuccess && cnt->status > TerminateError )
1734  {
1735  SCIPmessagePrintWarning(nlpidata->messagehdlr, "Worhp failed because of an invalid function evaluation!\n");
1736  problem->lastsolstat = SCIP_NLPSOLSTAT_UNKNOWN;
1737  problem->lasttermstat = SCIP_NLPTERMSTAT_NUMERR;
1738  }
1739  else
1740  {
1741  SCIP_CALL( evaluateWorhpRun(problem) );
1742  }
1743 
1744  /* prints a status message with information about the current solver status */
1745  StatusMsg(opt, wsp, par, cnt);
1746 
1747  /* store statistics */
1748  problem->lastniter = wsp->MajorIter;
1749  problem->lasttime = GetTimerCont(&cnt->Timer);
1750 
1751  return SCIP_OKAY;
1752 } /*lint !e715*/
1753 
1754 /** gives solution status
1755  *
1756  * input:
1757  * - nlpi datastructure for solver interface
1758  * - problem datastructure for problem instance
1759  *
1760  * return: Solution Status
1761  */
1762 static
1763 SCIP_DECL_NLPIGETSOLSTAT( nlpiGetSolstatWorhp )
1764 {
1765  assert(nlpi != NULL);
1766  assert(problem != NULL);
1767 
1768  return problem->lastsolstat;
1769 } /*lint !e715*/
1770 
1771 /** gives termination reason
1772  *
1773  * input:
1774  * - nlpi datastructure for solver interface
1775  * - problem datastructure for problem instance
1776  *
1777  * return: Termination Status
1778  */
1779 static
1780 SCIP_DECL_NLPIGETTERMSTAT( nlpiGetTermstatWorhp )
1781 {
1782  assert(nlpi != NULL);
1783  assert(problem != NULL);
1784 
1785  return problem->lasttermstat;
1786 } /*lint !e715*/
1787 
1788 /** gives primal and dual solution values
1789  *
1790  * solver can return NULL in dual values if not available
1791  * but if solver provides dual values for one side of variable bounds, then it must also provide those for the other side
1792  *
1793  * for a ranged constraint, the dual variable is positive if the right hand side is active and negative if the left hand side is active
1794  *
1795  * input:
1796  * - nlpi datastructure for solver interface
1797  * - problem datastructure for problem instance
1798  * - primalvalues buffer to store pointer to array to primal values, or NULL if not needed
1799  * - consdualvalues buffer to store pointer to array to dual values of constraints, or NULL if not needed
1800  * - varlbdualvalues buffer to store pointer to array to dual values of variable lower bounds, or NULL if not needed
1801  * - varubdualvalues buffer to store pointer to array to dual values of variable lower bounds, or NULL if not needed
1802  * - objval buffer store the objective value, or NULL if not needed
1803  */
1804 static
1805 SCIP_DECL_NLPIGETSOLUTION( nlpiGetSolutionWorhp )
1806 {
1807  assert(problem != NULL);
1808 
1809  if( primalvalues != NULL )
1810  *primalvalues = problem->lastprimal;
1811 
1812  if( consdualvalues != NULL )
1813  *consdualvalues = problem->lastdualcons;
1814 
1815  if( varlbdualvalues != NULL )
1816  *varlbdualvalues = problem->lastduallb;
1817 
1818  if( varubdualvalues != NULL )
1819  *varubdualvalues = problem->lastdualub;
1820 
1821  if( objval != NULL )
1822  {
1823  if( problem->lastprimal != NULL )
1824  {
1825  /* TODO store last solution value instead of reevaluating the objective function */
1826  SCIP_CALL( SCIPnlpiOracleEvalObjectiveValue(problem->oracle, problem->lastprimal, objval) );
1827  }
1828  else
1829  *objval = SCIP_INVALID;
1830  }
1831 
1832  return SCIP_OKAY;
1833 } /*lint !e715*/
1834 
1835 /** gives solve statistics
1836  *
1837  * input:
1838  * - nlpi datastructure for solver interface
1839  * - problem datastructure for problem instance
1840  * - statistics pointer to store statistics
1841  *
1842  * output:
1843  * - statistics solve statistics
1844  */
1845 static
1846 SCIP_DECL_NLPIGETSTATISTICS( nlpiGetStatisticsWorhp )
1847 {
1848  assert(nlpi != NULL);
1849  assert(problem != NULL);
1850 
1851  SCIPnlpStatisticsSetNIterations(statistics, problem->lastniter);
1852  SCIPnlpStatisticsSetTotalTime(statistics, problem->lasttime);
1853 
1854  return SCIP_OKAY;
1855 } /*lint !e715*/
1856 
1857 /** gives required size of a buffer to store a warmstart object
1858  *
1859  * input:
1860  * - nlpi datastructure for solver interface
1861  * - problem datastructure for problem instance
1862  * - size pointer to store required size for warmstart buffer
1863  *
1864  * output:
1865  * - size required size for warmstart buffer
1866  */
1867 static
1868 SCIP_DECL_NLPIGETWARMSTARTSIZE( nlpiGetWarmstartSizeWorhp )
1869 {
1870  /* TODO */
1871 
1872  return SCIP_OKAY; /*lint !e527*/
1873 } /*lint !e715*/
1874 
1875 /** stores warmstart information in buffer
1876  *
1877  * required size of buffer should have been obtained by SCIPnlpiGetWarmstartSize before
1878  *
1879  * input:
1880  * - nlpi datastructure for solver interface
1881  * - problem datastructure for problem instance
1882  * - buffer memory to store warmstart information
1883  *
1884  * output:
1885  * - buffer warmstart information in solver specific data structure
1886  */
1887 static
1888 SCIP_DECL_NLPIGETWARMSTARTMEMO( nlpiGetWarmstartMemoWorhp )
1889 {
1890  /* TODO */
1891 
1892  return SCIP_OKAY; /*lint !e527*/
1893 } /*lint !e715*/
1894 
1895 /** sets warmstart information in solver
1896  *
1897  * write warmstart to buffer
1898  *
1899  * input:
1900  * - nlpi datastructure for solver interface
1901  * - problem datastructure for problem instance
1902  * - buffer warmstart information
1903  */
1904 static
1905 SCIP_DECL_NLPISETWARMSTARTMEMO( nlpiSetWarmstartMemoWorhp )
1906 {
1907  /* TODO */
1908 
1909  return SCIP_OKAY; /*lint !e527*/
1910 } /*lint !e715*/
1911 
1912 /** gets integer parameter of NLP
1913  *
1914  * input:
1915  * - nlpi NLP interface structure
1916  * - problem datastructure for problem instance
1917  * - type parameter number
1918  * - ival pointer to store the parameter value
1919  *
1920  * output:
1921  * - ival parameter value
1922  */
1923 static
1924 SCIP_DECL_NLPIGETINTPAR( nlpiGetIntParWorhp )
1925 {
1926  assert(nlpi != NULL);
1927  assert(ival != NULL);
1928  assert(problem != NULL);
1929 
1930  switch( type )
1931  {
1933  {
1934  *ival = 1;
1935  break;
1936  }
1937 
1938  case SCIP_NLPPAR_VERBLEVEL:
1939  {
1940  *ival = problem->verblevel;
1941  break;
1942  }
1943 
1944  case SCIP_NLPPAR_FEASTOL:
1945  {
1946  SCIPerrorMessage("feasibility tolerance parameter is of type real.\n");
1947  return SCIP_PARAMETERWRONGTYPE;
1948  }
1949 
1950  case SCIP_NLPPAR_RELOBJTOL:
1951  {
1952  SCIPerrorMessage("relative objective tolerance parameter is of type real.\n");
1953  return SCIP_PARAMETERWRONGTYPE;
1954  }
1955 
1956  case SCIP_NLPPAR_LOBJLIM:
1957  {
1958  SCIPerrorMessage("objective limit parameter is of type real.\n");
1959  return SCIP_PARAMETERWRONGTYPE;
1960  }
1961 
1962  case SCIP_NLPPAR_INFINITY:
1963  {
1964  SCIPerrorMessage("infinity parameter is of type real.\n");
1965  return SCIP_PARAMETERWRONGTYPE;
1966  }
1967 
1968  case SCIP_NLPPAR_ITLIM:
1969  {
1970  *ival = problem->itlim;
1971  break;
1972  }
1973 
1974  case SCIP_NLPPAR_TILIM:
1975  {
1976  SCIPerrorMessage("time limit parameter is of type real.\n");
1977  return SCIP_PARAMETERWRONGTYPE;
1978  }
1979 
1980  case SCIP_NLPPAR_OPTFILE:
1981  {
1982  SCIPerrorMessage("optfile parameter is of type string.\n");
1983  return SCIP_PARAMETERWRONGTYPE;
1984  }
1985 
1986  case SCIP_NLPPAR_FASTFAIL:
1987  {
1988  *ival = problem->fastfail ? 1 : 0;
1989  break;
1990  }
1991 
1992  default:
1993  {
1994  SCIPerrorMessage("Parameter %d not known to Worhp interface.\n", type);
1995  return SCIP_PARAMETERUNKNOWN;
1996  }
1997  }
1998 
1999  return SCIP_OKAY;
2000 } /*lint !e715*/
2001 
2002 /** sets integer parameter of NLP
2003  *
2004  * input:
2005  * - nlpi NLP interface structure
2006  * - problem datastructure for problem instance
2007  * - type parameter number
2008  * - ival parameter value
2009  */
2010 static
2011 SCIP_DECL_NLPISETINTPAR( nlpiSetIntParWorhp )
2012 {
2013  assert(nlpi != NULL);
2014  assert(problem != NULL);
2015 
2016  switch( type )
2017  {
2019  {
2020  if( ival == 0 || ival == 1 )
2021  {
2022  SCIPdebugMessage("from scratch parameter not supported by Worhp interface yet. Ignored.\n");
2023  }
2024  else
2025  {
2026  SCIPerrorMessage("Value %d for parameter from scratch out of range {0, 1}\n", ival);
2027  return SCIP_PARAMETERWRONGVAL;
2028  }
2029  break;
2030  }
2031 
2032  case SCIP_NLPPAR_VERBLEVEL:
2033  {
2034  assert(ival >= 0);
2035  problem->verblevel = ival;
2036  break;
2037  }
2038 
2039  case SCIP_NLPPAR_FEASTOL:
2040  {
2041  SCIPerrorMessage("feasibility tolerance parameter is of type real.\n");
2042  return SCIP_PARAMETERWRONGTYPE;
2043  }
2044 
2045  case SCIP_NLPPAR_RELOBJTOL:
2046  {
2047  SCIPerrorMessage("relative objective tolerance parameter is of type real.\n");
2048  return SCIP_PARAMETERWRONGTYPE;
2049  }
2050 
2051  case SCIP_NLPPAR_LOBJLIM:
2052  {
2053  SCIPerrorMessage("objective limit parameter is of type real.\n");
2054  return SCIP_PARAMETERWRONGTYPE;
2055  }
2056 
2057  case SCIP_NLPPAR_INFINITY:
2058  {
2059  SCIPerrorMessage("infinity parameter is of type real.\n");
2060  return SCIP_PARAMETERWRONGTYPE;
2061  }
2062 
2063  case SCIP_NLPPAR_ITLIM:
2064  {
2065  if( ival >= 0 )
2066  problem->itlim = ival;
2067  else
2068  {
2069  SCIPerrorMessage("Value %d for parameter iteration limit is negative\n", ival);
2070  return SCIP_PARAMETERWRONGVAL;
2071  }
2072  break;
2073  }
2074 
2075  case SCIP_NLPPAR_TILIM:
2076  {
2077  SCIPerrorMessage("time limit parameter is of type real.\n");
2078  return SCIP_PARAMETERWRONGTYPE;
2079  }
2080 
2081  case SCIP_NLPPAR_OPTFILE:
2082  {
2083  SCIPerrorMessage("optfile parameter is of type string.\n");
2084  return SCIP_PARAMETERWRONGTYPE;
2085  }
2086 
2087  case SCIP_NLPPAR_FASTFAIL:
2088  {
2089  if( ival == 0 || ival == 1 )
2090  {
2091  problem->fastfail = ival;
2092  }
2093  else
2094  {
2095  SCIPerrorMessage("Value %d for parameter fastfail out of range {0, 1}\n", ival);
2096  return SCIP_PARAMETERWRONGVAL;
2097  }
2098  break;
2099  }
2100 
2101  default:
2102  {
2103  SCIPerrorMessage("Parameter %d not known to Worhp interface.\n", type);
2104  return SCIP_PARAMETERUNKNOWN;
2105  }
2106  }
2107 
2108  return SCIP_OKAY;
2109 } /*lint !e715*/
2110 
2111 /** gets floating point parameter of NLP
2112  *
2113  * input:
2114  * - nlpi NLP interface structure
2115  * - problem datastructure for problem instance, can be NULL only if type == SCIP_NLPPAR_INFINITY
2116  * - type parameter number
2117  * - dval pointer to store the parameter value
2118  *
2119  * output:
2120  * - dval parameter value
2121  */
2122 static
2123 SCIP_DECL_NLPIGETREALPAR( nlpiGetRealParWorhp )
2124 {
2125  SCIP_NLPIDATA* data = SCIPnlpiGetData(nlpi);
2126 
2127  assert(data != NULL);
2128  assert(dval != NULL);
2129 
2130  switch( type )
2131  {
2133  {
2134  SCIPerrorMessage("fromscratch parameter is of type int.\n");
2135  return SCIP_PARAMETERWRONGTYPE;
2136  }
2137 
2138  case SCIP_NLPPAR_VERBLEVEL:
2139  {
2140  SCIPerrorMessage("verblevel parameter is of type int.\n");
2141  return SCIP_PARAMETERWRONGTYPE;
2142  }
2143 
2144  case SCIP_NLPPAR_FEASTOL:
2145  {
2146  *dval = problem->feastol;
2147  break;
2148  }
2149 
2150  case SCIP_NLPPAR_RELOBJTOL:
2151  {
2152  *dval = problem->relobjtol;
2153  break;
2154  }
2155 
2156  case SCIP_NLPPAR_LOBJLIM:
2157  {
2158  *dval = problem->lobjlim;
2159  break;
2160  }
2161 
2162  case SCIP_NLPPAR_INFINITY:
2163  {
2164  *dval = data->infinity;
2165  break;
2166  }
2167 
2168  case SCIP_NLPPAR_ITLIM:
2169  {
2170  SCIPerrorMessage("itlim parameter is of type int.\n");
2171  return SCIP_PARAMETERWRONGTYPE;
2172  }
2173 
2174  case SCIP_NLPPAR_TILIM:
2175  {
2176  *dval = problem->timelim;
2177  break;
2178  }
2179 
2180  case SCIP_NLPPAR_OPTFILE:
2181  {
2182  SCIPerrorMessage("optfile parameter is of type string.\n");
2183  return SCIP_PARAMETERWRONGTYPE;
2184  }
2185 
2186  case SCIP_NLPPAR_FASTFAIL:
2187  {
2188  SCIPerrorMessage("fastfail parameter is of type int.\n");
2189  return SCIP_PARAMETERWRONGTYPE;
2190  }
2191 
2192  default:
2193  {
2194  break;
2195  }
2196  }
2197 
2198  return SCIP_OKAY; /*lint !e527*/
2199 } /*lint !e715*/
2200 
2201 /** sets floating point parameter of NLP
2202  *
2203  * input:
2204  * - nlpi NLP interface structure
2205  * - problem datastructure for problem instance, can be NULL only if type == SCIP_NLPPAR_INFINITY
2206  * - type parameter number
2207  * - dval parameter value
2208  */
2209 static
2210 SCIP_DECL_NLPISETREALPAR( nlpiSetRealParWorhp )
2211 {
2212  SCIP_NLPIDATA* data = SCIPnlpiGetData(nlpi);
2213 
2214  assert(data != NULL);
2215 
2216  switch( type )
2217  {
2219  {
2220  SCIPerrorMessage("fromscratch parameter is of type real.\n");
2221  return SCIP_PARAMETERWRONGTYPE;
2222  }
2223 
2224  case SCIP_NLPPAR_VERBLEVEL:
2225  {
2226  SCIPerrorMessage("verblevel parameter is of type real.\n");
2227  return SCIP_PARAMETERWRONGTYPE;
2228  }
2229 
2230  case SCIP_NLPPAR_FEASTOL:
2231  {
2232  problem->feastol = dval;
2233  break;
2234  }
2235 
2236  case SCIP_NLPPAR_RELOBJTOL:
2237  {
2238  problem->relobjtol = dval;
2239  break;
2240  }
2241 
2242  case SCIP_NLPPAR_LOBJLIM:
2243  {
2244  problem->lobjlim = dval;
2245  break;
2246  }
2247 
2248  case SCIP_NLPPAR_INFINITY:
2249  {
2250  data->infinity = dval;
2251  break;
2252  }
2253 
2254  case SCIP_NLPPAR_ITLIM:
2255  {
2256  SCIPerrorMessage("itlim parameter is of type real.\n");
2257  return SCIP_PARAMETERWRONGTYPE;
2258  }
2259 
2260  case SCIP_NLPPAR_TILIM:
2261  {
2262  problem->timelim = dval;
2263  break;
2264  }
2265 
2266  case SCIP_NLPPAR_OPTFILE:
2267  {
2268  SCIPerrorMessage("optfile parameter is of type string.\n");
2269  return SCIP_PARAMETERWRONGTYPE;
2270  }
2271 
2272  case SCIP_NLPPAR_FASTFAIL:
2273  {
2274  SCIPerrorMessage("optfile parameter is of type int.\n");
2275  return SCIP_PARAMETERWRONGTYPE;
2276  }
2277 
2278  default:
2279  {
2280  break;
2281  }
2282  }
2283 
2284  return SCIP_OKAY; /*lint !e527*/
2285 } /*lint !e715*/
2286 
2287 /** gets string parameter of NLP
2288  *
2289  * input:
2290  * - nlpi NLP interface structure
2291  * - problem datastructure for problem instance
2292  * - type parameter number
2293  * - sval pointer to store the string value, the user must not modify the string
2294  *
2295  * output:
2296  * - sval parameter value
2297  */
2298 static
2299 SCIP_DECL_NLPIGETSTRINGPAR( nlpiGetStringParWorhp )
2300 {
2301  SCIP_NLPIDATA* nlpidata = SCIPnlpiGetData(nlpi);
2302 
2303  if( type == SCIP_NLPPAR_OPTFILE )
2304  {
2305  SCIPmessagePrintWarning(nlpidata->messagehdlr, "optfile parameter not supported by Worhp interface yet. Ignored.\n");
2306  }
2307  else
2308  {
2309  SCIPerrorMessage("parameter %d is not of type string.\n", type);
2310  return SCIP_PARAMETERWRONGTYPE;
2311  }
2312 
2313  return SCIP_OKAY; /*lint !e527*/
2314 } /*lint !e715*/
2315 
2316 /** sets string parameter of NLP
2317  *
2318  * input:
2319  * - nlpi NLP interface structure
2320  * - problem datastructure for problem instance
2321  * - type parameter number
2322  * - sval parameter value
2323  */
2324 static
2325 SCIP_DECL_NLPISETSTRINGPAR( nlpiSetStringParWorhp )
2326 {
2327  SCIP_NLPIDATA* nlpidata = SCIPnlpiGetData(nlpi);
2328 
2329  if( type == SCIP_NLPPAR_OPTFILE )
2330  {
2331  SCIPmessagePrintWarning(nlpidata->messagehdlr, "optfile parameter not supported by Worhp interface yet. Ignored.\n");
2332  }
2333  else
2334  {
2335  SCIPerrorMessage("parameter %d is not of type string.\n", type);
2336  return SCIP_PARAMETERWRONGTYPE;
2337  }
2338 
2339  return SCIP_OKAY; /*lint !e527*/
2340 } /*lint !e715*/
2341 
2342 /** sets message handler for message output
2343  *
2344  * input:
2345  * - nlpi NLP interface structure
2346  * - messagehdlr SCIP message handler, or NULL to suppress all output
2347  */
2348 static
2349 SCIP_DECL_NLPISETMESSAGEHDLR( nlpiSetMessageHdlrWorhp )
2350 {
2351  SCIP_NLPIDATA* nlpidata;
2352 
2353  assert(nlpi != NULL);
2354 
2355  nlpidata = SCIPnlpiGetData(nlpi);
2356  assert(nlpidata != NULL);
2357 
2358  nlpidata->messagehdlr = messagehdlr;
2359 
2360  return SCIP_OKAY; /*lint !e527*/
2361 } /*lint !e715*/
2362 
2363 /*
2364  * NLP solver interface specific interface methods
2365  */
2366 
2367 /** create solver interface for Worhp solver */
2369  BMS_BLKMEM* blkmem, /**< block memory data structure */
2370  SCIP_NLPI** nlpi, /**< pointer to buffer for nlpi address */
2371  SCIP_Bool useip /**< TRUE for using Interior Point, FALSE for SQP */
2372  )
2373 {
2374  SCIP_NLPIDATA* nlpidata;
2375  char name[SCIP_MAXSTRLEN];
2376  int priority;
2377 
2378  assert(blkmem != NULL);
2379  assert(nlpi != NULL);
2380 
2381  /* create Worhp solver interface data */
2382  SCIP_ALLOC( BMSallocBlockMemory(blkmem, &nlpidata) );
2383  BMSclearMemory(nlpidata);
2384 
2385  nlpidata->blkmem = blkmem;
2386  nlpidata->useip = useip;
2387 
2388  /* initialize parameter */
2389  nlpidata->infinity = SCIP_DEFAULT_INFINITY;
2390 
2391  /* disable Worhp's keyboard handler, not useful here and not threadsafe */
2392  (void) setenv("WORHP_DISABLE_KEYBOARD_HANDLER", "1", 0);
2393 
2394 #if DEFAULT_VERBLEVEL == 0
2395  /* disable Worhp output by default */
2396  SetWorhpPrint(noprint);
2397 #endif
2398 
2399  /* checks the version of the library and header files */
2400  CHECK_WORHP_VERSION
2401 
2402  /* create solver interface */
2403  if( useip )
2404  {
2405  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "worhp-ip");
2406  priority = NLPI_PRIORITY_IP;
2407  }
2408  else
2409  {
2410  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "worhp-sqp");
2411  priority = NLPI_PRIORITY_SQP;
2412  }
2413 
2414  SCIP_CALL( SCIPnlpiCreate(nlpi,
2415  name, NLPI_DESC, priority,
2416  nlpiCopyWorhp, nlpiFreeWorhp, nlpiGetSolverPointerWorhp,
2417  nlpiCreateProblemWorhp, nlpiFreeProblemWorhp, nlpiGetProblemPointerWorhp,
2418  nlpiAddVarsWorhp, nlpiAddConstraintsWorhp, nlpiSetObjectiveWorhp,
2419  nlpiChgVarBoundsWorhp, nlpiChgConsSidesWorhp, nlpiDelVarSetWorhp, nlpiDelConstraintSetWorhp,
2420  nlpiChgLinearCoefsWorhp, nlpiChgQuadraticCoefsWorhp, nlpiChgExprtreeWorhp, nlpiChgNonlinCoefWorhp,
2421  nlpiChgObjConstantWorhp, nlpiSetInitialGuessWorhp, nlpiSolveWorhp, nlpiGetSolstatWorhp, nlpiGetTermstatWorhp,
2422  nlpiGetSolutionWorhp, nlpiGetStatisticsWorhp,
2423  nlpiGetWarmstartSizeWorhp, nlpiGetWarmstartMemoWorhp, nlpiSetWarmstartMemoWorhp,
2424  nlpiGetIntParWorhp, nlpiSetIntParWorhp, nlpiGetRealParWorhp, nlpiSetRealParWorhp, nlpiGetStringParWorhp, nlpiSetStringParWorhp,
2425  nlpiSetMessageHdlrWorhp,
2426  nlpidata) );
2427 
2428  return SCIP_OKAY;
2429 }
2430 
2431 /** gets string that identifies Worhp (version number) */
2433  void
2434  )
2435 {
2436 #ifdef WORHP_VERSION
2437  return "WORHP " WORHP_VERSION;
2438 #else
2439  static char solvername[20];
2440  sprintf(solvername, "WORHP %d.%d." WORHP_PATCH, WORHP_MAJOR, WORHP_MINOR);
2441  return solvername;
2442 #endif
2443 }
2444 
2445 /** gets string that describes Worhp (version number) */
2447  void
2448  )
2449 {
2450  return "Nonlinear programming solver developed at Research Institute Steinbeis (www.worhp.de)";
2451 }
2452 
2453 /** returns whether Worhp is available, i.e., whether it has been linked in */
2455  void
2456  )
2457 {
2458  return TRUE;
2459 }
static SCIP_DECL_NLPICHGEXPRTREE(nlpiChgExprtreeWorhp)
Definition: nlpi_worhp.c:1432
BMS_BLKMEM * blkmem
Definition: nlpi_worhp.c:70
SCIP_RETCODE SCIPnlpiOracleEvalConstraintValues(SCIP_NLPIORACLE *oracle, const SCIP_Real *x, SCIP_Real *convals)
Definition: nlpioracle.c:2435
#define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
Definition: memory.h:449
static SCIP_DECL_NLPICHGOBJCONSTANT(nlpiChgObjConstantWorhp)
Definition: nlpi_worhp.c:1479
enum SCIP_NlpTermStat SCIP_NLPTERMSTAT
Definition: type_nlpi.h:84
static SCIP_RETCODE userDG(SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:531
Params * par
Definition: nlpi_worhp.c:93
static void noprint(int mode, const char s[])
Definition: nlpi_worhp.c:632
const SCIP_Real * SCIPnlpiOracleGetVarUbs(SCIP_NLPIORACLE *oracle)
Definition: nlpioracle.c:2225
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:130
methods to interpret (evaluate) an expression tree "fast"
SCIP_RETCODE SCIPnlpiOracleGetJacobianSparsity(SCIP_NLPIORACLE *oracle, const int **offset, const int **col)
Definition: nlpioracle.c:2510
static SCIP_DECL_NLPIGETINTPAR(nlpiGetIntParWorhp)
Definition: nlpi_worhp.c:1924
SCIP_RETCODE SCIPnlpiOracleGetHessianLagSparsity(SCIP_NLPIORACLE *oracle, const int **offset, const int **col)
Definition: nlpioracle.c:2790
SCIP_NLPSOLSTAT lastsolstat
Definition: nlpi_ipopt.cpp:146
int SCIPnlpiOracleGetNVars(SCIP_NLPIORACLE *oracle)
Definition: nlpioracle.c:2195
SCIP_Real lobjlim
Definition: nlpi_worhp.c:99
Control * cnt
Definition: nlpi_worhp.c:94
static SCIP_DECL_NLPICHGVARBOUNDS(nlpiChgVarBoundsWorhp)
Definition: nlpi_worhp.c:1241
#define MAXPERTURB
Definition: nlpi_worhp.c:53
static SCIP_DECL_NLPISETSTRINGPAR(nlpiSetStringParWorhp)
Definition: nlpi_worhp.c:2325
static SCIP_DECL_NLPICHGQUADCOEFS(nlpiChgQuadraticCoefsWorhp)
Definition: nlpi_worhp.c:1408
#define infinity
Definition: gastrans.c:71
SCIP_Real * lastdualcons
Definition: nlpi_worhp.c:79
static SCIP_DECL_NLPIGETPROBLEMPOINTER(nlpiGetProblemPointerWorhp)
Definition: nlpi_worhp.c:1086
#define SCIP_MAXSTRLEN
Definition: def.h:259
static void invalidateSolution(SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:113
#define NLPI_PRIORITY_SQP
Definition: nlpi_worhp.c:46
static SCIP_DECL_NLPICHGNONLINCOEF(nlpiChgNonlinCoefWorhp)
Definition: nlpi_worhp.c:1458
internal methods for NLPI solver interfaces
static SCIP_RETCODE evaluateWorhpRun(SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:135
SCIP_RETCODE SCIPnlpiOracleSetObjective(SCIP_NLPIORACLE *oracle, const SCIP_Real constant, int nlin, const int *lininds, const SCIP_Real *linvals, int nquadelems, const SCIP_QUADELEM *quadelems, const int *exprvaridxs, const SCIP_EXPRTREE *exprtree)
Definition: nlpioracle.c:1607
static SCIP_DECL_NLPISETINTPAR(nlpiSetIntParWorhp)
Definition: nlpi_worhp.c:2011
methods to store an NLP and request function, gradient, and hessian values
const char * SCIPgetSolverDescWorhp(void)
Definition: nlpi_worhp.c:2446
static SCIP_DECL_NLPISETINITIALGUESS(nlpiSetInitialGuessWorhp)
Definition: nlpi_worhp.c:1501
SCIP_NLPIORACLE * oracle
static SCIP_DECL_NLPIGETWARMSTARTMEMO(nlpiGetWarmstartMemoWorhp)
Definition: nlpi_worhp.c:1888
#define FALSE
Definition: def.h:64
SCIP_Real SCIPnlpiOracleGetConstraintLhs(SCIP_NLPIORACLE *oracle, int considx)
Definition: nlpioracle.c:2276
static SCIP_DECL_NLPIADDVARS(nlpiAddVarsWorhp)
Definition: nlpi_worhp.c:1105
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10011
#define TRUE
Definition: def.h:63
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_RETCODE SCIPnlpiOracleEvalObjectiveValue(SCIP_NLPIORACLE *oracle, const SCIP_Real *x, SCIP_Real *objval)
Definition: nlpioracle.c:2397
static SCIP_DECL_NLPIGETSOLUTION(nlpiGetSolutionWorhp)
Definition: nlpi_worhp.c:1805
#define SCIPdebugMessage
Definition: pub_message.h:77
SCIP_RETCODE SCIPnlpiSetMessageHdlr(SCIP_NLPI *nlpi, SCIP_MESSAGEHDLR *messagehdlr)
Definition: nlpi.c:720
SCIP_RETCODE SCIPnlpiOracleEvalObjectiveGradient(SCIP_NLPIORACLE *oracle, const SCIP_Real *x, SCIP_Bool isnewx, SCIP_Real *objval, SCIP_Real *objgrad)
Definition: nlpioracle.c:2461
SCIP_Real relobjtol
Definition: nlpi_worhp.c:98
SCIP_RETCODE SCIPnlpiOracleDelConsSet(SCIP_NLPIORACLE *oracle, int *delstats)
Definition: nlpioracle.c:1824
SCIP_RETCODE SCIPnlpiOracleChgObjConstant(SCIP_NLPIORACLE *oracle, SCIP_Real objconstant)
Definition: nlpioracle.c:2179
int SCIPnlpiOracleGetNConstraints(SCIP_NLPIORACLE *oracle)
Definition: nlpioracle.c:2205
static SCIP_DECL_NLPIGETSTRINGPAR(nlpiGetStringParWorhp)
Definition: nlpi_worhp.c:2299
SCIP_Real * lastduallb
Definition: nlpi_worhp.c:80
#define BMSduplicateBlockMemoryArray(mem, ptr, source, num)
Definition: memory.h:443
int SCIPnlpiOracleGetConstraintDegree(SCIP_NLPIORACLE *oracle, int considx)
Definition: nlpioracle.c:2317
SCIP_RETCODE SCIPnlpiOracleChgExprtree(SCIP_NLPIORACLE *oracle, int considx, const int *exprvaridxs, const SCIP_EXPRTREE *exprtree)
Definition: nlpioracle.c:2097
SCIP_RETCODE SCIPnlpiOracleCreate(BMS_BLKMEM *blkmem, SCIP_NLPIORACLE **oracle)
Definition: nlpioracle.c:1325
SCIP_Bool firstrun
Definition: nlpi_ipopt.cpp:143
#define SCIPerrorMessage
Definition: pub_message.h:45
#define SCIPdebugPrintf
Definition: pub_message.h:80
const SCIP_Real * SCIPnlpiOracleGetVarLbs(SCIP_NLPIORACLE *oracle)
Definition: nlpioracle.c:2215
static SCIP_DECL_NLPISETMESSAGEHDLR(nlpiSetMessageHdlrWorhp)
Definition: nlpi_worhp.c:2349
SCIP_RETCODE SCIPnlpiOracleChgVarBounds(SCIP_NLPIORACLE *oracle, int nvars, const int *indices, const SCIP_Real *lbs, const SCIP_Real *ubs)
Definition: nlpioracle.c:1644
struct SCIP_NlpiData SCIP_NLPIDATA
Definition: type_nlpi.h:38
static SCIP_RETCODE userHM(SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:576
enum SCIP_NlpSolStat SCIP_NLPSOLSTAT
Definition: type_nlpi.h:69
SCIP_RETCODE SCIPnlpiOracleAddVars(SCIP_NLPIORACLE *oracle, int nvars, const SCIP_Real *lbs, const SCIP_Real *ubs, const char **varnames)
Definition: nlpioracle.c:1444
static SCIP_DECL_NLPIADDCONSTRAINTS(nlpiAddConstraintsWorhp)
Definition: nlpi_worhp.c:1160
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:417
internal miscellaneous methods
void SCIPrandomFree(SCIP_RANDNUMGEN **randnumgen, BMS_BLKMEM *blkmem)
Definition: misc.c:9350
SCIP_Real timelim
Definition: nlpi_worhp.c:100
static SCIP_DECL_NLPIDELVARSET(nlpiDelVarSetWorhp)
Definition: nlpi_worhp.c:1330
Workspace * wsp
Definition: nlpi_worhp.c:92
#define REALABS(x)
Definition: def.h:173
static SCIP_DECL_NLPIGETTERMSTAT(nlpiGetTermstatWorhp)
Definition: nlpi_worhp.c:1780
#define SCIP_CALL(x)
Definition: def.h:350
Worhp NLP interface.
static SCIP_DECL_NLPICOPY(nlpiCopyWorhp)
Definition: nlpi_worhp.c:917
#define SCIP_DEFAULT_FEASTOL
Definition: def.h:157
SCIP_Bool SCIPisWorhpAvailableWorhp(void)
Definition: nlpi_worhp.c:2454
static SCIP_DECL_NLPIGETREALPAR(nlpiGetRealParWorhp)
Definition: nlpi_worhp.c:2123
static SCIP_DECL_NLPISOLVE(nlpiSolveWorhp)
Definition: nlpi_worhp.c:1534
static SCIP_DECL_NLPIDELCONSSET(nlpiDelConstraintSetWorhp)
Definition: nlpi_worhp.c:1357
SCIP_Real feastol
Definition: nlpi_worhp.c:97
SCIP_Real SCIPnlpiOracleGetConstraintRhs(SCIP_NLPIORACLE *oracle, int considx)
Definition: nlpioracle.c:2289
#define BMSduplicateMemoryArray(ptr, source, num)
Definition: memory.h:125
SCIP_RETCODE SCIPnlpiOracleFree(SCIP_NLPIORACLE **oracle)
Definition: nlpioracle.c:1352
methods for catching the user CTRL-C interrupt
#define DEFAULT_RANDSEED
Definition: nlpi_worhp.c:51
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:446
static SCIP_DECL_NLPIFREE(nlpiFreeWorhp)
Definition: nlpi_worhp.c:942
#define NLPI_PRIORITY_IP
Definition: nlpi_worhp.c:45
SCIP_RETCODE SCIPnlpiCreate(SCIP_NLPI **nlpi, const char *name, const char *description, int priority, SCIP_DECL_NLPICOPY((*nlpicopy)), SCIP_DECL_NLPIFREE((*nlpifree)), SCIP_DECL_NLPIGETSOLVERPOINTER((*nlpigetsolverpointer)), SCIP_DECL_NLPICREATEPROBLEM((*nlpicreateproblem)), SCIP_DECL_NLPIFREEPROBLEM((*nlpifreeproblem)), SCIP_DECL_NLPIGETPROBLEMPOINTER((*nlpigetproblempointer)), SCIP_DECL_NLPIADDVARS((*nlpiaddvars)), SCIP_DECL_NLPIADDCONSTRAINTS((*nlpiaddconstraints)), SCIP_DECL_NLPISETOBJECTIVE((*nlpisetobjective)), SCIP_DECL_NLPICHGVARBOUNDS((*nlpichgvarbounds)), SCIP_DECL_NLPICHGCONSSIDES((*nlpichgconssides)), SCIP_DECL_NLPIDELVARSET((*nlpidelvarset)), SCIP_DECL_NLPIDELCONSSET((*nlpidelconsset)), SCIP_DECL_NLPICHGLINEARCOEFS((*nlpichglinearcoefs)), SCIP_DECL_NLPICHGQUADCOEFS((*nlpichgquadcoefs)), SCIP_DECL_NLPICHGEXPRTREE((*nlpichgexprtree)), SCIP_DECL_NLPICHGNONLINCOEF((*nlpichgnonlincoef)), SCIP_DECL_NLPICHGOBJCONSTANT((*nlpichgobjconstant)), SCIP_DECL_NLPISETINITIALGUESS((*nlpisetinitialguess)), SCIP_DECL_NLPISOLVE((*nlpisolve)), SCIP_DECL_NLPIGETSOLSTAT((*nlpigetsolstat)), SCIP_DECL_NLPIGETTERMSTAT((*nlpigettermstat)), SCIP_DECL_NLPIGETSOLUTION((*nlpigetsolution)), SCIP_DECL_NLPIGETSTATISTICS((*nlpigetstatistics)), SCIP_DECL_NLPIGETWARMSTARTSIZE((*nlpigetwarmstartsize)), SCIP_DECL_NLPIGETWARMSTARTMEMO((*nlpigetwarmstartmemo)), SCIP_DECL_NLPISETWARMSTARTMEMO((*nlpisetwarmstartmemo)), SCIP_DECL_NLPIGETINTPAR((*nlpigetintpar)), SCIP_DECL_NLPISETINTPAR((*nlpisetintpar)), SCIP_DECL_NLPIGETREALPAR((*nlpigetrealpar)), SCIP_DECL_NLPISETREALPAR((*nlpisetrealpar)), SCIP_DECL_NLPIGETSTRINGPAR((*nlpigetstringpar)), SCIP_DECL_NLPISETSTRINGPAR((*nlpisetstringpar)), SCIP_DECL_NLPISETMESSAGEHDLR((*nlpisetmessagehdlr)), SCIP_NLPIDATA *nlpidata)
Definition: nlpi.c:40
SCIP_RETCODE SCIPnlpiOraclePrintProblem(SCIP_NLPIORACLE *oracle, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: nlpioracle.c:2932
#define SCIP_Bool
Definition: def.h:61
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:435
SCIP_RETCODE SCIPnlpiOracleSetProblemName(SCIP_NLPIORACLE *oracle, const char *name)
Definition: nlpioracle.c:1409
static SCIP_DECL_NLPICHGCONSSIDES(nlpiChgConsSidesWorhp)
Definition: nlpi_worhp.c:1290
SCIP_RETCODE SCIPnlpiOracleAddConstraints(SCIP_NLPIORACLE *oracle, int nconss, const SCIP_Real *lhss, const SCIP_Real *rhss, const int *nlininds, int *const *lininds, SCIP_Real *const *linvals, const int *nquadelems, SCIP_QUADELEM *const *quadelems, int *const *exprvaridxs, SCIP_EXPRTREE *const *exprtrees, const char **consnames)
Definition: nlpioracle.c:1529
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition: memory.h:448
void SCIPnlpStatisticsSetNIterations(SCIP_NLPSTATISTICS *statistics, int niterations)
Definition: nlpi.c:836
#define MAX(x, y)
Definition: tclique_def.h:75
static SCIP_RETCODE userDF(SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:487
void SCIPnlpStatisticsSetTotalTime(SCIP_NLPSTATISTICS *statistics, SCIP_Real totaltime)
Definition: nlpi.c:846
static SCIP_DECL_NLPISETOBJECTIVE(nlpiSetObjectiveWorhp)
Definition: nlpi_worhp.c:1206
static SCIP_RETCODE userF(SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:422
SCIP_RETCODE SCIPnlpiOracleChgLinearCoefs(SCIP_NLPIORACLE *oracle, int considx, int nentries, const int *varidxs, const SCIP_Real *newcoefs)
Definition: nlpioracle.c:1902
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:116
SCIP_RETCODE SCIPnlpiOracleChgQuadCoefs(SCIP_NLPIORACLE *oracle, int considx, int nquadelems, const SCIP_QUADELEM *quadelems)
Definition: nlpioracle.c:1999
static SCIP_DECL_NLPIFREEPROBLEM(nlpiFreeProblemWorhp)
Definition: nlpi_worhp.c:1034
#define NLPI_DESC
Definition: nlpi_worhp.c:44
SCIP_RETCODE SCIPnlpiOracleChgConsSides(SCIP_NLPIORACLE *oracle, int nconss, const int *indices, const SCIP_Real *lhss, const SCIP_Real *rhss)
Definition: nlpioracle.c:1680
#define BMSclearMemory(ptr)
Definition: memory.h:111
static SCIP_RETCODE updateWorhp(SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:846
static SCIP_DECL_NLPIGETSOLVERPOINTER(nlpiGetSolverPointerWorhp)
Definition: nlpi_worhp.c:967
SCIP_Real SCIPrandomGetReal(SCIP_RANDNUMGEN *randnumgen, SCIP_Real minrandval, SCIP_Real maxrandval)
Definition: misc.c:9388
SCIP_RETCODE SCIPnlpiOracleDelVarSet(SCIP_NLPIORACLE *oracle, int *delstats)
Definition: nlpioracle.c:1714
const char * SCIPgetSolverNameWorhp(void)
Definition: nlpi_worhp.c:2432
static SCIP_DECL_NLPICHGLINEARCOEFS(nlpiChgLinearCoefsWorhp)
Definition: nlpi_worhp.c:1382
static SCIP_RETCODE initWorhp(SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:641
#define SCIP_DEFAULT_INFINITY
Definition: def.h:154
SCIP_RETCODE SCIPnlpiOracleChgExprParam(SCIP_NLPIORACLE *oracle, int considx, int paramidx, SCIP_Real paramval)
Definition: nlpioracle.c:2154
SCIP_NLPIDATA * SCIPnlpiGetData(SCIP_NLPI *nlpi)
Definition: nlpi.c:733
static SCIP_DECL_NLPIGETSTATISTICS(nlpiGetStatisticsWorhp)
Definition: nlpi_worhp.c:1846
SCIP_RETCODE SCIPnlpiOracleEvalHessianLag(SCIP_NLPIORACLE *oracle, const SCIP_Real *x, SCIP_Bool isnewx, SCIP_Real objfactor, const SCIP_Real *lambda, SCIP_Real *hessian)
Definition: nlpioracle.c:2889
static SCIP_DECL_NLPIGETWARMSTARTSIZE(nlpiGetWarmstartSizeWorhp)
Definition: nlpi_worhp.c:1868
#define DEFAULT_MAXITER
Definition: nlpi_worhp.c:50
SCIP_RANDNUMGEN * randnumgen
Definition: nlpi_worhp.c:71
#define SCIP_Real
Definition: def.h:149
SCIP_NLPTERMSTAT lasttermstat
Definition: nlpi_ipopt.cpp:147
static SCIP_DECL_NLPISETREALPAR(nlpiSetRealParWorhp)
Definition: nlpi_worhp.c:2210
SCIP_RETCODE SCIPrandomCreate(SCIP_RANDNUMGEN **randnumgen, BMS_BLKMEM *blkmem, unsigned int initialseed)
Definition: misc.c:9334
SCIP_Real * lastdualub
Definition: nlpi_worhp.c:81
#define SCIP_INVALID
Definition: def.h:169
OptVar * opt
Definition: nlpi_worhp.c:91
SCIP_Real * lastprimal
Definition: nlpi_worhp.c:78
static SCIP_RETCODE freeWorhp(SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:886
SCIP_RETCODE SCIPnlpiOracleSetInfinity(SCIP_NLPIORACLE *oracle, SCIP_Real infinity)
Definition: nlpioracle.c:1381
static SCIP_DECL_NLPISETWARMSTARTMEMO(nlpiSetWarmstartMemoWorhp)
Definition: nlpi_worhp.c:1905
static SCIP_RETCODE userG(SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:455
static SCIP_DECL_NLPICREATEPROBLEM(nlpiCreateProblemWorhp)
Definition: nlpi_worhp.c:982
SCIP_RETCODE SCIPnlpiOracleEvalJacobian(SCIP_NLPIORACLE *oracle, const SCIP_Real *x, SCIP_Bool isnewx, SCIP_Real *convals, SCIP_Real *jacobi)
Definition: nlpioracle.c:2651
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:433
SCIP_RETCODE SCIPcreateNlpSolverWorhp(BMS_BLKMEM *blkmem, SCIP_NLPI **nlpi, SCIP_Bool useip)
Definition: nlpi_worhp.c:2368
#define DEFAULT_VERBLEVEL
Definition: nlpi_worhp.c:48
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:419
#define SCIP_ALLOC(x)
Definition: def.h:361
static SCIP_DECL_NLPIGETSOLSTAT(nlpiGetSolstatWorhp)
Definition: nlpi_worhp.c:1763
SCIP_RETCODE SCIPnlpiSetRealPar(SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, SCIP_NLPPARAM type, SCIP_Real dval)
Definition: nlpi.c:671
#define DEFAULT_SCALEDKKT
Definition: nlpi_worhp.c:49