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