1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2021 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scipopt.org. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15
16 /**@file scip_nlp.c
17 * @ingroup OTHER_CFILES
18 * @brief public methods for nonlinear relaxations
19 * @author Tobias Achterberg
20 * @author Timo Berthold
21 * @author Gerald Gamrath
22 * @author Leona Gottwald
23 * @author Stefan Heinz
24 * @author Gregor Hendel
25 * @author Thorsten Koch
26 * @author Alexander Martin
27 * @author Marc Pfetsch
28 * @author Michael Winkler
29 * @author Kati Wolter
30 *
31 * @todo check all SCIP_STAGE_* switches, and include the new stages TRANSFORMED and INITSOLVE
32 */
33
34 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
35
36 #include "blockmemshell/memory.h"
37 #include "nlpi/nlpi.h"
38 #include "scip/debug.h"
39 #include "scip/nlp.h"
40 #include "scip/pub_message.h"
41 #include "scip/pub_misc.h"
42 #include "scip/pub_nlp.h"
43 #include "scip/pub_paramset.h"
44 #include "scip/scip_mem.h"
45 #include "scip/scip_nlp.h"
46 #include "scip/scip_param.h"
47 #include "scip/scip_sol.h"
48 #include "scip/set.h"
49 #include "scip/struct_mem.h"
50 #include "scip/struct_prob.h"
51 #include "scip/struct_scip.h"
52 #include "scip/struct_set.h"
53 #include "scip/struct_var.h"
54
55 /** method to call, when the priority of an NLPI was changed */
56 static
SCIP_DECL_PARAMCHGD(paramChgdNlpiPriority)57 SCIP_DECL_PARAMCHGD(paramChgdNlpiPriority)
58 { /*lint --e{715}*/
59 SCIP_PARAMDATA* paramdata;
60
61 paramdata = SCIPparamGetData(param);
62 assert(paramdata != NULL);
63
64 /* use SCIPsetSetPriorityNlpi() to mark the nlpis unsorted */
65 SCIP_CALL( SCIPsetNlpiPriority(scip, (SCIP_NLPI*)paramdata, SCIPparamGetInt(param)) );
66
67 return SCIP_OKAY;
68 }
69 /** includes an NLPI in SCIP */
SCIPincludeNlpi(SCIP * scip,SCIP_NLPI * nlpi)70 SCIP_RETCODE SCIPincludeNlpi(
71 SCIP* scip, /**< SCIP data structure */
72 SCIP_NLPI* nlpi /**< NLPI data structure */
73 )
74 {
75 char paramname[SCIP_MAXSTRLEN];
76 char paramdesc[SCIP_MAXSTRLEN];
77
78 assert(scip != NULL);
79 assert(nlpi != NULL);
80
81 SCIP_CALL( SCIPcheckStage(scip, "SCIPincludeNlpi", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
82
83 /* check whether NLPI is already present */
84 if( SCIPfindNlpi(scip, SCIPnlpiGetName(nlpi)) != NULL )
85 {
86 SCIPerrorMessage("NLPI <%s> already included.\n", SCIPnlpiGetName(nlpi));
87 return SCIP_INVALIDDATA;
88 }
89
90 SCIP_CALL( SCIPsetIncludeNlpi(scip->set, nlpi) );
91
92 /* add parameters */
93 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "nlpi/%s/priority", SCIPnlpiGetName(nlpi));
94 (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of NLPI <%s>", SCIPnlpiGetName(nlpi));
95 SCIP_CALL( SCIPaddIntParam(scip, paramname, paramdesc,
96 NULL, FALSE, SCIPnlpiGetPriority(nlpi), INT_MIN/4, INT_MAX/4,
97 paramChgdNlpiPriority, (SCIP_PARAMDATA*)nlpi) ); /*lint !e740*/
98
99 /* pass message handler (may be NULL) */
100 SCIP_CALL( SCIPnlpiSetMessageHdlr(nlpi, scip->messagehdlr) );
101
102 return SCIP_OKAY;
103 }
104
105 /** returns the NLPI of the given name, or NULL if not existing */
SCIPfindNlpi(SCIP * scip,const char * name)106 SCIP_NLPI* SCIPfindNlpi(
107 SCIP* scip, /**< SCIP data structure */
108 const char* name /**< name of NLPI */
109 )
110 {
111 assert(scip != NULL);
112 assert(scip->set != NULL);
113 assert(name != NULL);
114
115 return SCIPsetFindNlpi(scip->set, name);
116 }
117
118 /** returns the array of currently available NLPIs (sorted by priority) */
SCIPgetNlpis(SCIP * scip)119 SCIP_NLPI** SCIPgetNlpis(
120 SCIP* scip /**< SCIP data structure */
121 )
122 {
123 assert(scip != NULL);
124 assert(scip->set != NULL);
125
126 SCIPsetSortNlpis(scip->set);
127
128 return scip->set->nlpis;
129 }
130
131 /** returns the number of currently available NLPIs */
SCIPgetNNlpis(SCIP * scip)132 int SCIPgetNNlpis(
133 SCIP* scip /**< SCIP data structure */
134 )
135 {
136 assert(scip != NULL);
137 assert(scip->set != NULL);
138
139 return scip->set->nnlpis;
140 }
141
142 /** sets the priority of an NLPI */
SCIPsetNlpiPriority(SCIP * scip,SCIP_NLPI * nlpi,int priority)143 SCIP_RETCODE SCIPsetNlpiPriority(
144 SCIP* scip, /**< SCIP data structure */
145 SCIP_NLPI* nlpi, /**< NLPI */
146 int priority /**< new priority of the NLPI */
147 )
148 {
149 assert(scip != NULL);
150 assert(scip->set != NULL);
151
152 SCIPsetSetPriorityNlpi(scip->set, nlpi, priority);
153
154 return SCIP_OKAY;
155 }
156
157 /** returns whether the NLP relaxation has been enabled
158 *
159 * If the NLP relaxation is enabled, then SCIP will construct the NLP relaxation when the solving process is about to begin.
160 * To check whether an NLP is existing, use SCIPisNLPConstructed().
161 *
162 * @pre This method can be called if SCIP is in one of the following stages:
163 * - \ref SCIP_STAGE_INITPRESOLVE
164 * - \ref SCIP_STAGE_PRESOLVING
165 * - \ref SCIP_STAGE_EXITPRESOLVE
166 * - \ref SCIP_STAGE_PRESOLVED
167 * - \ref SCIP_STAGE_INITSOLVE
168 * - \ref SCIP_STAGE_SOLVING
169 *
170 * @see SCIPenableNLP
171 */
SCIPisNLPEnabled(SCIP * scip)172 SCIP_Bool SCIPisNLPEnabled(
173 SCIP* scip /**< SCIP data structure */
174 )
175 {
176 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisNLPEnabled", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
177
178 return scip->transprob->nlpenabled;
179 }
180
181 /** marks that there are constraints that are representable by nonlinear rows
182 *
183 * This method should be called by a constraint handler if it has constraints that have a representation as nonlinear rows.
184 *
185 * The function should be called before the branch-and-bound process is initialized, e.g., when presolve is exiting.
186 *
187 * @pre This method can be called if SCIP is in one of the following stages:
188 * - \ref SCIP_STAGE_INITPRESOLVE
189 * - \ref SCIP_STAGE_PRESOLVING
190 * - \ref SCIP_STAGE_EXITPRESOLVE
191 * - \ref SCIP_STAGE_PRESOLVED
192 * - \ref SCIP_STAGE_INITSOLVE
193 * - \ref SCIP_STAGE_SOLVING
194 */
SCIPenableNLP(SCIP * scip)195 void SCIPenableNLP(
196 SCIP* scip /**< SCIP data structure */
197 )
198 {
199 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPenableNLP", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
200
201 scip->transprob->nlpenabled = TRUE;
202 }
203
204 /** returns, whether an NLP has been constructed
205 *
206 * @pre This method can be called if SCIP is in one of the following stages:
207 * - \ref SCIP_STAGE_INITSOLVE
208 * - \ref SCIP_STAGE_SOLVING
209 */
SCIPisNLPConstructed(SCIP * scip)210 SCIP_Bool SCIPisNLPConstructed(
211 SCIP* scip /**< SCIP data structure */
212 )
213 {
214 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisNLPConstructed", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
215
216 return (scip->nlp != NULL);
217 }
218
219 /** returns whether the NLP has a continuous variable in a nonlinear term
220 *
221 * @pre This method can be called if SCIP is in one of the following stages:
222 * - \ref SCIP_STAGE_INITSOLVE
223 * - \ref SCIP_STAGE_SOLVING
224 */
SCIPhasNLPContinuousNonlinearity(SCIP * scip)225 SCIP_Bool SCIPhasNLPContinuousNonlinearity(
226 SCIP* scip /**< SCIP data structure */
227 )
228 {
229 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPhasNLPContinuousNonlinearity", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
230
231 if( scip->nlp == NULL )
232 {
233 SCIPerrorMessage("NLP has not been not constructed.\n");
234 SCIPABORT();
235 return FALSE; /*lint !e527*/
236 }
237
238 return SCIPnlpHasContinuousNonlinearity(scip->nlp);
239 }
240
241 /** gets current NLP variables along with the current number of NLP variables
242 *
243 * @pre This method can be called if SCIP is in one of the following stages:
244 * - \ref SCIP_STAGE_INITSOLVE
245 * - \ref SCIP_STAGE_SOLVING
246 */
SCIPgetNLPVarsData(SCIP * scip,SCIP_VAR *** vars,int * nvars)247 SCIP_RETCODE SCIPgetNLPVarsData(
248 SCIP* scip, /**< SCIP data structure */
249 SCIP_VAR*** vars, /**< pointer to store the array of NLP variables, or NULL */
250 int* nvars /**< pointer to store the number of NLP variables, or NULL */
251 )
252 {
253 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNLPVarsData", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
254
255 if( scip->nlp != NULL )
256 {
257 if( vars != NULL )
258 *vars = SCIPnlpGetVars(scip->nlp);
259 if( nvars != NULL )
260 *nvars = SCIPnlpGetNVars(scip->nlp);
261 }
262 else
263 {
264 SCIPerrorMessage("NLP has not been constructed.\n");
265 return SCIP_INVALIDCALL;
266 }
267
268 return SCIP_OKAY;
269 }
270
271 /** gets array with variables of the NLP
272 *
273 * @pre This method can be called if SCIP is in one of the following stages:
274 * - \ref SCIP_STAGE_INITSOLVE
275 * - \ref SCIP_STAGE_SOLVING
276 */
SCIPgetNLPVars(SCIP * scip)277 SCIP_VAR** SCIPgetNLPVars(
278 SCIP* scip /**< SCIP data structure */
279 )
280 {
281 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNLPVars", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
282
283 if( scip->nlp == NULL )
284 {
285 SCIPerrorMessage("NLP has not been constructed.\n");
286 SCIPABORT();
287 return NULL; /*lint !e527*/
288 }
289
290 return SCIPnlpGetVars(scip->nlp);
291 }
292
293 /** gets current number of variables in NLP
294 *
295 * @pre This method can be called if SCIP is in one of the following stages:
296 * - \ref SCIP_STAGE_INITSOLVE
297 * - \ref SCIP_STAGE_SOLVING
298 */
SCIPgetNNLPVars(SCIP * scip)299 int SCIPgetNNLPVars(
300 SCIP* scip /**< SCIP data structure */
301 )
302 {
303 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNNLPVars", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
304
305 if( scip->nlp == NULL )
306 {
307 SCIPerrorMessage("NLP has not been constructed.\n");
308 SCIPABORT();
309 return 0; /*lint !e527*/
310 }
311
312 return SCIPnlpGetNVars(scip->nlp);
313 }
314
315 /** computes for each variables the number of NLP rows in which the variable appears in a nonlinear var
316 *
317 * @pre This method can be called if SCIP is in one of the following stages:
318 * - \ref SCIP_STAGE_INITSOLVE
319 * - \ref SCIP_STAGE_SOLVING
320 */
SCIPgetNLPVarsNonlinearity(SCIP * scip,int * nlcount)321 SCIP_RETCODE SCIPgetNLPVarsNonlinearity(
322 SCIP* scip, /**< SCIP data structure */
323 int* nlcount /**< an array of length at least SCIPnlpGetNVars() to store nonlinearity counts of variables */
324 )
325 {
326 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNLPVarsNonlinearity", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
327
328 if( scip->nlp == NULL )
329 {
330 SCIPerrorMessage("NLP has not been constructed.\n");
331 return SCIP_INVALIDCALL;
332 }
333
334 SCIP_CALL( SCIPnlpGetVarsNonlinearity(scip->nlp, nlcount) );
335
336 return SCIP_OKAY;
337 }
338
339 /** returns dual solution values associated with lower bounds of NLP variables
340 *
341 * @pre This method can be called if SCIP is in one of the following stages:
342 * - \ref SCIP_STAGE_INITSOLVE
343 * - \ref SCIP_STAGE_SOLVING
344 */
SCIPgetNLPVarsLbDualsol(SCIP * scip)345 SCIP_Real* SCIPgetNLPVarsLbDualsol(
346 SCIP* scip /**< SCIP data structure */
347 )
348 {
349 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNLPVarsLbDualsol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
350
351 if( scip->nlp == NULL )
352 {
353 SCIPerrorMessage("NLP has not been constructed.\n");
354 SCIPABORT();
355 return NULL; /*lint !e527*/
356 }
357
358 return SCIPnlpGetVarsLbDualsol(scip->nlp);
359 }
360
361 /** returns dual solution values associated with upper bounds of NLP variables
362 *
363 * @pre This method can be called if SCIP is in one of the following stages:
364 * - \ref SCIP_STAGE_INITSOLVE
365 * - \ref SCIP_STAGE_SOLVING
366 */
SCIPgetNLPVarsUbDualsol(SCIP * scip)367 SCIP_Real* SCIPgetNLPVarsUbDualsol(
368 SCIP* scip /**< SCIP data structure */
369 )
370 {
371 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNLPVarsUbDualsol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
372
373 if( scip->nlp == NULL )
374 {
375 SCIPerrorMessage("NLP has not been constructed.\n");
376 SCIPABORT();
377 return NULL; /*lint !e527*/
378 }
379
380 return SCIPnlpGetVarsUbDualsol(scip->nlp);
381 }
382
383 /** gets current NLP nonlinear rows along with the current number of NLP nonlinear rows
384 *
385 * @pre This method can be called if SCIP is in one of the following stages:
386 * - \ref SCIP_STAGE_INITSOLVE
387 * - \ref SCIP_STAGE_SOLVING
388 */
SCIPgetNLPNlRowsData(SCIP * scip,SCIP_NLROW *** nlrows,int * nnlrows)389 SCIP_RETCODE SCIPgetNLPNlRowsData(
390 SCIP* scip, /**< SCIP data structure */
391 SCIP_NLROW*** nlrows, /**< pointer to store the array of NLP nonlinear rows, or NULL */
392 int* nnlrows /**< pointer to store the number of NLP nonlinear rows, or NULL */
393 )
394 {
395 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNLPNlRowsData", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
396
397 if( scip->nlp == NULL )
398 {
399 SCIPerrorMessage("NLP has not been constructed.\n");
400 return SCIP_INVALIDCALL;
401 }
402
403 if( nlrows != NULL )
404 *nlrows = SCIPnlpGetNlRows(scip->nlp);
405 if( nnlrows != NULL )
406 *nnlrows = SCIPnlpGetNNlRows(scip->nlp);
407
408 return SCIP_OKAY;
409 }
410
411 /** gets array with nonlinear rows of the NLP
412 *
413 * @pre This method can be called if SCIP is in one of the following stages:
414 * - \ref SCIP_STAGE_INITSOLVE
415 * - \ref SCIP_STAGE_SOLVING
416 */
SCIPgetNLPNlRows(SCIP * scip)417 SCIP_NLROW** SCIPgetNLPNlRows(
418 SCIP* scip /**< SCIP data structure */
419 )
420 {
421 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNLPNlRows", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
422
423 if( scip->nlp == NULL )
424 {
425 SCIPerrorMessage("NLP has not been constructed.\n");
426 SCIPABORT();
427 return NULL; /*lint !e527*/
428 }
429
430 return SCIPnlpGetNlRows(scip->nlp);
431 }
432
433 /** gets current number of nonlinear rows in NLP
434 *
435 * @pre This method can be called if SCIP is in one of the following stages:
436 * - \ref SCIP_STAGE_INITSOLVE
437 * - \ref SCIP_STAGE_SOLVING
438 */
SCIPgetNNLPNlRows(SCIP * scip)439 int SCIPgetNNLPNlRows(
440 SCIP* scip /**< SCIP data structure */
441 )
442 {
443 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNNLPNlRows", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
444
445 if( scip->nlp == NULL )
446 {
447 SCIPerrorMessage("NLP has not been constructed.\n");
448 SCIPABORT();
449 return 0; /*lint !e527*/
450 }
451
452 return SCIPnlpGetNNlRows(scip->nlp);
453 }
454
455 /** adds a nonlinear row to the NLP. This row is captured by the NLP.
456 *
457 * @pre This method can be called if SCIP is in one of the following stages:
458 * - \ref SCIP_STAGE_INITSOLVE
459 * - \ref SCIP_STAGE_SOLVING
460 */
SCIPaddNlRow(SCIP * scip,SCIP_NLROW * nlrow)461 SCIP_RETCODE SCIPaddNlRow(
462 SCIP* scip, /**< SCIP data structure */
463 SCIP_NLROW* nlrow /**< nonlinear row to add to NLP */
464 )
465 {
466 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddNlRow", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
467
468 if( scip->nlp == NULL )
469 {
470 SCIPerrorMessage("NLP has not been constructed.\n");
471 return SCIP_INVALIDCALL;
472 }
473
474 SCIP_CALL( SCIPnlpAddNlRow(scip->nlp, SCIPblkmem(scip), scip->set, scip->stat, nlrow) );
475
476 return SCIP_OKAY;
477 }
478
479 /** removes a nonlinear row from the NLP.
480 *
481 * @pre This method can be called if SCIP is in one of the following stages:
482 * - \ref SCIP_STAGE_INITSOLVE
483 * - \ref SCIP_STAGE_SOLVING
484 * - \ref SCIP_STAGE_SOLVED
485 * - \ref SCIP_STAGE_EXITSOLVE
486 */
SCIPdelNlRow(SCIP * scip,SCIP_NLROW * nlrow)487 SCIP_RETCODE SCIPdelNlRow(
488 SCIP* scip, /**< SCIP data structure */
489 SCIP_NLROW* nlrow /**< nonlinear row to add to NLP */
490 )
491 {
492 SCIP_CALL( SCIPcheckStage(scip, "SCIPdelNlRow", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
493
494 if( scip->nlp == NULL )
495 {
496 SCIPerrorMessage("NLP has not been constructed.\n");
497 return SCIP_INVALIDCALL;
498 }
499
500 SCIP_CALL( SCIPnlpDelNlRow(scip->nlp, SCIPblkmem(scip), scip->set, nlrow) );
501
502 return SCIP_OKAY;
503 }
504
505 /** makes sure that the NLP of the current node is flushed
506 *
507 * @pre This method can be called if SCIP is in one of the following stages:
508 * - \ref SCIP_STAGE_INITSOLVE
509 * - \ref SCIP_STAGE_SOLVING
510 */
SCIPflushNLP(SCIP * scip)511 SCIP_RETCODE SCIPflushNLP(
512 SCIP* scip /**< SCIP data structure */
513 )
514 {
515 SCIP_CALL( SCIPcheckStage(scip, "SCIPflushNLP", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
516
517 if( scip->nlp == NULL )
518 {
519 SCIPerrorMessage("NLP has not been constructed.\n");
520 return SCIP_INVALIDCALL;
521 }
522
523 SCIP_CALL( SCIPnlpFlush(scip->nlp, scip->mem->probmem, scip->set) );
524
525 return SCIP_OKAY;
526 }
527
528 /** sets or clears initial primal guess for NLP solution (start point for NLP solver)
529 *
530 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
531 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
532 *
533 * @pre This method can be called if SCIP is in one of the following stages:
534 * - \ref SCIP_STAGE_INITSOLVE
535 * - \ref SCIP_STAGE_SOLVING
536 */
SCIPsetNLPInitialGuess(SCIP * scip,SCIP_Real * initialguess)537 SCIP_RETCODE SCIPsetNLPInitialGuess(
538 SCIP* scip, /**< SCIP data structure */
539 SCIP_Real* initialguess /**< values of initial guess (corresponding to variables from SCIPgetNLPVarsData), or NULL to use no start point */
540 )
541 {
542 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetNLPInitialGuess", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
543
544 if( scip->nlp == NULL )
545 {
546 SCIPerrorMessage("NLP has not been constructed.\n");
547 return SCIP_INVALIDCALL;
548 }
549
550 SCIP_CALL( SCIPnlpSetInitialGuess(scip->nlp, SCIPblkmem(scip), initialguess) );
551
552 return SCIP_OKAY;
553 }
554
555 /** sets initial primal guess for NLP solution (start point for NLP solver)
556 *
557 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
558 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
559 *
560 * @pre This method can be called if SCIP is in one of the following stages:
561 * - \ref SCIP_STAGE_INITSOLVE
562 * - \ref SCIP_STAGE_SOLVING
563 */
SCIPsetNLPInitialGuessSol(SCIP * scip,SCIP_SOL * sol)564 SCIP_RETCODE SCIPsetNLPInitialGuessSol(
565 SCIP* scip, /**< SCIP data structure */
566 SCIP_SOL* sol /**< solution which values should be taken as initial guess, or NULL for LP solution */
567 )
568 {
569 SCIP_Real* vals;
570
571 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetNLPInitialGuessSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
572
573 if( scip->nlp == NULL )
574 {
575 SCIPerrorMessage("NLP has not been constructed.\n");
576 return SCIP_INVALIDCALL;
577 }
578
579 SCIP_CALL( SCIPallocBufferArray(scip, &vals, SCIPnlpGetNVars(scip->nlp)) );
580 SCIP_CALL( SCIPgetSolVals(scip, sol, SCIPnlpGetNVars(scip->nlp), SCIPnlpGetVars(scip->nlp), vals) );
581 SCIP_CALL( SCIPnlpSetInitialGuess(scip->nlp, SCIPblkmem(scip), vals) );
582 SCIPfreeBufferArray(scip, &vals);
583
584 return SCIP_OKAY;
585 }
586
587 /** solves the current NLP
588 *
589 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
590 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
591 *
592 * @pre This method can be called if SCIP is in one of the following stages:
593 * - \ref SCIP_STAGE_INITSOLVE
594 * - \ref SCIP_STAGE_SOLVING
595 */
SCIPsolveNLP(SCIP * scip)596 SCIP_RETCODE SCIPsolveNLP(
597 SCIP* scip /**< SCIP data structure */
598 )
599 {
600 SCIP_CALL( SCIPcheckStage(scip, "SCIPsolveNLP", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
601
602 if( scip->nlp == NULL )
603 {
604 SCIPerrorMessage("NLP has not been constructed.\n");
605 return SCIP_INVALIDCALL;
606 }
607
608 SCIP_CALL( SCIPnlpSolve(scip->nlp, SCIPblkmem(scip), scip->set, scip->messagehdlr, scip->stat) );
609
610 return SCIP_OKAY;
611 }
612
613 /** gets solution status of current NLP
614 *
615 * @pre This method can be called if SCIP is in one of the following stages:
616 * - \ref SCIP_STAGE_INITSOLVE
617 * - \ref SCIP_STAGE_SOLVING
618 */
SCIPgetNLPSolstat(SCIP * scip)619 SCIP_NLPSOLSTAT SCIPgetNLPSolstat(
620 SCIP* scip /**< SCIP data structure */
621 )
622 {
623 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNLPSolstat", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
624
625 if( scip->nlp == NULL )
626 {
627 SCIPerrorMessage("NLP has not been constructed.\n");
628 SCIPABORT();
629 return SCIP_NLPSOLSTAT_UNKNOWN; /*lint !e527*/
630 }
631
632 return SCIPnlpGetSolstat(scip->nlp);
633 }
634
635 /** gets termination status of last NLP solve
636 *
637 * @pre This method can be called if SCIP is in one of the following stages:
638 * - \ref SCIP_STAGE_INITSOLVE
639 * - \ref SCIP_STAGE_SOLVING
640 */
SCIPgetNLPTermstat(SCIP * scip)641 SCIP_NLPTERMSTAT SCIPgetNLPTermstat(
642 SCIP* scip /**< SCIP data structure */
643 )
644 {
645 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNLPTermstat", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
646
647 if( scip->nlp == NULL )
648 {
649 SCIPerrorMessage("NLP has not been constructed.\n");
650 SCIPABORT();
651 return SCIP_NLPTERMSTAT_OTHER; /*lint !e527*/
652 }
653
654 return SCIPnlpGetTermstat(scip->nlp);
655 }
656
657 /** gives statistics (number of iterations, solving time, ...) of last NLP solve
658 *
659 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
660 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
661 *
662 * @pre This method can be called if SCIP is in one of the following stages:
663 * - \ref SCIP_STAGE_INITSOLVE
664 * - \ref SCIP_STAGE_SOLVING
665 */
SCIPgetNLPStatistics(SCIP * scip,SCIP_NLPSTATISTICS * statistics)666 SCIP_RETCODE SCIPgetNLPStatistics(
667 SCIP* scip, /**< SCIP data structure */
668 SCIP_NLPSTATISTICS* statistics /**< pointer to store statistics */
669 )
670 {
671 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNLPStatistics", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
672
673 if( scip->nlp == NULL )
674 {
675 SCIPerrorMessage("NLP has not been constructed.\n");
676 return SCIP_INVALIDCALL;
677 }
678
679 SCIP_CALL( SCIPnlpGetStatistics(scip->nlp, statistics) );
680
681 return SCIP_OKAY;
682 }
683
684 /** gets objective value of current NLP
685 *
686 * @pre This method can be called if SCIP is in one of the following stages:
687 * - \ref SCIP_STAGE_INITSOLVE
688 * - \ref SCIP_STAGE_SOLVING
689 */
SCIPgetNLPObjval(SCIP * scip)690 SCIP_Real SCIPgetNLPObjval(
691 SCIP* scip /**< SCIP data structure */
692 )
693 {
694 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNLPObjval", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
695
696 if( scip->nlp != NULL )
697 {
698 return SCIPnlpGetObjval(scip->nlp);
699 }
700 else
701 {
702 SCIPerrorMessage("NLP has not been constructed.\n");
703 return SCIP_INVALID;
704 }
705 }
706
707 /** indicates whether a feasible solution for the current NLP is available
708 * thus, returns whether the solution status <= feasible
709 *
710 * @pre This method can be called if SCIP is in one of the following stages:
711 * - \ref SCIP_STAGE_INITSOLVE
712 * - \ref SCIP_STAGE_SOLVING
713 */
SCIPhasNLPSolution(SCIP * scip)714 SCIP_Bool SCIPhasNLPSolution(
715 SCIP* scip /**< SCIP data structure */
716 )
717 {
718 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPhasNLPSolution", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
719
720 if( scip->nlp == NULL )
721 {
722 SCIPerrorMessage("NLP has not been constructed.\n");
723 SCIPABORT();
724 return FALSE; /*lint !e527*/
725 }
726
727 return SCIPnlpHasSolution(scip->nlp);
728 }
729
730 /** gets fractional variables of last NLP solution along with solution values and fractionalities
731 *
732 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
733 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
734 *
735 * @pre This method can be called if SCIP is in one of the following stages:
736 * - \ref SCIP_STAGE_INITSOLVE
737 * - \ref SCIP_STAGE_SOLVING
738 */
SCIPgetNLPFracVars(SCIP * scip,SCIP_VAR *** fracvars,SCIP_Real ** fracvarssol,SCIP_Real ** fracvarsfrac,int * nfracvars,int * npriofracvars)739 SCIP_RETCODE SCIPgetNLPFracVars(
740 SCIP* scip, /**< SCIP data structure */
741 SCIP_VAR*** fracvars, /**< pointer to store the array of NLP fractional variables, or NULL */
742 SCIP_Real** fracvarssol, /**< pointer to store the array of NLP fractional variables solution values, or NULL */
743 SCIP_Real** fracvarsfrac, /**< pointer to store the array of NLP fractional variables fractionalities, or NULL */
744 int* nfracvars, /**< pointer to store the number of NLP fractional variables , or NULL */
745 int* npriofracvars /**< pointer to store the number of NLP fractional variables with maximal branching priority, or NULL */
746 )
747 {
748 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNLPFracVars", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
749
750 if( scip->nlp == NULL )
751 {
752 SCIPerrorMessage("NLP has not been constructed.\n");
753 return SCIP_INVALIDCALL;
754 }
755
756 SCIP_CALL( SCIPnlpGetFracVars(scip->nlp, SCIPblkmem(scip), scip->set, scip->stat, fracvars, fracvarssol, fracvarsfrac, nfracvars, npriofracvars) );
757
758 return SCIP_OKAY;
759 }
760
761 /** gets integer parameter of NLP
762 *
763 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
764 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
765 *
766 * @pre This method can be called if SCIP is in one of the following stages:
767 * - \ref SCIP_STAGE_INITSOLVE
768 * - \ref SCIP_STAGE_SOLVING
769 */
SCIPgetNLPIntPar(SCIP * scip,SCIP_NLPPARAM type,int * ival)770 SCIP_RETCODE SCIPgetNLPIntPar(
771 SCIP* scip, /**< SCIP data structure */
772 SCIP_NLPPARAM type, /**< parameter number */
773 int* ival /**< pointer to store the parameter value */
774 )
775 {
776 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNLPIntPar", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
777
778 if( scip->nlp == NULL )
779 {
780 SCIPerrorMessage("NLP has not been constructed.\n");
781 return SCIP_INVALIDCALL;
782 }
783
784 SCIP_CALL( SCIPnlpGetIntPar(scip->nlp, type, ival) );
785
786 return SCIP_OKAY;
787 }
788
789 /** sets integer parameter of NLP
790 *
791 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
792 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
793 *
794 * @pre This method can be called if SCIP is in one of the following stages:
795 * - \ref SCIP_STAGE_INITSOLVE
796 * - \ref SCIP_STAGE_SOLVING
797 */
SCIPsetNLPIntPar(SCIP * scip,SCIP_NLPPARAM type,int ival)798 SCIP_RETCODE SCIPsetNLPIntPar(
799 SCIP* scip, /**< SCIP data structure */
800 SCIP_NLPPARAM type, /**< parameter number */
801 int ival /**< parameter value */
802 )
803 {
804 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetNLPIntPar", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
805
806 if( scip->nlp == NULL )
807 {
808 SCIPerrorMessage("NLP has not been constructed.\n");
809 return SCIP_INVALIDCALL;
810 }
811
812 SCIP_CALL( SCIPnlpSetIntPar(scip->nlp, type, ival) );
813
814 return SCIP_OKAY;
815 }
816
817 /** gets floating point parameter of NLP
818 *
819 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
820 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
821 *
822 * @pre This method can be called if SCIP is in one of the following stages:
823 * - \ref SCIP_STAGE_INITSOLVE
824 * - \ref SCIP_STAGE_SOLVING
825 */
SCIPgetNLPRealPar(SCIP * scip,SCIP_NLPPARAM type,SCIP_Real * dval)826 SCIP_RETCODE SCIPgetNLPRealPar(
827 SCIP* scip, /**< SCIP data structure */
828 SCIP_NLPPARAM type, /**< parameter number */
829 SCIP_Real* dval /**< pointer to store the parameter value */
830 )
831 {
832 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNLPRealPar", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
833
834 if( scip->nlp == NULL )
835 {
836 SCIPerrorMessage("NLP has not been constructed.\n");
837 return SCIP_INVALIDCALL;
838 }
839
840 SCIP_CALL( SCIPnlpGetRealPar(scip->nlp, type, dval) );
841
842 return SCIP_OKAY;
843 }
844
845 /** sets floating point parameter of NLP
846 *
847 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
848 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
849 *
850 * @pre This method can be called if SCIP is in one of the following stages:
851 * - \ref SCIP_STAGE_INITSOLVE
852 * - \ref SCIP_STAGE_SOLVING
853 */
SCIPsetNLPRealPar(SCIP * scip,SCIP_NLPPARAM type,SCIP_Real dval)854 SCIP_RETCODE SCIPsetNLPRealPar(
855 SCIP* scip, /**< SCIP data structure */
856 SCIP_NLPPARAM type, /**< parameter number */
857 SCIP_Real dval /**< parameter value */
858 )
859 {
860 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetNLPRealPar", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
861
862 if( scip->nlp == NULL )
863 {
864 SCIPerrorMessage("NLP has not been constructed.\n");
865 return SCIP_INVALIDCALL;
866 }
867
868 SCIP_CALL( SCIPnlpSetRealPar(scip->nlp, type, dval) );
869
870 return SCIP_OKAY;
871 }
872
873 /** gets string parameter of NLP
874 *
875 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
876 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
877 *
878 * @pre This method can be called if SCIP is in one of the following stages:
879 * - \ref SCIP_STAGE_INITSOLVE
880 * - \ref SCIP_STAGE_SOLVING
881 */
SCIPgetNLPStringPar(SCIP * scip,SCIP_NLPPARAM type,const char ** sval)882 SCIP_RETCODE SCIPgetNLPStringPar(
883 SCIP* scip, /**< SCIP data structure */
884 SCIP_NLPPARAM type, /**< parameter number */
885 const char** sval /**< pointer to store the parameter value */
886 )
887 {
888 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNLPStringPar", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
889
890 if( scip->nlp == NULL )
891 {
892 SCIPerrorMessage("NLP has not been constructed.\n");
893 return SCIP_INVALIDCALL;
894 }
895
896 SCIP_CALL( SCIPnlpGetStringPar(scip->nlp, type, sval) );
897
898 return SCIP_OKAY;
899 }
900
901 /** sets string parameter of NLP
902 *
903 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
904 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
905 *
906 * @pre This method can be called if SCIP is in one of the following stages:
907 * - \ref SCIP_STAGE_INITSOLVE
908 * - \ref SCIP_STAGE_SOLVING
909 */
SCIPsetNLPStringPar(SCIP * scip,SCIP_NLPPARAM type,const char * sval)910 SCIP_RETCODE SCIPsetNLPStringPar(
911 SCIP* scip, /**< SCIP data structure */
912 SCIP_NLPPARAM type, /**< parameter number */
913 const char* sval /**< parameter value */
914 )
915 {
916 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetNLPStringPar", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
917
918 if( scip->nlp == NULL )
919 {
920 SCIPerrorMessage("NLP has not been constructed.\n");
921 return SCIP_INVALIDCALL;
922 }
923
924 SCIP_CALL( SCIPnlpSetStringPar(scip->nlp, type, sval) );
925
926 return SCIP_OKAY;
927 }
928
929 /** writes current NLP to a file
930 *
931 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
932 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
933 *
934 * @pre This method can be called if SCIP is in one of the following stages:
935 * - \ref SCIP_STAGE_INITSOLVE
936 * - \ref SCIP_STAGE_SOLVING
937 */
SCIPwriteNLP(SCIP * scip,const char * filename)938 SCIP_RETCODE SCIPwriteNLP(
939 SCIP* scip, /**< SCIP data structure */
940 const char* filename /**< file name */
941 )
942 {
943 SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteNLP", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
944
945 if( scip->nlp == NULL )
946 {
947 SCIPerrorMessage("NLP has not been constructed.\n");
948 return SCIP_INVALIDCALL;
949 }
950
951 SCIP_CALL( SCIPnlpWrite(scip->nlp, scip->set, scip->messagehdlr, filename) );
952
953 return SCIP_OKAY;
954 }
955
956 /** gets the NLP interface and problem used by the SCIP NLP;
957 * with the NLPI and its problem you can use all of the methods defined in nlpi/nlpi.h;
958 *
959 * @warning You have to make sure, that the full internal state of the NLPI does not change or is recovered completely
960 * after the end of the method that uses the NLPI. In particular, if you manipulate the NLP or its solution
961 * (e.g. by calling one of the SCIPnlpiAdd...() or the SCIPnlpiSolve() method), you have to check in advance
962 * whether the NLP is currently solved. If this is the case, you have to make sure, the internal solution
963 * status is recovered completely at the end of your method. Additionally you have to resolve the NLP with
964 * SCIPnlpiSolve() in order to reinstall the internal solution status.
965 *
966 * @warning Make also sure, that all parameter values that you have changed are set back to their original values.
967 *
968 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
969 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
970 *
971 * @pre This method can be called if SCIP is in one of the following stages:
972 * - \ref SCIP_STAGE_INITSOLVE
973 * - \ref SCIP_STAGE_SOLVING
974 */
SCIPgetNLPI(SCIP * scip,SCIP_NLPI ** nlpi,SCIP_NLPIPROBLEM ** nlpiproblem)975 SCIP_RETCODE SCIPgetNLPI(
976 SCIP* scip, /**< SCIP data structure */
977 SCIP_NLPI** nlpi, /**< pointer to store the NLP solver interface */
978 SCIP_NLPIPROBLEM** nlpiproblem /**< pointer to store the NLP solver interface problem */
979 )
980 {
981 assert(nlpi != NULL);
982 assert(nlpiproblem != NULL);
983
984 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNLPI", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
985
986 if( scip->nlp == NULL )
987 {
988 SCIPerrorMessage("NLP has not been constructed.\n");
989 return SCIP_INVALIDCALL;
990 }
991
992 *nlpi = SCIPnlpGetNLPI(scip->nlp);
993 *nlpiproblem = SCIPnlpGetNLPIProblem(scip->nlp);
994
995 return SCIP_OKAY;
996 }
997
998
999 /*
1000 * NLP diving methods
1001 */
1002
1003 /**@name NLP Diving Methods */
1004 /**@{ */
1005
1006 /** initiates NLP diving making methods SCIPchgVarObjDiveNLP(), SCIPchgVarBoundsDiveNLP(), SCIPchgVarsBoundsDiveNLP(), and SCIPsolveDiveNLP() available
1007 *
1008 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1009 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1010 *
1011 * @pre This method can be called if SCIP is in one of the following stages:
1012 * - \ref SCIP_STAGE_INITSOLVE
1013 * - \ref SCIP_STAGE_SOLVING
1014 */
SCIPstartDiveNLP(SCIP * scip)1015 SCIP_RETCODE SCIPstartDiveNLP(
1016 SCIP* scip /**< SCIP data structure */
1017 )
1018 {
1019 SCIP_CALL( SCIPcheckStage(scip, "SCIPstartDiveNLP", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1020
1021 if( scip->nlp == NULL )
1022 {
1023 SCIPerrorMessage("NLP has not been constructed.\n");
1024 return SCIP_INVALIDCALL;
1025 }
1026
1027 SCIP_CALL( SCIPnlpStartDive(scip->nlp, SCIPblkmem(scip), scip->set) );
1028
1029 return SCIP_OKAY;
1030 }
1031
1032 /** ends NLP diving
1033 *
1034 * Resets changes made by SCIPchgVarObjDiveNLP(), SCIPchgVarBoundsDiveNLP(), and SCIPchgVarsBoundsDiveNLP().
1035 *
1036 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1037 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1038 *
1039 * @pre This method can be called if SCIP is in one of the following stages:
1040 * - \ref SCIP_STAGE_INITSOLVE
1041 * - \ref SCIP_STAGE_SOLVING
1042 */
SCIPendDiveNLP(SCIP * scip)1043 SCIP_RETCODE SCIPendDiveNLP(
1044 SCIP* scip /**< SCIP data structure */
1045 )
1046 {
1047 SCIP_CALL( SCIPcheckStage(scip, "SCIPendDiveNLP", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1048
1049 if( scip->nlp == NULL )
1050 {
1051 SCIPerrorMessage("NLP has not been constructed.\n");
1052 return SCIP_INVALIDCALL;
1053 }
1054
1055 SCIP_CALL( SCIPnlpEndDive(scip->nlp, SCIPblkmem(scip), scip->set) );
1056
1057 return SCIP_OKAY;
1058 }
1059
1060 /** changes linear objective coefficient of a variable in diving NLP
1061 *
1062 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1063 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1064 *
1065 * @pre This method can be called if SCIP is in one of the following stages:
1066 * - \ref SCIP_STAGE_INITSOLVE
1067 * - \ref SCIP_STAGE_SOLVING
1068 */
SCIPchgVarObjDiveNLP(SCIP * scip,SCIP_VAR * var,SCIP_Real coef)1069 SCIP_RETCODE SCIPchgVarObjDiveNLP(
1070 SCIP* scip, /**< SCIP data structure */
1071 SCIP_VAR* var, /**< variable which coefficient to change */
1072 SCIP_Real coef /**< new value for coefficient */
1073 )
1074 {
1075 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarObjDiveNLP", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1076
1077 assert( var->scip == scip );
1078
1079 if( scip->nlp == NULL )
1080 {
1081 SCIPerrorMessage("NLP has not been constructed.\n");
1082 return SCIP_INVALIDCALL;
1083 }
1084
1085 SCIP_CALL( SCIPnlpChgVarObjDive(scip->nlp, SCIPblkmem(scip), scip->set, scip->stat, var, coef) );
1086
1087 return SCIP_OKAY;
1088 }
1089
1090 /** changes bounds of a variable in diving NLP
1091 *
1092 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1093 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1094 *
1095 * @pre This method can be called if SCIP is in one of the following stages:
1096 * - \ref SCIP_STAGE_INITSOLVE
1097 * - \ref SCIP_STAGE_SOLVING
1098 */
SCIPchgVarBoundsDiveNLP(SCIP * scip,SCIP_VAR * var,SCIP_Real lb,SCIP_Real ub)1099 SCIP_RETCODE SCIPchgVarBoundsDiveNLP(
1100 SCIP* scip, /**< SCIP data structure */
1101 SCIP_VAR* var, /**< variable which bounds to change */
1102 SCIP_Real lb, /**< new lower bound */
1103 SCIP_Real ub /**< new upper bound */
1104 )
1105 {
1106 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBoundsDiveNLP", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1107
1108 assert( var->scip == scip );
1109
1110 if( scip->nlp == NULL )
1111 {
1112 SCIPerrorMessage("NLP has not been constructed.\n");
1113 return SCIP_INVALIDCALL;
1114 }
1115
1116 SCIP_CALL( SCIPnlpChgVarBoundsDive(scip->nlp, var, lb, ub) );
1117
1118 return SCIP_OKAY;
1119 }
1120
1121 /** changes bounds of a set of variables in diving NLP
1122 *
1123 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1124 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1125 *
1126 * @pre This method can be called if SCIP is in one of the following stages:
1127 * - \ref SCIP_STAGE_INITSOLVE
1128 * - \ref SCIP_STAGE_SOLVING
1129 */
SCIPchgVarsBoundsDiveNLP(SCIP * scip,int nvars,SCIP_VAR ** vars,SCIP_Real * lbs,SCIP_Real * ubs)1130 SCIP_RETCODE SCIPchgVarsBoundsDiveNLP(
1131 SCIP* scip, /**< SCIP data structure */
1132 int nvars, /**< number of variables which bounds to changes */
1133 SCIP_VAR** vars, /**< variables which bounds to change */
1134 SCIP_Real* lbs, /**< new lower bounds */
1135 SCIP_Real* ubs /**< new upper bounds */
1136 )
1137 {
1138 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarsBoundsDiveNLP", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1139
1140 if( scip->nlp == NULL )
1141 {
1142 SCIPerrorMessage("NLP has not been constructed.\n");
1143 return SCIP_INVALIDCALL;
1144 }
1145
1146 SCIP_CALL( SCIPnlpChgVarsBoundsDive(scip->nlp, scip->set, nvars, vars, lbs, ubs) );
1147
1148 return SCIP_OKAY;
1149 }
1150
1151 /** solves diving NLP
1152 *
1153 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1154 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1155 *
1156 * @pre This method can be called if SCIP is in one of the following stages:
1157 * - \ref SCIP_STAGE_INITSOLVE
1158 * - \ref SCIP_STAGE_SOLVING
1159 */
SCIPsolveDiveNLP(SCIP * scip)1160 SCIP_RETCODE SCIPsolveDiveNLP(
1161 SCIP* scip /**< SCIP data structure */
1162 )
1163 {
1164 SCIP_CALL( SCIPcheckStage(scip, "SCIPsolveDiveNLP", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1165
1166 if( scip->nlp == NULL )
1167 {
1168 SCIPerrorMessage("NLP has not been constructed.\n");
1169 return SCIP_INVALIDCALL;
1170 }
1171
1172 SCIP_CALL( SCIPnlpSolveDive(scip->nlp, SCIPblkmem(scip), scip->set, scip->messagehdlr, scip->stat) );
1173
1174 return SCIP_OKAY;
1175 }
1176
1177 /**@} */
1178
1179
1180 /*
1181 * NLP nonlinear row methods
1182 */
1183
1184 /** creates and captures an NLP row
1185 *
1186 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1187 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1188 *
1189 * @pre This method can be called if SCIP is in one of the following stages:
1190 * - \ref SCIP_STAGE_PRESOLVED
1191 * - \ref SCIP_STAGE_INITSOLVE
1192 * - \ref SCIP_STAGE_SOLVING
1193 */
SCIPcreateNlRow(SCIP * scip,SCIP_NLROW ** nlrow,const char * name,SCIP_Real constant,int nlinvars,SCIP_VAR ** linvars,SCIP_Real * lincoefs,int nquadvars,SCIP_VAR ** quadvars,int nquadelems,SCIP_QUADELEM * quadelems,SCIP_EXPRTREE * expression,SCIP_Real lhs,SCIP_Real rhs,SCIP_EXPRCURV curvature)1194 SCIP_RETCODE SCIPcreateNlRow(
1195 SCIP* scip, /**< SCIP data structure */
1196 SCIP_NLROW** nlrow, /**< buffer to store pointer to nonlinear row */
1197 const char* name, /**< name of nonlinear row */
1198 SCIP_Real constant, /**< constant */
1199 int nlinvars, /**< number of linear variables */
1200 SCIP_VAR** linvars, /**< linear variables, or NULL if nlinvars == 0 */
1201 SCIP_Real* lincoefs, /**< linear coefficients, or NULL if nlinvars == 0 */
1202 int nquadvars, /**< number variables in quadratic terms */
1203 SCIP_VAR** quadvars, /**< variables in quadratic terms, or NULL if nquadvars == 0 */
1204 int nquadelems, /**< number of elements in quadratic term */
1205 SCIP_QUADELEM* quadelems, /**< elements (i.e., monomials) in quadratic term, or NULL if nquadelems == 0 */
1206 SCIP_EXPRTREE* expression, /**< nonlinear expression, or NULL */
1207 SCIP_Real lhs, /**< left hand side */
1208 SCIP_Real rhs, /**< right hand side */
1209 SCIP_EXPRCURV curvature /**< curvature of the nonlinear row */
1210 )
1211 {
1212 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateNlRow", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1213
1214 SCIP_CALL( SCIPnlrowCreate(nlrow, scip->mem->probmem, scip->set,
1215 name, constant, nlinvars, linvars, lincoefs, nquadvars, quadvars, nquadelems, quadelems, expression, lhs, rhs, curvature) );
1216
1217 return SCIP_OKAY;
1218 }
1219
1220 /** creates and captures an NLP nonlinear row without any coefficients
1221 *
1222 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1223 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1224 *
1225 * @pre This method can be called if SCIP is in one of the following stages:
1226 * - \ref SCIP_STAGE_PRESOLVED
1227 * - \ref SCIP_STAGE_INITSOLVE
1228 * - \ref SCIP_STAGE_SOLVING
1229 */
SCIPcreateEmptyNlRow(SCIP * scip,SCIP_NLROW ** nlrow,const char * name,SCIP_Real lhs,SCIP_Real rhs)1230 SCIP_RETCODE SCIPcreateEmptyNlRow(
1231 SCIP* scip, /**< SCIP data structure */
1232 SCIP_NLROW** nlrow, /**< pointer to nonlinear row */
1233 const char* name, /**< name of nonlinear row */
1234 SCIP_Real lhs, /**< left hand side */
1235 SCIP_Real rhs /**< right hand side */
1236 )
1237 {
1238 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateEmptyNlRow", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1239
1240 SCIP_CALL( SCIPnlrowCreate(nlrow, scip->mem->probmem, scip->set,
1241 name, 0.0, 0, NULL, NULL, 0, NULL, 0, NULL, NULL, lhs, rhs, SCIP_EXPRCURV_UNKNOWN) );
1242
1243 return SCIP_OKAY;
1244 }
1245
1246 /** creates and captures an NLP row from a linear row
1247 *
1248 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1249 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1250 *
1251 * @pre This method can be called if SCIP is in one of the following stages:
1252 * - \ref SCIP_STAGE_PRESOLVED
1253 * - \ref SCIP_STAGE_INITSOLVE
1254 * - \ref SCIP_STAGE_SOLVING
1255 */
SCIPcreateNlRowFromRow(SCIP * scip,SCIP_NLROW ** nlrow,SCIP_ROW * row)1256 SCIP_RETCODE SCIPcreateNlRowFromRow(
1257 SCIP* scip, /**< SCIP data structure */
1258 SCIP_NLROW** nlrow, /**< pointer to nonlinear row */
1259 SCIP_ROW* row /**< the linear row to copy */
1260 )
1261 {
1262 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateNlRowFromRow", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1263
1264 SCIP_CALL( SCIPnlrowCreateFromRow(nlrow, scip->mem->probmem, scip->set, row) );
1265
1266 return SCIP_OKAY;
1267 }
1268
1269 /** increases usage counter of NLP nonlinear row
1270 *
1271 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1272 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1273 *
1274 * @pre This method can be called if SCIP is in one of the following stages:
1275 * - \ref SCIP_STAGE_PRESOLVED
1276 * - \ref SCIP_STAGE_INITSOLVE
1277 * - \ref SCIP_STAGE_SOLVING
1278 */
SCIPcaptureNlRow(SCIP * scip,SCIP_NLROW * nlrow)1279 SCIP_RETCODE SCIPcaptureNlRow(
1280 SCIP* scip, /**< SCIP data structure */
1281 SCIP_NLROW* nlrow /**< nonlinear row to capture */
1282 )
1283 {
1284 SCIP_CALL( SCIPcheckStage(scip, "SCIPcaptureNlRow", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1285
1286 SCIPnlrowCapture(nlrow);
1287
1288 return SCIP_OKAY;
1289 }
1290
1291 /** decreases usage counter of NLP nonlinear row, and frees memory if necessary
1292 *
1293 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1294 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1295 *
1296 * @pre This method can be called if SCIP is in one of the following stages:
1297 * - \ref SCIP_STAGE_PRESOLVED
1298 * - \ref SCIP_STAGE_INITSOLVE
1299 * - \ref SCIP_STAGE_SOLVING
1300 * - \ref SCIP_STAGE_EXITSOLVE
1301 */
SCIPreleaseNlRow(SCIP * scip,SCIP_NLROW ** nlrow)1302 SCIP_RETCODE SCIPreleaseNlRow(
1303 SCIP* scip, /**< SCIP data structure */
1304 SCIP_NLROW** nlrow /**< pointer to nonlinear row */
1305 )
1306 {
1307 SCIP_CALL( SCIPcheckStage(scip, "SCIPreleaseNlRow", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE) );
1308
1309 SCIP_CALL( SCIPnlrowRelease(nlrow, scip->mem->probmem, scip->set) );
1310
1311 return SCIP_OKAY;
1312 }
1313
1314 /** changes left hand side of NLP nonlinear row
1315 *
1316 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1317 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1318 *
1319 * @pre This method can be called if SCIP is in one of the following stages:
1320 * - \ref SCIP_STAGE_PRESOLVED
1321 * - \ref SCIP_STAGE_INITSOLVE
1322 * - \ref SCIP_STAGE_SOLVING
1323 */
SCIPchgNlRowLhs(SCIP * scip,SCIP_NLROW * nlrow,SCIP_Real lhs)1324 SCIP_RETCODE SCIPchgNlRowLhs(
1325 SCIP* scip, /**< SCIP data structure */
1326 SCIP_NLROW* nlrow, /**< NLP nonlinear row */
1327 SCIP_Real lhs /**< new left hand side */
1328 )
1329 {
1330 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgNlRowLhs", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1331
1332 SCIP_CALL( SCIPnlrowChgLhs(nlrow, scip->set, scip->stat, scip->nlp, lhs) );
1333
1334 return SCIP_OKAY;
1335 }
1336
1337 /** changes right hand side of NLP nonlinear row
1338 *
1339 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1340 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1341 *
1342 * @pre This method can be called if SCIP is in one of the following stages:
1343 * - \ref SCIP_STAGE_PRESOLVED
1344 * - \ref SCIP_STAGE_INITSOLVE
1345 * - \ref SCIP_STAGE_SOLVING
1346 */
SCIPchgNlRowRhs(SCIP * scip,SCIP_NLROW * nlrow,SCIP_Real rhs)1347 SCIP_RETCODE SCIPchgNlRowRhs(
1348 SCIP* scip, /**< SCIP data structure */
1349 SCIP_NLROW* nlrow, /**< NLP nonlinear row */
1350 SCIP_Real rhs /**< new right hand side */
1351 )
1352 {
1353 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgNlRowRhs", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1354
1355 SCIP_CALL( SCIPnlrowChgRhs(nlrow, scip->set, scip->stat, scip->nlp, rhs) );
1356
1357 return SCIP_OKAY;
1358 }
1359
1360 /** changes constant of NLP nonlinear row
1361 *
1362 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1363 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1364 *
1365 * @pre This method can be called if SCIP is in one of the following stages:
1366 * - \ref SCIP_STAGE_PRESOLVED
1367 * - \ref SCIP_STAGE_INITSOLVE
1368 * - \ref SCIP_STAGE_SOLVING
1369 */
SCIPchgNlRowConstant(SCIP * scip,SCIP_NLROW * nlrow,SCIP_Real constant)1370 SCIP_RETCODE SCIPchgNlRowConstant(
1371 SCIP* scip, /**< SCIP data structure */
1372 SCIP_NLROW* nlrow, /**< NLP row */
1373 SCIP_Real constant /**< new value for constant */
1374 )
1375 {
1376 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgNlRowConstant", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1377
1378 SCIP_CALL( SCIPnlrowChgConstant(nlrow, scip->set, scip->stat, scip->nlp, constant) );
1379
1380 return SCIP_OKAY;
1381 }
1382
1383 /** adds variable with a linear coefficient to the nonlinear row
1384 *
1385 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1386 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1387 *
1388 * @pre This method can be called if SCIP is in one of the following stages:
1389 * - \ref SCIP_STAGE_PRESOLVED
1390 * - \ref SCIP_STAGE_INITSOLVE
1391 * - \ref SCIP_STAGE_SOLVING
1392 */
SCIPaddLinearCoefToNlRow(SCIP * scip,SCIP_NLROW * nlrow,SCIP_VAR * var,SCIP_Real val)1393 SCIP_RETCODE SCIPaddLinearCoefToNlRow(
1394 SCIP* scip, /**< SCIP data structure */
1395 SCIP_NLROW* nlrow, /**< NLP row */
1396 SCIP_VAR* var, /**< problem variable */
1397 SCIP_Real val /**< value of coefficient in linear part of row */
1398 )
1399 {
1400 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddLinearCoefToNlRow", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1401
1402 SCIP_CALL( SCIPnlrowAddLinearCoef(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->nlp, var, val) );
1403
1404 return SCIP_OKAY;
1405 }
1406
1407 /** adds variables with linear coefficients to the row
1408 *
1409 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1410 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1411 *
1412 * @pre This method can be called if SCIP is in one of the following stages:
1413 * - \ref SCIP_STAGE_PRESOLVED
1414 * - \ref SCIP_STAGE_INITSOLVE
1415 * - \ref SCIP_STAGE_SOLVING
1416 */
SCIPaddLinearCoefsToNlRow(SCIP * scip,SCIP_NLROW * nlrow,int nvars,SCIP_VAR ** vars,SCIP_Real * vals)1417 SCIP_RETCODE SCIPaddLinearCoefsToNlRow(
1418 SCIP* scip, /**< SCIP data structure */
1419 SCIP_NLROW* nlrow, /**< NLP row */
1420 int nvars, /**< number of variables to add to the row */
1421 SCIP_VAR** vars, /**< problem variables to add */
1422 SCIP_Real* vals /**< values of coefficients in linear part of row */
1423 )
1424 {
1425 int v;
1426
1427 assert(nvars == 0 || vars != NULL);
1428 assert(nvars == 0 || vals != NULL);
1429
1430 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddLinearCoefsToNlRow", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1431
1432 /* add the variables to the row */
1433 for( v = 0; v < nvars; ++v )
1434 {
1435 SCIP_CALL( SCIPnlrowAddLinearCoef(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->nlp, vars[v], vals[v]) );
1436 }
1437
1438 return SCIP_OKAY;
1439 }
1440
1441 /** changes linear coefficient of a variables in a row
1442 *
1443 * Setting the coefficient to 0.0 means that it is removed from the row
1444 * the variable does not need to exists before.
1445 *
1446 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1447 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1448 *
1449 * @pre This method can be called if SCIP is in one of the following stages:
1450 * - \ref SCIP_STAGE_PRESOLVED
1451 * - \ref SCIP_STAGE_INITSOLVE
1452 * - \ref SCIP_STAGE_SOLVING
1453 */
SCIPchgNlRowLinearCoef(SCIP * scip,SCIP_NLROW * nlrow,SCIP_VAR * var,SCIP_Real coef)1454 SCIP_RETCODE SCIPchgNlRowLinearCoef(
1455 SCIP* scip, /**< SCIP data structure */
1456 SCIP_NLROW* nlrow, /**< NLP row */
1457 SCIP_VAR* var, /**< variable */
1458 SCIP_Real coef /**< new value of coefficient */
1459 )
1460 {
1461 assert(var != NULL);
1462
1463 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgNlRowLinearCoef", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1464
1465 SCIP_CALL( SCIPnlrowChgLinearCoef(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->nlp, var, coef) );
1466
1467 return SCIP_OKAY;
1468 }
1469
1470 /** adds quadratic variable to the nonlinear row
1471 *
1472 * After adding a quadratic variable, it can be used to add quadratic elements.
1473 *
1474 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1475 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1476 *
1477 * @pre This method can be called if SCIP is in one of the following stages:
1478 * - \ref SCIP_STAGE_PRESOLVED
1479 * - \ref SCIP_STAGE_INITSOLVE
1480 * - \ref SCIP_STAGE_SOLVING
1481 */
SCIPaddQuadVarToNlRow(SCIP * scip,SCIP_NLROW * nlrow,SCIP_VAR * var)1482 SCIP_RETCODE SCIPaddQuadVarToNlRow(
1483 SCIP* scip, /**< SCIP data structure */
1484 SCIP_NLROW* nlrow, /**< NLP row */
1485 SCIP_VAR* var /**< problem variable */
1486 )
1487 {
1488 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddQuadVarToNlRow", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1489
1490 SCIP_CALL( SCIPnlrowAddQuadVar(nlrow, scip->mem->probmem, scip->set, var) );
1491
1492 return SCIP_OKAY;
1493 }
1494
1495 /** adds quadratic variables to the nonlinear row
1496 *
1497 * After adding quadratic variables, they can be used to add quadratic elements.
1498 *
1499 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1500 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1501 *
1502 * @pre This method can be called if SCIP is in one of the following stages:
1503 * - \ref SCIP_STAGE_PRESOLVED
1504 * - \ref SCIP_STAGE_INITSOLVE
1505 * - \ref SCIP_STAGE_SOLVING
1506 */
SCIPaddQuadVarsToNlRow(SCIP * scip,SCIP_NLROW * nlrow,int nvars,SCIP_VAR ** vars)1507 SCIP_RETCODE SCIPaddQuadVarsToNlRow(
1508 SCIP* scip, /**< SCIP data structure */
1509 SCIP_NLROW* nlrow, /**< NLP row */
1510 int nvars, /**< number of problem variables */
1511 SCIP_VAR** vars /**< problem variables */
1512 )
1513 {
1514 int v;
1515
1516 assert(nvars == 0 || vars != NULL);
1517
1518 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddQuadVarsToNlRow", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1519
1520 SCIP_CALL( SCIPnlrowEnsureQuadVarsSize(nlrow, scip->mem->probmem, scip->set, SCIPnlrowGetNQuadVars(nlrow) + nvars) );
1521 for( v = 0; v < nvars; ++v )
1522 {
1523 SCIP_CALL( SCIPnlrowAddQuadVar(nlrow, scip->mem->probmem, scip->set, vars[v]) );
1524 }
1525
1526 return SCIP_OKAY;
1527 }
1528
1529 /** add a quadratic element to the nonlinear row
1530 *
1531 * Variable indices of the quadratic element need to be relative to quadratic variables array of row.
1532 *
1533 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1534 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1535 *
1536 * @pre This method can be called if SCIP is in one of the following stages:
1537 * - \ref SCIP_STAGE_PRESOLVED
1538 * - \ref SCIP_STAGE_INITSOLVE
1539 * - \ref SCIP_STAGE_SOLVING
1540 */
SCIPaddQuadElementToNlRow(SCIP * scip,SCIP_NLROW * nlrow,SCIP_QUADELEM quadelem)1541 SCIP_RETCODE SCIPaddQuadElementToNlRow(
1542 SCIP* scip, /**< SCIP data structure */
1543 SCIP_NLROW* nlrow, /**< NLP row */
1544 SCIP_QUADELEM quadelem /**< quadratic element */
1545 )
1546 {
1547 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddQuadElementToNlRow", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1548
1549 SCIP_CALL( SCIPnlrowAddQuadElement(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->nlp, quadelem) );
1550
1551 /* invalidate curvature */
1552 if( quadelem.coef != 0.0 )
1553 SCIPnlrowSetCurvature(nlrow, SCIP_EXPRCURV_UNKNOWN);
1554
1555 return SCIP_OKAY;
1556 }
1557
1558 /** adds quadratic elements to the nonlinear row
1559 *
1560 * Variable indices of the quadratic elements need to be relative to quadratic variables array of row.
1561 *
1562 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1563 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1564 *
1565 * @pre This method can be called if SCIP is in one of the following stages:
1566 * - \ref SCIP_STAGE_PRESOLVED
1567 * - \ref SCIP_STAGE_INITSOLVE
1568 * - \ref SCIP_STAGE_SOLVING
1569 */
SCIPaddQuadElementsToNlRow(SCIP * scip,SCIP_NLROW * nlrow,int nquadelems,SCIP_QUADELEM * quadelems)1570 SCIP_RETCODE SCIPaddQuadElementsToNlRow(
1571 SCIP* scip, /**< SCIP data structure */
1572 SCIP_NLROW* nlrow, /**< NLP row */
1573 int nquadelems, /**< number of quadratic elements */
1574 SCIP_QUADELEM* quadelems /**< quadratic elements */
1575 )
1576 {
1577 int v;
1578
1579 assert(nquadelems == 0 || quadelems != NULL);
1580
1581 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddQuadElementsToNlRow", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1582
1583 SCIP_CALL( SCIPnlrowEnsureQuadElementsSize(nlrow, scip->mem->probmem, scip->set, SCIPnlrowGetNQuadElems(nlrow) + nquadelems) );
1584 for( v = 0; v < nquadelems; ++v )
1585 {
1586 SCIP_CALL( SCIPnlrowAddQuadElement(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->nlp, quadelems[v]) );
1587 }
1588
1589 /* invalidate curvature */
1590 SCIPnlrowSetCurvature(nlrow, SCIP_EXPRCURV_UNKNOWN);
1591
1592 return SCIP_OKAY;
1593 }
1594
1595 /** changes coefficient in quadratic part of a row
1596 *
1597 * Setting the coefficient in the quadelement to 0.0 means that it is removed from the row
1598 * the element does not need to exists before.
1599 *
1600 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1601 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1602 *
1603 * @pre This method can be called if SCIP is in one of the following stages:
1604 * - \ref SCIP_STAGE_PRESOLVED
1605 * - \ref SCIP_STAGE_INITSOLVE
1606 * - \ref SCIP_STAGE_SOLVING
1607 */
SCIPchgNlRowQuadElement(SCIP * scip,SCIP_NLROW * nlrow,SCIP_QUADELEM quadelement)1608 SCIP_RETCODE SCIPchgNlRowQuadElement(
1609 SCIP* scip, /**< SCIP data structure */
1610 SCIP_NLROW* nlrow, /**< NLP row */
1611 SCIP_QUADELEM quadelement /**< new quadratic element, or update for existing one */
1612 )
1613 {
1614 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgNlRowQuadElement", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1615
1616 SCIP_CALL( SCIPnlrowChgQuadElem(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->nlp, quadelement) );
1617
1618 return SCIP_OKAY;
1619 }
1620
1621 /** sets or deletes expression tree in the nonlinear row
1622 *
1623 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1624 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1625 *
1626 * @pre This method can be called if SCIP is in one of the following stages:
1627 * - \ref SCIP_STAGE_PRESOLVED
1628 * - \ref SCIP_STAGE_INITSOLVE
1629 * - \ref SCIP_STAGE_SOLVING
1630 */
SCIPsetNlRowExprtree(SCIP * scip,SCIP_NLROW * nlrow,SCIP_EXPRTREE * exprtree)1631 SCIP_RETCODE SCIPsetNlRowExprtree(
1632 SCIP* scip, /**< SCIP data structure */
1633 SCIP_NLROW* nlrow, /**< NLP row */
1634 SCIP_EXPRTREE* exprtree /**< expression tree, or NULL */
1635 )
1636 {
1637 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetNlRowExprtree", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1638
1639 SCIP_CALL( SCIPnlrowChgExprtree(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->nlp, exprtree) );
1640
1641 /* invalidate curvature */
1642 SCIPnlrowSetCurvature(nlrow, SCIP_EXPRCURV_UNKNOWN);
1643
1644 return SCIP_OKAY;
1645 }
1646
1647 /** sets a parameter of expression tree in the nonlinear row
1648 *
1649 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1650 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1651 *
1652 * @pre This method can be called if SCIP is in one of the following stages:
1653 * - \ref SCIP_STAGE_PRESOLVED
1654 * - \ref SCIP_STAGE_INITSOLVE
1655 * - \ref SCIP_STAGE_SOLVING
1656 */
SCIPsetNlRowExprtreeParam(SCIP * scip,SCIP_NLROW * nlrow,int paramidx,SCIP_Real paramval)1657 SCIP_RETCODE SCIPsetNlRowExprtreeParam(
1658 SCIP* scip, /**< SCIP data structure */
1659 SCIP_NLROW* nlrow, /**< NLP row */
1660 int paramidx, /**< index of parameter in expression tree */
1661 SCIP_Real paramval /**< new value of parameter in expression tree */
1662 )
1663 {
1664 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetNlRowExprtreeParam", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1665
1666 SCIP_CALL( SCIPnlrowChgExprtreeParam(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->nlp, paramidx, paramval) );
1667
1668 return SCIP_OKAY;
1669 }
1670
1671 /** sets parameters of expression tree in the nonlinear row
1672 *
1673 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1674 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1675 *
1676 * @pre This method can be called if SCIP is in one of the following stages:
1677 * - \ref SCIP_STAGE_PRESOLVED
1678 * - \ref SCIP_STAGE_INITSOLVE
1679 * - \ref SCIP_STAGE_SOLVING
1680 */
SCIPsetNlRowExprtreeParams(SCIP * scip,SCIP_NLROW * nlrow,SCIP_Real * paramvals)1681 SCIP_RETCODE SCIPsetNlRowExprtreeParams(
1682 SCIP* scip, /**< SCIP data structure */
1683 SCIP_NLROW* nlrow, /**< NLP row */
1684 SCIP_Real* paramvals /**< new values of parameter in expression tree */
1685 )
1686 {
1687 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetNlRowExprtreeParams", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1688
1689 SCIP_CALL( SCIPnlrowChgExprtreeParams(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->nlp, paramvals) );
1690
1691 return SCIP_OKAY;
1692 }
1693
1694 /** recalculates the activity of a nonlinear row in the last NLP solution
1695 *
1696 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1697 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1698 *
1699 * @pre This method can be called if SCIP is in one of the following stages:
1700 * - \ref SCIP_STAGE_PRESOLVED
1701 * - \ref SCIP_STAGE_INITSOLVE
1702 * - \ref SCIP_STAGE_SOLVING
1703 */
SCIPrecalcNlRowNLPActivity(SCIP * scip,SCIP_NLROW * nlrow)1704 SCIP_RETCODE SCIPrecalcNlRowNLPActivity(
1705 SCIP* scip, /**< SCIP data structure */
1706 SCIP_NLROW* nlrow /**< NLP nonlinear row */
1707 )
1708 {
1709 SCIP_CALL( SCIPcheckStage(scip, "SCIPrecalcNlRowNLPActivity", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1710
1711 if( scip->nlp == NULL )
1712 {
1713 SCIPerrorMessage("do not have NLP for computing NLP activity\n");
1714 return SCIP_INVALIDCALL;
1715 }
1716
1717 SCIP_CALL( SCIPnlrowRecalcNLPActivity(nlrow, scip->set, scip->stat, scip->nlp) );
1718
1719 return SCIP_OKAY;
1720 }
1721
1722 /** returns the activity of a nonlinear row in the last NLP solution
1723 *
1724 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1725 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1726 *
1727 * @pre This method can be called if SCIP is in one of the following stages:
1728 * - \ref SCIP_STAGE_INITSOLVE
1729 * - \ref SCIP_STAGE_SOLVING
1730 */
SCIPgetNlRowNLPActivity(SCIP * scip,SCIP_NLROW * nlrow,SCIP_Real * activity)1731 SCIP_RETCODE SCIPgetNlRowNLPActivity(
1732 SCIP* scip, /**< SCIP data structure */
1733 SCIP_NLROW* nlrow, /**< NLP nonlinear row */
1734 SCIP_Real* activity /**< pointer to store activity value */
1735 )
1736 {
1737 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNlRowNLPActivity", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1738
1739 if( scip->nlp == NULL )
1740 {
1741 SCIPerrorMessage("do not have NLP for computing NLP activity\n");
1742 return SCIP_INVALIDCALL;
1743 }
1744
1745 SCIP_CALL( SCIPnlrowGetNLPActivity(nlrow, scip->set, scip->stat, scip->nlp, activity) );
1746
1747 return SCIP_OKAY;
1748 }
1749
1750 /** gives the feasibility of a nonlinear row in the last NLP solution: negative value means infeasibility
1751 *
1752 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1753 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1754 *
1755 * @pre This method can be called if SCIP is in one of the following stages:
1756 * - \ref SCIP_STAGE_INITSOLVE
1757 * - \ref SCIP_STAGE_SOLVING
1758 */
SCIPgetNlRowNLPFeasibility(SCIP * scip,SCIP_NLROW * nlrow,SCIP_Real * feasibility)1759 SCIP_RETCODE SCIPgetNlRowNLPFeasibility(
1760 SCIP* scip, /**< SCIP data structure */
1761 SCIP_NLROW* nlrow, /**< NLP nonlinear row */
1762 SCIP_Real* feasibility /**< pointer to store feasibility value */
1763 )
1764 {
1765 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNlRowNLPFeasibility", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1766
1767 if( scip->nlp == NULL )
1768 {
1769 SCIPerrorMessage("do not have NLP for computing NLP feasibility\n");
1770 return SCIP_INVALIDCALL;
1771 }
1772
1773 SCIP_CALL( SCIPnlrowGetNLPFeasibility(nlrow, scip->set, scip->stat, scip->nlp, feasibility) );
1774
1775 return SCIP_OKAY;
1776 }
1777
1778 /** recalculates the activity of a nonlinear row for the current pseudo solution
1779 *
1780 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1781 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1782 *
1783 * @pre This method can be called if SCIP is in one of the following stages:
1784 * - \ref SCIP_STAGE_INITSOLVE
1785 * - \ref SCIP_STAGE_SOLVING
1786 */
SCIPrecalcNlRowPseudoActivity(SCIP * scip,SCIP_NLROW * nlrow)1787 SCIP_RETCODE SCIPrecalcNlRowPseudoActivity(
1788 SCIP* scip, /**< SCIP data structure */
1789 SCIP_NLROW* nlrow /**< NLP nonlinear row */
1790 )
1791 {
1792 SCIP_CALL( SCIPcheckStage(scip, "SCIPrecalcNlRowPseudoActivity", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1793
1794 SCIP_CALL( SCIPnlrowRecalcPseudoActivity(nlrow, scip->set, scip->stat) );
1795
1796 return SCIP_OKAY;
1797 }
1798
1799 /** gives the activity of a nonlinear row for the current pseudo solution
1800 *
1801 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1802 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1803 *
1804 * @pre This method can be called if SCIP is in one of the following stages:
1805 * - \ref SCIP_STAGE_INITSOLVE
1806 * - \ref SCIP_STAGE_SOLVING
1807 */
SCIPgetNlRowPseudoActivity(SCIP * scip,SCIP_NLROW * nlrow,SCIP_Real * pseudoactivity)1808 SCIP_RETCODE SCIPgetNlRowPseudoActivity(
1809 SCIP* scip, /**< SCIP data structure */
1810 SCIP_NLROW* nlrow, /**< NLP nonlinear row */
1811 SCIP_Real* pseudoactivity /**< pointer to store pseudo activity value */
1812 )
1813 {
1814 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNlRowPseudoActivity", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1815
1816 SCIP_CALL( SCIPnlrowGetPseudoActivity(nlrow, scip->set, scip->stat, pseudoactivity) );
1817
1818 return SCIP_OKAY;
1819 }
1820
1821 /** gives the feasibility of a nonlinear row for the current pseudo solution: negative value means infeasibility
1822 *
1823 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1824 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1825 *
1826 * @pre This method can be called if SCIP is in one of the following stages:
1827 * - \ref SCIP_STAGE_INITSOLVE
1828 * - \ref SCIP_STAGE_SOLVING
1829 */
SCIPgetNlRowPseudoFeasibility(SCIP * scip,SCIP_NLROW * nlrow,SCIP_Real * pseudofeasibility)1830 SCIP_RETCODE SCIPgetNlRowPseudoFeasibility(
1831 SCIP* scip, /**< SCIP data structure */
1832 SCIP_NLROW* nlrow, /**< NLP nonlinear row */
1833 SCIP_Real* pseudofeasibility /**< pointer to store pseudo feasibility value */
1834 )
1835 {
1836 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNlRowPseudoFeasibility", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1837
1838 SCIP_CALL( SCIPnlrowGetPseudoFeasibility(nlrow, scip->set, scip->stat, pseudofeasibility) );
1839
1840 return SCIP_OKAY;
1841 }
1842
1843 /** recalculates the activity of a nonlinear row in the last NLP or pseudo solution
1844 *
1845 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1846 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1847 *
1848 * @pre This method can be called if SCIP is in one of the following stages:
1849 * - \ref SCIP_STAGE_INITSOLVE
1850 * - \ref SCIP_STAGE_SOLVING
1851 */
SCIPrecalcNlRowActivity(SCIP * scip,SCIP_NLROW * nlrow)1852 SCIP_RETCODE SCIPrecalcNlRowActivity(
1853 SCIP* scip, /**< SCIP data structure */
1854 SCIP_NLROW* nlrow /**< NLP nonlinear row */
1855 )
1856 {
1857 SCIP_CALL( SCIPcheckStage(scip, "SCIPrecalcNlRowActivity", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1858
1859 if( scip->nlp != NULL && SCIPnlpHasCurrentNodeNLP(scip->nlp) && SCIPnlpHasSolution(scip->nlp) )
1860 {
1861 SCIP_CALL( SCIPnlrowRecalcNLPActivity(nlrow, scip->set, scip->stat, scip->nlp) );
1862 }
1863 else
1864 {
1865 SCIP_CALL( SCIPnlrowRecalcPseudoActivity(nlrow, scip->set, scip->stat) );
1866 }
1867
1868 return SCIP_OKAY;
1869 }
1870
1871 /** gives the activity of a nonlinear row in the last NLP or pseudo solution
1872 *
1873 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1874 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1875 *
1876 * @pre This method can be called if SCIP is in one of the following stages:
1877 * - \ref SCIP_STAGE_INITSOLVE
1878 * - \ref SCIP_STAGE_SOLVING
1879 */
SCIPgetNlRowActivity(SCIP * scip,SCIP_NLROW * nlrow,SCIP_Real * activity)1880 SCIP_RETCODE SCIPgetNlRowActivity(
1881 SCIP* scip, /**< SCIP data structure */
1882 SCIP_NLROW* nlrow, /**< NLP nonlinear row */
1883 SCIP_Real* activity /**< pointer to store activity value */
1884 )
1885 {
1886 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNlRowActivity", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1887
1888 if( scip->nlp != NULL && SCIPnlpHasCurrentNodeNLP(scip->nlp) && SCIPnlpHasSolution(scip->nlp) )
1889 {
1890 SCIP_CALL( SCIPnlrowGetNLPActivity(nlrow, scip->set, scip->stat, scip->nlp, activity) );
1891 }
1892 else
1893 {
1894 SCIP_CALL( SCIPnlrowGetPseudoActivity(nlrow, scip->set, scip->stat, activity) );
1895 }
1896
1897 return SCIP_OKAY;
1898 }
1899
1900 /** gives the feasibility of a nonlinear row in the last NLP or pseudo solution
1901 *
1902 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1903 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1904 *
1905 * @pre This method can be called if SCIP is in one of the following stages:
1906 * - \ref SCIP_STAGE_INITSOLVE
1907 * - \ref SCIP_STAGE_SOLVING
1908 */
SCIPgetNlRowFeasibility(SCIP * scip,SCIP_NLROW * nlrow,SCIP_Real * feasibility)1909 SCIP_RETCODE SCIPgetNlRowFeasibility(
1910 SCIP* scip, /**< SCIP data structure */
1911 SCIP_NLROW* nlrow, /**< NLP nonlinear row */
1912 SCIP_Real* feasibility /**< pointer to store feasibility value */
1913 )
1914 {
1915 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNlRowFeasibility", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1916
1917 if( scip->nlp != NULL && SCIPnlpHasCurrentNodeNLP(scip->nlp) && SCIPnlpHasSolution(scip->nlp) )
1918 {
1919 SCIP_CALL( SCIPnlrowGetNLPFeasibility(nlrow, scip->set, scip->stat, scip->nlp, feasibility) );
1920 }
1921 else
1922 {
1923 SCIP_CALL( SCIPnlrowGetPseudoFeasibility(nlrow, scip->set, scip->stat, feasibility) );
1924 }
1925
1926 return SCIP_OKAY;
1927 }
1928
1929 /** gives the activity of a nonlinear row for the given primal solution or NLP solution or pseudo solution
1930 *
1931 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1932 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1933 *
1934 * @pre This method can be called if SCIP is in one of the following stages:
1935 * - \ref SCIP_STAGE_INITSOLVE
1936 * - \ref SCIP_STAGE_SOLVING
1937 */
SCIPgetNlRowSolActivity(SCIP * scip,SCIP_NLROW * nlrow,SCIP_SOL * sol,SCIP_Real * activity)1938 SCIP_RETCODE SCIPgetNlRowSolActivity(
1939 SCIP* scip, /**< SCIP data structure */
1940 SCIP_NLROW* nlrow, /**< NLP nonlinear row */
1941 SCIP_SOL* sol, /**< primal CIP solution, or NULL for NLP solution of pseudo solution */
1942 SCIP_Real* activity /**< pointer to store activity value */
1943 )
1944 {
1945 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNlRowSolActivity", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1946
1947 if( sol != NULL )
1948 {
1949 SCIP_CALL( SCIPnlrowGetSolActivity(nlrow, scip->set, scip->stat, sol, activity) );
1950 }
1951 else if( scip->nlp != NULL && SCIPnlpHasCurrentNodeNLP(scip->nlp) && SCIPnlpHasSolution(scip->nlp) )
1952 {
1953 SCIP_CALL( SCIPnlrowGetNLPActivity(nlrow, scip->set, scip->stat, scip->nlp, activity) );
1954 }
1955 else
1956 {
1957 SCIP_CALL( SCIPnlrowGetPseudoActivity(nlrow, scip->set, scip->stat, activity) );
1958 }
1959
1960 return SCIP_OKAY;
1961 }
1962
1963 /** gives the feasibility of a nonlinear row for the given primal solution
1964 *
1965 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1966 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1967 *
1968 * @pre This method can be called if SCIP is in one of the following stages:
1969 * - \ref SCIP_STAGE_INITSOLVE
1970 * - \ref SCIP_STAGE_SOLVING
1971 */
SCIPgetNlRowSolFeasibility(SCIP * scip,SCIP_NLROW * nlrow,SCIP_SOL * sol,SCIP_Real * feasibility)1972 SCIP_RETCODE SCIPgetNlRowSolFeasibility(
1973 SCIP* scip, /**< SCIP data structure */
1974 SCIP_NLROW* nlrow, /**< NLP nonlinear row */
1975 SCIP_SOL* sol, /**< primal CIP solution */
1976 SCIP_Real* feasibility /**< pointer to store feasibility value */
1977 )
1978 {
1979 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNlRowSolFeasibility", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1980
1981 if( sol != NULL )
1982 {
1983 SCIP_CALL( SCIPnlrowGetSolFeasibility(nlrow, scip->set, scip->stat, sol, feasibility) );
1984 }
1985 else if( scip->nlp != NULL && SCIPnlpHasCurrentNodeNLP(scip->nlp) && SCIPnlpHasSolution(scip->nlp) )
1986 {
1987 SCIP_CALL( SCIPnlrowGetNLPFeasibility(nlrow, scip->set, scip->stat, scip->nlp, feasibility) );
1988 }
1989 else
1990 {
1991 SCIP_CALL( SCIPnlrowGetPseudoFeasibility(nlrow, scip->set, scip->stat, feasibility) );
1992 }
1993
1994 return SCIP_OKAY;
1995 }
1996
1997 /** gives the minimal and maximal activity of a nonlinear row w.r.t. the variable's bounds
1998 *
1999 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2000 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2001 *
2002 * @pre This method can be called if SCIP is in one of the following stages:
2003 * - \ref SCIP_STAGE_PRESOLVED
2004 * - \ref SCIP_STAGE_INITSOLVE
2005 * - \ref SCIP_STAGE_SOLVING
2006 */
SCIPgetNlRowActivityBounds(SCIP * scip,SCIP_NLROW * nlrow,SCIP_Real * minactivity,SCIP_Real * maxactivity)2007 SCIP_RETCODE SCIPgetNlRowActivityBounds(
2008 SCIP* scip, /**< SCIP data structure */
2009 SCIP_NLROW* nlrow, /**< NLP row */
2010 SCIP_Real* minactivity, /**< buffer to store minimal activity, or NULL */
2011 SCIP_Real* maxactivity /**< buffer to store maximal activity, or NULL */
2012 )
2013 {
2014 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNlRowActivityBounds", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2015
2016 SCIP_CALL( SCIPnlrowGetActivityBounds(nlrow, scip->set, scip->stat, minactivity, maxactivity) );
2017
2018 return SCIP_OKAY;
2019 }
2020
2021 /** output nonlinear row to file stream
2022 *
2023 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2024 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2025 *
2026 * @pre This method can be called if SCIP is in one of the following stages:
2027 * - \ref SCIP_STAGE_PRESOLVED
2028 * - \ref SCIP_STAGE_INITSOLVE
2029 * - \ref SCIP_STAGE_SOLVING
2030 */
SCIPprintNlRow(SCIP * scip,SCIP_NLROW * nlrow,FILE * file)2031 SCIP_RETCODE SCIPprintNlRow(
2032 SCIP* scip, /**< SCIP data structure */
2033 SCIP_NLROW* nlrow, /**< NLP row */
2034 FILE* file /**< output file (or NULL for standard output) */
2035 )
2036 {
2037 assert(nlrow != NULL);
2038
2039 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintNlRow", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2040
2041 SCIP_CALL( SCIPnlrowPrint(nlrow, scip->messagehdlr, file) );
2042
2043 return SCIP_OKAY;
2044 }
2045