Scippy

SCIP

Solving Constraint Integer Programs

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