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