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-2022 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 scipopt.org. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file nlpi_worhp.c
17  * @ingroup DEFPLUGINS_NLPI
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 "scip/nlpi_worhp.h"
29 #include "scip/nlpioracle.h"
30 #include "scip/exprinterpret.h"
31 #include "scip/interrupt.h"
32 #include "scip/scip_nlpi.h"
33 #include "scip/scip_general.h"
34 #include "scip/scip_message.h"
35 #include "scip/scip_mem.h"
36 #include "scip/scip_numerics.h"
37 #include "scip/scip_randnumgen.h"
38 #include "scip/scip_solve.h"
39 #include "scip/pub_misc.h"
40 
41 #include <stdio.h>
42 #include <stdlib.h>
43 
44 #include "worhp/worhp.h"
45 
46 #if WORHP_MAJOR < 2 && WORHP_MINOR < 10
47 #error "Require at least Worhp 1.10"
48 #endif
49 
50 #define NLPI_DESC "Worhp interface" /**< description of solver */
51 #define NLPI_PRIORITY_IP 0 /**< priority of NLP solver (Interior Point) */
52 #define NLPI_PRIORITY_SQP -2000 /**< priority of NLP solver (SQP) */
53 
54 #define DEFAULT_VERBLEVEL 0 /**< default verbosity level (0: normal 1: full 2: debug >2: more debug) */
55 #define DEFAULT_SCALEDKKT TRUE /**< default whether KKT conditions are allowed to be scaled in the solver */
56 #define DEFAULT_RANDSEED 107 /**< initial random seed */
57 
58 #define MAXPERTURB 0.01 /**< maximal perturbation of bounds in starting point heuristic */
59 
60 /*
61  * Data structures
62  */
63 
64 struct SCIP_NlpiData
65 {
66  SCIP_Bool useip; /**< should the Interior Point solver of Worhp be used? */
67 };
68 
69 struct SCIP_NlpiProblem
70 {
71  SCIP_NLPIORACLE* oracle; /**< Oracle-helper to store and evaluate NLP */
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 
98 /*
99  * Local methods
100  */
101 
102 /** clears the last solution information */
103 static
105  SCIP* scip, /**< SCIP data structure */
106  SCIP_NLPIPROBLEM* problem /**< pointer to problem data structure */
107  )
108 {
109  assert(problem != NULL);
110 
111  SCIPfreeBlockMemoryArrayNull(scip, &(problem->lastprimal), problem->lastprimalsize);
112  SCIPfreeBlockMemoryArrayNull(scip, &(problem->lastdualcons), problem->lastdualconssize);
113  SCIPfreeBlockMemoryArrayNull(scip, &(problem->lastduallb), problem->lastduallbsize);
114  SCIPfreeBlockMemoryArrayNull(scip, &(problem->lastdualub), problem->lastdualubsize);
115 
116  problem->lastprimalsize = 0;
117  problem->lastdualconssize = 0;
118  problem->lastduallbsize = 0;
119  problem->lastdualubsize = 0;
122 }
123 
124 /** evaluate last Worhp run */
125 static
127  SCIP* scip, /**< SCIP data structure */
128  SCIP_NLPIPROBLEM* problem /**< pointer to problem data structure */
129  )
130 {
131  int i;
132 
133  assert(problem != NULL);
134  assert(problem->opt != NULL);
135  assert(problem->wsp != NULL);
136  assert(problem->par != NULL);
137  assert(problem->cnt != NULL);
138 
139  switch( problem->cnt->status )
140  {
141  case InitError:
142  {
143  /* initialization error */
144  SCIPdebugMsg(scip, "Worhp failed because of initialization error!\n");
145  invalidateSolution(scip, problem);
148  break;
149  }
150 
151  case DataError:
152  {
153  /* data error */
154  SCIPdebugMsg(scip, "Worhp failed because of data error!\n");
155  invalidateSolution(scip, problem);
158  break;
159  }
160 
161  case LicenseError:
162  {
163  /* license error */
164  SCIPerrorMessage("Worhp failed because of license error!\n");
165  invalidateSolution(scip, problem);
168  break;
169  }
170 
171  case evalsNaN:
172  {
173  /* evaluation errors */
174  SCIPdebugMsg(scip, "Worhp failed because of a NaN value in an evaluation!\n");
175  invalidateSolution(scip, problem);
178  break;
179  }
180 
181  case QPerror:
182  case MinimumStepsize:
183  case TooBig:
184  case LinearSolverFailed:
185  {
186  /* numerical errors during solution of NLP */
187  SCIPdebugMsg(scip, "Worhp failed because of a numerical error during optimization!\n");
188  invalidateSolution(scip, problem);
191  break;
192  }
193 
194  case MaxCalls:
195  case MaxIter:
196  {
197  /* maximal number of calls or iteration */
198  SCIPdebugMsg(scip, "Worhp failed because maximal number of calls or iterations is reached!\n");
199  invalidateSolution(scip, problem);
202  break;
203  }
204 
205  case Timeout:
206  {
207  /* time limit reached */
208  SCIPdebugMsg(scip, "Worhp failed because time limit is reached!\n");
209  invalidateSolution(scip, problem);
212  break;
213  }
214 
215  case DivergingPrimal:
216  case DivergingDual:
217  {
218  /* iterates diverge */
219  SCIPdebugMsg(scip, "Worhp failed because of diverging iterates!\n");
220  invalidateSolution(scip, problem);
223  break;
224  }
225 
226  case LocalInfeas:
227  case LocalInfeasOptimal:
228  {
229  /* infeasible stationary point found */
230  SCIPdebugMsg(scip, "Worhp failed because of convergence against infeasible stationary point!\n");
231  invalidateSolution(scip, problem);
234  break;
235  }
236 
237  case GlobalInfeas:
238  {
239  /* infeasible stationary point found */
240  SCIPdebugMsg(scip, "Worhp failed because of convergence against infeasible stationary point!\n");
241  invalidateSolution(scip, problem);
244  break;
245  }
246 
247  case RegularizationFailed:
248  {
249  /* regularization of Hessian matrix failed */
250  SCIPdebugMsg(scip, "Worhp failed because of regularization of Hessian matrix failed!\n");
251  invalidateSolution(scip, problem);
254  break;
255  }
256 
257  case OptimalSolution:
258  {
259  /* everything went fine */
260  SCIPdebugMsg(scip, "Worhp terminated successfully at a local optimum!\n");
263  break;
264  }
265 
266  case OptimalSolutionConstantF:
267  {
268  /* feasible point, KKT conditions are not satisfied, and Worhp thinks that there is no objective function */
269  SCIPdebugMsg(scip, "Worhp terminated successfully with a feasible point but KKT are not met!\n");
272  break;
273  }
274 
275  case AcceptableSolutionSKKT:
276  case AcceptableSolutionScaled:
277  case AcceptablePreviousScaled:
278  {
279  /* feasible point but KKT conditions are violated in unscaled space */
280  SCIPdebugMsg(scip, "Worhp terminated successfully with a feasible point but KKT are violated in unscaled space!\n");
283  break;
284  }
285 
286  case LowPassFilterOptimal:
287  {
288  /* feasible and no further progress */
289  SCIPdebugMsg(scip, "Worhp terminated at feasible solution without further progress!\n");
292  break;
293  }
294 
295  case FeasibleSolution:
296  {
297  /* feasible and in feasibility mode, i.e., optimality not required */
298  SCIPdebugMsg(scip, "Worhp terminated at feasible solution, optimality was not required!\n");
301  break;
302  }
303 
304  case AcceptableSolution:
305  case AcceptableSolutionConstantF:
306  {
307  /* acceptable solution found, but stopped due to limit or error */
308  SCIPdebugMsg(scip, "Worhp terminated at acceptable solution due to limit or error!\n");
311  break;
312  }
313 
314  case AcceptablePrevious:
315  case AcceptablePreviousConstantF:
316  {
317  /* previously acceptable solution was found, but stopped due to limit or error */
318  SCIPdebugMsg(scip, "Worhp previously found acceptable solution but terminated due to limit or error!\n");
321  break;
322  }
323 
324  case LowPassFilterAcceptable:
325  {
326  /* acceptable solution found, and no further progress */
327  SCIPdebugMsg(scip, "Worhp found acceptable solution but terminated due no further progress!\n");
330  break;
331  }
332 
333  case SearchDirectionZero:
334  case SearchDirectionSmall:
335  {
336  /* acceptable solution found, but search direction is small or zero */
337  SCIPdebugMsg(scip, "Worhp found acceptable solution but search direction is small or zero!\n");
340  break;
341  }
342 
343  case FritzJohn:
344  case NotDiffable:
345  case Unbounded:
346  {
347  /* acceptable solution found, but not optimal */
348  SCIPdebugMsg(scip, "Worhp found acceptable solution but terminated perhaps due to nondifferentiability, unboundedness or at Fritz John point!\n");
351  break;
352  }
353 
354  default:
355  {
356  SCIPerrorMessage("Worhp returned with unknown solution status %d\n", problem->cnt->status);
359  return SCIP_OKAY;
360  }
361  }
362 
363  /* store solution */
364  if( problem->lastprimal == NULL )
365  {
366  if( problem->opt->m > 0 )
367  {
368  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &problem->lastdualcons, problem->opt->Mu, problem->opt->m) );
369  problem->lastdualconssize = problem->opt->m;
370  }
371 
372  if( problem->opt->n > 0 )
373  {
374  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &problem->lastprimal, problem->opt->X, problem->opt->n) );
375  problem->lastprimalsize = problem->opt->n;
376 
377  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &problem->lastduallb, problem->opt->n) );
378  problem->lastduallbsize = problem->opt->n;
379 
380  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &problem->lastdualub, problem->opt->n) );
381  problem->lastdualubsize = problem->opt->n;
382  }
383  }
384  else
385  {
386  BMScopyMemoryArray(problem->lastprimal, problem->opt->X, problem->opt->n);
387  BMScopyMemoryArray(problem->lastdualcons, problem->opt->Mu, problem->opt->m);
388  }
389 
390  for( i = 0; i < problem->opt->n; ++i )
391  {
392  if( problem->opt->Lambda[i] <= 0.0 )
393  {
394  problem->lastduallb[i] = -problem->opt->Lambda[i];
395  problem->lastdualub[i] = 0.0;
396  }
397  else
398  {
399  problem->lastduallb[i] = 0.0;
400  problem->lastdualub[i] = problem->opt->Lambda[i];
401  }
402  }
403 
404  assert(problem->lastprimal != NULL || problem->opt->n == 0);
405  assert(problem->lastdualcons != NULL || problem->opt->m == 0);
406  assert(problem->lastduallb != NULL || problem->opt->n == 0);
407  assert(problem->lastdualub != NULL || problem->opt->n == 0);
408 
409  return SCIP_OKAY;
410 }
411 
412 /** evaluates objective function and store the result in the corresponding Worhp data fields */
413 static
415  SCIP* scip, /**< SCIP data structure */
416  SCIP_NLPIPROBLEM* problem /**< pointer to problem data structure */
417  )
418 {
419  SCIP_Real objval;
420 
421  assert(problem != NULL);
422  assert(problem->oracle != NULL);
423  assert(problem->opt != NULL);
424  assert(problem->wsp != NULL);
425  assert(problem->opt->n == SCIPnlpiOracleGetNVars(problem->oracle));
426  assert(problem->opt->m == SCIPnlpiOracleGetNConstraints(problem->oracle));
427 
428  SCIP_CALL( SCIPnlpiOracleEvalObjectiveValue(scip, problem->oracle, problem->opt->X, &objval) );
429  problem->opt->F = problem->wsp->ScaleObj * objval;
430 
431 #ifdef SCIP_DEBUG_USERF
432  {
433  int i;
434 
435  printf("userF()\n");
436  for( i = 0; i < problem->opt->n; ++i )
437  printf(" x[%d] = %g\n", i, problem->opt->X[i]);
438  printf(" obj = %g\n", problem->opt->F);
439  }
440 #endif
441 
442  return SCIP_OKAY;
443 }
444 
445 /** evaluates constraints and store the result in the corresponding Worhp data fields */
446 static
448  SCIP* scip, /**< SCIP data structure */
449  SCIP_NLPIPROBLEM* problem /**< pointer to problem data structure */
450  )
451 {
452  assert(problem != NULL);
453  assert(problem->oracle != NULL);
454  assert(problem->opt != NULL);
455  assert(problem->wsp != NULL);
456  assert(problem->opt->n == SCIPnlpiOracleGetNVars(problem->oracle));
457  assert(problem->opt->m == SCIPnlpiOracleGetNConstraints(problem->oracle));
458 
459  SCIP_CALL( SCIPnlpiOracleEvalConstraintValues(scip, problem->oracle, problem->opt->X, problem->opt->G) );
460 
461 #ifdef SCIP_DEBUG_USERG
462  {
463  int i;
464 
465  printf("userG()\n");
466  for( i = 0; i < problem->opt->n; ++i )
467  printf(" x[%d] = %g\n", i, problem->opt->X[i]);
468 
469  for( i = 0; i < problem->opt->m; ++i )
470  printf(" cons[%d] = %g\n", i, problem->opt->G[i]);
471  }
472 #endif
473 
474  return SCIP_OKAY;
475 }
476 
477 /** computes objective gradient and store the result in the corresponding Worhp data fields */
478 static
480  SCIP* scip, /**< SCIP data structure */
481  SCIP_NLPIPROBLEM* problem /**< pointer to problem data structure */
482  )
483 {
484  SCIP_Real objval;
485 
486  assert(problem != NULL);
487  assert(problem->oracle != NULL);
488  assert(problem->opt != NULL);
489  assert(problem->wsp != NULL);
490  assert(problem->opt->n == SCIPnlpiOracleGetNVars(problem->oracle));
491  assert(problem->opt->m == SCIPnlpiOracleGetNConstraints(problem->oracle));
492 
493  /* TODO this needs to be changed if we store the gradient of the objective function in a sparse format */
494  SCIP_CALL( SCIPnlpiOracleEvalObjectiveGradient(scip, problem->oracle, problem->opt->X, TRUE, &objval,
495  problem->wsp->DF.val) );
496 
497  /* scale gradient if necessary */
498  if( problem->wsp->ScaleObj != 1.0 )
499  {
500  int i;
501  for( i = 0; i < problem->opt->n; ++i )
502  problem->wsp->DF.val[i] *= problem->wsp->ScaleObj;
503  }
504 
505 #ifdef SCIP_DEBUG_USERDF
506  {
507  int i;
508 
509  printf("userDF()\n");
510  for( i = 0; i < problem->opt->n; ++i )
511  printf(" x[%d] = %g\n", i, problem->opt->X[i]);
512 
513  for( i = 0; i < problem->opt->n; ++i )
514  printf(" DF[%d] = %g\n", i, problem->wsp->DF.val[i]);
515  }
516 #endif
517 
518  return SCIP_OKAY;
519 }
520 
521 /** computes jacobian matrix and store the result in the corresponding Worhp data fields */
522 static
524  SCIP* scip, /**< SCIP data structure */
525  SCIP_NLPIPROBLEM* problem /**< pointer to problem data structure */
526  )
527 {
528  SCIP_RETCODE retcode;
529  SCIP_Real* jacvals;
530 
531  assert(problem != NULL);
532  assert(problem->oracle != NULL);
533  assert(problem->opt != NULL);
534  assert(problem->wsp != NULL);
535  assert(problem->opt->n == SCIPnlpiOracleGetNVars(problem->oracle));
536  assert(problem->opt->m == SCIPnlpiOracleGetNConstraints(problem->oracle));
537 
538  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &jacvals, problem->wsp->DG.nnz) );
539  retcode = SCIPnlpiOracleEvalJacobian(scip, problem->oracle, problem->opt->X, TRUE, NULL, jacvals);
540 
541  if( retcode == SCIP_OKAY )
542  {
543  int i;
544 
545  /* map values with DG indices */
546  for( i = 0; i < problem->wsp->DG.nnz; ++i )
547  {
548  problem->wsp->DG.val[i] = jacvals[ problem->wsp->DG.perm[i]-1 ];
549  }
550 
551 #ifdef SCIP_DEBUG_USERDG
552  printf("userDG()\n");
553  for( i = 0; i < problem->opt->n; ++i )
554  printf(" x[%d] = %g\n", i, problem->opt->X[i]);
555  for( i = 0; i < problem->wsp->DG.nnz; ++i )
556  printf(" DG[%d] = %g\n", i, problem->wsp->DG.val[i]);
557 #endif
558  }
559 
560  /* free memory */
561  SCIPfreeBlockMemoryArray(scip, &jacvals, problem->wsp->DG.nnz);
562 
563  return retcode;
564 }
565 
566 /** computes hessian matrix and store the result in the corresponding Worhp data fields */
567 static
569  SCIP* scip, /**< SCIP data structure */
570  SCIP_NLPIPROBLEM* problem /**< pointer to problem data structure */
571  )
572 {
573  const int* offset;
574  SCIP_Real* hessianvals;
575  SCIP_RETCODE retcode;
576  int nnonz;
577 
578  assert(problem != NULL);
579  assert(problem->oracle != NULL);
580  assert(problem->opt != NULL);
581  assert(problem->wsp != NULL);
582  assert(problem->opt->n == SCIPnlpiOracleGetNVars(problem->oracle));
583  assert(problem->opt->m == SCIPnlpiOracleGetNConstraints(problem->oracle));
584 
585  /* get nonzero entries in HM of SCIP (excludes unused diagonal entries) */
586  SCIP_CALL( SCIPnlpiOracleGetHessianLagSparsity(scip, problem->oracle, &offset, NULL) );
587  nnonz = offset[problem->opt->n];
588 
589  /* evaluate hessian */
590  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &hessianvals, problem->wsp->HM.nnz) );
591  retcode = SCIPnlpiOracleEvalHessianLag(scip, problem->oracle, problem->opt->X, TRUE, TRUE, problem->wsp->ScaleObj,
592  problem->opt->Mu, hessianvals);
593 
594  if( retcode == SCIP_OKAY )
595  {
596  int i;
597 
598  assert(problem->wsp->HM.nnz >= nnonz);
599  for( i = 0; i < problem->wsp->HM.nnz; ++i )
600  {
601  /* an entry i with HM.perm[i] - 1 >= nnonz corresponds to an in SCIP non-existing diagonal element */
602  if( problem->wsp->HM.perm[i] - 1 >= nnonz )
603  problem->wsp->HM.val[i] = 0.0;
604  else
605  problem->wsp->HM.val[i] = hessianvals[ problem->wsp->HM.perm[i] - 1 ];
606  }
607 
608 #ifdef SCIP_DEBUG_HM
609  printf("userHM()\n");
610  for( i = 0; i < problem->opt->n; ++i )
611  printf(" x[%d] = %g\n", i, problem->opt->X[i]);
612  for( i = 0; i < problem->wsp->HM.nnz; ++i )
613  printf(" HM[%d] = %g\n", i, problem->wsp->HM.val[i]);
614 #endif
615  }
616 
617  /* free memory */
618  SCIPfreeBlockMemoryArray(scip, &hessianvals, problem->wsp->HM.nnz);
619 
620  return retcode;
621 }
622 
623 /** Worhp print callback function that does nothing */ /*lint -e{715}*/
624 static void noprint(
625  int mode, /**< the mode */
626  const char s[] /**< a string */
627  )
628 { /*lint --e{715}*/
629 }
630 
631 /** initialize Worhp data */
632 static
634  SCIP* scip, /**< SCIP data structure */
635  SCIP_NLPI* nlpi, /**< pointer to NLPI datastructure */
636  SCIP_NLPIPROBLEM* problem /**< pointer to problem data structure */
637  )
638 {
639  Workspace* wsp;
640  Control* cnt;
641  OptVar* opt;
642  Params* par;
643  const SCIP_Real* lbs;
644  const SCIP_Real* ubs;
645  const int* offset;
646  const int* cols;
647  int i;
648  int j;
649 
650  assert(nlpi != NULL);
651  assert(problem != NULL);
652  assert(problem->cnt != NULL);
653  assert(problem->wsp != NULL);
654  assert(problem->par != NULL);
655  assert(problem->opt != NULL);
656  assert(problem->firstrun);
657 
658  wsp = problem->wsp;
659  cnt = problem->cnt;
660  opt = problem->opt;
661  par = problem->par;
662 
663  /* properly zeros everything */
664  WorhpPreInit(opt, wsp, par, cnt);
665 
666  /* set problem dimensions */
667  opt->n = SCIPnlpiOracleGetNVars(problem->oracle);
668  opt->m = SCIPnlpiOracleGetNConstraints(problem->oracle);
669  SCIPdebugMsg(scip, "nvars %d nconss %d\n", opt->n, opt->m);
670 
671  /* assume that objective function is dense; TODO use sparse representation */
672  wsp->DF.nnz = opt->n;
673 
674  /* get number of non-zero entries in Jacobian */
675  SCIP_CALL( SCIPnlpiOracleGetJacobianSparsity(scip, problem->oracle, &offset, NULL) );
676  wsp->DG.nnz = offset[opt->m];
677  SCIPdebugMsg(scip, "nnonz jacobian %d\n", wsp->DG.nnz);
678 
679  /* get number of non-zero entries in hessian
680  *
681  * note that Worhp wants to have the full diagonal in ANY case
682  */
683  SCIP_CALL( SCIPnlpiOracleGetHessianLagSparsity(scip, problem->oracle, &offset, &cols) );
684  wsp->HM.nnz = 0;
685 
686  j = offset[0];
687  for( i = 0; i < opt->n; ++i )
688  {
689  /* diagonal element */
690  ++(wsp->HM.nnz);
691 
692  /* strict lower triangle elements */
693  for( ; j < offset[i+1]; ++j )
694  {
695  if( i != cols[j] )
696  {
697  assert(i > cols[j]);
698  ++(wsp->HM.nnz);
699  }
700  }
701  }
702  assert(offset[opt->n] <= wsp->HM.nnz);
703  SCIPdebugMsg(scip, "nnonz hessian %d\n", wsp->HM.nnz);
704 
705  /* initialize data in Worhp */
706  WorhpInit(opt, wsp, par, cnt);
707  if (cnt->status != FirstCall)
708  {
709  SCIPerrorMessage("Initialisation failed.\n");
710  return SCIP_ERROR;
711  }
712 
713  /* set variable bounds */
714  lbs = SCIPnlpiOracleGetVarLbs(problem->oracle);
715  ubs = SCIPnlpiOracleGetVarUbs(problem->oracle);
716 
717  BMScopyMemoryArray(opt->XL, lbs, opt->n);
718  BMScopyMemoryArray(opt->XU, ubs, opt->n);
719 
720 #ifdef SCIP_DEBUG
721  for( i = 0; i < opt->n; ++i )
722  {
723  SCIPdebugMsg(scip, "bounds %d [%g,%g]\n", i, opt->XL[i], opt->XU[i]);
724  }
725 #endif
726 
727  /* set constraint sides */
728  for( i = 0; i < opt->m; ++i )
729  {
730  opt->GL[i] = SCIPnlpiOracleGetConstraintLhs(problem->oracle, i);
731  opt->GU[i] = SCIPnlpiOracleGetConstraintRhs(problem->oracle, i);
732 
733  /* adjust constraint sides when both are infinite */
734  if( SCIPisInfinity(scip, -opt->GL[i]) && SCIPisInfinity(scip, opt->GU[i]) )
735  {
736  SCIPwarningMessage(scip, "Lhs and rhs of constraint %d are infinite.\n", i);
737  opt->GL[i] = -SCIPinfinity(scip) / 10.0;
738  opt->GU[i] = SCIPinfinity(scip) / 10.0;
739  }
740 
741  SCIPdebugMsg(scip, "sides %d [%g,%g]\n", i, opt->GL[i], opt->GU[i]);
742  }
743 
744  /* set column indices of objective function; note that indices go from 1 to n */
745  /* if( wsp->DF.NeedStructure ) evaluates to FALSE if DF is dense */
746  {
747  SCIPdebugPrintf("column indices of objective function:");
748  for( i = 0; i < opt->n; ++i )
749  {
750  wsp->DF.row[i] = i + 1;
751  SCIPdebugPrintf(" %d", wsp->DF.row[i]);
752  }
753  SCIPdebugPrintf("\n");
754  }
755 
756  /* set column and row indices of non-zero entries in Jacobian matrix */
757  /* if( wsp->DG.NeedStructure ) evaluates to FALSE if DG is dense */
758  {
759  int nnonz;
760 
761  SCIP_CALL( SCIPnlpiOracleGetJacobianSparsity(scip, problem->oracle, &offset, &cols) );
762  assert(offset[opt->m] == wsp->DG.nnz);
763 
764  nnonz = 0;
765  j = offset[0];
766  for( i = 0; i < opt->m; ++i )
767  {
768  for( ; j < offset[i+1]; ++j )
769  {
770  wsp->DG.row[nnonz] = i + 1;
771  wsp->DG.col[nnonz] = cols[j] + 1;
772  ++nnonz;
773  }
774  }
775  assert(nnonz == wsp->DG.nnz);
776 
777  /* sort arrays w.r.t the column-major order */
778  SortWorhpMatrix(&wsp->DG);
779  }
780 
781  /* set column and row indices of non-zero entries in hessian matrix */
782  if( problem->par->UserHM || problem->par->FidifHM || problem->par->BFGSmethod > 1 )
783  {
784  int nnonz;
785  int k;
786 
787  SCIP_CALL( SCIPnlpiOracleGetHessianLagSparsity(scip, problem->oracle, &offset, &cols) );
788  assert(offset[opt->n] <= wsp->HM.nnz);
789 
790  k = offset[opt->n];
791  nnonz = 0;
792  j = offset[0];
793  for( i = 0; i < opt->n; ++i )
794  {
795  SCIP_Bool adddiag = TRUE;
796 
797  for( ; j < offset[i+1]; ++j )
798  {
799  problem->wsp->HM.row[nnonz] = i + 1;
800  problem->wsp->HM.col[nnonz] = cols[j] + 1;
801  ++nnonz;
802 
803  if( i == cols[j] )
804  adddiag = FALSE;
805  }
806 
807  /* Worhp wants to have each diagonal element */
808  if( adddiag )
809  {
810  problem->wsp->HM.row[k] = i + 1;
811  problem->wsp->HM.col[k] = i + 1;
812  ++k;
813  }
814  }
815  assert(nnonz == offset[opt->n]);
816  assert(k == wsp->HM.nnz);
817 
818  /* sort arrays w.r.t the LT column-major order */
819  SortWorhpMatrix(&wsp->HM);
820 
821 #ifdef SCIP_DEBUG
822  SCIPdebugMsg(scip, "column and row indices of hessian:\n");
823  for( i = 0; i < wsp->HM.nnz; ++i )
824  {
825  SCIPdebugMsg(scip, " entry %d: (row,col) = (%d,%d)\n", i, wsp->HM.row[i], wsp->HM.col[i]);
826  }
827 #endif
828  }
829 
830  return SCIP_OKAY;
831 }
832 
833 /** update Worhp data */
834 static
836  SCIP_NLPIPROBLEM* problem /**< pointer to problem data structure */
837  )
838 {
839  const SCIP_Real* lbs;
840  const SCIP_Real* ubs;
841  int i;
842 
843  assert(problem != NULL);
844  assert(problem->cnt != NULL);
845  assert(problem->wsp != NULL);
846  assert(problem->par != NULL);
847  assert(problem->opt != NULL);
848  assert(problem->oracle != NULL);
849  assert(problem->opt->n == SCIPnlpiOracleGetNVars(problem->oracle));
850  assert(problem->opt->m == SCIPnlpiOracleGetNConstraints(problem->oracle));
851 
852  WorhpRestart(problem->opt, problem->wsp, problem->par, problem->cnt);
853 
854  /* update variable bounds */
855  lbs = SCIPnlpiOracleGetVarLbs(problem->oracle);
856  ubs = SCIPnlpiOracleGetVarUbs(problem->oracle);
857  for( i = 0; i < problem->opt->n; ++i )
858  {
859  problem->opt->XL[i] = lbs[i];
860  problem->opt->XU[i] = ubs[i];
861  }
862 
863  /* update constraint sides */
864  for( i = 0; i < problem->opt->m; ++i )
865  {
866  problem->opt->GL[i] = SCIPnlpiOracleGetConstraintLhs(problem->oracle, i);
867  problem->opt->GU[i] = SCIPnlpiOracleGetConstraintRhs(problem->oracle, i);
868  }
869 
870  return SCIP_OKAY;
871 }
872 
873 /** frees Worhp data */
874 static
876  SCIP_NLPIPROBLEM* problem /**< pointer to problem data structure */
877  )
878 {
879  assert(problem != NULL);
880  assert(problem->cnt != NULL);
881  assert(problem->wsp != NULL);
882  assert(problem->par != NULL);
883  assert(problem->opt != NULL);
884 
885  if( problem->opt->initialised )
886  WorhpFree(problem->opt, problem->wsp, problem->par, problem->cnt);
887 
888  return SCIP_OKAY;
889 }
890 
891 /** pass NLP solve parameters to Ipopt */
892 static
894  SCIP* scip, /**< SCIP data structure */
895  SCIP_NLPI* nlpi, /**< Worhp interface */
896  Params* par, /**< Worhp parameters */
897  const SCIP_NLPPARAM nlpparam /**< NLP solve parameters */
898  )
899 {
900  SCIP_NLPIDATA* nlpidata;
901 
902  assert(par != NULL);
903  assert(nlpi != NULL);
904 
905  nlpidata = SCIPnlpiGetData(nlpi);
906  assert(nlpidata != NULL);
907 
908  par->Algorithm = nlpidata->useip ? 2 : 1;
909  par->ScaledKKT = DEFAULT_SCALEDKKT;
910  par->sKKTOnlyAcceptable = DEFAULT_SCALEDKKT;
911  par->Infty = SCIPinfinity(scip);
912 
913  if( nlpparam.warmstart )
914  {
915  SCIPdebugMsg(scip, "warmstart parameter not supported by Worhp interface yet. Ignored.\n");
916  }
917 
918  if( nlpparam.lobjlimit > -SCIP_REAL_MAX )
919  {
920  SCIPwarningMessage(scip, "lobjlimit parameter not supported by Worhp interface yet. Ignored.\n");
921  }
922 
923  if( nlpparam.fastfail )
924  {
925  SCIPdebugMsg(scip, "fastfail parameter not supported by Worhp interface yet. Ignored.\n");
926  }
927 
928  par->TolFeas = nlpparam.feastol;
929  par->TolOpti = nlpparam.opttol;
930  par->TolComp = nlpparam.opttol;
931  par->Timeout = nlpparam.timelimit;
932  par->MaxIter = nlpparam.iterlimit;
933  par->NLPprint = nlpparam.verblevel - 1; /* Worhp verbosity levels: -1 = off, 0 = normal, 1 = debug, >1 = more debug */
934 
935 #ifdef CHECKFUNVALUES
936  /* activate gradient and hessian check */
937  par->CheckValuesDF = TRUE;
938  par->CheckValuesDG = TRUE;
939  par->CheckValuesHM = TRUE;
940 #endif
941 
942  return SCIP_OKAY;
943 }
944 
945 /*
946  * Callback methods of NLP solver interface
947  */
948 
949 /** copy method of NLP interface (called when SCIP copies plugins) */
950 static
951 SCIP_DECL_NLPICOPY(nlpiCopyWorhp)
952 {
953  SCIP_NLPIDATA* sourcedata;
954 
955  assert(sourcenlpi != NULL);
956 
957  sourcedata = SCIPnlpiGetData(sourcenlpi);
958  assert(sourcedata != NULL);
959 
960  SCIP_CALL( SCIPincludeNlpSolverWorhp(scip, sourcedata->useip) );
961 
962  return SCIP_OKAY;
963 } /*lint !e715*/
964 
965 /** destructor of NLP interface to free nlpi data */
966 static
967 SCIP_DECL_NLPIFREE(nlpiFreeWorhp)
968 {
969  assert(nlpi != NULL);
970  assert(nlpidata != NULL);
971  assert(*nlpidata != NULL);
972 
973  SCIPfreeBlockMemory(scip, nlpidata);
974  assert(*nlpidata == NULL);
975 
976  return SCIP_OKAY;
977 } /*lint !e715*/
978 
979 /** creates a problem instance */
980 static
981 SCIP_DECL_NLPICREATEPROBLEM(nlpiCreateProblemWorhp)
982 {
983  assert(nlpi != NULL);
984  assert(problem != NULL);
985 
987  assert( *problem != NULL );
988 
989  /* initialize problem */
990  (*problem)->firstrun = TRUE;
991  SCIP_CALL( SCIPnlpiOracleCreate(scip, &(*problem)->oracle) );
992  SCIP_CALL( SCIPnlpiOracleSetProblemName(scip, (*problem)->oracle, name) );
993 
994  /* allocate memory for Worhp data */
995  SCIP_CALL( SCIPallocBlockMemory(scip, &(*problem)->opt) );
996  SCIP_CALL( SCIPallocBlockMemory(scip, &(*problem)->wsp) );
997  SCIP_CALL( SCIPallocBlockMemory(scip, &(*problem)->par) );
998  SCIP_CALL( SCIPallocBlockMemory(scip, &(*problem)->cnt) );
999  WorhpPreInit((*problem)->opt, (*problem)->wsp, (*problem)->par, (*problem)->cnt);
1000 
1001  /* create random number generator */
1002  SCIP_CALL( SCIPcreateRandom(scip, &(*problem)->randnumgen, DEFAULT_RANDSEED, TRUE) );
1003 
1004  return SCIP_OKAY;
1005 } /*lint !e715*/
1006 
1007 /** free a problem instance */
1008 static
1009 SCIP_DECL_NLPIFREEPROBLEM(nlpiFreeProblemWorhp)
1010 {
1011  assert(nlpi != NULL);
1012  assert(problem != NULL);
1013  assert(*problem != NULL);
1014 
1015  if( (*problem)->opt != NULL )
1016  {
1017  /* free memory for last solution information */
1018  invalidateSolution(scip, *problem);
1019 
1020  assert((*problem)->wsp != NULL);
1021  assert((*problem)->par != NULL);
1022  assert((*problem)->cnt != NULL);
1023 
1024  /* free Worhp data */
1025  SCIP_CALL( freeWorhp(*problem) );
1026  SCIPfreeBlockMemory(scip, &(*problem)->cnt);
1027  SCIPfreeBlockMemory(scip, &(*problem)->par);
1028  SCIPfreeBlockMemory(scip, &(*problem)->wsp);
1029  SCIPfreeBlockMemory(scip, &(*problem)->opt);
1030  }
1031 
1032  if( (*problem)->oracle != NULL )
1033  {
1034  SCIP_CALL( SCIPnlpiOracleFree(scip, &(*problem)->oracle) );
1035  }
1036 
1037  SCIPfreeRandom(scip, &(*problem)->randnumgen);
1038  SCIPfreeMemoryArrayNull(scip, &(*problem)->initguess);
1039  SCIPfreeBlockMemory(scip, problem);
1040  *problem = NULL;
1041 
1042  return SCIP_OKAY;
1043 } /*lint !e715*/
1044 
1045 /** add variables */
1046 static
1047 SCIP_DECL_NLPIADDVARS( nlpiAddVarsWorhp )
1048 {
1049  assert(nlpi != NULL);
1050  assert(problem != NULL);
1051  assert(problem->oracle != NULL);
1052 
1053  SCIP_CALL( SCIPnlpiOracleAddVars(scip, problem->oracle, nvars, lbs, ubs, varnames) );
1054 
1055  SCIPfreeMemoryArrayNull(scip, &problem->initguess);
1056  invalidateSolution(scip, problem);
1057  problem->firstrun = TRUE;
1058 
1059  return SCIP_OKAY; /*lint !e527*/
1060 } /*lint !e715*/
1061 
1062 
1063 /** add constraints */
1064 static
1065 SCIP_DECL_NLPIADDCONSTRAINTS(nlpiAddConstraintsWorhp)
1066 {
1067  assert(nlpi != NULL);
1068  assert(problem != NULL);
1069  assert(problem->oracle != NULL);
1070 
1071  SCIP_CALL( SCIPnlpiOracleAddConstraints(scip, problem->oracle,
1072  nconss, lhss, rhss,
1073  nlininds, lininds, linvals,
1074  exprs, names) );
1075 
1076  invalidateSolution(scip, problem);
1077  problem->firstrun = TRUE;
1078 
1079  return SCIP_OKAY; /*lint !e527*/
1080 } /*lint !e715*/
1081 
1082 /** sets or overwrites objective, a minimization problem is expected */
1083 static
1084 SCIP_DECL_NLPISETOBJECTIVE(nlpiSetObjectiveWorhp)
1085 {
1086  assert(nlpi != NULL);
1087  assert(problem != NULL);
1088  assert(problem->oracle != NULL);
1089 
1090  /* We pass the objective gradient in dense form to WORHP, so if the sparsity of that gradient changes, we do not need
1091  * to reset WORHP (firstrun=TRUE). However, if the sparsity of the Hessian matrix of the objective changes, then the
1092  * sparsity pattern of the Hessian of the Lagrangian may change. Thus, reset Worhp if the objective was and/or
1093  * becomes nonlinear, but leave firstrun untouched if it was and stays linear.
1094  */
1095  if( expr != NULL || SCIPnlpiOracleIsConstraintNonlinear(problem->oracle, -1) )
1096  problem->firstrun = TRUE;
1097 
1098  SCIP_CALL( SCIPnlpiOracleSetObjective(scip, problem->oracle,
1099  constant, nlins, lininds, linvals, expr) );
1100 
1101  invalidateSolution(scip, problem);
1102 
1103  return SCIP_OKAY; /*lint !e527*/
1104 } /*lint !e715*/
1105 
1106 /** change variable bounds */
1107 static
1108 SCIP_DECL_NLPICHGVARBOUNDS(nlpiChgVarBoundsWorhp)
1109 {
1110 #ifdef SCIP_DISABLED_CODE
1111  const SCIP_Real* oldlbs = SCIPnlpiOracleGetVarLbs(problem->oracle);
1112  const SCIP_Real* oldubs = SCIPnlpiOracleGetVarUbs(problem->oracle);
1113  int i;
1114 #endif
1115 
1116  assert(nlpi != NULL);
1117  assert(problem != NULL);
1118  assert(problem->oracle != NULL);
1119 
1120 #ifdef SCIP_DISABLED_CODE
1121  /* TODO check WORHP version here */
1122  /* So far, Worhp can not handle fixed variables (and fixed variables that have been unfixed) when applying a
1123  * restart. The following code needs to be removed when this has changed.
1124  */
1125  for( i = 0; i < nvars; ++i )
1126  {
1127  int index = indices[i];
1128  SCIPdebugMsg(scip, "change bounds of %d from [%g,%g] -> [%g,%g]\n", index, oldlbs[index], oldubs[index],
1129  lbs[i], ubs[i]);
1130 
1131  if( REALABS(lbs[i] - ubs[i]) <= problem->feastol )
1132  problem->firstrun = TRUE;
1133  else
1134  if( REALABS(oldlbs[index] - oldubs[index]) <= problem->feastol )
1135  problem->firstrun = TRUE;
1136  }
1137 #endif
1138 
1139  SCIP_CALL( SCIPnlpiOracleChgVarBounds(scip, problem->oracle, nvars, indices, lbs, ubs) );
1140 
1141  invalidateSolution(scip, problem);
1142 
1143  return SCIP_OKAY; /*lint !e527*/
1144 } /*lint !e715*/
1145 
1146 /** change constraint bounds */
1147 static
1148 SCIP_DECL_NLPICHGCONSSIDES(nlpiChgConsSidesWorhp)
1149 {
1150  assert(nlpi != NULL);
1151  assert(problem != NULL);
1152  assert(problem->oracle != NULL);
1153 
1154 #ifdef SCIP_DEBUG
1155  {
1156  SCIP_Real oldlhs;
1157  SCIP_Real oldrhs;
1158  int i;
1159 
1160  for( i = 0; i < nconss; ++i )
1161  {
1162  int index = indices[i];
1163  oldlhs = SCIPnlpiOracleGetConstraintLhs(problem->oracle, index);
1164  oldrhs = SCIPnlpiOracleGetConstraintRhs(problem->oracle, index);
1165  SCIPdebugMsg(scip, "change constraint side of %d from [%g,%g] -> [%g,%g]\n", index, oldlhs, oldrhs, lhss[i], rhss[i]);
1166  }
1167  }
1168 #endif
1169 
1170  SCIP_CALL( SCIPnlpiOracleChgConsSides(scip, problem->oracle, nconss, indices, lhss, rhss) );
1171 
1172  invalidateSolution(scip, problem);
1173 
1174  return SCIP_OKAY; /*lint !e527*/
1175 } /*lint !e715*/
1176 
1177 /** delete a set of variables */
1178 static
1179 SCIP_DECL_NLPIDELVARSET(nlpiDelVarSetWorhp)
1180 {
1181  assert(nlpi != NULL);
1182  assert(problem != NULL);
1183  assert(problem->oracle != NULL);
1184 
1185  SCIP_CALL( SCIPnlpiOracleDelVarSet(scip, problem->oracle, dstats) );
1186 
1187  SCIPfreeMemoryArrayNull(scip, &problem->initguess); /* @TODO keep initguess for remaining variables */
1188 
1189  invalidateSolution(scip, problem);
1190  problem->firstrun = TRUE;
1191 
1192  return SCIP_OKAY; /*lint !e527*/
1193 } /*lint !e715*/
1194 
1195 /** delete a set of constraints */
1196 static
1197 SCIP_DECL_NLPIDELCONSSET(nlpiDelConstraintSetWorhp)
1198 {
1199  assert(nlpi != NULL);
1200  assert(problem != NULL);
1201  assert(problem->oracle != NULL);
1202 
1203  SCIP_CALL( SCIPnlpiOracleDelConsSet(scip, problem->oracle, dstats) );
1204 
1205  invalidateSolution(scip, problem);
1206  problem->firstrun = TRUE;
1207 
1208  return SCIP_OKAY; /*lint !e527*/
1209 } /*lint !e715*/
1210 
1211 /** changes (or adds) linear coefficients in a constraint or objective */
1212 static
1213 SCIP_DECL_NLPICHGLINEARCOEFS(nlpiChgLinearCoefsWorhp)
1214 {
1215  assert(nlpi != NULL);
1216  assert(problem != NULL);
1217  assert(problem->oracle != NULL);
1218 
1219  SCIP_CALL( SCIPnlpiOracleChgLinearCoefs(scip, problem->oracle, idx, nvals, varidxs, vals) );
1220 
1221  invalidateSolution(scip, problem);
1222  problem->firstrun = TRUE;
1223 
1224  return SCIP_OKAY; /*lint !e527*/
1225 } /*lint !e715*/
1226 
1227 /** replaces the expression of a constraint or objective */
1228 static
1229 SCIP_DECL_NLPICHGEXPR(nlpiChgExprWorhp)
1230 {
1231  assert(nlpi != NULL);
1232  assert(problem != NULL);
1233  assert(problem->oracle != NULL);
1234 
1235  SCIP_CALL( SCIPnlpiOracleChgExpr(scip, problem->oracle, idxcons, expr) );
1236 
1237  invalidateSolution(scip, problem);
1238  problem->firstrun = TRUE;
1239 
1240  return SCIP_OKAY; /*lint !e527*/
1241 } /*lint !e715*/
1242 
1243 /** change the constant offset in the objective */
1244 static
1245 SCIP_DECL_NLPICHGOBJCONSTANT(nlpiChgObjConstantWorhp)
1246 {
1247  assert(nlpi != NULL);
1248  assert(problem != NULL);
1249  assert(problem->oracle != NULL);
1250 
1251  SCIP_CALL( SCIPnlpiOracleChgObjConstant(scip, problem->oracle, objconstant) );
1252 
1253  return SCIP_OKAY; /*lint !e527*/
1254 } /*lint !e715*/
1255 
1256 /** sets initial guess for primal variables */
1257 static
1258 SCIP_DECL_NLPISETINITIALGUESS(nlpiSetInitialGuessWorhp)
1259 {
1260  assert(nlpi != NULL);
1261  assert(problem != NULL);
1262  assert(problem->oracle != NULL);
1263 
1264  if( primalvalues != NULL )
1265  {
1266  if( !problem->initguess )
1267  {
1268  SCIP_CALL( SCIPduplicateMemoryArray(scip, &problem->initguess, primalvalues, SCIPnlpiOracleGetNVars(problem->oracle)) );
1269  }
1270  else
1271  {
1272  BMScopyMemoryArray(problem->initguess, primalvalues, SCIPnlpiOracleGetNVars(problem->oracle));
1273  }
1274  }
1275  else
1276  {
1277  SCIPfreeMemoryArrayNull(scip, &problem->initguess);
1278  }
1279 
1280  return SCIP_OKAY;
1281 } /*lint !e715*/
1282 
1283 /** tries to solve NLP */
1284 static
1285 SCIP_DECL_NLPISOLVE(nlpiSolveWorhp)
1286 {
1287  Workspace* wsp = problem->wsp;
1288  Control* cnt = problem->cnt;
1289  OptVar* opt = problem->opt;
1290  Params* par = problem->par;
1291  int status;
1292  int i;
1293 
1294  SCIPdebugMsg(scip, "solve with parameters " SCIP_NLPPARAM_PRINT(param));
1295 
1296  SCIP_CALL( SCIPnlpiOracleResetEvalTime(scip, problem->oracle) );
1297 
1298  if( param.timelimit == 0.0 )
1299  {
1300  /* there is nothing we can do if we are not given any time */
1301  problem->lastniter = 0;
1302  problem->lasttime = 0.0;
1303  problem->lasttermstat = SCIP_NLPTERMSTAT_TIMELIMIT;
1304  problem->lastsolstat = SCIP_NLPSOLSTAT_UNKNOWN;
1305 
1306  return SCIP_OKAY;
1307  }
1308 
1309  problem->lastniter = -1;
1310  problem->lasttime = -1.0;
1311 
1312  if( param.verblevel == 0 )
1313  {
1314  SetWorhpPrint(noprint);
1315  }
1316  else
1317  {
1318  /* TODO this should go to a function that prints to the SCIP message handler
1319  * all this doesn't seem threadsafe at all!
1320  */
1321  SetWorhpPrint(WorhpDefaultPrintFunction);
1322  }
1323 
1324  /* initialize Worhp data if necessary */
1325  if( problem->firstrun )
1326  {
1327  SCIP_CALL( freeWorhp(problem) );
1328  SCIP_CALL( initWorhp(scip, nlpi, problem) );
1329  problem->firstrun = FALSE;
1330  }
1331  else
1332  {
1333  SCIP_CALL( updateWorhp(problem) );
1334  }
1335 
1336  /* set parameters */
1337  InitParams(&status, par);
1338 
1339  if( status != OK )
1340  return SCIP_INVALIDCALL;
1341 
1342  SCIP_CALL( handleNlpParam(scip, nlpi, par, param) );
1343 
1344 #ifdef SCIP_DEBUG
1345  SCIP_CALL( SCIPnlpiOraclePrintProblem(problem->oracle, nlpidata->messagehdlr, NULL) );
1346 #endif
1347 
1348  /* set initial guess (if available) */
1349  if( problem->initguess != NULL )
1350  {
1351  BMScopyMemoryArray(problem->opt->X, problem->initguess, problem->opt->n);
1352  }
1353  else
1354  {
1355  SCIP_Real lb, ub;
1356 
1357  assert(problem->randnumgen != NULL);
1358 
1359  SCIPdebugMsg(scip, "Worhp started without initial primal values; make up starting guess by projecting 0 onto variable bounds\n");
1360 
1361  for( i = 0; i < problem->opt->n; ++i )
1362  {
1363  lb = SCIPnlpiOracleGetVarLbs(problem->oracle)[i];
1364  ub = SCIPnlpiOracleGetVarUbs(problem->oracle)[i];
1365 
1366  if( lb > 0.0 )
1367  problem->opt->X[i] = SCIPrandomGetReal(problem->randnumgen, lb, lb + MAXPERTURB*MIN(1.0, ub-lb));
1368  else if( ub < 0.0 )
1369  problem->opt->X[i] = SCIPrandomGetReal(problem->randnumgen, ub - MAXPERTURB*MIN(1.0, ub-lb), ub);
1370  else
1371  problem->opt->X[i] = SCIPrandomGetReal(problem->randnumgen,
1372  MAX(lb, -MAXPERTURB*MIN(1.0, ub-lb)), MIN(ub, MAXPERTURB*MIN(1.0, ub-lb)));
1373  }
1374  }
1375 
1376 #ifdef SCIP_DEBUG
1377  SCIPdebugMsg(scip, "start point:\n");
1378  for( i = 0; i < problem->opt->n; ++i )
1379  {
1380  SCIPdebugMsg(scip, "x[%d] = %f\n", i, problem->opt->X[i]);
1381  }
1382 #endif
1383 
1384  /*
1385  * Worhp Reverse Communication loop.
1386  * In every iteration poll GetUserAction for the requested action, i.e. one
1387  * of {callWorhp, iterOutput, evalF, evalG, evalDF, evalDG, evalHM, fidif}.
1388  *
1389  * Make sure to reset the requested user action afterwards by calling
1390  * DoneUserAction, except for 'callWorhp' and 'fidif'.
1391  */
1392  while( cnt->status < TerminateSuccess && cnt->status > TerminateError && !SCIPisSolveInterrupted(scip) )
1393  {
1394  /*
1395  * Worhp's main routine.
1396  * Do not manually reset callWorhp, this is only done by the FD routines.
1397  */
1398  if( GetUserAction(cnt, callWorhp) )
1399  {
1400  Worhp(opt, wsp, par, cnt);
1401  /* No DoneUserAction! */
1402  }
1403 
1404  /*
1405  * Show iteration output.
1406  * The call to IterationOutput() may be replaced by user-defined code.
1407  */
1408  if( GetUserAction(cnt, iterOutput) )
1409  {
1410  IterationOutput(opt, wsp, par, cnt);
1411  DoneUserAction(cnt, iterOutput);
1412  }
1413 
1414  /*
1415  * Evaluate the objective function.
1416  * The call to UserF may be replaced by user-defined code.
1417  */
1418  if( GetUserAction(cnt, evalF) )
1419  {
1420  if( userF(scip, problem) != SCIP_OKAY )
1421  break;
1422  DoneUserAction(cnt, evalF);
1423  }
1424 
1425  /*
1426  * Evaluate the constraints.
1427  * The call to UserG may be replaced by user-defined code.
1428  */
1429  if( GetUserAction(cnt, evalG) )
1430  {
1431  if( userG(scip, problem) != SCIP_OKAY )
1432  break;
1433  DoneUserAction(cnt, evalG);
1434  }
1435 
1436  /*
1437  * Evaluate the gradient of the objective function.
1438  * The call to UserDF may be replaced by user-defined code.
1439  */
1440  if( GetUserAction(cnt, evalDF) )
1441  {
1442  if( userDF(scip, problem) != SCIP_OKAY )
1443  break;
1444  DoneUserAction(cnt, evalDF);
1445  }
1446 
1447  /*
1448  * Evaluate the Jacobian of the constraints.
1449  * The call to UserDG may be replaced by user-defined code.
1450  */
1451  if( GetUserAction(cnt, evalDG) )
1452  {
1453  if( userDG(scip, problem) != SCIP_OKAY )
1454  break;
1455  DoneUserAction(cnt, evalDG);
1456  }
1457 
1458  /*
1459  * Evaluate the Hessian matrix of the Lagrange function (L = f + mu*g)
1460  * The call to UserHM may be replaced by user-defined code.
1461  */
1462  if( GetUserAction(cnt, evalHM) )
1463  {
1464  if( userHM(scip, problem) != SCIP_OKAY)
1465  break;
1466  DoneUserAction(cnt, evalHM);
1467  }
1468 
1469  /*
1470  * Use finite differences with RC to determine derivatives
1471  * Do not reset fidif, this is done by the FD routine.
1472  */
1473  if( GetUserAction(cnt, fidif) )
1474  {
1475  WorhpFidif(opt, wsp, par, cnt);
1476  /* No DoneUserAction! */
1477  }
1478  }
1479 
1480  /* interpret Worhp result */
1482  {
1483  problem->lastsolstat = SCIP_NLPSOLSTAT_UNKNOWN;
1484  problem->lasttermstat = SCIP_NLPTERMSTAT_INTERRUPT;
1485  }
1486  else if( cnt->status < TerminateSuccess && cnt->status > TerminateError )
1487  {
1488  SCIPwarningMessage(scip, "Worhp failed because of an invalid function evaluation!\n");
1489  problem->lastsolstat = SCIP_NLPSOLSTAT_UNKNOWN;
1490  problem->lasttermstat = SCIP_NLPTERMSTAT_NUMERICERROR;
1491  }
1492  else
1493  {
1494  SCIP_CALL( evaluateWorhpRun(scip, problem) );
1495  }
1496 
1497  /* prints a status message with information about the current solver status */
1498  StatusMsg(opt, wsp, par, cnt);
1499 
1500  /* store statistics */
1501  problem->lastniter = wsp->MajorIter;
1502  problem->lasttime = GetTimerCont(&cnt->Timer);
1503 
1504  return SCIP_OKAY;
1505 } /*lint !e715*/
1506 
1507 /** gives solution status */
1508 static
1509 SCIP_DECL_NLPIGETSOLSTAT(nlpiGetSolstatWorhp)
1510 {
1511  assert(nlpi != NULL);
1512  assert(problem != NULL);
1513 
1514  return problem->lastsolstat;
1515 } /*lint !e715*/
1516 
1517 /** gives termination reason */
1518 static
1519 SCIP_DECL_NLPIGETTERMSTAT(nlpiGetTermstatWorhp)
1520 {
1521  assert(nlpi != NULL);
1522  assert(problem != NULL);
1523 
1524  return problem->lasttermstat;
1525 } /*lint !e715*/
1526 
1527 /** gives primal and dual solution values */
1528 static
1529 SCIP_DECL_NLPIGETSOLUTION( nlpiGetSolutionWorhp )
1530 {
1531  assert(problem != NULL);
1532 
1533  if( primalvalues != NULL )
1534  *primalvalues = problem->lastprimal;
1535 
1536  if( consdualvalues != NULL )
1537  *consdualvalues = problem->lastdualcons;
1538 
1539  if( varlbdualvalues != NULL )
1540  *varlbdualvalues = problem->lastduallb;
1541 
1542  if( varubdualvalues != NULL )
1543  *varubdualvalues = problem->lastdualub;
1544 
1545  if( objval != NULL )
1546  {
1547  if( problem->lastprimal != NULL )
1548  {
1549  /* TODO store last solution value instead of reevaluating the objective function */
1550  SCIP_CALL( SCIPnlpiOracleEvalObjectiveValue(scip, problem->oracle, problem->lastprimal, objval) );
1551  }
1552  else
1553  *objval = SCIP_INVALID;
1554  }
1555 
1556  return SCIP_OKAY;
1557 } /*lint !e715*/
1558 
1559 /** gives solve statistics */
1560 static
1561 SCIP_DECL_NLPIGETSTATISTICS(nlpiGetStatisticsWorhp)
1562 {
1563  assert(nlpi != NULL);
1564  assert(problem != NULL);
1565  assert(statistics != NULL);
1566 
1567  statistics->niterations = problem->lastniter;
1568  statistics->totaltime = problem->lasttime;
1569  statistics->evaltime = SCIPnlpiOracleGetEvalTime(scip, problem->oracle);
1570  statistics->consviol = problem->wsp->FeasOrigMax;
1571  statistics->boundviol = 0.0;
1572 
1573  return SCIP_OKAY;
1574 } /*lint !e715*/
1575 
1576 /*
1577  * NLP solver interface specific interface methods
1578  */
1579 
1580 /** create solver interface for Worhp solver and includes it into SCIP, if Worhp is available */
1582  SCIP* scip, /**< SCIP data structure */
1583  SCIP_Bool useip /**< TRUE for using Interior Point, FALSE for SQP */
1584  )
1585 {
1586  SCIP_NLPIDATA* nlpidata;
1587  char name[SCIP_MAXSTRLEN];
1588  int priority;
1589 
1590  /* create Worhp solver interface data */
1591  SCIP_CALL( SCIPallocBlockMemory(scip, &nlpidata) );
1592  nlpidata->useip = useip;
1593 
1594  /* disable Worhp's keyboard handler, not useful here and not threadsafe */
1595  (void) setenv("WORHP_DISABLE_KEYBOARD_HANDLER", "1", 0);
1596 
1597 #if DEFAULT_VERBLEVEL == 0
1598  /* disable Worhp output by default */
1599  SetWorhpPrint(noprint);
1600 #endif
1601 
1602  /* checks the version of the library and header files */
1603  CHECK_WORHP_VERSION
1604 
1605  /* create solver interface */
1606  if( useip )
1607  {
1608  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "worhp-ip");
1609  priority = NLPI_PRIORITY_IP;
1610  }
1611  else
1612  {
1613  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "worhp-sqp");
1614  priority = NLPI_PRIORITY_SQP;
1615  }
1616 
1617  SCIP_CALL( SCIPincludeNlpi(scip,
1618  name, NLPI_DESC, priority,
1619  nlpiCopyWorhp, nlpiFreeWorhp, NULL,
1620  nlpiCreateProblemWorhp, nlpiFreeProblemWorhp, NULL,
1621  nlpiAddVarsWorhp, nlpiAddConstraintsWorhp, nlpiSetObjectiveWorhp,
1622  nlpiChgVarBoundsWorhp, nlpiChgConsSidesWorhp, nlpiDelVarSetWorhp, nlpiDelConstraintSetWorhp,
1623  nlpiChgLinearCoefsWorhp, nlpiChgExprWorhp,
1624  nlpiChgObjConstantWorhp, nlpiSetInitialGuessWorhp, nlpiSolveWorhp, nlpiGetSolstatWorhp, nlpiGetTermstatWorhp,
1625  nlpiGetSolutionWorhp, nlpiGetStatisticsWorhp,
1626  nlpidata) );
1627 
1628  if( useip ) /* TODO lookup whether Worhp info has already been included instead of assuming that worhp-up will be included */
1629  {
1631  }
1632 
1633  return SCIP_OKAY;
1634 }
1635 
1636 /** gets string that identifies Worhp (version number) */
1638  void
1639  )
1640 {
1641 #ifdef WORHP_VERSION
1642  return "WORHP " WORHP_VERSION;
1643 #else
1644  static char solvername[20];
1645  sprintf(solvername, "WORHP %d.%d." WORHP_PATCH, WORHP_MAJOR, WORHP_MINOR);
1646  return solvername;
1647 #endif
1648 }
1649 
1650 /** gets string that describes Worhp (version number) */
1652  void
1653  )
1654 {
1655  return "Nonlinear programming solver developed at Research Institute Steinbeis (www.worhp.de)";
1656 }
1657 
1658 /** returns whether Worhp is available, i.e., whether it has been linked in */
1660  void
1661  )
1662 {
1663  return TRUE;
1664 }
void SCIPfreeRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen)
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:101
SCIP_RETCODE SCIPnlpiOracleEvalObjectiveGradient(SCIP *scip, SCIP_NLPIORACLE *oracle, const SCIP_Real *x, SCIP_Bool isnewx, SCIP_Real *objval, SCIP_Real *objgrad)
Definition: nlpioracle.c:1959
static SCIP_DECL_NLPICHGOBJCONSTANT(nlpiChgObjConstantWorhp)
Definition: nlpi_worhp.c:1245
enum SCIP_NlpTermStat SCIP_NLPTERMSTAT
Definition: type_nlpi.h:185
SCIP_NLPIDATA * SCIPnlpiGetData(SCIP_NLPI *nlpi)
Definition: nlpi.c:683
SCIP_RETCODE SCIPnlpiOracleChgLinearCoefs(SCIP *scip, SCIP_NLPIORACLE *oracle, int considx, int nentries, const int *varidxs, const SCIP_Real *newcoefs)
Definition: nlpioracle.c:1548
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:84
Params * par
Definition: nlpi_worhp.c:94
static void noprint(int mode, const char s[])
Definition: nlpi_worhp.c:624
methods to interpret (evaluate) an expression "fast"
#define SCIPduplicateMemoryArray(scip, ptr, source, num)
Definition: scip_mem.h:67
SCIP_Real opttol
Definition: type_nlpi.h:61
#define SCIPfreeMemoryArrayNull(scip, ptr)
Definition: scip_mem.h:72
SCIP_RETCODE SCIPincludeNlpSolverWorhp(SCIP *scip, SCIP_Bool useip)
Definition: nlpi_worhp.c:1581
SCIP_NLPSOLSTAT lastsolstat
Definition: nlpi_worhp.c:75
public methods for memory management
Control * cnt
Definition: nlpi_worhp.c:95
static SCIP_DECL_NLPICHGVARBOUNDS(nlpiChgVarBoundsWorhp)
Definition: nlpi_worhp.c:1108
#define MAXPERTURB
Definition: nlpi_worhp.c:58
SCIP_Bool warmstart
Definition: type_nlpi.h:68
SCIP_Real * lastdualcons
Definition: nlpi_worhp.c:80
#define SCIP_MAXSTRLEN
Definition: def.h:293
#define NLPI_PRIORITY_SQP
Definition: nlpi_worhp.c:52
public solving methods
SCIP_Real feastol
Definition: type_nlpi.h:60
methods to store an NLP and request function, gradient, and Hessian values
SCIP_RETCODE SCIPnlpiOracleEvalHessianLag(SCIP *scip, SCIP_NLPIORACLE *oracle, const SCIP_Real *x, SCIP_Bool isnewx_obj, SCIP_Bool isnewx_cons, SCIP_Real objfactor, const SCIP_Real *lambda, SCIP_Real *hessian)
Definition: nlpioracle.c:2371
const char * SCIPgetSolverDescWorhp(void)
Definition: nlpi_worhp.c:1651
static SCIP_DECL_NLPISETINITIALGUESS(nlpiSetInitialGuessWorhp)
Definition: nlpi_worhp.c:1258
SCIP_NLPIORACLE * oracle
#define FALSE
Definition: def.h:87
unsigned short verblevel
Definition: type_nlpi.h:65
static SCIP_DECL_NLPIADDVARS(nlpiAddVarsWorhp)
Definition: nlpi_worhp.c:1047
SCIP_RETCODE SCIPnlpiOracleAddConstraints(SCIP *scip, SCIP_NLPIORACLE *oracle, int nconss, const SCIP_Real *lhss, const SCIP_Real *rhss, const int *nlininds, int *const *lininds, SCIP_Real *const *linvals, SCIP_EXPR **exprs, const char **consnames)
Definition: nlpioracle.c:1158
SCIP_Real SCIPinfinity(SCIP *scip)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10755
#define TRUE
Definition: def.h:86
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
static SCIP_DECL_NLPIGETSOLUTION(nlpiGetSolutionWorhp)
Definition: nlpi_worhp.c:1529
SCIP_RETCODE SCIPnlpiOracleSetProblemName(SCIP *scip, SCIP_NLPIORACLE *oracle, const char *name)
Definition: nlpioracle.c:1036
SCIP_Real SCIPnlpiOracleGetEvalTime(SCIP *scip, SCIP_NLPIORACLE *oracle)
Definition: nlpioracle.c:2434
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:99
SCIP_RETCODE SCIPnlpiOracleSetObjective(SCIP *scip, SCIP_NLPIORACLE *oracle, const SCIP_Real constant, int nlin, const int *lininds, const SCIP_Real *linvals, SCIP_EXPR *expr)
Definition: nlpioracle.c:1219
SCIP_RETCODE SCIPnlpiOraclePrintProblem(SCIP *scip, SCIP_NLPIORACLE *oracle, FILE *file)
Definition: nlpioracle.c:2445
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:111
SCIP_Real SCIPnlpiOracleGetConstraintRhs(SCIP_NLPIORACLE *oracle, int considx)
Definition: nlpioracle.c:1812
#define SCIPdebugMsg
Definition: scip_message.h:69
SCIP_Real timelimit
Definition: type_nlpi.h:63
public methods for numerical tolerances
SCIP_Real * lastduallb
Definition: nlpi_worhp.c:81
public methods for NLPI solver interfaces
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip_mem.h:96
SCIP_Bool firstrun
Definition: nlpi_worhp.c:88
#define SCIPerrorMessage
Definition: pub_message.h:55
int SCIPnlpiOracleGetNConstraints(SCIP_NLPIORACLE *oracle)
Definition: nlpioracle.c:1717
#define SCIPdebugPrintf
Definition: pub_message.h:90
struct SCIP_NlpiData SCIP_NLPIDATA
Definition: type_nlpi.h:43
enum SCIP_NlpSolStat SCIP_NLPSOLSTAT
Definition: type_nlpi.h:159
#define SCIP_NLPPARAM_PRINT(param)
Definition: type_nlpi.h:133
int SCIPnlpiOracleGetNVars(SCIP_NLPIORACLE *oracle)
Definition: nlpioracle.c:1707
SCIP_RETCODE SCIPnlpiOracleResetEvalTime(SCIP *scip, SCIP_NLPIORACLE *oracle)
Definition: nlpioracle.c:2418
SCIP_RETCODE SCIPnlpiOracleChgVarBounds(SCIP *scip, SCIP_NLPIORACLE *oracle, int nvars, const int *indices, const SCIP_Real *lbs, const SCIP_Real *ubs)
Definition: nlpioracle.c:1248
static SCIP_DECL_NLPIADDCONSTRAINTS(nlpiAddConstraintsWorhp)
Definition: nlpi_worhp.c:1065
#define NULL
Definition: lpi_spx1.cpp:155
static SCIP_DECL_NLPIDELVARSET(nlpiDelVarSetWorhp)
Definition: nlpi_worhp.c:1179
Workspace * wsp
Definition: nlpi_worhp.c:93
#define REALABS(x)
Definition: def.h:201
SCIP_RETCODE SCIPnlpiOracleGetJacobianSparsity(SCIP *scip, SCIP_NLPIORACLE *oracle, const int **offset, const int **col)
Definition: nlpioracle.c:2018
static SCIP_RETCODE userHM(SCIP *scip, SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:568
SCIP_RETCODE SCIPnlpiOracleAddVars(SCIP *scip, SCIP_NLPIORACLE *oracle, int nvars, const SCIP_Real *lbs, const SCIP_Real *ubs, const char **varnames)
Definition: nlpioracle.c:1072
static SCIP_DECL_NLPIGETTERMSTAT(nlpiGetTermstatWorhp)
Definition: nlpi_worhp.c:1519
#define SCIP_CALL(x)
Definition: def.h:384
Worhp NLP interface.
static SCIP_DECL_NLPICOPY(nlpiCopyWorhp)
Definition: nlpi_worhp.c:951
SCIP_Bool SCIPisWorhpAvailableWorhp(void)
Definition: nlpi_worhp.c:1659
SCIP_RETCODE SCIPnlpiOracleChgExpr(SCIP *scip, SCIP_NLPIORACLE *oracle, int considx, SCIP_EXPR *expr)
Definition: nlpioracle.c:1644
static SCIP_DECL_NLPISOLVE(nlpiSolveWorhp)
Definition: nlpi_worhp.c:1285
static SCIP_DECL_NLPIDELCONSSET(nlpiDelConstraintSetWorhp)
Definition: nlpi_worhp.c:1197
SCIP_Real SCIPnlpiOracleGetConstraintLhs(SCIP_NLPIORACLE *oracle, int considx)
Definition: nlpioracle.c:1799
methods for catching the user CTRL-C interrupt
SCIP_RETCODE SCIPcreateRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen, unsigned int initialseed, SCIP_Bool useglobalseed)
#define DEFAULT_RANDSEED
Definition: nlpi_worhp.c:56
static SCIP_DECL_NLPIFREE(nlpiFreeWorhp)
Definition: nlpi_worhp.c:967
#define NLPI_PRIORITY_IP
Definition: nlpi_worhp.c:51
public data structures and miscellaneous methods
SCIP_RETCODE SCIPnlpiOracleEvalJacobian(SCIP *scip, SCIP_NLPIORACLE *oracle, const SCIP_Real *x, SCIP_Bool isnewx, SCIP_Real *convals, SCIP_Real *jacobi)
Definition: nlpioracle.c:2150
SCIP_RETCODE SCIPnlpiOracleDelVarSet(SCIP *scip, SCIP_NLPIORACLE *oracle, int *delstats)
Definition: nlpioracle.c:1320
#define SCIP_Bool
Definition: def.h:84
static SCIP_DECL_NLPICHGCONSSIDES(nlpiChgConsSidesWorhp)
Definition: nlpi_worhp.c:1148
#define MAX(x, y)
Definition: tclique_def.h:83
SCIP_RETCODE SCIPnlpiOracleCreate(SCIP *scip, SCIP_NLPIORACLE **oracle)
Definition: nlpioracle.c:974
SCIP_Real lobjlimit
Definition: type_nlpi.h:59
static SCIP_DECL_NLPISETOBJECTIVE(nlpiSetObjectiveWorhp)
Definition: nlpi_worhp.c:1084
const SCIP_Real * SCIPnlpiOracleGetVarLbs(SCIP_NLPIORACLE *oracle)
Definition: nlpioracle.c:1727
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:127
static SCIP_DECL_NLPIFREEPROBLEM(nlpiFreeProblemWorhp)
Definition: nlpi_worhp.c:1009
static SCIP_RETCODE userG(SCIP *scip, SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:447
SCIP_Bool SCIPnlpiOracleIsConstraintNonlinear(SCIP_NLPIORACLE *oracle, int considx)
Definition: nlpioracle.c:1838
#define NLPI_DESC
Definition: nlpi_worhp.c:50
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
static SCIP_RETCODE updateWorhp(SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:835
const SCIP_Real * SCIPnlpiOracleGetVarUbs(SCIP_NLPIORACLE *oracle)
Definition: nlpioracle.c:1737
SCIP_RETCODE SCIPnlpiOracleFree(SCIP *scip, SCIP_NLPIORACLE **oracle)
Definition: nlpioracle.c:1004
SCIP_Real SCIPrandomGetReal(SCIP_RANDNUMGEN *randnumgen, SCIP_Real minrandval, SCIP_Real maxrandval)
Definition: misc.c:10025
#define SCIP_REAL_MAX
Definition: def.h:178
const char * SCIPgetSolverNameWorhp(void)
Definition: nlpi_worhp.c:1637
static SCIP_DECL_NLPICHGLINEARCOEFS(nlpiChgLinearCoefsWorhp)
Definition: nlpi_worhp.c:1213
general public methods
SCIP_RETCODE SCIPnlpiOracleEvalObjectiveValue(SCIP *scip, SCIP_NLPIORACLE *oracle, const SCIP_Real *x, SCIP_Real *objval)
Definition: nlpioracle.c:1878
public methods for random numbers
static SCIP_RETCODE evaluateWorhpRun(SCIP *scip, SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:126
static SCIP_DECL_NLPIGETSTATISTICS(nlpiGetStatisticsWorhp)
Definition: nlpi_worhp.c:1561
static SCIP_RETCODE userDF(SCIP *scip, SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:479
SCIP_RETCODE SCIPnlpiOracleEvalConstraintValues(SCIP *scip, SCIP_NLPIORACLE *oracle, const SCIP_Real *x, SCIP_Real *convals)
Definition: nlpioracle.c:1927
#define SCIP_Real
Definition: def.h:177
SCIP_NLPTERMSTAT lasttermstat
Definition: nlpi_worhp.c:74
SCIP_RETCODE SCIPnlpiOracleGetHessianLagSparsity(SCIP *scip, SCIP_NLPIORACLE *oracle, const int **offset, const int **col)
Definition: nlpioracle.c:2277
static SCIP_DECL_NLPICHGEXPR(nlpiChgExprWorhp)
Definition: nlpi_worhp.c:1229
public methods for message handling
SCIP_Real * lastdualub
Definition: nlpi_worhp.c:82
#define SCIP_INVALID
Definition: def.h:197
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:875
static SCIP_RETCODE handleNlpParam(SCIP *scip, SCIP_NLPI *nlpi, Params *par, const SCIP_NLPPARAM nlpparam)
Definition: nlpi_worhp.c:893
SCIP_RETCODE SCIPincludeExternalCodeInformation(SCIP *scip, const char *name, const char *description)
Definition: scip_general.c:704
static SCIP_DECL_NLPICREATEPROBLEM(nlpiCreateProblemWorhp)
Definition: nlpi_worhp.c:981
static SCIP_RETCODE userF(SCIP *scip, SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:414
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip_mem.h:102
SCIP_RETCODE SCIPincludeNlpi(SCIP *scip, 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_NLPICHGEXPR((*nlpichgexpr)), 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_NLPIDATA *nlpidata)
Definition: scip_nlpi.c:98
#define SCIPallocClearBlockMemory(scip, ptr)
Definition: scip_mem.h:82
static SCIP_RETCODE userDG(SCIP *scip, SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:523
SCIPallocBlockMemory(scip, subsol))
SCIP_RETCODE SCIPnlpiOracleChgConsSides(SCIP *scip, SCIP_NLPIORACLE *oracle, int nconss, const int *indices, const SCIP_Real *lhss, const SCIP_Real *rhss)
Definition: nlpioracle.c:1285
static SCIP_DECL_NLPIGETSOLSTAT(nlpiGetSolstatWorhp)
Definition: nlpi_worhp.c:1509
SCIP_RETCODE SCIPnlpiOracleDelConsSet(SCIP *scip, SCIP_NLPIORACLE *oracle, int *delstats)
Definition: nlpioracle.c:1462
static void invalidateSolution(SCIP *scip, SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:104
SCIP_NLPPARAM_FASTFAIL fastfail
Definition: type_nlpi.h:66
static SCIP_RETCODE initWorhp(SCIP *scip, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:633
SCIP_Bool SCIPisSolveInterrupted(SCIP *scip)
Definition: scip_solve.c:3548
SCIP_RETCODE SCIPnlpiOracleChgObjConstant(SCIP *scip, SCIP_NLPIORACLE *oracle, SCIP_Real objconstant)
Definition: nlpioracle.c:1690
#define DEFAULT_SCALEDKKT
Definition: nlpi_worhp.c:55