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