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-2025 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"
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
74struct SCIP_NlpiData
75{
76 SCIP_Bool useip; /**< should the Interior Point solver of Worhp be used? */
77};
78
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 */
113static
115 SCIP* scip, /**< SCIP data structure */
116 SCIP_NLPIPROBLEM* problem /**< pointer to problem data structure */
117 )
118{
119 assert(problem != NULL);
120
125
126 problem->lastprimalsize = 0;
127 problem->lastdualconssize = 0;
128 problem->lastduallbsize = 0;
129 problem->lastdualubsize = 0;
132}
133
134/** evaluate last Worhp run */
135static
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 */
423static
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 */
456static
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 */
488static
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 */
532static
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 */
577static
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) */
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, FALSE);
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}*/
634static void noprint(
635 int mode, /**< the mode */
636 const char s[] /**< a string */
637 )
638{ /*lint --e{715}*/
639}
640
641/** initialize Worhp data */
642static
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 int nnlnz;
660
661 assert(nlpi != NULL);
662 assert(problem != NULL);
663 assert(problem->cnt != NULL);
664 assert(problem->wsp != NULL);
665 assert(problem->par != NULL);
666 assert(problem->opt != NULL);
667 assert(problem->firstrun);
668
669 wsp = problem->wsp;
670 cnt = problem->cnt;
671 opt = problem->opt;
672 par = problem->par;
673
674 /* properly zeros everything */
675 WorhpPreInit(opt, wsp, par, cnt);
676
677 /* set problem dimensions */
678 opt->n = SCIPnlpiOracleGetNVars(problem->oracle);
679 opt->m = SCIPnlpiOracleGetNConstraints(problem->oracle);
680 SCIPdebugMsg(scip, "nvars %d nconss %d\n", opt->n, opt->m);
681
682 /* assume that objective function is dense; TODO use sparse representation */
683 wsp->DF.nnz = opt->n;
684
685 /* get number of non-zero entries in Jacobian */
686 SCIP_CALL( SCIPnlpiOracleGetJacobianRowSparsity(scip, problem->oracle, &offset, NULL, NULL, &nnlnz) );
687 wsp->DG.nnz = offset[opt->m];
688 SCIPdebugMsg(scip, "nnonz jacobian %d\n", wsp->DG.nnz);
689
690 /* get number of non-zero entries in hessian
691 *
692 * note that Worhp wants to have the full diagonal in ANY case
693 */
694 SCIP_CALL( SCIPnlpiOracleGetHessianLagSparsity(scip, problem->oracle, &offset, &cols, FALSE) );
695 wsp->HM.nnz = 0;
696
697 j = offset[0];
698 for( i = 0; i < opt->n; ++i )
699 {
700 /* diagonal element */
701 ++(wsp->HM.nnz);
702
703 /* strict lower triangle elements */
704 for( ; j < offset[i+1]; ++j )
705 {
706 if( i != cols[j] )
707 {
708 assert(i > cols[j]);
709 ++(wsp->HM.nnz);
710 }
711 }
712 }
713 assert(offset[opt->n] <= wsp->HM.nnz);
714 SCIPdebugMsg(scip, "nnonz hessian %d\n", wsp->HM.nnz);
715
716 /* initialize data in Worhp */
717 WorhpInit(opt, wsp, par, cnt);
718 if (cnt->status != FirstCall)
719 {
720 SCIPerrorMessage("Initialisation failed.\n");
721 return SCIP_ERROR;
722 }
723
724 /* set variable bounds */
725 lbs = SCIPnlpiOracleGetVarLbs(problem->oracle);
726 ubs = SCIPnlpiOracleGetVarUbs(problem->oracle);
727
728 BMScopyMemoryArray(opt->XL, lbs, opt->n);
729 BMScopyMemoryArray(opt->XU, ubs, opt->n);
730
731#ifdef SCIP_DEBUG
732 for( i = 0; i < opt->n; ++i )
733 {
734 SCIPdebugMsg(scip, "bounds %d [%g,%g]\n", i, opt->XL[i], opt->XU[i]);
735 }
736#endif
737
738 /* set constraint sides */
739 for( i = 0; i < opt->m; ++i )
740 {
741 opt->GL[i] = SCIPnlpiOracleGetConstraintLhs(problem->oracle, i);
742 opt->GU[i] = SCIPnlpiOracleGetConstraintRhs(problem->oracle, i);
743
744 /* adjust constraint sides when both are infinite */
745 if( SCIPisInfinity(scip, -opt->GL[i]) && SCIPisInfinity(scip, opt->GU[i]) )
746 {
747 SCIPwarningMessage(scip, "Lhs and rhs of constraint %d are infinite.\n", i);
748 opt->GL[i] = -SCIPinfinity(scip) / 10.0;
749 opt->GU[i] = SCIPinfinity(scip) / 10.0;
750 }
751
752 SCIPdebugMsg(scip, "sides %d [%g,%g]\n", i, opt->GL[i], opt->GU[i]);
753 }
754
755 /* set column indices of objective function; note that indices go from 1 to n */
756 /* if( wsp->DF.NeedStructure ) evaluates to FALSE if DF is dense */
757 {
758 SCIPdebugPrintf("column indices of objective function:");
759 for( i = 0; i < opt->n; ++i )
760 {
761 wsp->DF.row[i] = i + 1;
762 SCIPdebugPrintf(" %d", wsp->DF.row[i]);
763 }
764 SCIPdebugPrintf("\n");
765 }
766
767 /* set column and row indices of non-zero entries in Jacobian matrix */
768 /* if( wsp->DG.NeedStructure ) evaluates to FALSE if DG is dense */
769 {
770 int nnonz;
771
772 SCIP_CALL( SCIPnlpiOracleGetJacobianRowSparsity(scip, problem->oracle, &offset, &cols, NULL, &nnlnz) );
773 assert(offset[opt->m] == wsp->DG.nnz);
774
775 nnonz = 0;
776 j = offset[0];
777 for( i = 0; i < opt->m; ++i )
778 {
779 for( ; j < offset[i+1]; ++j )
780 {
781 wsp->DG.row[nnonz] = i + 1;
782 wsp->DG.col[nnonz] = cols[j] + 1;
783 ++nnonz;
784 }
785 }
786 assert(nnonz == wsp->DG.nnz);
787
788 /* sort arrays w.r.t the column-major order */
789 SortWorhpMatrix(&wsp->DG);
790 }
791
792 /* set column and row indices of non-zero entries in hessian matrix */
793 if( problem->par->UserHM || problem->par->FidifHM || problem->par->BFGSmethod > 1 )
794 {
795 int nnonz;
796 int k;
797
798 SCIP_CALL( SCIPnlpiOracleGetHessianLagSparsity(scip, problem->oracle, &offset, &cols, FALSE) );
799 assert(offset[opt->n] <= wsp->HM.nnz);
800
801 k = offset[opt->n];
802 nnonz = 0;
803 j = offset[0];
804 for( i = 0; i < opt->n; ++i )
805 {
806 SCIP_Bool adddiag = TRUE;
807
808 for( ; j < offset[i+1]; ++j )
809 {
810 problem->wsp->HM.row[nnonz] = i + 1;
811 problem->wsp->HM.col[nnonz] = cols[j] + 1;
812 ++nnonz;
813
814 if( i == cols[j] )
815 adddiag = FALSE;
816 }
817
818 /* Worhp wants to have each diagonal element */
819 if( adddiag )
820 {
821 problem->wsp->HM.row[k] = i + 1;
822 problem->wsp->HM.col[k] = i + 1;
823 ++k;
824 }
825 }
826 assert(nnonz == offset[opt->n]);
827 assert(k == wsp->HM.nnz);
828
829 /* sort arrays w.r.t the LT column-major order */
830 SortWorhpMatrix(&wsp->HM);
831
832#ifdef SCIP_DEBUG
833 SCIPdebugMsg(scip, "column and row indices of hessian:\n");
834 for( i = 0; i < wsp->HM.nnz; ++i )
835 {
836 SCIPdebugMsg(scip, " entry %d: (row,col) = (%d,%d)\n", i, wsp->HM.row[i], wsp->HM.col[i]);
837 }
838#endif
839 }
840
841 return SCIP_OKAY;
842}
843
844/** update Worhp data */
845static
847 SCIP_NLPIPROBLEM* problem /**< pointer to problem data structure */
848 )
849{
850 const SCIP_Real* lbs;
851 const SCIP_Real* ubs;
852 int i;
853
854 assert(problem != NULL);
855 assert(problem->cnt != NULL);
856 assert(problem->wsp != NULL);
857 assert(problem->par != NULL);
858 assert(problem->opt != NULL);
859 assert(problem->oracle != NULL);
860 assert(problem->opt->n == SCIPnlpiOracleGetNVars(problem->oracle));
861 assert(problem->opt->m == SCIPnlpiOracleGetNConstraints(problem->oracle));
862
863 WorhpRestart(problem->opt, problem->wsp, problem->par, problem->cnt);
864
865 /* update variable bounds */
866 lbs = SCIPnlpiOracleGetVarLbs(problem->oracle);
867 ubs = SCIPnlpiOracleGetVarUbs(problem->oracle);
868 for( i = 0; i < problem->opt->n; ++i )
869 {
870 problem->opt->XL[i] = lbs[i];
871 problem->opt->XU[i] = ubs[i];
872 }
873
874 /* update constraint sides */
875 for( i = 0; i < problem->opt->m; ++i )
876 {
877 problem->opt->GL[i] = SCIPnlpiOracleGetConstraintLhs(problem->oracle, i);
878 problem->opt->GU[i] = SCIPnlpiOracleGetConstraintRhs(problem->oracle, i);
879 }
880
881 return SCIP_OKAY;
882}
883
884/** frees Worhp data */
885static
887 SCIP_NLPIPROBLEM* problem /**< pointer to problem data structure */
888 )
889{
890 assert(problem != NULL);
891 assert(problem->cnt != NULL);
892 assert(problem->wsp != NULL);
893 assert(problem->par != NULL);
894 assert(problem->opt != NULL);
895
896 if( problem->opt->initialised )
897 WorhpFree(problem->opt, problem->wsp, problem->par, problem->cnt);
898
899 return SCIP_OKAY;
900}
901
902/** pass NLP solve parameters to Ipopt */
903static
905 SCIP* scip, /**< SCIP data structure */
906 SCIP_NLPI* nlpi, /**< Worhp interface */
907 Params* par, /**< Worhp parameters */
908 const SCIP_NLPPARAM nlpparam /**< NLP solve parameters */
909 )
910{
911 SCIP_NLPIDATA* nlpidata;
912
913 assert(par != NULL);
914 assert(nlpi != NULL);
915
916 nlpidata = SCIPnlpiGetData(nlpi);
917 assert(nlpidata != NULL);
918
919 par->Algorithm = nlpidata->useip ? 2 : 1;
920 par->ScaledKKT = DEFAULT_SCALEDKKT;
921 par->sKKTOnlyAcceptable = DEFAULT_SCALEDKKT;
922 par->Infty = SCIPinfinity(scip);
923
924 if( nlpparam.warmstart )
925 {
926 SCIPdebugMsg(scip, "warmstart parameter not supported by Worhp interface yet. Ignored.\n");
927 }
928
929 if( nlpparam.lobjlimit > -SCIP_REAL_MAX )
930 {
931 SCIPwarningMessage(scip, "lobjlimit parameter not supported by Worhp interface yet. Ignored.\n");
932 }
933
934 if( nlpparam.fastfail )
935 {
936 SCIPdebugMsg(scip, "fastfail parameter not supported by Worhp interface yet. Ignored.\n");
937 }
938
939 par->TolFeas = nlpparam.feastol;
940 par->TolOpti = nlpparam.opttol;
941 par->TolComp = nlpparam.opttol;
942 par->Timeout = nlpparam.timelimit;
943 par->MaxIter = nlpparam.iterlimit;
944 par->NLPprint = nlpparam.verblevel - 1; /* Worhp verbosity levels: -1 = off, 0 = normal, 1 = debug, >1 = more debug */
945
946#ifdef CHECKFUNVALUES
947 /* activate gradient and hessian check */
948 par->CheckValuesDF = TRUE;
949 par->CheckValuesDG = TRUE;
950 par->CheckValuesHM = TRUE;
951#endif
952
953 return SCIP_OKAY;
954}
955
956/*
957 * Callback methods of NLP solver interface
958 */
959
960/** copy method of NLP interface (called when SCIP copies plugins) */
961static
962SCIP_DECL_NLPICOPY(nlpiCopyWorhp)
963{
964 SCIP_NLPIDATA* sourcedata;
965
966 assert(sourcenlpi != NULL);
967
968 sourcedata = SCIPnlpiGetData(sourcenlpi);
969 assert(sourcedata != NULL);
970
971 SCIP_CALL( SCIPincludeNlpSolverWorhp(scip, sourcedata->useip) );
972
973 return SCIP_OKAY;
974} /*lint !e715*/
975
976/** destructor of NLP interface to free nlpi data */
977static
978SCIP_DECL_NLPIFREE(nlpiFreeWorhp)
979{
980 assert(nlpi != NULL);
981 assert(nlpidata != NULL);
982 assert(*nlpidata != NULL);
983
984 SCIPfreeBlockMemory(scip, nlpidata);
985 assert(*nlpidata == NULL);
986
987 return SCIP_OKAY;
988} /*lint !e715*/
989
990/** creates a problem instance */
991static
992SCIP_DECL_NLPICREATEPROBLEM(nlpiCreateProblemWorhp)
993{
994 assert(nlpi != NULL);
995 assert(problem != NULL);
996
998 assert( *problem != NULL );
999
1000 /* initialize problem */
1001 (*problem)->firstrun = TRUE;
1002 SCIP_CALL( SCIPnlpiOracleCreate(scip, &(*problem)->oracle) );
1003 SCIP_CALL( SCIPnlpiOracleSetProblemName(scip, (*problem)->oracle, name) );
1004
1005 /* allocate memory for Worhp data */
1006 SCIP_CALL( SCIPallocBlockMemory(scip, &(*problem)->opt) );
1007 SCIP_CALL( SCIPallocBlockMemory(scip, &(*problem)->wsp) );
1008 SCIP_CALL( SCIPallocBlockMemory(scip, &(*problem)->par) );
1009 SCIP_CALL( SCIPallocBlockMemory(scip, &(*problem)->cnt) );
1010 WorhpPreInit((*problem)->opt, (*problem)->wsp, (*problem)->par, (*problem)->cnt);
1011
1012 /* create random number generator */
1013 SCIP_CALL( SCIPcreateRandom(scip, &(*problem)->randnumgen, DEFAULT_RANDSEED, TRUE) );
1014
1015 return SCIP_OKAY;
1016} /*lint !e715*/
1017
1018/** free a problem instance */
1019static
1020SCIP_DECL_NLPIFREEPROBLEM(nlpiFreeProblemWorhp)
1021{
1022 assert(nlpi != NULL);
1023 assert(problem != NULL);
1024 assert(*problem != NULL);
1025
1026 if( (*problem)->opt != NULL )
1027 {
1028 /* free memory for last solution information */
1029 invalidateSolution(scip, *problem);
1030
1031 assert((*problem)->wsp != NULL);
1032 assert((*problem)->par != NULL);
1033 assert((*problem)->cnt != NULL);
1034
1035 /* free Worhp data */
1036 SCIP_CALL( freeWorhp(*problem) );
1037 SCIPfreeBlockMemory(scip, &(*problem)->cnt);
1038 SCIPfreeBlockMemory(scip, &(*problem)->par);
1039 SCIPfreeBlockMemory(scip, &(*problem)->wsp);
1040 SCIPfreeBlockMemory(scip, &(*problem)->opt);
1041 }
1042
1043 if( (*problem)->oracle != NULL )
1044 {
1045 SCIP_CALL( SCIPnlpiOracleFree(scip, &(*problem)->oracle) );
1046 }
1047
1048 SCIPfreeRandom(scip, &(*problem)->randnumgen);
1049 SCIPfreeMemoryArrayNull(scip, &(*problem)->initguess);
1050 SCIPfreeBlockMemory(scip, problem);
1051 *problem = NULL;
1052
1053 return SCIP_OKAY;
1054} /*lint !e715*/
1055
1056/** add variables */
1057static
1058SCIP_DECL_NLPIADDVARS( nlpiAddVarsWorhp )
1059{
1060 assert(nlpi != NULL);
1061 assert(problem != NULL);
1062 assert(problem->oracle != NULL);
1063
1064 SCIP_CALL( SCIPnlpiOracleAddVars(scip, problem->oracle, nvars, lbs, ubs, varnames) );
1065
1066 SCIPfreeMemoryArrayNull(scip, &problem->initguess);
1067 invalidateSolution(scip, problem);
1068 problem->firstrun = TRUE;
1069
1070 return SCIP_OKAY; /*lint !e527*/
1071} /*lint !e715*/
1072
1073
1074/** add constraints */
1075static
1076SCIP_DECL_NLPIADDCONSTRAINTS(nlpiAddConstraintsWorhp)
1077{
1078 assert(nlpi != NULL);
1079 assert(problem != NULL);
1080 assert(problem->oracle != NULL);
1081
1083 nconss, lhss, rhss,
1084 nlininds, lininds, linvals,
1085 exprs, names) );
1086
1087 invalidateSolution(scip, problem);
1088 problem->firstrun = TRUE;
1089
1090 return SCIP_OKAY; /*lint !e527*/
1091} /*lint !e715*/
1092
1093/** sets or overwrites objective, a minimization problem is expected */
1094static
1095SCIP_DECL_NLPISETOBJECTIVE(nlpiSetObjectiveWorhp)
1096{
1097 assert(nlpi != NULL);
1098 assert(problem != NULL);
1099 assert(problem->oracle != NULL);
1100
1101 /* We pass the objective gradient in dense form to WORHP, so if the sparsity of that gradient changes, we do not need
1102 * to reset WORHP (firstrun=TRUE). However, if the sparsity of the Hessian matrix of the objective changes, then the
1103 * sparsity pattern of the Hessian of the Lagrangian may change. Thus, reset Worhp if the objective was and/or
1104 * becomes nonlinear, but leave firstrun untouched if it was and stays linear.
1105 */
1106 if( expr != NULL || SCIPnlpiOracleIsConstraintNonlinear(problem->oracle, -1) )
1107 problem->firstrun = TRUE;
1108
1109 SCIP_CALL( SCIPnlpiOracleSetObjective(scip, problem->oracle,
1110 constant, nlins, lininds, linvals, expr) );
1111
1112 invalidateSolution(scip, problem);
1113
1114 return SCIP_OKAY; /*lint !e527*/
1115} /*lint !e715*/
1116
1117/** change variable bounds */
1118static
1119SCIP_DECL_NLPICHGVARBOUNDS(nlpiChgVarBoundsWorhp)
1120{
1121#ifdef SCIP_DISABLED_CODE
1122 const SCIP_Real* oldlbs = SCIPnlpiOracleGetVarLbs(problem->oracle);
1123 const SCIP_Real* oldubs = SCIPnlpiOracleGetVarUbs(problem->oracle);
1124 int i;
1125#endif
1126
1127 assert(nlpi != NULL);
1128 assert(problem != NULL);
1129 assert(problem->oracle != NULL);
1130
1131#ifdef SCIP_DISABLED_CODE
1132 /* TODO check WORHP version here */
1133 /* So far, Worhp can not handle fixed variables (and fixed variables that have been unfixed) when applying a
1134 * restart. The following code needs to be removed when this has changed.
1135 */
1136 for( i = 0; i < nvars; ++i )
1137 {
1138 int index = indices[i];
1139 SCIPdebugMsg(scip, "change bounds of %d from [%g,%g] -> [%g,%g]\n", index, oldlbs[index], oldubs[index],
1140 lbs[i], ubs[i]);
1141
1142 if( REALABS(lbs[i] - ubs[i]) <= problem->feastol )
1143 problem->firstrun = TRUE;
1144 else
1145 if( REALABS(oldlbs[index] - oldubs[index]) <= problem->feastol )
1146 problem->firstrun = TRUE;
1147 }
1148#endif
1149
1150 SCIP_CALL( SCIPnlpiOracleChgVarBounds(scip, problem->oracle, nvars, indices, lbs, ubs) );
1151
1152 invalidateSolution(scip, problem);
1153
1154 return SCIP_OKAY; /*lint !e527*/
1155} /*lint !e715*/
1156
1157/** change constraint bounds */
1158static
1159SCIP_DECL_NLPICHGCONSSIDES(nlpiChgConsSidesWorhp)
1160{
1161 assert(nlpi != NULL);
1162 assert(problem != NULL);
1163 assert(problem->oracle != NULL);
1164
1165#ifdef SCIP_DEBUG
1166 {
1167 SCIP_Real oldlhs;
1168 SCIP_Real oldrhs;
1169 int i;
1170
1171 for( i = 0; i < nconss; ++i )
1172 {
1173 int index = indices[i];
1174 oldlhs = SCIPnlpiOracleGetConstraintLhs(problem->oracle, index);
1175 oldrhs = SCIPnlpiOracleGetConstraintRhs(problem->oracle, index);
1176 SCIPdebugMsg(scip, "change constraint side of %d from [%g,%g] -> [%g,%g]\n", index, oldlhs, oldrhs, lhss[i], rhss[i]);
1177 }
1178 }
1179#endif
1180
1181 SCIP_CALL( SCIPnlpiOracleChgConsSides(scip, problem->oracle, nconss, indices, lhss, rhss) );
1182
1183 invalidateSolution(scip, problem);
1184
1185 return SCIP_OKAY; /*lint !e527*/
1186} /*lint !e715*/
1187
1188/** delete a set of variables */
1189static
1190SCIP_DECL_NLPIDELVARSET(nlpiDelVarSetWorhp)
1191{
1192 assert(nlpi != NULL);
1193 assert(problem != NULL);
1194 assert(problem->oracle != NULL);
1195
1196 SCIP_CALL( SCIPnlpiOracleDelVarSet(scip, problem->oracle, dstats) );
1197
1198 SCIPfreeMemoryArrayNull(scip, &problem->initguess); /* @TODO keep initguess for remaining variables */
1199
1200 invalidateSolution(scip, problem);
1201 problem->firstrun = TRUE;
1202
1203 return SCIP_OKAY; /*lint !e527*/
1204} /*lint !e715*/
1205
1206/** delete a set of constraints */
1207static
1208SCIP_DECL_NLPIDELCONSSET(nlpiDelConstraintSetWorhp)
1209{
1210 assert(nlpi != NULL);
1211 assert(problem != NULL);
1212 assert(problem->oracle != NULL);
1213
1214 SCIP_CALL( SCIPnlpiOracleDelConsSet(scip, problem->oracle, dstats) );
1215
1216 invalidateSolution(scip, problem);
1217 problem->firstrun = TRUE;
1218
1219 return SCIP_OKAY; /*lint !e527*/
1220} /*lint !e715*/
1221
1222/** changes (or adds) linear coefficients in a constraint or objective */
1223static
1224SCIP_DECL_NLPICHGLINEARCOEFS(nlpiChgLinearCoefsWorhp)
1225{
1226 assert(nlpi != NULL);
1227 assert(problem != NULL);
1228 assert(problem->oracle != NULL);
1229
1230 SCIP_CALL( SCIPnlpiOracleChgLinearCoefs(scip, problem->oracle, idx, nvals, varidxs, vals) );
1231
1232 invalidateSolution(scip, problem);
1233 problem->firstrun = TRUE;
1234
1235 return SCIP_OKAY; /*lint !e527*/
1236} /*lint !e715*/
1237
1238/** replaces the expression of a constraint or objective */
1239static
1240SCIP_DECL_NLPICHGEXPR(nlpiChgExprWorhp)
1241{
1242 assert(nlpi != NULL);
1243 assert(problem != NULL);
1244 assert(problem->oracle != NULL);
1245
1246 SCIP_CALL( SCIPnlpiOracleChgExpr(scip, problem->oracle, idxcons, expr) );
1247
1248 invalidateSolution(scip, problem);
1249 problem->firstrun = TRUE;
1250
1251 return SCIP_OKAY; /*lint !e527*/
1252} /*lint !e715*/
1253
1254/** change the constant offset in the objective */
1255static
1256SCIP_DECL_NLPICHGOBJCONSTANT(nlpiChgObjConstantWorhp)
1257{
1258 assert(nlpi != NULL);
1259 assert(problem != NULL);
1260 assert(problem->oracle != NULL);
1261
1262 SCIP_CALL( SCIPnlpiOracleChgObjConstant(scip, problem->oracle, objconstant) );
1263
1264 return SCIP_OKAY; /*lint !e527*/
1265} /*lint !e715*/
1266
1267/** sets initial guess for primal variables */
1268static
1269SCIP_DECL_NLPISETINITIALGUESS(nlpiSetInitialGuessWorhp)
1270{
1271 assert(nlpi != NULL);
1272 assert(problem != NULL);
1273 assert(problem->oracle != NULL);
1274
1275 if( primalvalues != NULL )
1276 {
1277 if( !problem->initguess )
1278 {
1279 SCIP_CALL( SCIPduplicateMemoryArray(scip, &problem->initguess, primalvalues, SCIPnlpiOracleGetNVars(problem->oracle)) );
1280 }
1281 else
1282 {
1283 BMScopyMemoryArray(problem->initguess, primalvalues, SCIPnlpiOracleGetNVars(problem->oracle));
1284 }
1285 }
1286 else
1287 {
1288 SCIPfreeMemoryArrayNull(scip, &problem->initguess);
1289 }
1290
1291 return SCIP_OKAY;
1292} /*lint !e715*/
1293
1294/** tries to solve NLP */
1295static
1296SCIP_DECL_NLPISOLVE(nlpiSolveWorhp)
1297{
1298 Workspace* wsp = problem->wsp;
1299 Control* cnt = problem->cnt;
1300 OptVar* opt = problem->opt;
1301 Params* par = problem->par;
1302 int status;
1303 int i;
1304
1305 SCIPdebugMsg(scip, "solve with parameters " SCIP_NLPPARAM_PRINT(param));
1306
1307 SCIP_CALL( SCIPnlpiOracleResetEvalTime(scip, problem->oracle) );
1308
1309 if( param.timelimit == 0.0 )
1310 {
1311 /* there is nothing we can do if we are not given any time */
1312 problem->lastniter = 0;
1313 problem->lasttime = 0.0;
1314 problem->lasttermstat = SCIP_NLPTERMSTAT_TIMELIMIT;
1315 problem->lastsolstat = SCIP_NLPSOLSTAT_UNKNOWN;
1316
1317 return SCIP_OKAY;
1318 }
1319
1320 problem->lastniter = -1;
1321 problem->lasttime = -1.0;
1322
1323 if( param.verblevel == 0 )
1324 {
1325 SetWorhpPrint(noprint);
1326 }
1327 else
1328 {
1329 /* TODO this should go to a function that prints to the SCIP message handler
1330 * all this doesn't seem threadsafe at all!
1331 */
1332 SetWorhpPrint(WorhpDefaultPrintFunction);
1333 }
1334
1335 /* initialize Worhp data if necessary */
1336 if( problem->firstrun )
1337 {
1338 SCIP_CALL( freeWorhp(problem) );
1339 SCIP_CALL( initWorhp(scip, nlpi, problem) );
1340 problem->firstrun = FALSE;
1341 }
1342 else
1343 {
1344 SCIP_CALL( updateWorhp(problem) );
1345 }
1346
1347 /* set parameters */
1348 InitParams(&status, par);
1349
1350 if( status != OK )
1351 return SCIP_INVALIDCALL;
1352
1353 SCIP_CALL( handleNlpParam(scip, nlpi, par, param) );
1354
1355#ifdef SCIP_DEBUG
1356 SCIP_CALL( SCIPnlpiOraclePrintProblem(scip, problem->oracle, NULL) );
1357#endif
1358
1359 /* set initial guess (if available) */
1360 if( problem->initguess != NULL )
1361 {
1362 BMScopyMemoryArray(problem->opt->X, problem->initguess, problem->opt->n);
1363 }
1364 else
1365 {
1366 SCIP_Real lb, ub;
1367
1368 assert(problem->randnumgen != NULL);
1369
1370 SCIPdebugMsg(scip, "Worhp started without initial primal values; make up starting guess by projecting 0 onto variable bounds\n");
1371
1372 for( i = 0; i < problem->opt->n; ++i )
1373 {
1374 lb = SCIPnlpiOracleGetVarLbs(problem->oracle)[i];
1375 ub = SCIPnlpiOracleGetVarUbs(problem->oracle)[i];
1376
1377 if( lb > 0.0 )
1378 problem->opt->X[i] = SCIPrandomGetReal(problem->randnumgen, lb, lb + MAXPERTURB*MIN(1.0, ub-lb));
1379 else if( ub < 0.0 )
1380 problem->opt->X[i] = SCIPrandomGetReal(problem->randnumgen, ub - MAXPERTURB*MIN(1.0, ub-lb), ub);
1381 else
1382 problem->opt->X[i] = SCIPrandomGetReal(problem->randnumgen,
1383 MAX(lb, -MAXPERTURB*MIN(1.0, ub-lb)), MIN(ub, MAXPERTURB*MIN(1.0, ub-lb)));
1384 }
1385 }
1386
1387#ifdef SCIP_DEBUG
1388 SCIPdebugMsg(scip, "start point:\n");
1389 for( i = 0; i < problem->opt->n; ++i )
1390 {
1391 SCIPdebugMsg(scip, "x[%d] = %f\n", i, problem->opt->X[i]);
1392 }
1393#endif
1394
1395 /*
1396 * Worhp Reverse Communication loop.
1397 * In every iteration poll GetUserAction for the requested action, i.e. one
1398 * of {callWorhp, iterOutput, evalF, evalG, evalDF, evalDG, evalHM, fidif}.
1399 *
1400 * Make sure to reset the requested user action afterwards by calling
1401 * DoneUserAction, except for 'callWorhp' and 'fidif'.
1402 */
1403 while( cnt->status < TerminateSuccess && cnt->status > TerminateError && !SCIPisSolveInterrupted(scip) )
1404 {
1405 /*
1406 * Worhp's main routine.
1407 * Do not manually reset callWorhp, this is only done by the FD routines.
1408 */
1409 if( GetUserAction(cnt, callWorhp) )
1410 {
1411 Worhp(opt, wsp, par, cnt);
1412 /* No DoneUserAction! */
1413 }
1414
1415 /*
1416 * Show iteration output.
1417 * The call to IterationOutput() may be replaced by user-defined code.
1418 */
1419 if( GetUserAction(cnt, iterOutput) )
1420 {
1421 IterationOutput(opt, wsp, par, cnt);
1422 DoneUserAction(cnt, iterOutput);
1423 }
1424
1425 /*
1426 * Evaluate the objective function.
1427 * The call to UserF may be replaced by user-defined code.
1428 */
1429 if( GetUserAction(cnt, evalF) )
1430 {
1431 if( userF(scip, problem) != SCIP_OKAY )
1432 break;
1433 DoneUserAction(cnt, evalF);
1434 }
1435
1436 /*
1437 * Evaluate the constraints.
1438 * The call to UserG may be replaced by user-defined code.
1439 */
1440 if( GetUserAction(cnt, evalG) )
1441 {
1442 if( userG(scip, problem) != SCIP_OKAY )
1443 break;
1444 DoneUserAction(cnt, evalG);
1445 }
1446
1447 /*
1448 * Evaluate the gradient of the objective function.
1449 * The call to UserDF may be replaced by user-defined code.
1450 */
1451 if( GetUserAction(cnt, evalDF) )
1452 {
1453 if( userDF(scip, problem) != SCIP_OKAY )
1454 break;
1455 DoneUserAction(cnt, evalDF);
1456 }
1457
1458 /*
1459 * Evaluate the Jacobian of the constraints.
1460 * The call to UserDG may be replaced by user-defined code.
1461 */
1462 if( GetUserAction(cnt, evalDG) )
1463 {
1464 if( userDG(scip, problem) != SCIP_OKAY )
1465 break;
1466 DoneUserAction(cnt, evalDG);
1467 }
1468
1469 /*
1470 * Evaluate the Hessian matrix of the Lagrange function (L = f + mu*g)
1471 * The call to UserHM may be replaced by user-defined code.
1472 */
1473 if( GetUserAction(cnt, evalHM) )
1474 {
1475 if( userHM(scip, problem) != SCIP_OKAY)
1476 break;
1477 DoneUserAction(cnt, evalHM);
1478 }
1479
1480 /*
1481 * Use finite differences with RC to determine derivatives
1482 * Do not reset fidif, this is done by the FD routine.
1483 */
1484 if( GetUserAction(cnt, fidif) )
1485 {
1486 WorhpFidif(opt, wsp, par, cnt);
1487 /* No DoneUserAction! */
1488 }
1489 }
1490
1491 /* interpret Worhp result */
1493 {
1494 problem->lastsolstat = SCIP_NLPSOLSTAT_UNKNOWN;
1495 problem->lasttermstat = SCIP_NLPTERMSTAT_INTERRUPT;
1496 }
1497 else if( cnt->status < TerminateSuccess && cnt->status > TerminateError )
1498 {
1499 SCIPwarningMessage(scip, "Worhp failed because of an invalid function evaluation!\n");
1500 problem->lastsolstat = SCIP_NLPSOLSTAT_UNKNOWN;
1501 problem->lasttermstat = SCIP_NLPTERMSTAT_NUMERICERROR;
1502 }
1503 else
1504 {
1505 SCIP_CALL( evaluateWorhpRun(scip, problem) );
1506 }
1507
1508 /* prints a status message with information about the current solver status */
1509 StatusMsg(opt, wsp, par, cnt);
1510
1511 /* store statistics */
1512 problem->lastniter = wsp->MajorIter;
1513 problem->lasttime = GetTimerCont(&cnt->Timer);
1514
1515 return SCIP_OKAY;
1516} /*lint !e715*/
1517
1518/** gives solution status */
1519static
1520SCIP_DECL_NLPIGETSOLSTAT(nlpiGetSolstatWorhp)
1521{
1522 assert(nlpi != NULL);
1523 assert(problem != NULL);
1524
1525 return problem->lastsolstat;
1526} /*lint !e715*/
1527
1528/** gives termination reason */
1529static
1530SCIP_DECL_NLPIGETTERMSTAT(nlpiGetTermstatWorhp)
1531{
1532 assert(nlpi != NULL);
1533 assert(problem != NULL);
1534
1535 return problem->lasttermstat;
1536} /*lint !e715*/
1537
1538/** gives primal and dual solution values */
1539static
1540SCIP_DECL_NLPIGETSOLUTION( nlpiGetSolutionWorhp )
1541{
1542 assert(problem != NULL);
1543
1544 if( primalvalues != NULL )
1545 *primalvalues = problem->lastprimal;
1546
1547 if( consdualvalues != NULL )
1548 *consdualvalues = problem->lastdualcons;
1549
1550 if( varlbdualvalues != NULL )
1551 *varlbdualvalues = problem->lastduallb;
1552
1553 if( varubdualvalues != NULL )
1554 *varubdualvalues = problem->lastdualub;
1555
1556 if( objval != NULL )
1557 {
1558 if( problem->lastprimal != NULL )
1559 {
1560 /* TODO store last solution value instead of reevaluating the objective function */
1561 SCIP_CALL( SCIPnlpiOracleEvalObjectiveValue(scip, problem->oracle, problem->lastprimal, objval) );
1562 }
1563 else
1564 *objval = SCIP_INVALID;
1565 }
1566
1567 return SCIP_OKAY;
1568} /*lint !e715*/
1569
1570/** gives solve statistics */
1571static
1572SCIP_DECL_NLPIGETSTATISTICS(nlpiGetStatisticsWorhp)
1573{
1574 assert(nlpi != NULL);
1575 assert(problem != NULL);
1576 assert(statistics != NULL);
1577
1578 statistics->niterations = problem->lastniter;
1579 statistics->totaltime = problem->lasttime;
1580 statistics->evaltime = SCIPnlpiOracleGetEvalTime(scip, problem->oracle);
1581 statistics->consviol = problem->wsp->FeasOrigMax;
1582 statistics->boundviol = 0.0;
1583
1584 return SCIP_OKAY;
1585} /*lint !e715*/
1586
1587/*
1588 * NLP solver interface specific interface methods
1589 */
1590
1591/** create solver interface for Worhp solver and includes it into SCIP, if Worhp is available */
1593 SCIP* scip, /**< SCIP data structure */
1594 SCIP_Bool useip /**< TRUE for using Interior Point, FALSE for SQP */
1595 )
1596{
1597 SCIP_NLPIDATA* nlpidata;
1598 char name[SCIP_MAXSTRLEN];
1599 int priority;
1600
1601 /* create Worhp solver interface data */
1602 SCIP_CALL( SCIPallocBlockMemory(scip, &nlpidata) );
1603 nlpidata->useip = useip;
1604
1605 /* disable Worhp's keyboard handler, not useful here and not threadsafe */
1606 (void) setenv("WORHP_DISABLE_KEYBOARD_HANDLER", "1", 0);
1607
1608#if DEFAULT_VERBLEVEL == 0
1609 /* disable Worhp output by default */
1610 SetWorhpPrint(noprint);
1611#endif
1612
1613 /* checks the version of the library and header files */
1614 CHECK_WORHP_VERSION
1615
1616 /* create solver interface */
1617 if( useip )
1618 {
1619 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "worhp-ip");
1620 priority = NLPI_PRIORITY_IP;
1621 }
1622 else
1623 {
1624 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "worhp-sqp");
1625 priority = NLPI_PRIORITY_SQP;
1626 }
1627
1629 name, NLPI_DESC, priority,
1630 nlpiCopyWorhp, nlpiFreeWorhp, NULL,
1631 nlpiCreateProblemWorhp, nlpiFreeProblemWorhp, NULL,
1632 nlpiAddVarsWorhp, nlpiAddConstraintsWorhp, nlpiSetObjectiveWorhp,
1633 nlpiChgVarBoundsWorhp, nlpiChgConsSidesWorhp, nlpiDelVarSetWorhp, nlpiDelConstraintSetWorhp,
1634 nlpiChgLinearCoefsWorhp, nlpiChgExprWorhp,
1635 nlpiChgObjConstantWorhp, nlpiSetInitialGuessWorhp, nlpiSolveWorhp, nlpiGetSolstatWorhp, nlpiGetTermstatWorhp,
1636 nlpiGetSolutionWorhp, nlpiGetStatisticsWorhp,
1637 nlpidata) );
1638
1639 if( useip ) /* TODO lookup whether Worhp info has already been included instead of assuming that worhp-up will be included */
1640 {
1642 }
1643
1644 return SCIP_OKAY;
1645}
1646
1647/** gets string that identifies Worhp (version number) */
1649 void
1650 )
1651{
1652#ifdef WORHP_VERSION
1653 return "WORHP " WORHP_VERSION;
1654#else
1655 static char solvername[20];
1656 sprintf(solvername, "WORHP %d.%d." WORHP_PATCH, WORHP_MAJOR, WORHP_MINOR);
1657 return solvername;
1658#endif
1659}
1660
1661/** gets string that describes Worhp (version number) */
1663 void
1664 )
1665{
1666 return "Nonlinear programming solver developed at Research Institute Steinbeis (www.worhp.de)";
1667}
1668
1669/** returns whether Worhp is available, i.e., whether it has been linked in */
1671 void
1672 )
1673{
1674 return TRUE;
1675}
#define NULL
Definition: def.h:248
#define SCIP_MAXSTRLEN
Definition: def.h:269
#define SCIP_REAL_MAX
Definition: def.h:158
#define SCIP_INVALID
Definition: def.h:178
#define SCIP_Bool
Definition: def.h:91
#define MIN(x, y)
Definition: def.h:224
#define SCIP_Real
Definition: def.h:156
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define MAX(x, y)
Definition: def.h:220
#define REALABS(x)
Definition: def.h:182
#define SCIP_CALL(x)
Definition: def.h:355
methods to interpret (evaluate) an expression "fast"
#define SCIPdebugMsg
Definition: scip_message.h:78
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
SCIP_RETCODE SCIPincludeNlpSolverWorhp(SCIP *scip, SCIP_Bool useip)
Definition: nlpi_worhp.c:1592
SCIP_RETCODE SCIPnlpiOracleEvalObjectiveValue(SCIP *scip, SCIP_NLPIORACLE *oracle, const SCIP_Real *x, SCIP_Real *objval)
Definition: nlpioracle.c:2124
SCIP_RETCODE SCIPnlpiOracleChgLinearCoefs(SCIP *scip, SCIP_NLPIORACLE *oracle, int considx, int nentries, const int *varidxs, const SCIP_Real *newcoefs)
Definition: nlpioracle.c:1774
SCIP_RETCODE SCIPnlpiOracleGetJacobianRowSparsity(SCIP *scip, SCIP_NLPIORACLE *oracle, const int **rowoffsets, const int **cols, const SCIP_Bool **colnlflags, int *nnlnz)
Definition: nlpioracle.c:2264
SCIP_RETCODE SCIPnlpiOracleGetHessianLagSparsity(SCIP *scip, SCIP_NLPIORACLE *oracle, const int **offset, const int **allnz, SCIP_Bool colwise)
Definition: nlpioracle.c:2670
SCIP_RETCODE SCIPnlpiOracleChgVarBounds(SCIP *scip, SCIP_NLPIORACLE *oracle, int nvars, const int *indices, const SCIP_Real *lbs, const SCIP_Real *ubs)
Definition: nlpioracle.c:1474
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:1384
SCIP_Bool SCIPnlpiOracleIsConstraintNonlinear(SCIP_NLPIORACLE *oracle, int considx)
Definition: nlpioracle.c:2084
SCIP_RETCODE SCIPnlpiOracleDelVarSet(SCIP *scip, SCIP_NLPIORACLE *oracle, int *delstats)
Definition: nlpioracle.c:1546
SCIP_RETCODE SCIPnlpiOracleEvalConstraintValues(SCIP *scip, SCIP_NLPIORACLE *oracle, const SCIP_Real *x, SCIP_Real *convals)
Definition: nlpioracle.c:2173
SCIP_RETCODE SCIPnlpiOracleCreate(SCIP *scip, SCIP_NLPIORACLE **oracle)
Definition: nlpioracle.c:1200
SCIP_RETCODE SCIPnlpiOracleEvalObjectiveGradient(SCIP *scip, SCIP_NLPIORACLE *oracle, const SCIP_Real *x, SCIP_Bool isnewx, SCIP_Real *objval, SCIP_Real *objgrad)
Definition: nlpioracle.c:2205
SCIP_RETCODE SCIPnlpiOracleResetEvalTime(SCIP *scip, SCIP_NLPIORACLE *oracle)
Definition: nlpioracle.c:2821
SCIP_RETCODE SCIPnlpiOraclePrintProblem(SCIP *scip, SCIP_NLPIORACLE *oracle, FILE *file)
Definition: nlpioracle.c:2848
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:1445
SCIP_Real SCIPnlpiOracleGetConstraintRhs(SCIP_NLPIORACLE *oracle, int considx)
Definition: nlpioracle.c:2038
SCIP_Real SCIPnlpiOracleGetEvalTime(SCIP *scip, SCIP_NLPIORACLE *oracle)
Definition: nlpioracle.c:2837
SCIP_RETCODE SCIPnlpiOracleChgConsSides(SCIP *scip, SCIP_NLPIORACLE *oracle, int nconss, const int *indices, const SCIP_Real *lhss, const SCIP_Real *rhss)
Definition: nlpioracle.c:1511
SCIP_Real SCIPnlpiOracleGetConstraintLhs(SCIP_NLPIORACLE *oracle, int considx)
Definition: nlpioracle.c:2025
SCIP_RETCODE SCIPnlpiOracleAddVars(SCIP *scip, SCIP_NLPIORACLE *oracle, int nvars, const SCIP_Real *lbs, const SCIP_Real *ubs, const char **varnames)
Definition: nlpioracle.c:1298
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, SCIP_Bool colwise)
Definition: nlpioracle.c:2770
int SCIPnlpiOracleGetNVars(SCIP_NLPIORACLE *oracle)
Definition: nlpioracle.c:1933
int SCIPnlpiOracleGetNConstraints(SCIP_NLPIORACLE *oracle)
Definition: nlpioracle.c:1943
SCIP_RETCODE SCIPnlpiOracleEvalJacobian(SCIP *scip, SCIP_NLPIORACLE *oracle, const SCIP_Real *x, SCIP_Bool isnewx, SCIP_Real *convals, SCIP_Real *jacobi)
Definition: nlpioracle.c:2543
SCIP_RETCODE SCIPnlpiOracleDelConsSet(SCIP *scip, SCIP_NLPIORACLE *oracle, int *delstats)
Definition: nlpioracle.c:1688
SCIP_RETCODE SCIPnlpiOracleSetProblemName(SCIP *scip, SCIP_NLPIORACLE *oracle, const char *name)
Definition: nlpioracle.c:1262
SCIP_RETCODE SCIPnlpiOracleChgObjConstant(SCIP *scip, SCIP_NLPIORACLE *oracle, SCIP_Real objconstant)
Definition: nlpioracle.c:1916
const SCIP_Real * SCIPnlpiOracleGetVarLbs(SCIP_NLPIORACLE *oracle)
Definition: nlpioracle.c:1953
const SCIP_Real * SCIPnlpiOracleGetVarUbs(SCIP_NLPIORACLE *oracle)
Definition: nlpioracle.c:1963
SCIP_RETCODE SCIPnlpiOracleFree(SCIP *scip, SCIP_NLPIORACLE **oracle)
Definition: nlpioracle.c:1230
SCIP_RETCODE SCIPnlpiOracleChgExpr(SCIP *scip, SCIP_NLPIORACLE *oracle, int considx, SCIP_EXPR *expr)
Definition: nlpioracle.c:1870
const char * SCIPgetSolverNameWorhp(void)
Definition: nlpi_worhp.c:1648
const char * SCIPgetSolverDescWorhp(void)
Definition: nlpi_worhp.c:1662
SCIP_Bool SCIPisWorhpAvailableWorhp(void)
Definition: nlpi_worhp.c:1670
SCIP_RETCODE SCIPincludeExternalCodeInformation(SCIP *scip, const char *name, const char *description)
Definition: scip_general.c:769
#define SCIPfreeMemoryArrayNull(scip, ptr)
Definition: scip_mem.h:81
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:110
#define SCIPallocClearBlockMemory(scip, ptr)
Definition: scip_mem.h:91
#define SCIPduplicateMemoryArray(scip, ptr, source, num)
Definition: scip_mem.h:76
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:93
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:108
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip_mem.h:111
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip_mem.h:89
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip_mem.h:105
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:113
SCIP_NLPIDATA * SCIPnlpiGetData(SCIP_NLPI *nlpi)
Definition: nlpi.c:712
SCIP_Bool SCIPisSolveInterrupted(SCIP *scip)
Definition: scip_solve.c:3580
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
void SCIPfreeRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen)
SCIP_Real SCIPrandomGetReal(SCIP_RANDNUMGEN *randnumgen, SCIP_Real minrandval, SCIP_Real maxrandval)
Definition: misc.c:10245
SCIP_RETCODE SCIPcreateRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen, unsigned int initialseed, SCIP_Bool useglobalseed)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10827
methods for catching the user CTRL-C interrupt
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:134
static SCIP_RETCODE userG(SCIP *scip, SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:457
static void noprint(int mode, const char s[])
Definition: nlpi_worhp.c:634
static SCIP_DECL_NLPICHGLINEARCOEFS(nlpiChgLinearCoefsWorhp)
Definition: nlpi_worhp.c:1224
static SCIP_DECL_NLPIADDVARS(nlpiAddVarsWorhp)
Definition: nlpi_worhp.c:1058
static SCIP_RETCODE userDG(SCIP *scip, SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:533
#define MAXPERTURB
Definition: nlpi_worhp.c:68
static SCIP_DECL_NLPICREATEPROBLEM(nlpiCreateProblemWorhp)
Definition: nlpi_worhp.c:992
static SCIP_DECL_NLPIDELVARSET(nlpiDelVarSetWorhp)
Definition: nlpi_worhp.c:1190
static SCIP_RETCODE userDF(SCIP *scip, SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:489
static SCIP_RETCODE userHM(SCIP *scip, SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:578
static SCIP_DECL_NLPISOLVE(nlpiSolveWorhp)
Definition: nlpi_worhp.c:1296
static SCIP_DECL_NLPISETINITIALGUESS(nlpiSetInitialGuessWorhp)
Definition: nlpi_worhp.c:1269
static SCIP_DECL_NLPICOPY(nlpiCopyWorhp)
Definition: nlpi_worhp.c:962
static SCIP_DECL_NLPIGETTERMSTAT(nlpiGetTermstatWorhp)
Definition: nlpi_worhp.c:1530
#define NLPI_PRIORITY_SQP
Definition: nlpi_worhp.c:62
static SCIP_DECL_NLPIFREEPROBLEM(nlpiFreeProblemWorhp)
Definition: nlpi_worhp.c:1020
static SCIP_DECL_NLPIADDCONSTRAINTS(nlpiAddConstraintsWorhp)
Definition: nlpi_worhp.c:1076
static SCIP_RETCODE userF(SCIP *scip, SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:424
static SCIP_RETCODE initWorhp(SCIP *scip, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:643
static SCIP_DECL_NLPISETOBJECTIVE(nlpiSetObjectiveWorhp)
Definition: nlpi_worhp.c:1095
static SCIP_RETCODE updateWorhp(SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:846
static SCIP_DECL_NLPICHGVARBOUNDS(nlpiChgVarBoundsWorhp)
Definition: nlpi_worhp.c:1119
static void invalidateSolution(SCIP *scip, SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:114
static SCIP_DECL_NLPICHGEXPR(nlpiChgExprWorhp)
Definition: nlpi_worhp.c:1240
static SCIP_DECL_NLPICHGOBJCONSTANT(nlpiChgObjConstantWorhp)
Definition: nlpi_worhp.c:1256
#define NLPI_PRIORITY_IP
Definition: nlpi_worhp.c:61
#define DEFAULT_RANDSEED
Definition: nlpi_worhp.c:66
static SCIP_DECL_NLPICHGCONSSIDES(nlpiChgConsSidesWorhp)
Definition: nlpi_worhp.c:1159
static SCIP_DECL_NLPIDELCONSSET(nlpiDelConstraintSetWorhp)
Definition: nlpi_worhp.c:1208
static SCIP_RETCODE freeWorhp(SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:886
static SCIP_DECL_NLPIFREE(nlpiFreeWorhp)
Definition: nlpi_worhp.c:978
static SCIP_DECL_NLPIGETSOLUTION(nlpiGetSolutionWorhp)
Definition: nlpi_worhp.c:1540
static SCIP_DECL_NLPIGETSOLSTAT(nlpiGetSolstatWorhp)
Definition: nlpi_worhp.c:1520
static SCIP_RETCODE handleNlpParam(SCIP *scip, SCIP_NLPI *nlpi, Params *par, const SCIP_NLPPARAM nlpparam)
Definition: nlpi_worhp.c:904
#define DEFAULT_SCALEDKKT
Definition: nlpi_worhp.c:65
#define NLPI_DESC
Definition: nlpi_worhp.c:60
static SCIP_RETCODE evaluateWorhpRun(SCIP *scip, SCIP_NLPIPROBLEM *problem)
Definition: nlpi_worhp.c:136
static SCIP_DECL_NLPIGETSTATISTICS(nlpiGetStatisticsWorhp)
Definition: nlpi_worhp.c:1572
Worhp NLP interface.
methods to store an NLP and request function, gradient, and Hessian values
public methods for message output
#define SCIPerrorMessage
Definition: pub_message.h:64
#define SCIPdebugPrintf
Definition: pub_message.h:99
public data structures and miscellaneous methods
general public methods
public methods for memory management
public methods for message handling
public methods for NLPI solver interfaces
public methods for numerical tolerances
public methods for random numbers
public solving methods
SCIP_Real timelimit
Definition: type_nlpi.h:72
SCIP_Real feastol
Definition: type_nlpi.h:69
SCIP_Bool warmstart
Definition: type_nlpi.h:77
SCIP_Real opttol
Definition: type_nlpi.h:70
SCIP_NLPPARAM_FASTFAIL fastfail
Definition: type_nlpi.h:75
SCIP_Real lobjlimit
Definition: type_nlpi.h:68
unsigned short verblevel
Definition: type_nlpi.h:74
SCIP_Real * lastprimal
Definition: nlpi_conopt.c:90
SCIP_Real * lastduallb
Definition: nlpi_conopt.c:92
SCIP_Real * lastdualcons
Definition: nlpi_conopt.c:91
SCIP_Bool firstrun
Definition: nlpi_conopt.c:81
SCIP_NLPIORACLE * oracle
Definition: nlpi_conopt.c:78
SCIP_Real lasttime
Definition: nlpi_ipopt.cpp:200
SCIP_RANDNUMGEN * randnumgen
Definition: nlpi_conopt.c:79
Workspace * wsp
Definition: nlpi_worhp.c:103
Control * cnt
Definition: nlpi_worhp.c:105
SCIP_Real * lastdualub
Definition: nlpi_conopt.c:93
SCIP_NLPTERMSTAT lasttermstat
Definition: nlpi_worhp.c:84
SCIP_NLPSOLSTAT lastsolstat
Definition: nlpi_worhp.c:85
SCIP_Real * initguess
Definition: nlpi_conopt.c:82
#define SCIP_NLPPARAM_PRINT(param)
Definition: type_nlpi.h:142
enum SCIP_NlpSolStat SCIP_NLPSOLSTAT
Definition: type_nlpi.h:168
@ SCIP_NLPTERMSTAT_OKAY
Definition: type_nlpi.h:173
@ SCIP_NLPTERMSTAT_TIMELIMIT
Definition: type_nlpi.h:174
@ SCIP_NLPTERMSTAT_NUMERICERROR
Definition: type_nlpi.h:178
@ SCIP_NLPTERMSTAT_OTHER
Definition: type_nlpi.h:182
@ SCIP_NLPTERMSTAT_EVALERROR
Definition: type_nlpi.h:179
@ SCIP_NLPTERMSTAT_LICENSEERROR
Definition: type_nlpi.h:181
@ SCIP_NLPTERMSTAT_ITERLIMIT
Definition: type_nlpi.h:175
@ SCIP_NLPTERMSTAT_OUTOFMEMORY
Definition: type_nlpi.h:180
@ SCIP_NLPTERMSTAT_INTERRUPT
Definition: type_nlpi.h:177
@ SCIP_NLPSOLSTAT_UNBOUNDED
Definition: type_nlpi.h:165
@ SCIP_NLPSOLSTAT_GLOBINFEASIBLE
Definition: type_nlpi.h:164
@ SCIP_NLPSOLSTAT_LOCINFEASIBLE
Definition: type_nlpi.h:163
@ SCIP_NLPSOLSTAT_FEASIBLE
Definition: type_nlpi.h:162
@ SCIP_NLPSOLSTAT_LOCOPT
Definition: type_nlpi.h:161
@ SCIP_NLPSOLSTAT_UNKNOWN
Definition: type_nlpi.h:166
enum SCIP_NlpTermStat SCIP_NLPTERMSTAT
Definition: type_nlpi.h:184
struct SCIP_NlpiData SCIP_NLPIDATA
Definition: type_nlpi.h:52
@ SCIP_OKAY
Definition: type_retcode.h:42
@ SCIP_INVALIDCALL
Definition: type_retcode.h:51
@ SCIP_ERROR
Definition: type_retcode.h:43
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63