Scippy

SCIP

Solving Constraint Integer Programs

nlpi_conopt.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_conopt.c
26 * @ingroup DEFPLUGINS_NLPI
27 * @brief CONOPT NLP interface
28 * @author Ksenia Bestuzheva
29 *
30 * NLP interface for the CONOPT solver.
31 *
32 * This file can only be compiled if CONOPT is available.
33 * Otherwise, to resolve public functions, use nlpi_conopt_dummy.c.
34 */
35
36/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
37
38#include "scip/nlpi_conopt.h"
39#include "scip/nlpioracle.h"
40#include "scip/scip_mem.h"
41#include "scip/scip_numerics.h"
42#include "scip/scip_nlp.h"
43#include "scip/scip_nlpi.h"
45#include "scip/pub_misc.h"
46#include "scip/pub_message.h"
47#include "scip/type_clock.h"
48#include "scip/scip_general.h"
49
50#include "scip/scip_message.h"
51#include "scip/scip_timing.h"
52
53#include "conopt.h"
54
55#define NLPI_NAME "conopt" /**< short concise name of solver */
56#define NLPI_DESC "CONOPT interface" /**< description of solver */
57#define NLPI_PRIORITY 2000 /**< priority of NLP solver */
58
59#define DEFAULT_RANDSEED 107 /**< initial random seed */
60#define MAXPERTURB 0.01 /**< maximal perturbation of bounds in starting point heuristic */
61
62/*
63 * Data structures
64 */
65
66struct SCIP_NlpiData
67{
68 SCIP_CLOCK* solvetime; /**< clock for measuring solving time */
69 int license_int_1; /**< integer 1 of CONOPT license */
70 int license_int_2; /**< integer 2 of CONOPT license */
71 int license_int_3; /**< integer 3 of CONOPT license */
72 char license_text[81]; /**< text of CONOPT license */
73};
74
76{
77 SCIP* scip; /**< SCIP data structure */
78 SCIP_NLPIORACLE* oracle; /**< Oracle-helper to store and evaluate NLP */
79 SCIP_RANDNUMGEN* randnumgen; /**< random number generator */
80
81 SCIP_Bool firstrun; /**< whether the next NLP solve will be the first one (with the current problem structure) */
82 SCIP_Real* initguess; /**< initial values for primal variables, or NULL if not known */
83
84 SCIP_NLPSOLSTAT solstat; /**< solution status from last NLP solve */
85 SCIP_NLPTERMSTAT termstat; /**< termination status from last NLP solve */
86 SCIP_Real solvetime; /**< time spend for last NLP solve */
87 int niterations; /**< number of iterations for last NLP solve */
88 SCIP_Real objval; /**< objective value from last run */
89
90 SCIP_Real* lastprimal; /**< primal solution from last run, if available */
91 SCIP_Real* lastdualcons; /**< dual solution from last run, if available */
92 SCIP_Real* lastduallb; /**< dual solution for lower bounds from last run, if available */
93 SCIP_Real* lastdualub; /**< dual solution for upper bounds from last run, if available */
94 int varsolsize; /**< size of solution values arrays corresponding to variables */
95 int conssolsize; /**< size of solution values array corresponding to constraints */
96
97 coiHandle_t CntVect; /**< pointer to CONOPT Control Vector */
98
99 /* options that will be passed to CONOPT via callbacks */
100 int verblevel; /**< verbosity level, same as in SCIP_NlpParam: 0 off, 1 normal, 2 debug, > 2 more debug */
101 SCIP_Real opttol; /**< optimality tolerance */
102
103 /* statistics */
104 int ncalls; /**< overall number of solver calls */
105 int nsuccess; /**< number of successes (optimal or feasible solution found or proven unbounded) */
106 int nlocinfeas; /**< number of calls resulting in local infeasibility */
107 int nother; /**< number of other calls */
108 int nlimit; /**< number of calls where the solver terminated due to a time or iteration limit */
109};
110
111/*
112 * Local methods
113 */
114
115/** Implementations of CONOPT callbacks */
116
117/** CONOPT callback to pass solution back to SCIP
118 *
119 * The dual values are multiplied by -1, since CONOPT's definition of marginal values is 'by
120 * how much the objective increases if we increase the constraint side by +eps', which, for
121 * minimisation problems (which is always the case here), is the negative of what SCIP expects.
122 */
123static int COI_CALLCONV Solution(
124 const double XVAL[], /**< solution values of the variables (provided by CONOPT) */
125 const double XMAR[], /**< marginal values (provided by CONOPT) */
126 const int XBAS[], /**< basis indicators for the variables (provided by CONOPT) */
127 const int XSTA[], /**< status values for the variables (provided by CONOPT) */
128 const double YVAL[], /**< values of the left hand sides of all rows in the optimal solution (provided by CONOPT) */
129 const double YMAR[], /**< marginal values corresponding to rows (provided by CONOPT) */
130 const int YBAS[], /**< basis indicators for the rows or constraints (provided by CONOPT) */
131 const int YSTA[], /**< status values for the rows or constraints (provided by CONOPT) */
132 int NUMVAR, /**< number of variables (provided by CONOPT) */
133 int NUMCON, /**< number of constraints (provided by CONOPT) */
134 void* USRMEM /**< user memory pointer (i.e. pointer to SCIP_NLPIPROBLEM) */
135 )
136{
137 SCIP_NLPIPROBLEM* problem = (SCIP_NLPIPROBLEM*)USRMEM;
138 int noraclevars;
139 int noracleconss;
140
141 assert(problem != NULL);
142 assert(problem->oracle != NULL);
143
144 noraclevars = SCIPnlpiOracleGetNVars(problem->oracle);
145 noracleconss = SCIPnlpiOracleGetNConstraints(problem->oracle);
146
147 /* number of SCIP variables always less or equal, since CONOPT variables can also contain slack variables */
148 assert(NUMVAR >= noraclevars);
149
150 /* CONOPT has one more constraint than oracle (the objective) */
151 assert(NUMCON == noracleconss + 1);
152
153 /* copy values from CONOPT into SCIP arrays. Note that in CONOPT, there is one
154 * extra constraint (the objective) and slack variables that are not explicitly
155 * present in SCIP, which the code below does not copy */
156 if( problem->lastprimal == NULL )
157 {
158 if( NUMVAR > 0 )
159 {
160 if( SCIPduplicateBlockMemoryArray(problem->scip, &problem->lastprimal, XVAL, noraclevars) != SCIP_OKAY ||
161 SCIPallocClearBlockMemoryArray(problem->scip, &problem->lastduallb, noraclevars) != SCIP_OKAY ||
162 SCIPallocClearBlockMemoryArray(problem->scip, &problem->lastdualub, noraclevars) != SCIP_OKAY )
163 {
164 SCIPerrorMessage("Failed to allocate memory for a solution from CONOPT\n");
165 return 1;
166 }
167 problem->varsolsize = noraclevars;
168 }
169 if( NUMCON > 0 )
170 {
171 if( SCIPduplicateBlockMemoryArray(problem->scip, &problem->lastdualcons, YMAR, noracleconss) != SCIP_OKAY )
172 {
173 SCIPerrorMessage("Failed to allocate memory for a solution from CONOPT\n");
174 return 1;
175 }
176 problem->conssolsize = noracleconss;
177 }
178 }
179 else
180 {
181 assert(noraclevars <= problem->varsolsize);
182 assert(noracleconss <= problem->conssolsize);
183 BMScopyMemoryArray(problem->lastprimal, XVAL, noraclevars);
184 BMSclearMemoryArray(problem->lastduallb, noraclevars);
185 BMSclearMemoryArray(problem->lastdualub, noraclevars);
186 BMScopyMemoryArray(problem->lastdualcons, YMAR, noracleconss);
187 }
188
189 /* replace initial guess with the obtained solution */
190 if( problem->lastprimal != NULL )
191 {
192 if( problem->initguess == NULL )
193 {
194 if( SCIPduplicateMemoryArray(problem->scip, &problem->initguess, problem->lastprimal, noraclevars) != SCIP_OKAY )
195 {
196 SCIPerrorMessage("Failed to allocate memory for an initial guess from\n");
197 return 1;
198 }
199 }
200 else
201 BMScopyMemoryArray(problem->initguess, problem->lastprimal, noraclevars);
202 }
203
204 /* get dual multipliers for variable bounds */
205 for( int i = 0; i < noraclevars; i++ )
206 {
207 if( XBAS[i] == 0 ) /* Xi is at lower bound */
208 problem->lastduallb[i] = -XMAR[i];
209 else if( XBAS[i] == 1 ) /* Xi is at upper bound */
210 problem->lastdualub[i] = -XMAR[i];
211 }
212
213 for( int i = 0; i < NUMCON-1; i++ )
214 (problem->lastdualcons[i]) *= -1;
215
216 return 0;
217} /*lint !e715*/
218
219/** CONOPT callback to pass variable bounds, constraint types and sides
220 * and Jacobian structure and constant values to CONOPT
221 */
222static int COI_CALLCONV ReadMatrix(
223 double LOWER[], /**< lower bounds on the variables (set to CONOPT's minus infinity before callback is issued */
224 double CURR[], /**< initial values of the variables (set to zero before callback is issued */
225 double UPPER[], /**< upper bounds on the variables (set to CONOPT's plus infinity before callback is issued */
226 int VSTA[], /**< initial status values for the variable (used if coidef_inistat() was called with IniStat = 1 or 2) */
227 int TYPE[], /**< constraint types (equation, inequality, free) */
228 double RHS[], /**< right hand sides values of constraints (default is zero) */
229 int ESTA[], /**<initial status values for constraint slacks (used if coidef_inistat() was called with IniStat = 1 or 2) */
230 int COLSTA[], /**< starting indices of Jacobian columns in ROWNO */
231 int ROWNO[], /**< row numbers of Jacobian nonzeros */
232 double VALUE[], /**< values of the Jacobian elements (defined for all constant Jacobian elements) */
233 int NLFLAG[], /**< flags marking nonlinear Jacobian elements (following the same sparse representation as ROWNO) */
234 int NUMVAR, /**< number of variables as defined in COIDEF_NumVar() */
235 int NUMCON, /**< number of constraints as defined in COIDEF_NumCon() */
236 int NUMNZ, /**< number of Jacobian elements as defined in COIDEF_NumNz() */
237 void* USRMEM /**< user memory pointer (i.e. pointer to SCIP_NLPIPROBLEM) */
238 )
239{
240 SCIP_NLPIPROBLEM* problem = (SCIP_NLPIPROBLEM*)USRMEM;
241 SCIP* scip;
242 SCIP_NLPIORACLE* oracle;
243 const SCIP_Real* lbs;
244 const SCIP_Real* ubs;
245 int norigvars;
246 int nslackvars = 0;
247 int njacnlnnz;
248 int* rangeconsidxs = NULL;
249 const SCIP_Bool* jacrownlflags;
250 const int* jaccoloffsets;
251 const int* jacrows;
252 int nobjnz;
253 const int* objnz;
254 const SCIP_Bool* objnlflags;
255 int nobjnlnz;
256 int objnzcnt = 0;
257 int* nrownz;
258 SCIP_RETCODE retcode;
259
260 assert(problem != NULL);
261
262 oracle = problem->oracle;
263 assert(oracle != NULL);
264
265 scip = problem->scip;
266 assert(scip != NULL);
267
268 SCIPdebugMsg(scip, "NLP sizes passed to CONOPT: NUMVAR = %d, NUMCON = %d, NUMNZ = %d\n", NUMVAR, NUMCON, NUMNZ);
269
270 norigvars = SCIPnlpiOracleGetNVars(oracle);
271 lbs = SCIPnlpiOracleGetVarLbs(oracle);
272 ubs = SCIPnlpiOracleGetVarUbs(oracle);
273
274 /* save indices of range constraints if there are any */
275 if( NUMVAR - norigvars > 0 )
276 {
277 retcode = SCIPallocBufferArray(scip, &rangeconsidxs, NUMVAR - norigvars);
278 if( retcode != SCIP_OKAY )
279 {
280 SCIPerrorMessage("No memory in a callback of CONOPT\n");
281 return 1;
282 }
283 }
284
285 /* add all 'normal' (i.e. non-slack) variables here */
286 for( int i = 0; i < norigvars; i++ )
287 {
288 if( !SCIPisInfinity(scip, -lbs[i]) )
289 LOWER[i] = lbs[i];
290 if( !SCIPisInfinity(scip, ubs[i]) )
291 UPPER[i] = ubs[i];
292 }
293
294 /* specify initial values of original variables,
295 * (if there is a previous solution, it is stored in initguess) */
296 if( problem->initguess != NULL )
297 {
298 BMScopyMemoryArray(CURR, problem->initguess, norigvars);
299
300 /* some values may have been set outside the bounds - project them */
301 for( int i = 0; i < norigvars; ++i )
302 {
303 if( lbs[i] > CURR[i] )
304 CURR[i] = SCIPrandomGetReal(problem->randnumgen, lbs[i], lbs[i] + MAXPERTURB*MIN(1.0, ubs[i]-lbs[i]));
305 else if( ubs[i] < CURR[i] )
306 CURR[i] = SCIPrandomGetReal(problem->randnumgen, ubs[i] - MAXPERTURB*MIN(1.0, ubs[i]-lbs[i]), ubs[i]);
307 }
308 }
309 else
310 {
311 /* if no initial guess given, project 0 onto variable bounds */
312 assert(problem->randnumgen != NULL);
313
314 SCIPdebugMsg(scip, "CONOPT started without initial primal values; make up starting guess by projecting 0 onto variable bounds\n");
315
316 for( int i = 0; i < norigvars; ++i )
317 {
318 if( lbs[i] > 0.0 )
319 CURR[i] = SCIPrandomGetReal(problem->randnumgen, lbs[i], lbs[i] + MAXPERTURB*MIN(1.0, ubs[i]-lbs[i]));
320 else if( ubs[i] < 0.0 )
321 CURR[i] = SCIPrandomGetReal(problem->randnumgen, ubs[i] - MAXPERTURB*MIN(1.0, ubs[i]-lbs[i]), ubs[i]);
322 else
323 CURR[i] = SCIPrandomGetReal(problem->randnumgen,
324 MAX(lbs[i], -MAXPERTURB*MIN(1.0, ubs[i]-lbs[i])), MIN(ubs[i], MAXPERTURB*MIN(1.0, ubs[i]-lbs[i])));
325 }
326 }
327
328 for( int i = 0; i < NUMCON-1; i++ )
329 {
332
333 assert(lhs <= rhs);
334
335 if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) )
336 {
337 TYPE[i] = 0; /* an equality or a ranged row modelled as equality */
338
339 if( !SCIPisEQ(scip, lhs, rhs) )
340 {
341 assert(rangeconsidxs != NULL);
342
343 /* range constraint lhs <= g(x) <= rhs: reformulate as g(x) - s = 0 and lhs <= s <= rhs */
344 RHS[i] = 0.0;
345 LOWER[norigvars + nslackvars] = lhs;
346 UPPER[norigvars + nslackvars] = rhs;
347
348 /* set initial value of slack variable */
349 if( lhs > 0.0 )
350 CURR[norigvars + nslackvars] = SCIPrandomGetReal(problem->randnumgen, lhs, lhs + MAXPERTURB*MIN(1.0, rhs-lhs));
351 else if( rhs < 0.0 )
352 CURR[norigvars + nslackvars] = SCIPrandomGetReal(problem->randnumgen, rhs - MAXPERTURB*MIN(1.0, rhs-lhs), rhs);
353 else
354 CURR[norigvars + nslackvars] = SCIPrandomGetReal(problem->randnumgen,
355 MAX(lhs, -MAXPERTURB*MIN(1.0, rhs-lhs)), MIN(rhs, MAXPERTURB*MIN(1.0, rhs-lhs)));
356
357 rangeconsidxs[nslackvars] = i;
358 nslackvars++;
359 }
360 else
361 RHS[i] = lhs;
362 }
363 else if( !SCIPisInfinity(scip, -lhs) )
364 {
365 TYPE[i] = 1;
366 RHS[i] = lhs;
367 }
368 else if( !SCIPisInfinity(scip, rhs) )
369 {
370 TYPE[i] = 2;
371 RHS[i] = rhs;
372 }
373 else
374 TYPE[i] = 3;
375 }
376 assert(norigvars + nslackvars == NUMVAR);
377
378 /* the last constraint is the objective */
379 TYPE[NUMCON-1] = 3; /* objective must be a free row */
380 RHS[NUMCON-1] = 0.0;
381
382 /* Jacobian information */
383
384 retcode = SCIPnlpiOracleGetJacobianColSparsity(scip, oracle, &jaccoloffsets, &jacrows, &jacrownlflags, &njacnlnnz);
385 if( retcode != SCIP_OKAY )
386 {
387 SCIPerrorMessage("Error in Jacobian sparsity computation\n");
388 return 2;
389 }
390 assert(jaccoloffsets == NULL || jaccoloffsets[norigvars] <= NUMNZ);
391
392 /* move structure info into COLSTA and ROWNO; while doing so, also add nonzeroes for the objective
393 * (which CONOPT sees as the last constraint, i.e. constraint with index NUMCON-1) */
394 retcode = SCIPallocCleanBufferArray(scip, &nrownz, NUMCON);
395 if( retcode != SCIP_OKAY )
396 {
397 SCIPerrorMessage("No memory in a callback of CONOPT\n");
398 return 1;
399 }
400
401 retcode = SCIPnlpiOracleGetObjGradientNnz(scip, oracle, &objnz, &objnlflags, &nobjnz, &nobjnlnz);
402 assert(nobjnz > 0 || objnz == NULL);
403 if( retcode != SCIP_OKAY )
404 {
405 SCIPerrorMessage("Error in the ReadMatrix callback of CONOPT\n");
406 return 2;
407 }
408
409 for( int i = 0; i < norigvars; i++ )
410 {
411 /* starts of columns get shifted by how many objective nonzeros were added */
412 COLSTA[i] = jaccoloffsets != NULL ? jaccoloffsets[i] + objnzcnt : objnzcnt;
413
414 if( jaccoloffsets != NULL )
415 {
416 /* nonzeroes of constraints */
417 for( int j = jaccoloffsets[i]; j < jaccoloffsets[i+1]; j++ )
418 {
419 ROWNO[j+objnzcnt] = jacrows[j];
420 NLFLAG[j+objnzcnt] = jacrownlflags[j] ? 1 : 0;
421 if( NLFLAG[j+objnzcnt] == 0 )
422 {
423 /* for linear terms, compute the (constant) Jacobian values */
424 VALUE[j+objnzcnt] = SCIPnlpiOracleGetConstraintLinearCoef(oracle, jacrows[j], nrownz[jacrows[j]]);
425 ++(nrownz[jacrows[j]]);
426 }
427 }
428 }
429
430 /* nonzeroes of objective */
431 if( objnz != NULL && objnzcnt < nobjnz && i == objnz[objnzcnt] )
432 {
433 int idx = jaccoloffsets != NULL ? jaccoloffsets[i+1] + objnzcnt : objnzcnt;
434
435 ROWNO[idx] = NUMCON - 1;
436 NLFLAG[idx] = objnlflags[objnzcnt] ? 1 : 0;
437 if( NLFLAG[idx] == 0 )
438 {
439 /* in the oracle, index -1 is used for the objective */
440 VALUE[idx] = SCIPnlpiOracleGetConstraintLinearCoef(oracle, -1, nrownz[NUMCON-1]);
441 ++(nrownz[NUMCON-1]);
442 }
443 ++objnzcnt;
444 }
445 }
446 assert(COLSTA[0] == 0);
447 COLSTA[norigvars] = jaccoloffsets != NULL ? jaccoloffsets[norigvars] + objnzcnt : objnzcnt;
448 BMSclearMemoryArray(nrownz, NUMCON);
450
451 if( nslackvars > 0 )
452 {
453 /* add a nonzero for each slack variable */
454 for( int i = 0; i < nslackvars; i++ )
455 {
456 COLSTA[norigvars+i] = COLSTA[norigvars] + i; /* for each slack var, only one nonzero is added */
457 ROWNO[COLSTA[norigvars+i]] = rangeconsidxs[i];
458 NLFLAG[COLSTA[norigvars+i]] = 0;
459 VALUE[COLSTA[norigvars+i]] = -1.0;
460 }
461 SCIPfreeBufferArray(scip, &rangeconsidxs);
462 COLSTA[NUMVAR] = NUMNZ;
463 }
464
465#ifndef NDEBUG
466 for( int i = 0; i < NUMNZ; ++i )
467 assert(ROWNO[i] >= 0 && ROWNO[i] < NUMCON);
468#endif
469
470#ifdef STRUCTURE_DEBUG
471 SCIPdebugMsg(scip, "Jacobian structure information:\n");
472 SCIPdebugMsg(scip, "COLSTA =\n");
473 for( int i = 0; i <= NUMVAR; i++ )
474 printf("%d, ", COLSTA[i]);
475 printf("\n");
476
477 SCIPdebugMsg(scip, "ROWNO =\n");
478 for( int i = 0; i < NUMNZ; i++ )
479 printf("%d, ", ROWNO[i]);
480 printf("\n");
481
482 SCIPdebugMsg(scip, "NLFLAG =\n");
483 for( int i = 0; i < NUMNZ; i++ )
484 printf("%d, ", NLFLAG[i]);
485 printf("\n");
486
487 SCIPdebugMsg(scip, "VALUE =\n");
488 for( int i = 0; i < NUMNZ; i++ )
489 if( SCIPisInfinity(scip, VALUE[i]) )
490 printf("inf, ");
491 else
492 printf("%g, ", VALUE[i]);
493 printf("\n");
494 fflush(stdout);
495#endif
496
497 return 0;
498} /*lint !e715*/
499
500/** callback for CONOPT's standard output */
501static int COI_CALLCONV Message(
502 int SMSG, /**< number of lines in the message that should go to the Screen file, between 0 and 30 */
503 int DMSG, /**< number of lines in the message that should go to the Status file, between 0 and 30 */
504 int NMSG, /**< number of lines in the message that should go to the Documentation file, between 0 and 30 */
505 char* MSGV[], /**< array with the lengths of the individual message lines, the lengths are between 1 and 132 */
506 void* USRMEM /**< user memory pointer (i.e. pointer to SCIP_NLPIPROBLEM) */
507 )
508{
509 SCIP_NLPIPROBLEM* problem = (SCIP_NLPIPROBLEM*)USRMEM;
510
511 assert(problem != NULL);
512 assert(problem->scip != NULL);
513
514 if( problem->verblevel > 0 )
515 {
516 for( int i = 0; i < SMSG; i++ )
517 SCIPinfoMessage(problem->scip, NULL, "%s\n", MSGV[i]);
518 }
519
520 return 0;
521} /*lint !e715*/
522
523/** callback for CONOPT's standard error output */
524static int COI_CALLCONV ErrMsg(
525 int ROWNO, /**< number of row */
526 int COLNO, /**< number of column */
527 int POSNO, /**< number of a Jacobian element */
528 const char* MSG, /**< the message */
529 void* USRMEM /**< user memory pointer (i.e. pointer to SCIP_NLPIPROBLEM) */
530 )
531{
532 SCIP_NLPIPROBLEM* problem = (SCIP_NLPIPROBLEM*)USRMEM;
533
534 if( problem->verblevel > 0 )
535 {
536 if( ROWNO == -1 && COLNO == -1 )
537 SCIPinfoMessage(problem->scip, NULL, "\nCONOPT error/warning: Jacobian element %d: ", POSNO);
538 else if( ROWNO == -1 )
539 SCIPinfoMessage(problem->scip, NULL, "\nCONOPT error/warning: variable %d: ", COLNO);
540 else if( COLNO == -1 )
541 SCIPinfoMessage(problem->scip, NULL, "\nCONOPT error/warning: constraint %d: ", ROWNO);
542 else
543 SCIPinfoMessage(problem->scip, NULL, "\nCONOPT error/warning: variable %d appearing in constraint %d: ", COLNO, ROWNO);
544 SCIPinfoMessage(problem->scip, NULL, "%s\n", MSG);
545 }
546
547 return 0;
548}
549
550/** callback for CONOPT to report the solving statuses */
551static int COI_CALLCONV Status(
552 int MODSTA, /**< model status (corresponds to SCIP's solstat) */
553 int SOLSTA, /**< solver status (corresponds to SCIP's termstat) */
554 int ITER, /**< number of iterations */
555 double OBJVAL, /**< objective value */
556 void* USRMEM /**< user memory pointer (i.e. pointer to SCIP_NLPIPROBLEM) */
557 )
558{
559 SCIP* scip;
560 SCIP_NLPIPROBLEM* problem = (SCIP_NLPIPROBLEM*)USRMEM;
561 SCIP_Bool other = FALSE;
562 SCIP_Bool limit = FALSE;
563
564 assert(problem != NULL);
565
566 scip = problem->scip;
567 assert(scip != NULL);
568
569 SCIPdebugMsg(scip, "CONOPT has finished optimizing\n");
570 SCIPdebugMsg(scip, "Iteration count = %8d\n", ITER);
571 SCIPdebugMsg(scip, "Objective value = %10f\n", OBJVAL);
572
573 problem->niterations = ITER;
574 problem->objval = OBJVAL;
575 ++(problem->ncalls);
576
577 switch( MODSTA )
578 {
579 case 1:
580 SCIPdebugMsg(scip, "NLP problem solved to global optimality\n");
582 ++(problem->nsuccess);
583 break;
584 case 2:
585 SCIPdebugMsg(scip, "NLP problem solved to local optimality\n");
587 ++(problem->nsuccess);
588 break;
589 case 3:
590 SCIPdebugMsg(scip, "NLP problem unbounded\n");
592 ++(problem->nsuccess);
593 break;
594 case 4:
595 SCIPdebugMsg(scip, "NLP problem infeasible\n");
597 ++(problem->nsuccess);
598 break;
599 case 5:
600 SCIPdebugMsg(scip, "NLP problem locally infeasible\n");
602 ++(problem->nlocinfeas);
603 break;
604 case 7: /* intermediate non-optimal */
606 break;
607 case 6: /* intermediate infeasible */
608 case 12: /* unknown error */
609 case 13:
610 SCIPdebugMsg(scip, "NLP problem status unknown (CONOPT status %d)\n", MODSTA);
612 other = TRUE;
613 break;
614 default:
615 SCIPerrorMessage("CONOPT returned an unexpected solution status %d\n", MODSTA);
617 other = TRUE;
618 }
619
620 switch( SOLSTA )
621 {
622 case 1:
624 SCIPdebugMsg(scip, "CONOPT terminated with normal status.\n");
625 break;
626 case 2:
628 SCIPdebugMsg(scip, "CONOPT terminated due to an iteration limit.\n");
629 limit = TRUE;
630 break;
631 case 3:
633 SCIPdebugMsg(scip, "CONOPT terminated due to a time limit.\n");
634 limit = TRUE;
635 break;
636 case 4: /* terminated by solver */
638 SCIPdebugMsg(scip, "CONOPT terminated due to numerical trouble.\n");
639 break;
640 case 5:
642 SCIPdebugMsg(scip, "CONOPT terminated due to evaluation errors.\n");
643 break;
644 case 8:
646 SCIPdebugMsg(scip, "CONOPT interrupted by user.\n");
647 break;
648 case 6: /* unknown */
649 case 9: /* error: setup failure */
650 case 10: /* error: solver failure */
651 case 11: /* error: internal solver error */
652 SCIPdebugMsg(scip, "CONOPT terminated with status %d\n", SOLSTA);
654 break;
655 default:
656 SCIPerrorMessage("CONOPT returned an unexpected termination status %d\n", SOLSTA);
658 }
659
660 if( other )
661 {
662 if( limit )
663 ++(problem->nlimit);
664 else
665 ++(problem->nother);
666 }
667
668 return 0;
669}
670
671/** CONOPT callback for function and Jacobian evaluation
672 *
673 * The callback has three modes, indicated by MODE:
674 *
675 * 1: Only evaluate the sum of the nonlinear and linear terms in row ROWNO and return the value in G.
676 * 2: Only evaluate the nonlinear Jacobian elements in row ROWNO and return them in JAC.
677 * 3: Perform both option 1 and 2.
678 */
679static int COI_CALLCONV FDEval(
680 const double X[], /**< point of evaluation (provided by CONOPT) */
681 double* G, /**< value of the function */
682 double JAC[], /**< vector of Jacobian values */
683 int ROWNO, /**< number of the row for which nonlinearities are to be evaluated (provided by CONOPT) */
684 const int JACNUM[], /**< list of column numbers for the nonlinear nonzero Jacobian elements in
685 * the current row (provided by CONOPT when MODE = 2 or 3) */
686 int MODE, /**< indicator for mode of evaluation (provided by CONOPT) */
687 int IGNERR, /**< indicator whether CONOPT assumes the point to be safe (0) or potentially unsafe (1) */
688 int* ERRCNT, /**< scalar function evaluation error indicator (set to 1 if a function value cannot be computed */
689 int NUMVAR, /**< number of variables (provided by CONOPT) */
690 int NUMJAC, /**< number of nonlinear nonzero Jacobian elements in the current row */
691 int THREAD, /**< only relevant in multi-threading environments */
692 void* USRMEM /**< user memory pointer (i.e. pointer to SCIP_NLPIPROBLEM) */
693 )
694{
695 SCIP_RETCODE retcode;
696 SCIP_NLPIPROBLEM* problem = (SCIP_NLPIPROBLEM*)USRMEM;
697
698 assert(problem != NULL);
699 assert(ROWNO <= SCIPnlpiOracleGetNConstraints(problem->oracle));
700
701 if( MODE == 1 )
702 {
703 /* the last 'constraint' is the objective */
704 retcode = ROWNO < SCIPnlpiOracleGetNConstraints(problem->oracle) ?
705 SCIPnlpiOracleEvalConstraintValue(problem->scip, problem->oracle, ROWNO, X, G) :
706 SCIPnlpiOracleEvalObjectiveValue(problem->scip, problem->oracle, X, G);
707 if( retcode != SCIP_OKAY || *G == SCIP_INVALID ) /*lint !e777*/
708 *ERRCNT = 1;
709 }
710
711 if( MODE == 2 || MODE == 3 )
712 {
713 /* the last 'constraint' is the objective */
714 retcode = ROWNO < SCIPnlpiOracleGetNConstraints(problem->oracle) ?
715 SCIPnlpiOracleEvalConstraintGradient(problem->scip, problem->oracle, ROWNO, X, TRUE, G, JAC) :
716 SCIPnlpiOracleEvalObjectiveGradient(problem->scip, problem->oracle, X, TRUE, G, JAC);
717 if( retcode != SCIP_OKAY )
718 *ERRCNT = 1;
719 }
720
721 return 0;
722} /*lint !e715*/
723
724/** CONOPT callback to pass some of the options (not supported via COIDEF_* functions) to CONOPT */
725static int COI_CALLCONV Option(
726 int NCALL, /**< number of callback call (provided by CONOPT) */
727 double* RVAL, /**< pointer to set the value of a real option */
728 int* IVAL, /**< pointer to set the value of an integer option */
729 int* LVAL, /**< pointer to set the value of a binary option */
730 char* NAME, /**< pointer to set the name of the option */
731 void* USRMEM /**< user memory pointer (i.e. pointer to SCIP_NLPIPROBLEM) */
732 )
733{
734 SCIP_NLPIPROBLEM* problem = (SCIP_NLPIPROBLEM*)USRMEM;
735
736 assert(problem != NULL);
737
738 switch( NCALL )
739 {
740 case 0: /* information about stopping criteria */
741 strcpy(NAME, "LOCNPT");
742 if( problem->verblevel >= 2 )
743 *IVAL = 1;
744 else
745 *IVAL = 0;
746 break;
747 case 1: /* optimality tolerance */
748 strcpy(NAME, "RTREDG");
749 *RVAL = problem->opttol;
750 break;
751 default:
752 *NAME = '\0';
753 }
754
755 return 0;
756} /*lint !e715*/
757
758/** CONOPT callback to define structure of the Hessian of the Lagrangian */
759static int COI_CALLCONV LagrStr(
760 int HSRW[], /**< row numbers of the lower triangular part of the Hessian */
761 int HSCL[], /**< column numbers of the lower triangular part of the Hessian; elements must be
762 * sorted column-wise, and within each column, row-wise */
763 int* NODRV, /**< can be set to 1 if the derivatives could not be computed */
764 int NUMVAR, /**< number of variables as defined in coidef_numvar() (provided by CONOPT) */
765 int NUMCON, /**< number of constraints as defined in coidef_numcon() (provided by CONOPT) */
766 int NHESS, /**< number of nonzero elements in the Hessian (provided by CONOPT) */
767 void* USRMEM /**< user memory pointer (i.e. pointer to SCIP_NLPIPROBLEM) */
768 )
769{
770 SCIP_NLPIPROBLEM* problem = (SCIP_NLPIPROBLEM*)USRMEM;
771 const int* hessoffsets;
772 const int* rows;
773 int col = 0;
774
775 assert(problem != NULL);
776
777 if( SCIPnlpiOracleGetHessianLagSparsity(problem->scip, problem->oracle, &hessoffsets, &rows, TRUE) != SCIP_OKAY )
778 {
779 *NODRV = 1;
780 return 0;
781 }
782
783 for( int i = 0; i < NHESS; i++ )
784 {
785 /* check if it's time to switch to the next row (this will also skip empty rows) */
786 while( i == hessoffsets[col+1] )
787 col++;
788
789 HSRW[i] = rows[i];
790 HSCL[i] = col;
791 }
792
793 return 0;
794} /*lint !e715*/
795
796/** CONOPT callback to compute the Hessian of the Lagrangian
797 *
798 * the Lagrangian is written as L = sum_{r in rows}U[r] * function(r)
799 */
800static int COI_CALLCONV LagrVal(
801 const double X[], /**< point in which the Hessian should be computed (provided by CONOPT) */
802 const double U[], /**< vector of weights on the individual constraints (provided by CONOPT) */
803 const int HSRW[], /**< row numbers of the lower triangular part of the Hessian (provided by CONOPT) */
804 const int HSCL[], /**< column numbers of the lower triangular part of the Hessian; elements must be
805 * sorted column-wise, and within each column, row-wise (provided by CONOPT) */
806 double HSVL[], /**< values of Hessian entries */
807 int* NODRV, /**< can be set to 1 if the derivatives could not be computed */
808 int NUMVAR, /**< number of variables as defined in coidef_numvar() (provided by CONOPT) */
809 int NUMCON, /**< number of constraints as defined in coidef_numcon() (provided by CONOPT) */
810 int NHESS, /**< number of nonzero elements in the Hessian (provided by CONOPT) */
811 void* USRMEM /**< user memory pointer (i.e. pointer to SCIP_NLPIPROBLEM) */
812 )
813{
814 SCIP_NLPIPROBLEM* problem = (SCIP_NLPIPROBLEM*)USRMEM;
815
816 assert(problem != NULL);
817
818 /* TODO better handling for isnew? */
819 if( SCIPnlpiOracleEvalHessianLag(problem->scip, problem->oracle, X, TRUE, TRUE, U[NUMCON-1], U, HSVL, TRUE)
820 != SCIP_OKAY )
821 *NODRV = 1;
822
823 return 0;
824} /*lint !e715*/
825
826/* NLPI local methods */
827
828/** frees solution arrays and sets the solstat and termstat to unknown and other, resp. */
829static
831 SCIP_NLPIPROBLEM* problem /**< data structure of problem */
832 )
833{
834 assert(problem != NULL);
835
836 SCIPfreeBlockMemoryArrayNull(problem->scip, &(problem->lastprimal), problem->varsolsize);
837 SCIPfreeBlockMemoryArrayNull(problem->scip, &(problem->lastdualcons), problem->conssolsize);
838 SCIPfreeBlockMemoryArrayNull(problem->scip, &(problem->lastduallb), problem->varsolsize);
839 SCIPfreeBlockMemoryArrayNull(problem->scip, &(problem->lastdualub), problem->varsolsize);
840 problem->varsolsize = 0;
841 problem->conssolsize = 0;
842
845}
846
848 SCIP* scip, /**< SCIP data structure */
849 SCIP_NLPIDATA* data, /**< pointer to NLPIDATA structure */
850 SCIP_NLPIPROBLEM* problem /**< pointer to NLPI problem structure */
851 )
852{
853 int COI_Error = 0; /* CONOPT error counter */
854 int nrangeconss = 0;
855 int nconss;
856 int nvars;
857 const int* jacoffsets;
858 const int* hessoffsets;
859 int nnlnz;
860 const int* objgradnz;
861 const SCIP_Bool* objnl;
862 int nobjgradnz;
863 int nobjgradnls;
864
865 assert(data != NULL);
866 assert(problem != NULL);
867 assert(problem->oracle != NULL);
868
869 if( data->solvetime == NULL )
870 if( data->solvetime == NULL )
871 {
872 SCIP_CALL( SCIPcreateClock(scip, &(data->solvetime)) );
873 }
874
875 nconss = SCIPnlpiOracleGetNConstraints(problem->oracle);
876 nvars = SCIPnlpiOracleGetNVars(problem->oracle);
877
878 /* count range constraints: because CONOPT doesn't support them directly, will need to add a slack variable for each ranged constraint */
879 for( int i = 0; i < nconss; i++ )
880 {
883
884 if( !SCIPisInfinity(problem->scip, -lhs) && !SCIPisInfinity(problem->scip, rhs) && !SCIPisEQ(scip, lhs, rhs) )
885 nrangeconss++;
886 }
887
888 /* tell CONOPT that we may have empty columns */
889 COI_Error += COIDEF_EmptyCol(problem->CntVect, 1);
890
891 /* inform CONOPT about problem sizes */
892 COI_Error += COIDEF_NumVar(problem->CntVect, nvars + nrangeconss);
893 COI_Error += COIDEF_NumCon(problem->CntVect, nconss + 1); /* objective counts as another constraint here */
894
895 /* jacobian information */
896 SCIP_CALL( SCIPnlpiOracleGetJacobianColSparsity(scip, problem->oracle, &jacoffsets, NULL, NULL, &nnlnz) );
897 SCIP_CALL( SCIPnlpiOracleGetObjGradientNnz(scip, problem->oracle, &objgradnz, &objnl, &nobjgradnz, &nobjgradnls) );
898
899 /* each slack var adds a Jacobian nnz; objective also counts as constraint */
900 COI_Error += COIDEF_NumNz(problem->CntVect, jacoffsets != NULL ? jacoffsets[nvars] + nrangeconss + nobjgradnz :
901 nrangeconss + nobjgradnz);
902
903 /* Jacobian nonzeroes include those of constraints and objective */
904 COI_Error += COIDEF_NumNlNz(problem->CntVect, nnlnz + nobjgradnls);
905
906 /* hessian sparsity information */
908 COI_Error += COIDEF_NumHess(problem->CntVect, hessoffsets[nvars]);
909
910 /* tell CONOPT to minimise the objective (the oracle always gives a minimisation problem) */
911 COI_Error += COIDEF_OptDir(problem->CntVect, -1);
912
913 /* oracle gives objective as a constraint, hence use ObjCon (not ObjVar) here;
914 * we treat objective as the last constraint, hence index nconss */
915 COI_Error += COIDEF_ObjCon(problem->CntVect, nconss);
916
917 /* register callback routines */
918 COI_Error += COIDEF_Message(problem->CntVect, Message);
919 COI_Error += COIDEF_ErrMsg(problem->CntVect, ErrMsg);
920 COI_Error += COIDEF_Status(problem->CntVect, Status);
921 COI_Error += COIDEF_Solution(problem->CntVect, Solution);
922 COI_Error += COIDEF_ReadMatrix(problem->CntVect, ReadMatrix);
923 COI_Error += COIDEF_FDEval(problem->CntVect, FDEval);
924 COI_Error += COIDEF_Option(problem->CntVect, Option);
925 COI_Error += COIDEF_2DLagrStr(problem->CntVect, LagrStr);
926 COI_Error += COIDEF_2DLagrVal(problem->CntVect, LagrVal);
927
928 /* tell CONOPT that our function evaluations include the linear terms */
929 COI_Error += COIDEF_FVincLin(problem->CntVect, 1);
930
931 /* pass the problem pointer to CONOPT, so that it may be used in CONOPT callbacks */
932 COI_Error += COIDEF_UsrMem(problem->CntVect, (void*)problem);
933
934 /* register license, if available */
935 if( data->license_text[0] != '\0' )
936 COI_Error += COIDEF_License(problem->CntVect, data->license_int_1, data->license_int_2, data->license_int_3, data->license_text);
937
938 if( COI_Error )
939 SCIPinfoMessage(scip, NULL, "Error %d encountered during initialising CONOPT\n", COI_Error);
940
941 return SCIP_OKAY;
942}
943
945 SCIP_NLPIPROBLEM* problem, /**< pointer to problem data structure */
946 const SCIP_NLPPARAM param /**< NLP solve parameters */
947 )
948{
949 int COI_Error = 0; /* CONOPT error counter */
950
951 assert(problem != NULL);
952
953 if( param.warmstart )
954 {
955 SCIPdebugMsg(problem->scip, "warmstart parameter not supported by CONOPT interface yet. Ignored.\n");
956 }
957 if( param.lobjlimit > -SCIP_REAL_MAX )
958 {
959 SCIPwarningMessage(problem->scip, "lobjlimit parameter not supported by CONOPT interface yet. Ignored.\n");
960 }
961 if( param.fastfail )
962 {
963 SCIPdebugMsg(problem->scip, "fastfail parameter not supported by CONOPT interface yet. Ignored.\n");
964 }
965
966 /* options that we can set directly */
967 COI_Error += COIDEF_ItLim(problem->CntVect, param.iterlimit);
968 COI_Error += COIDEF_ResLim(problem->CntVect, param.timelimit);
969
970 /* options that need to be handled in callbacks */
971 problem->verblevel = param.verblevel;
972 problem->opttol = param.opttol;
973
974 if( COI_Error )
975 SCIPinfoMessage(problem->scip, NULL, "Errors encountered during setting parameters, %d\n", COI_Error);
976}
977
978
979/*
980 * Callback methods of NLP solver interface
981 */
982
983/** copy method of NLP interface (called when SCIP copies plugins) */
984static
985SCIP_DECL_NLPICOPY(nlpiCopyConopt)
986{
987 SCIP_NLPI* targetnlpi;
988 SCIP_NLPIDATA* sourcenlpidata;
989
991
992 /* if license is set in source NLPI, maybe set via SCIPsetLicenseConopt(),
993 * then pass it on to the copy
994 */
995 sourcenlpidata = SCIPnlpiGetData(sourcenlpi);
996 assert(sourcenlpidata != NULL);
997 if( sourcenlpidata->license_text[0] != '\0' )
998 {
999 targetnlpi = SCIPfindNlpi(scip, NLPI_NAME);
1000 assert(targetnlpi != NULL);
1001
1002 SCIPsetLicenseConopt(targetnlpi, sourcenlpidata->license_int_1,
1003 sourcenlpidata->license_int_2, sourcenlpidata->license_int_3, sourcenlpidata->license_text);
1004 }
1005
1006 return SCIP_OKAY; /*lint !e527*/
1007} /*lint !e715*/
1008
1009/** destructor of NLP interface to free nlpi data */
1010static
1011SCIP_DECL_NLPIFREE(nlpiFreeConopt)
1012{
1013 assert(nlpi != NULL);
1014 assert(nlpidata != NULL);
1015 assert(*nlpidata != NULL);
1016
1017 if( (*nlpidata)->solvetime != NULL )
1018 if( (*nlpidata)->solvetime != NULL )
1019 {
1020 SCIP_CALL( SCIPfreeClock(scip, &((*nlpidata)->solvetime)) );
1021 }
1022
1023 SCIPfreeBlockMemory(scip, nlpidata);
1024 assert(*nlpidata == NULL);
1025
1026 return SCIP_OKAY;
1027} /*lint !e715*/
1028
1029#ifdef SCIP_DISABLED_CODE
1030/** gets pointer for NLP solver */
1031static
1032SCIP_DECL_NLPIGETSOLVERPOINTER(nlpiGetSolverPointerXyz)
1033{
1034 SCIPerrorMessage("method of xyz nonlinear solver is not implemented\n");
1035 SCIPABORT();
1036
1037 return NULL; /*lint !e527*/
1038} /*lint !e715*/
1039#else
1040#define nlpiGetSolverPointerConopt NULL
1041#endif
1042
1043/** create a problem instance */
1044static
1045SCIP_DECL_NLPICREATEPROBLEM(nlpiCreateProblemConopt)
1046{
1047 assert(nlpi != NULL);
1048 assert(problem != NULL);
1049
1051 assert(*problem != NULL);
1052
1053 (*problem)->firstrun = TRUE;
1054 (*problem)->scip = scip;
1055
1056 /* initialize oracle */
1057 SCIP_CALL( SCIPnlpiOracleCreate(scip, &(*problem)->oracle) );
1058 SCIP_CALL( SCIPnlpiOracleSetProblemName(scip, (*problem)->oracle, name) );
1059
1060 if( COI_Create(&((*problem)->CntVect)) || (*problem)->CntVect == NULL )
1061 {
1062 SCIPerrorMessage("Could not create CONOPT control vector\n");
1063 return SCIP_ERROR;
1064 }
1065
1066 /* create random number generator */
1067 SCIP_CALL( SCIPcreateRandom(scip, &(*problem)->randnumgen, DEFAULT_RANDSEED, TRUE) );
1068
1069 return SCIP_OKAY; /*lint !e527*/
1070} /*lint !e715*/
1071
1072/** free a problem instance */
1073static
1074SCIP_DECL_NLPIFREEPROBLEM(nlpiFreeProblemConopt)
1075{
1076 assert(nlpi != NULL);
1077 assert(problem != NULL);
1078 assert(*problem != NULL);
1079
1080 invalidateSolution(*problem);
1081
1082 if( (*problem)->oracle != NULL )
1083 {
1084 SCIP_CALL( SCIPnlpiOracleFree(scip, &(*problem)->oracle) );
1085 }
1086
1087 SCIPfreeRandom(scip, &(*problem)->randnumgen);
1088 SCIPfreeMemoryArrayNull(scip, &(*problem)->initguess);
1089
1090 if( COI_Free(&((*problem)->CntVect)) )
1091 {
1092 SCIPerrorMessage("Error when freeing CONOPT control vector\n");
1093 return SCIP_ERROR;
1094 }
1095
1096 SCIPfreeBlockMemory(scip, problem);
1097 *problem = NULL;
1098
1099#ifdef PRINT_NLPSTATS
1100 SCIPinfoMessage(scip, NULL, "\nNLP solver CONOPT stats: ncalls = %d, nsuccess = %d, nlimit = %d, nlocinfeas = %d, nother = %d\n",
1101 (*problem)->ncalls, (*problem)->nsuccess, (*problem)->nlimit, (*problem)->nlocinfeas, (*problem)->nother);
1102#endif
1103
1104 return SCIP_OKAY;
1105} /*lint !e715*/
1106
1107#ifdef SCIP_DISABLED_CODE
1108/** gets pointer to solver-internal problem instance */
1109static
1110SCIP_DECL_NLPIGETPROBLEMPOINTER(nlpiGetProblemPointerXyz)
1111{
1112 SCIPerrorMessage("method of xyz nonlinear solver is not implemented\n");
1113 SCIPABORT();
1114
1115 return NULL; /*lint !e527*/
1116} /*lint !e715*/
1117#else
1118#define nlpiGetProblemPointerConopt NULL
1119#endif
1120
1121/** add variables */
1122static
1123SCIP_DECL_NLPIADDVARS(nlpiAddVarsConopt)
1124{
1125 assert(nlpi != NULL);
1126 assert(problem != NULL);
1127 assert(problem->oracle != NULL);
1128
1129 SCIP_CALL( SCIPnlpiOracleAddVars(scip, problem->oracle, nvars, lbs, ubs, varnames) );
1130
1131 invalidateSolution(problem);
1132 problem->firstrun = TRUE;
1133
1134 return SCIP_OKAY; /*lint !e527*/
1135} /*lint !e715*/
1136
1137
1138/** add constraints */
1139static
1140SCIP_DECL_NLPIADDCONSTRAINTS(nlpiAddConstraintsConopt)
1141{
1142 assert(nlpi != NULL);
1143 assert(problem != NULL);
1144 assert(problem->oracle != NULL);
1145
1146 SCIP_CALL( SCIPnlpiOracleAddConstraints(scip, problem->oracle, nconss, lhss, rhss,
1147 nlininds, lininds, linvals, exprs, names) );
1148
1149 invalidateSolution(problem);
1150 problem->firstrun = TRUE;
1151
1152 return SCIP_OKAY; /*lint !e527*/
1153} /*lint !e715*/
1154
1155/** sets or overwrites objective, a minimization problem is expected */
1156static
1157SCIP_DECL_NLPISETOBJECTIVE(nlpiSetObjectiveConopt)
1158{
1159 assert(nlpi != NULL);
1160 assert(problem != NULL);
1161 assert(problem->oracle != NULL);
1162
1163 SCIP_CALL( SCIPnlpiOracleSetObjective(scip, problem->oracle, constant, nlins, lininds, linvals, expr) );
1164
1165 invalidateSolution(problem);
1166 problem->firstrun = TRUE;
1167
1168 return SCIP_OKAY; /*lint !e527*/
1169} /*lint !e715*/
1170
1171/** change variable bounds */
1172static
1173SCIP_DECL_NLPICHGVARBOUNDS(nlpiChgVarBoundsConopt)
1174{
1175 assert(nlpi != NULL);
1176 assert(problem != NULL);
1177 assert(problem->oracle != NULL);
1178
1179 SCIP_CALL( SCIPnlpiOracleChgVarBounds(scip, problem->oracle, nvars, indices, lbs, ubs) );
1180
1181 invalidateSolution(problem);
1182
1183 return SCIP_OKAY; /*lint !e527*/
1184} /*lint !e715*/
1185
1186/** change constraint bounds */
1187static
1188SCIP_DECL_NLPICHGCONSSIDES(nlpiChgConsSidesConopt)
1189{
1190 SCIP_NLPIORACLE* oracle;
1191
1192 assert(nlpi != NULL);
1193 assert(problem != NULL);
1194
1195 oracle = problem->oracle;
1196 assert(oracle != NULL);
1197
1198 /* check if any range constraints appear or disappear; if they do, this means new slack variables,
1199 * and thus a change in problem structure */
1200 for( int i = 0; i < nconss; ++i )
1201 {
1202 SCIP_Real oldlhs;
1203 SCIP_Real oldrhs;
1204
1205 assert(indices != NULL);
1206 assert(indices[i] >= 0);
1207 assert(indices[i] < SCIPnlpiOracleGetNConstraints(oracle));
1208
1209 oldlhs = SCIPnlpiOracleGetConstraintLhs(oracle, indices[i]);
1210 oldrhs = SCIPnlpiOracleGetConstraintRhs(oracle, indices[i]);
1211
1212 if( !SCIPisInfinity(scip, -oldlhs) && !SCIPisInfinity(scip, oldrhs) && SCIPisLT(scip, oldlhs, oldrhs) )
1213 {
1214 /* the old constraint is a range constraint, check if this changes with the new sides */
1215 if( lhss == NULL || rhss == NULL || SCIPisInfinity(scip, -lhss[i]) || SCIPisInfinity(scip, rhss[i]) ||
1216 SCIPisEQ(scip, lhss[i], rhss[i]) )
1217 {
1218 problem->firstrun = TRUE;
1219 break;
1220 }
1221 }
1222 else
1223 {
1224 /* the old constraint is not a range constraint, check if this changes with the new sides */
1225 if( lhss != NULL && rhss != NULL && !SCIPisInfinity(scip, -lhss[i]) && !SCIPisInfinity(scip, rhss[i]) &&
1226 SCIPisLT(scip, lhss[i], rhss[i]) )
1227 {
1228 problem->firstrun = TRUE;
1229 break;
1230 }
1231 }
1232 }
1233
1234 SCIP_CALL( SCIPnlpiOracleChgConsSides(scip, oracle, nconss, indices, lhss, rhss) );
1235
1236 invalidateSolution(problem);
1237
1238 return SCIP_OKAY; /*lint !e527*/
1239} /*lint !e715*/
1240
1241/** delete a set of variables */
1242static
1243SCIP_DECL_NLPIDELVARSET(nlpiDelVarSetConopt)
1244{
1245 assert(nlpi != NULL);
1246 assert(problem != NULL);
1247 assert(problem->oracle != NULL);
1248
1249 SCIP_CALL( SCIPnlpiOracleDelVarSet(scip, problem->oracle, dstats) );
1250
1251 invalidateSolution(problem);
1252 problem->firstrun = TRUE;
1253
1254 return SCIP_OKAY; /*lint !e527*/
1255} /*lint !e715*/
1256
1257/** delete a set of constraints */
1258static
1259SCIP_DECL_NLPIDELCONSSET(nlpiDelConstraintSetConopt)
1260{
1261 assert(nlpi != NULL);
1262 assert(problem != NULL);
1263 assert(problem->oracle != NULL);
1264
1265 SCIP_CALL( SCIPnlpiOracleDelConsSet(scip, problem->oracle, dstats) );
1266
1267 invalidateSolution(problem);
1268 problem->firstrun = TRUE;
1269
1270 return SCIP_OKAY; /*lint !e527*/
1271} /*lint !e715*/
1272
1273/** changes (or adds) linear coefficients in a constraint or objective */
1274static
1275SCIP_DECL_NLPICHGLINEARCOEFS(nlpiChgLinearCoefsConopt)
1276{
1277 assert(nlpi != NULL);
1278 assert(problem != NULL);
1279 assert(problem->oracle != NULL);
1280
1281 SCIP_CALL( SCIPnlpiOracleChgLinearCoefs(scip, problem->oracle, idx, nvals, varidxs, vals) );
1282
1283 invalidateSolution(problem);
1284 problem->firstrun = TRUE;
1285
1286 return SCIP_OKAY; /*lint !e527*/
1287} /*lint !e715*/
1288
1289/** replaces the expression tree of a constraint or objective */
1290static
1291SCIP_DECL_NLPICHGEXPR(nlpiChgExprConopt)
1292{
1293 assert(nlpi != NULL);
1294 assert(problem != NULL);
1295 assert(problem->oracle != NULL);
1296
1297 SCIP_CALL( SCIPnlpiOracleChgExpr(scip, problem->oracle, idxcons, expr) );
1298
1299 invalidateSolution(problem);
1300 problem->firstrun = TRUE;
1301
1302 return SCIP_OKAY; /*lint !e527*/
1303} /*lint !e715*/
1304
1305/** change the constant offset in the objective */
1306static
1307SCIP_DECL_NLPICHGOBJCONSTANT(nlpiChgObjConstantConopt)
1308{
1309 assert(nlpi != NULL);
1310 assert(problem != NULL);
1311 assert(problem->oracle != NULL);
1312
1313 SCIP_CALL( SCIPnlpiOracleChgObjConstant(scip, problem->oracle, objconstant) );
1314
1315 return SCIP_OKAY; /*lint !e527*/
1316} /*lint !e715*/
1317
1318/** sets initial guess */
1319static
1320SCIP_DECL_NLPISETINITIALGUESS(nlpiSetInitialGuessConopt)
1321{
1322 assert(nlpi != NULL);
1323 assert(problem != NULL);
1324 assert(problem->oracle != NULL);
1325
1326 if( primalvalues != NULL )
1327 {
1328 if( !problem->initguess )
1329 {
1330 SCIP_CALL( SCIPduplicateMemoryArray(scip, &problem->initguess, primalvalues, SCIPnlpiOracleGetNVars(problem->oracle)) );
1331 }
1332 else
1333 BMScopyMemoryArray(problem->initguess, primalvalues, SCIPnlpiOracleGetNVars(problem->oracle));
1334 }
1335 else
1336 SCIPfreeMemoryArrayNull(scip, &problem->initguess);
1337
1338 return SCIP_OKAY;
1339} /*lint !e715*/
1340
1341/** try to solve NLP
1342 *
1343 * Note that SCIP will already have reset a timelimit of SCIP_REAL_MAX to the time remaining for the SCIP solve in SCIPnlpiSolve().
1344 */
1345static
1346SCIP_DECL_NLPISOLVE(nlpiSolveConopt)
1347{
1348 SCIP_NLPIDATA* data;
1349 int COI_Error; /* CONOPT error counter */
1350
1351 assert(nlpi != NULL);
1352 assert(problem != NULL);
1353
1354 data = SCIPnlpiGetData(nlpi);
1355 assert(data != NULL);
1356
1357 SCIPdebugMsg(scip, "solve with parameters " SCIP_NLPPARAM_PRINT(param));
1358
1359 SCIP_CALL( SCIPnlpiOracleResetEvalTime(scip, problem->oracle) );
1360
1361 if( param.timelimit == 0.0 )
1362 {
1363 /* there is nothing we can do if we are not given any time */
1364 problem->niterations = 0;
1365 problem->solvetime = 0.0;
1366 problem->termstat = SCIP_NLPTERMSTAT_TIMELIMIT;
1367 problem->solstat = SCIP_NLPSOLSTAT_UNKNOWN;
1368
1369 return SCIP_OKAY;
1370 }
1371
1372 problem->niterations = -1;
1373 problem->solvetime = -1.0;
1374
1375 /* set CONOPT parameters */
1376 handleConoptParam(problem, param);
1377
1378 /* initialize Conopt data if necessary */
1379 if( problem->firstrun )
1380 {
1381 SCIP_CALL( initConopt(scip, data, problem) );
1382 problem->firstrun = FALSE;
1383 }
1384
1385 /* measure time */
1386 SCIP_CALL( SCIPresetClock(scip, data->solvetime) );
1387 SCIP_CALL( SCIPstartClock(scip, data->solvetime) );
1388
1389 /* optimize */
1390 COI_Error = COI_Solve(problem->CntVect);
1391
1392 /* CONOPT may return either a positive error code, which is one of its own error codes,
1393 * or a negative error code that is a SCIP_RETCODE returned from one of the callbacks */
1394 if( COI_Error )
1395 {
1396 switch( COI_Error )
1397 {
1398 case -1:
1399 SCIPdebugMsg(scip, "Insufficient memory in CONOPT callback\n");
1400 break;
1401 case -2:
1402 SCIPdebugMsg(scip, "Problem structure computation error in CONOPT's ReadMatrix callback\n");
1403 break;
1404 default:
1405 SCIPdebugMsg(scip, "Errors encountered in CONOPT during solution, %d\n", COI_Error);
1406 }
1407 }
1408
1409 /* store statistics (some statistics are passed back to SCIP by the Status callback) */
1410 problem->solvetime = SCIPgetClockTime(scip, data->solvetime);
1411
1412 return SCIP_OKAY; /*lint !e527*/
1413} /*lint !e715*/
1414
1415/** gives solution status */
1416static
1417SCIP_DECL_NLPIGETSOLSTAT(nlpiGetSolstatConopt)
1418{
1419 assert(nlpi != NULL);
1420 assert(problem != NULL);
1421
1422 return problem->solstat;
1423} /*lint !e715*/
1424
1425/** gives termination reason */
1426static
1427SCIP_DECL_NLPIGETTERMSTAT(nlpiGetTermstatConopt)
1428{
1429 assert(nlpi != NULL);
1430 assert(problem != NULL);
1431
1432 return problem->termstat;
1433} /*lint !e715*/
1434
1435/** gives primal and dual solution values */
1436static
1437SCIP_DECL_NLPIGETSOLUTION(nlpiGetSolutionConopt)
1438{
1439 assert(problem != NULL);
1440
1441 if( primalvalues != NULL )
1442 *primalvalues = problem->lastprimal;
1443
1444 if( consdualvalues != NULL )
1445 *consdualvalues = problem->lastdualcons;
1446
1447 if( varlbdualvalues != NULL )
1448 *varlbdualvalues = problem->lastduallb;
1449
1450 if( varubdualvalues != NULL )
1451 *varubdualvalues = problem->lastdualub;
1452
1453 if( objval != NULL )
1454 *objval = problem->objval;
1455
1456 return SCIP_OKAY; /*lint !e527*/
1457} /*lint !e715*/
1458
1459/** gives solve statistics */
1460static
1461SCIP_DECL_NLPIGETSTATISTICS(nlpiGetStatisticsConopt)
1462{
1463 assert(nlpi != NULL);
1464 assert(problem != NULL);
1465 assert(statistics != NULL);
1466
1467 statistics->niterations = problem->niterations;
1468 statistics->totaltime = problem->solvetime;
1469 statistics->evaltime = SCIPnlpiOracleGetEvalTime(scip, problem->oracle);
1470 statistics->consviol = SCIP_INVALID; /* TODO currently unavailable in CONOPT; might change */
1471 statistics->boundviol = 0.0;
1472
1473 return SCIP_OKAY;
1474} /*lint !e715*/
1475
1476/*
1477 * NLP solver interface specific interface methods
1478 */
1479
1480/** create solver interface for Conopt solver and includes it into SCIP */
1482 SCIP* scip /**< SCIP data structure */
1483 )
1484{
1485 SCIP_NLPIDATA* nlpidata;
1486
1487 /* create Conopt solver interface data */
1489
1490#if defined(CONOPT_LICENSE_INT_1) && defined(CONOPT_LICENSE_INT_2) && defined(CONOPT_LICENSE_INT_3) && \
1491 defined(CONOPT_LICENSE_TEXT)
1492 nlpidata->license_int_1 = CONOPT_LICENSE_INT_1;
1493 nlpidata->license_int_2 = CONOPT_LICENSE_INT_2;
1494 nlpidata->license_int_3 = CONOPT_LICENSE_INT_3;
1495 (void) SCIPsnprintf(nlpidata->license_text, (int)sizeof(nlpidata->license_text), "%s", CONOPT_LICENSE_TEXT);
1496#endif
1497
1498 /* create and include solver interface */
1501 nlpiCopyConopt, nlpiFreeConopt, nlpiGetSolverPointerConopt,
1502 nlpiCreateProblemConopt, nlpiFreeProblemConopt, nlpiGetProblemPointerConopt,
1503 nlpiAddVarsConopt, nlpiAddConstraintsConopt, nlpiSetObjectiveConopt,
1504 nlpiChgVarBoundsConopt, nlpiChgConsSidesConopt, nlpiDelVarSetConopt, nlpiDelConstraintSetConopt,
1505 nlpiChgLinearCoefsConopt, nlpiChgExprConopt, nlpiChgObjConstantConopt,
1506 nlpiSetInitialGuessConopt, nlpiSolveConopt,
1507 nlpiGetSolstatConopt, nlpiGetTermstatConopt, nlpiGetSolutionConopt, nlpiGetStatisticsConopt,
1508 nlpidata) );
1509
1511
1512 return SCIP_OKAY;
1513}
1514
1515/** sets the license to be passed to CONOPT's COIDEF_License */
1517 SCIP_NLPI* nlpi, /**< CONOPT NLPI */
1518 int integer_1, /**< CONOPT_LICENSE_INT_1 */
1519 int integer_2, /**< CONOPT_LICENSE_INT_2 */
1520 int integer_3, /**< CONOPT_LICENSE_INT_3 */
1521 const char* text /**< CONOPT_LICENSE_TEXT */
1522 )
1523{
1524 SCIP_NLPIDATA* data;
1525 assert(nlpi != NULL);
1526
1527 data = SCIPnlpiGetData(nlpi);
1528 assert(data != NULL);
1529
1530 data->license_int_1 = integer_1;
1531 data->license_int_2 = integer_2;
1532 data->license_int_3 = integer_3;
1533 (void) SCIPsnprintf(data->license_text, (int)sizeof(data->license_text), "%s", text);
1534}
1535
1536#define STR_HELPER(x) #x
1537#define STR(x) STR_HELPER(x)
1538
1539/** gets string that identifies CONOPT */
1541 void
1542 )
1543{
1544 return "CONOPT " STR(CONOPT_VERSION_MAJOR) "." STR(CONOPT_VERSION_MINOR) "." STR(CONOPT_VERSION_PATCH);
1545}
1546
1547/** gets string that describes CONOPT */
1549 void
1550 )
1551{
1552 return "Feasible path solver for large-scale nonlinear problems (conopt.com)";
1553}
1554
1555/** returns whether CONOPT is available, i.e., whether it has been linked in */
1557 void
1558 )
1559{
1560 return TRUE;
1561}
#define NULL
Definition: def.h:248
#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 SCIPABORT()
Definition: def.h:327
#define SCIP_CALL(x)
Definition: def.h:355
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:208
#define SCIPdebugMsg
Definition: scip_message.h:78
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
SCIP_RETCODE SCIPincludeNlpSolverConopt(SCIP *scip)
Definition: nlpi_conopt.c:1481
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 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_RETCODE SCIPnlpiOracleDelVarSet(SCIP *scip, SCIP_NLPIORACLE *oracle, int *delstats)
Definition: nlpioracle.c:1546
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 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 SCIPnlpiOracleGetJacobianColSparsity(SCIP *scip, SCIP_NLPIORACLE *oracle, const int **coloffsets, const int **rows, const SCIP_Bool **rownlflags, int *nnlnz)
Definition: nlpioracle.c:2318
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
SCIP_RETCODE SCIPnlpiOracleEvalConstraintGradient(SCIP *scip, SCIP_NLPIORACLE *oracle, const int considx, const SCIP_Real *x, SCIP_Bool isnewx, SCIP_Real *conval, SCIP_Real *congrad)
Definition: nlpioracle.c:2234
int SCIPnlpiOracleGetNVars(SCIP_NLPIORACLE *oracle)
Definition: nlpioracle.c:1933
int SCIPnlpiOracleGetNConstraints(SCIP_NLPIORACLE *oracle)
Definition: nlpioracle.c:1943
SCIP_RETCODE SCIPnlpiOracleGetObjGradientNnz(SCIP *scip, SCIP_NLPIORACLE *oracle, const int **nz, const SCIP_Bool **nlnz, int *nnz, int *nnlnz)
Definition: nlpioracle.c:2410
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
SCIP_RETCODE SCIPnlpiOracleEvalConstraintValue(SCIP *scip, SCIP_NLPIORACLE *oracle, int considx, const SCIP_Real *x, SCIP_Real *conval)
Definition: nlpioracle.c:2149
SCIP_Real SCIPnlpiOracleGetConstraintLinearCoef(SCIP_NLPIORACLE *oracle, int considx, int varpos)
Definition: nlpioracle.c:2064
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
void SCIPsetLicenseConopt(SCIP_NLPI *nlpi, int integer_1, int integer_2, int integer_3, const char *text)
Definition: nlpi_conopt.c:1516
const char * SCIPgetSolverDescConopt(void)
Definition: nlpi_conopt.c:1548
SCIP_Bool SCIPisConoptAvailableConopt(void)
Definition: nlpi_conopt.c:1556
const char * SCIPgetSolverNameConopt(void)
Definition: nlpi_conopt.c:1540
SCIP_RETCODE SCIPincludeExternalCodeInformation(SCIP *scip, const char *name, const char *description)
Definition: scip_general.c:769
#define SCIPfreeCleanBufferArray(scip, ptr)
Definition: scip_mem.h:146
#define SCIPallocCleanBufferArray(scip, ptr, num)
Definition: scip_mem.h:142
#define SCIPfreeMemoryArrayNull(scip, ptr)
Definition: scip_mem.h:81
#define SCIPallocClearBlockMemory(scip, ptr)
Definition: scip_mem.h:91
#define SCIPallocClearBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:97
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
#define SCIPduplicateMemoryArray(scip, ptr, source, num)
Definition: scip_mem.h:76
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:108
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip_mem.h:111
#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_NLPI * SCIPfindNlpi(SCIP *scip, const char *name)
Definition: scip_nlpi.c:179
SCIP_NLPIDATA * SCIPnlpiGetData(SCIP_NLPI *nlpi)
Definition: nlpi.c:712
SCIP_RETCODE SCIPcreateClock(SCIP *scip, SCIP_CLOCK **clck)
Definition: scip_timing.c:76
SCIP_RETCODE SCIPresetClock(SCIP *scip, SCIP_CLOCK *clck)
Definition: scip_timing.c:144
SCIP_RETCODE SCIPfreeClock(SCIP *scip, SCIP_CLOCK **clck)
Definition: scip_timing.c:127
SCIP_Real SCIPgetClockTime(SCIP *scip, SCIP_CLOCK *clck)
Definition: scip_timing.c:319
SCIP_RETCODE SCIPstartClock(SCIP *scip, SCIP_CLOCK *clck)
Definition: scip_timing.c:161
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
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
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:134
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:130
static SCIP_DECL_NLPICHGCONSSIDES(nlpiChgConsSidesConopt)
Definition: nlpi_conopt.c:1188
static SCIP_DECL_NLPICHGLINEARCOEFS(nlpiChgLinearCoefsConopt)
Definition: nlpi_conopt.c:1275
static int COI_CALLCONV LagrStr(int HSRW[], int HSCL[], int *NODRV, int NUMVAR, int NUMCON, int NHESS, void *USRMEM)
Definition: nlpi_conopt.c:759
#define NLPI_PRIORITY
Definition: nlpi_conopt.c:57
#define STR(x)
Definition: nlpi_conopt.c:1537
#define MAXPERTURB
Definition: nlpi_conopt.c:60
static SCIP_DECL_NLPIFREEPROBLEM(nlpiFreeProblemConopt)
Definition: nlpi_conopt.c:1074
static void handleConoptParam(SCIP_NLPIPROBLEM *problem, const SCIP_NLPPARAM param)
Definition: nlpi_conopt.c:944
static SCIP_DECL_NLPICHGOBJCONSTANT(nlpiChgObjConstantConopt)
Definition: nlpi_conopt.c:1307
static SCIP_DECL_NLPIADDCONSTRAINTS(nlpiAddConstraintsConopt)
Definition: nlpi_conopt.c:1140
static SCIP_DECL_NLPISETOBJECTIVE(nlpiSetObjectiveConopt)
Definition: nlpi_conopt.c:1157
static SCIP_DECL_NLPIGETSOLSTAT(nlpiGetSolstatConopt)
Definition: nlpi_conopt.c:1417
static int COI_CALLCONV ReadMatrix(double LOWER[], double CURR[], double UPPER[], int VSTA[], int TYPE[], double RHS[], int ESTA[], int COLSTA[], int ROWNO[], double VALUE[], int NLFLAG[], int NUMVAR, int NUMCON, int NUMNZ, void *USRMEM)
Definition: nlpi_conopt.c:222
static int COI_CALLCONV FDEval(const double X[], double *G, double JAC[], int ROWNO, const int JACNUM[], int MODE, int IGNERR, int *ERRCNT, int NUMVAR, int NUMJAC, int THREAD, void *USRMEM)
Definition: nlpi_conopt.c:679
#define NLPI_NAME
Definition: nlpi_conopt.c:55
static SCIP_DECL_NLPICHGEXPR(nlpiChgExprConopt)
Definition: nlpi_conopt.c:1291
static int COI_CALLCONV LagrVal(const double X[], const double U[], const int HSRW[], const int HSCL[], double HSVL[], int *NODRV, int NUMVAR, int NUMCON, int NHESS, void *USRMEM)
Definition: nlpi_conopt.c:800
static SCIP_DECL_NLPICREATEPROBLEM(nlpiCreateProblemConopt)
Definition: nlpi_conopt.c:1045
#define nlpiGetSolverPointerConopt
Definition: nlpi_conopt.c:1040
static SCIP_DECL_NLPIDELVARSET(nlpiDelVarSetConopt)
Definition: nlpi_conopt.c:1243
#define nlpiGetProblemPointerConopt
Definition: nlpi_conopt.c:1118
static SCIP_DECL_NLPIDELCONSSET(nlpiDelConstraintSetConopt)
Definition: nlpi_conopt.c:1259
static SCIP_DECL_NLPICHGVARBOUNDS(nlpiChgVarBoundsConopt)
Definition: nlpi_conopt.c:1173
#define DEFAULT_RANDSEED
Definition: nlpi_conopt.c:59
static int COI_CALLCONV Solution(const double XVAL[], const double XMAR[], const int XBAS[], const int XSTA[], const double YVAL[], const double YMAR[], const int YBAS[], const int YSTA[], int NUMVAR, int NUMCON, void *USRMEM)
Definition: nlpi_conopt.c:123
static int COI_CALLCONV ErrMsg(int ROWNO, int COLNO, int POSNO, const char *MSG, void *USRMEM)
Definition: nlpi_conopt.c:524
static SCIP_RETCODE initConopt(SCIP *scip, SCIP_NLPIDATA *data, SCIP_NLPIPROBLEM *problem)
Definition: nlpi_conopt.c:847
static int COI_CALLCONV Status(int MODSTA, int SOLSTA, int ITER, double OBJVAL, void *USRMEM)
Definition: nlpi_conopt.c:551
static SCIP_DECL_NLPIGETTERMSTAT(nlpiGetTermstatConopt)
Definition: nlpi_conopt.c:1427
static SCIP_DECL_NLPIGETSOLUTION(nlpiGetSolutionConopt)
Definition: nlpi_conopt.c:1437
static SCIP_DECL_NLPISETINITIALGUESS(nlpiSetInitialGuessConopt)
Definition: nlpi_conopt.c:1320
static SCIP_DECL_NLPIADDVARS(nlpiAddVarsConopt)
Definition: nlpi_conopt.c:1123
static SCIP_DECL_NLPIGETSTATISTICS(nlpiGetStatisticsConopt)
Definition: nlpi_conopt.c:1461
static SCIP_DECL_NLPIFREE(nlpiFreeConopt)
Definition: nlpi_conopt.c:1011
static int COI_CALLCONV Message(int SMSG, int DMSG, int NMSG, char *MSGV[], void *USRMEM)
Definition: nlpi_conopt.c:501
static int COI_CALLCONV Option(int NCALL, double *RVAL, int *IVAL, int *LVAL, char *NAME, void *USRMEM)
Definition: nlpi_conopt.c:725
static SCIP_DECL_NLPICOPY(nlpiCopyConopt)
Definition: nlpi_conopt.c:985
#define NLPI_DESC
Definition: nlpi_conopt.c:56
static SCIP_DECL_NLPISOLVE(nlpiSolveConopt)
Definition: nlpi_conopt.c:1346
static void invalidateSolution(SCIP_NLPIPROBLEM *problem)
Definition: nlpi_conopt.c:830
CONOPT 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
public data structures and miscellaneous methods
general public methods
public methods for memory management
public methods for message handling
public methods for nonlinear relaxation
public methods for NLPI solver interfaces
public methods for numerical tolerances
public methods for random numbers
public methods for timing
@ RHS
SCIP_Real timelimit
Definition: type_nlpi.h:72
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
coiHandle_t CntVect
Definition: nlpi_conopt.c:97
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_RANDNUMGEN * randnumgen
Definition: nlpi_conopt.c:79
SCIP_Real solvetime
Definition: nlpi_conopt.c:86
SCIP_NLPTERMSTAT termstat
Definition: nlpi_conopt.c:85
SCIP_Real opttol
Definition: nlpi_conopt.c:101
SCIP_Real * lastdualub
Definition: nlpi_conopt.c:93
SCIP_Real objval
Definition: nlpi_conopt.c:88
SCIP_Real * initguess
Definition: nlpi_conopt.c:82
SCIP_NLPSOLSTAT solstat
Definition: nlpi_conopt.c:84
type definitions for clocks and timing issues
#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_ITERLIMIT
Definition: type_nlpi.h:175
@ SCIP_NLPTERMSTAT_INTERRUPT
Definition: type_nlpi.h:177
#define SCIP_DECL_NLPIGETSOLVERPOINTER(x)
Definition: type_nlpi.h:233
#define SCIP_DECL_NLPIGETPROBLEMPOINTER(x)
Definition: type_nlpi.h:272
@ 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_GLOBOPT
Definition: type_nlpi.h:160
@ 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_ERROR
Definition: type_retcode.h:43
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63