1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 2 /* */ 3 /* This file is part of the program and library */ 4 /* SCIP --- Solving Constraint Integer Programs */ 5 /* */ 6 /* Copyright (c) 2002-2023 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 scip_nlp.c 26 * @ingroup OTHER_CFILES 27 * @brief public methods for nonlinear relaxation 28 * @author Thorsten Gellermann 29 * @author Stefan Vigerske 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 "scip/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 /**@addtogroup PublicNLPMethods 56 * @{ 57 */ 58 59 /** returns whether the NLP relaxation has been enabled 60 * 61 * If the NLP relaxation is enabled, then SCIP will construct the NLP relaxation when the solving process is about to begin. 62 * To check whether an NLP is existing, use SCIPisNLPConstructed(). 63 * 64 * @pre This method can be called if SCIP is in one of the following stages: 65 * - \ref SCIP_STAGE_INITPRESOLVE 66 * - \ref SCIP_STAGE_PRESOLVING 67 * - \ref SCIP_STAGE_EXITPRESOLVE 68 * - \ref SCIP_STAGE_PRESOLVED 69 * - \ref SCIP_STAGE_INITSOLVE 70 * - \ref SCIP_STAGE_SOLVING 71 * 72 * @see SCIPenableNLP 73 */ 74 SCIP_Bool SCIPisNLPEnabled( 75 SCIP* scip /**< SCIP data structure */ 76 ) 77 { 78 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisNLPEnabled", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 79 80 return scip->transprob->nlpenabled; 81 } 82 83 /** notifies SCIP that the NLP relaxation should be initialized in INITSOLVE 84 * 85 * This method is typically called by a constraint handler that handles constraints that have a nonlinear representation as nonlinear rows, e.g., cons_nonlinear. 86 * 87 * The function should be called before the branch-and-bound process is initialized, e.g., when presolve is exiting. 88 * 89 * @pre This method can be called if SCIP is in one of the following stages: 90 * - \ref SCIP_STAGE_INITPRESOLVE 91 * - \ref SCIP_STAGE_PRESOLVING 92 * - \ref SCIP_STAGE_EXITPRESOLVE 93 * - \ref SCIP_STAGE_PRESOLVED 94 */ 95 void SCIPenableNLP( 96 SCIP* scip /**< SCIP data structure */ 97 ) 98 { 99 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPenableNLP", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 100 101 scip->transprob->nlpenabled = TRUE; 102 } 103 104 /** returns, whether an NLP has been constructed 105 * 106 * @pre This method can be called if SCIP is in one of the following stages: 107 * - \ref SCIP_STAGE_INITSOLVE 108 * - \ref SCIP_STAGE_SOLVING 109 */ 110 SCIP_Bool SCIPisNLPConstructed( 111 SCIP* scip /**< SCIP data structure */ 112 ) 113 { 114 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisNLPConstructed", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 115 116 return (scip->nlp != NULL); 117 } 118 119 /** checks whether the NLP has a continuous variable in a nonlinear term 120 * 121 * @pre This method can be called if SCIP is in one of the following stages: 122 * - \ref SCIP_STAGE_INITSOLVE 123 * - \ref SCIP_STAGE_SOLVING 124 */ 125 SCIP_RETCODE SCIPhasNLPContinuousNonlinearity( 126 SCIP* scip, /**< SCIP data structure */ 127 SCIP_Bool* result /**< buffer to store result */ 128 ) 129 { 130 SCIP_CALL( SCIPcheckStage(scip, "SCIPhasNLPContinuousNonlinearity", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 131 132 if( scip->nlp == NULL ) 133 { 134 SCIPerrorMessage("NLP has not been not constructed.\n"); 135 return SCIP_ERROR; 136 } 137 138 SCIP_CALL( SCIPnlpHasContinuousNonlinearity(scip->nlp, scip->mem->probmem, scip->set, scip->stat, result) ); 139 140 return SCIP_OKAY; 141 } 142 143 /** gets current NLP variables along with the current number of NLP variables 144 * 145 * @pre This method can be called if SCIP is in one of the following stages: 146 * - \ref SCIP_STAGE_INITSOLVE 147 * - \ref SCIP_STAGE_SOLVING 148 */ 149 SCIP_RETCODE SCIPgetNLPVarsData( 150 SCIP* scip, /**< SCIP data structure */ 151 SCIP_VAR*** vars, /**< pointer to store the array of NLP variables, or NULL */ 152 int* nvars /**< pointer to store the number of NLP variables, or NULL */ 153 ) 154 { 155 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNLPVarsData", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 156 157 if( scip->nlp != NULL ) 158 { 159 if( vars != NULL ) 160 *vars = SCIPnlpGetVars(scip->nlp); 161 if( nvars != NULL ) 162 *nvars = SCIPnlpGetNVars(scip->nlp); 163 } 164 else 165 { 166 SCIPerrorMessage("NLP has not been constructed.\n"); 167 return SCIP_INVALIDCALL; 168 } 169 170 return SCIP_OKAY; 171 } 172 173 /** gets array with variables of the NLP 174 * 175 * @pre This method can be called if SCIP is in one of the following stages: 176 * - \ref SCIP_STAGE_INITSOLVE 177 * - \ref SCIP_STAGE_SOLVING 178 */ 179 SCIP_VAR** SCIPgetNLPVars( 180 SCIP* scip /**< SCIP data structure */ 181 ) 182 { 183 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNLPVars", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 184 185 if( scip->nlp == NULL ) 186 { 187 SCIPerrorMessage("NLP has not been constructed.\n"); 188 SCIPABORT(); 189 return NULL; /*lint !e527*/ 190 } 191 192 return SCIPnlpGetVars(scip->nlp); 193 } 194 195 /** gets current number of variables in NLP 196 * 197 * @pre This method can be called if SCIP is in one of the following stages: 198 * - \ref SCIP_STAGE_INITSOLVE 199 * - \ref SCIP_STAGE_SOLVING 200 */ 201 int SCIPgetNNLPVars( 202 SCIP* scip /**< SCIP data structure */ 203 ) 204 { 205 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNNLPVars", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 206 207 if( scip->nlp == NULL ) 208 { 209 SCIPerrorMessage("NLP has not been constructed.\n"); 210 SCIPABORT(); 211 return 0; /*lint !e527*/ 212 } 213 214 return SCIPnlpGetNVars(scip->nlp); 215 } 216 217 /** computes for each variables the number of NLP rows in which the variable appears in the nonlinear part 218 * 219 * @pre This method can be called if SCIP is in one of the following stages: 220 * - \ref SCIP_STAGE_INITSOLVE 221 * - \ref SCIP_STAGE_SOLVING 222 */ 223 SCIP_RETCODE SCIPgetNLPVarsNonlinearity( 224 SCIP* scip, /**< SCIP data structure */ 225 int* nlcount /**< an array of length at least SCIPnlpGetNVars() to store nonlinearity counts of variables */ 226 ) 227 { 228 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNLPVarsNonlinearity", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 229 230 if( scip->nlp == NULL ) 231 { 232 SCIPerrorMessage("NLP has not been constructed.\n"); 233 return SCIP_INVALIDCALL; 234 } 235 236 SCIP_CALL( SCIPnlpGetVarsNonlinearity(scip->nlp, scip->mem->probmem, scip->set, scip->stat, nlcount) ); 237 238 return SCIP_OKAY; 239 } 240 241 /** returns dual solution values associated with lower bounds 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 */ 247 SCIP_Real* SCIPgetNLPVarsLbDualsol( 248 SCIP* scip /**< SCIP data structure */ 249 ) 250 { 251 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNLPVarsLbDualsol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 252 253 if( scip->nlp == NULL ) 254 { 255 SCIPerrorMessage("NLP has not been constructed.\n"); 256 SCIPABORT(); 257 return NULL; /*lint !e527*/ 258 } 259 260 return SCIPnlpGetVarsLbDualsol(scip->nlp); 261 } 262 263 /** returns dual solution values associated with upper bounds of NLP variables 264 * 265 * @pre This method can be called if SCIP is in one of the following stages: 266 * - \ref SCIP_STAGE_INITSOLVE 267 * - \ref SCIP_STAGE_SOLVING 268 */ 269 SCIP_Real* SCIPgetNLPVarsUbDualsol( 270 SCIP* scip /**< SCIP data structure */ 271 ) 272 { 273 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNLPVarsUbDualsol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 274 275 if( scip->nlp == NULL ) 276 { 277 SCIPerrorMessage("NLP has not been constructed.\n"); 278 SCIPABORT(); 279 return NULL; /*lint !e527*/ 280 } 281 282 return SCIPnlpGetVarsUbDualsol(scip->nlp); 283 } 284 285 /** gets current NLP nonlinear rows along with the current number of NLP nonlinear rows 286 * 287 * @pre This method can be called if SCIP is in one of the following stages: 288 * - \ref SCIP_STAGE_INITSOLVE 289 * - \ref SCIP_STAGE_SOLVING 290 */ 291 SCIP_RETCODE SCIPgetNLPNlRowsData( 292 SCIP* scip, /**< SCIP data structure */ 293 SCIP_NLROW*** nlrows, /**< pointer to store the array of NLP nonlinear rows, or NULL */ 294 int* nnlrows /**< pointer to store the number of NLP nonlinear rows, or NULL */ 295 ) 296 { 297 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNLPNlRowsData", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 298 299 if( scip->nlp == NULL ) 300 { 301 SCIPerrorMessage("NLP has not been constructed.\n"); 302 return SCIP_INVALIDCALL; 303 } 304 305 if( nlrows != NULL ) 306 *nlrows = SCIPnlpGetNlRows(scip->nlp); 307 if( nnlrows != NULL ) 308 *nnlrows = SCIPnlpGetNNlRows(scip->nlp); 309 310 return SCIP_OKAY; 311 } 312 313 /** gets array with nonlinear rows of the NLP 314 * 315 * @pre This method can be called if SCIP is in one of the following stages: 316 * - \ref SCIP_STAGE_INITSOLVE 317 * - \ref SCIP_STAGE_SOLVING 318 */ 319 SCIP_NLROW** SCIPgetNLPNlRows( 320 SCIP* scip /**< SCIP data structure */ 321 ) 322 { 323 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNLPNlRows", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 324 325 if( scip->nlp == NULL ) 326 { 327 SCIPerrorMessage("NLP has not been constructed.\n"); 328 SCIPABORT(); 329 return NULL; /*lint !e527*/ 330 } 331 332 return SCIPnlpGetNlRows(scip->nlp); 333 } 334 335 /** gets current number of nonlinear rows in NLP 336 * 337 * @pre This method can be called if SCIP is in one of the following stages: 338 * - \ref SCIP_STAGE_INITSOLVE 339 * - \ref SCIP_STAGE_SOLVING 340 */ 341 int SCIPgetNNLPNlRows( 342 SCIP* scip /**< SCIP data structure */ 343 ) 344 { 345 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNNLPNlRows", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 346 347 if( scip->nlp == NULL ) 348 { 349 SCIPerrorMessage("NLP has not been constructed.\n"); 350 SCIPABORT(); 351 return 0; /*lint !e527*/ 352 } 353 354 return SCIPnlpGetNNlRows(scip->nlp); 355 } 356 357 /** gets statistics on convexity of rows in NLP 358 * 359 * Reports counts on the current number of linear rows, convex inequalities, nonconvex inequalities, and nonlinear equalities or ranged rows. 360 * - A nonlinear inequality with infinity left-hand-side is accounted as convex if its expression has been marked as convex. 361 * - A nonlinear inequality with infinity right-hand-side is accounted as convex if its expression has been marked as concave. 362 * - Other nonlinear rows are accounted as nonconvex. Note that convexity for a nonlinear row may just not have been detected. 363 * 364 * @pre This method can be called if SCIP is in one of the following stages: 365 * - \ref SCIP_STAGE_INITSOLVE 366 * - \ref SCIP_STAGE_SOLVING 367 * - \ref SCIP_STAGE_SOLVED 368 */ 369 SCIP_RETCODE SCIPgetNLPNlRowsStat( 370 SCIP* scip, /**< SCIP data structure */ 371 int* nlinear, /**< buffer to store number of linear rows in NLP, or NULL */ 372 int* nconvexineq, /**< buffer to store number of convex inequalities in NLP, or NULL */ 373 int* nnonconvexineq, /**< buffer to store number of nonconvex inequalities in NLP, or NULL */ 374 int* nnonlineareq /**< buffer to store number of nonlinear equalities or ranged rows in NLP, or NULL */ 375 ) 376 { 377 SCIP_CALL( SCIPcheckStage(scip, "SCIPnlpGetNlRowsStat", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 378 379 if( scip->nlp == NULL ) 380 { 381 SCIPerrorMessage("NLP has not been constructed.\n"); 382 return SCIP_ERROR; 383 } 384 385 SCIPnlpGetNlRowsStat(scip->nlp, nlinear, nconvexineq, nnonconvexineq, nnonlineareq); 386 387 return SCIP_OKAY; 388 } 389 390 /** adds a nonlinear row to the NLP. This row is captured by the NLP. 391 * 392 * @pre This method can be called if SCIP is in one of the following stages: 393 * - \ref SCIP_STAGE_INITSOLVE 394 * - \ref SCIP_STAGE_SOLVING 395 */ 396 SCIP_RETCODE SCIPaddNlRow( 397 SCIP* scip, /**< SCIP data structure */ 398 SCIP_NLROW* nlrow /**< nonlinear row to add to NLP */ 399 ) 400 { 401 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddNlRow", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 402 403 if( scip->nlp == NULL ) 404 { 405 SCIPerrorMessage("NLP has not been constructed.\n"); 406 return SCIP_INVALIDCALL; 407 } 408 409 SCIP_CALL( SCIPnlpAddNlRow(scip->nlp, SCIPblkmem(scip), scip->set, scip->stat, nlrow) ); 410 411 return SCIP_OKAY; 412 } 413 414 /** removes a nonlinear row from the NLP 415 * 416 * This row is released in the NLP. 417 * 418 * @pre This method can be called if SCIP is in one of the following stages: 419 * - \ref SCIP_STAGE_INITSOLVE 420 * - \ref SCIP_STAGE_SOLVING 421 * - \ref SCIP_STAGE_SOLVED 422 * - \ref SCIP_STAGE_EXITSOLVE 423 */ 424 SCIP_RETCODE SCIPdelNlRow( 425 SCIP* scip, /**< SCIP data structure */ 426 SCIP_NLROW* nlrow /**< nonlinear row to add to NLP */ 427 ) 428 { 429 SCIP_CALL( SCIPcheckStage(scip, "SCIPdelNlRow", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 430 431 if( scip->nlp == NULL ) 432 { 433 SCIPerrorMessage("NLP has not been constructed.\n"); 434 return SCIP_INVALIDCALL; 435 } 436 437 SCIP_CALL( SCIPnlpDelNlRow(scip->nlp, SCIPblkmem(scip), scip->set, scip->stat, nlrow) ); 438 439 return SCIP_OKAY; 440 } 441 442 /** makes sure that the NLP of the current node is flushed 443 * 444 * @pre This method can be called if SCIP is in one of the following stages: 445 * - \ref SCIP_STAGE_INITSOLVE 446 * - \ref SCIP_STAGE_SOLVING 447 */ 448 SCIP_RETCODE SCIPflushNLP( 449 SCIP* scip /**< SCIP data structure */ 450 ) 451 { 452 SCIP_CALL( SCIPcheckStage(scip, "SCIPflushNLP", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 453 454 if( scip->nlp == NULL ) 455 { 456 SCIPerrorMessage("NLP has not been constructed.\n"); 457 return SCIP_INVALIDCALL; 458 } 459 460 SCIP_CALL( SCIPnlpFlush(scip->nlp, scip->mem->probmem, scip->set, scip->stat) ); 461 462 return SCIP_OKAY; 463 } 464 465 /** sets or clears initial primal guess for NLP solution (start point for NLP solver) 466 * 467 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 468 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 469 * 470 * @pre This method can be called if SCIP is in one of the following stages: 471 * - \ref SCIP_STAGE_INITSOLVE 472 * - \ref SCIP_STAGE_SOLVING 473 */ 474 SCIP_RETCODE SCIPsetNLPInitialGuess( 475 SCIP* scip, /**< SCIP data structure */ 476 SCIP_Real* initialguess /**< values of initial guess (corresponding to variables from SCIPgetNLPVarsData), or NULL to use no start point */ 477 ) 478 { 479 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetNLPInitialGuess", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 480 481 if( scip->nlp == NULL ) 482 { 483 SCIPerrorMessage("NLP has not been constructed.\n"); 484 return SCIP_INVALIDCALL; 485 } 486 487 SCIP_CALL( SCIPnlpSetInitialGuess(scip->set, scip->nlp, SCIPblkmem(scip), initialguess) ); 488 489 return SCIP_OKAY; 490 } 491 492 /** sets initial primal guess for NLP solution (start point for NLP solver) 493 * 494 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 495 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 496 * 497 * @pre This method can be called if SCIP is in one of the following stages: 498 * - \ref SCIP_STAGE_INITSOLVE 499 * - \ref SCIP_STAGE_SOLVING 500 */ 501 SCIP_RETCODE SCIPsetNLPInitialGuessSol( 502 SCIP* scip, /**< SCIP data structure */ 503 SCIP_SOL* sol /**< solution which values should be taken as initial guess, or NULL for LP solution */ 504 ) 505 { 506 SCIP_Real* vals; 507 508 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetNLPInitialGuessSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 509 510 if( scip->nlp == NULL ) 511 { 512 SCIPerrorMessage("NLP has not been constructed.\n"); 513 return SCIP_INVALIDCALL; 514 } 515 516 SCIP_CALL( SCIPallocBufferArray(scip, &vals, SCIPnlpGetNVars(scip->nlp)) ); 517 SCIP_CALL( SCIPgetSolVals(scip, sol, SCIPnlpGetNVars(scip->nlp), SCIPnlpGetVars(scip->nlp), vals) ); 518 SCIP_CALL( SCIPnlpSetInitialGuess(scip->set, scip->nlp, SCIPblkmem(scip), vals) ); 519 SCIPfreeBufferArray(scip, &vals); 520 521 return SCIP_OKAY; 522 } 523 524 /** solves the current NLP (or diving NLP if in diving mode) with given parameters 525 * 526 * Typical use is 527 * 528 * SCIP_NLPPARAM nlparam = { SCIP_NLPPARAM_DEFAULT(scip); } 529 * nlpparam.iterlimit = 42; 530 * SCIP_CALL( SCIPsolveNLPParam(scip, nlpparam) ); 531 * 532 * or, in one line: 533 * 534 * SCIP_CALL( SCIPsolveNLPParam(scip, (SCIP_NLPPARAM){ SCIP_NLPPARAM_DEFAULT(scip), .iterlimit = 42 }) ); 535 * 536 * To get the latter, also \ref SCIPsolveNLP can be used. 537 * 538 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 539 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 540 * 541 * @pre This method can be called if SCIP is in one of the following stages: 542 * - \ref SCIP_STAGE_INITSOLVE 543 * - \ref SCIP_STAGE_SOLVING 544 */ 545 SCIP_RETCODE SCIPsolveNLPParam( 546 SCIP* scip, /**< SCIP data structure */ 547 SCIP_NLPPARAM param /**< NLP solve parameters */ 548 ) 549 { 550 SCIP_CALL( SCIPcheckStage(scip, "SCIPsolveNLPParam", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 551 552 if( scip->nlp == NULL ) 553 { 554 SCIPerrorMessage("NLP has not been constructed.\n"); 555 return SCIP_INVALIDCALL; 556 } 557 558 SCIP_CALL( SCIPnlpSolve(scip->nlp, SCIPblkmem(scip), scip->set, scip->messagehdlr, scip->stat, scip->primal, scip->tree, ¶m) ); 559 560 return SCIP_OKAY; 561 } 562 563 #if defined(_MSC_VER) && _MSC_VER < 1800 564 /* warn that SCIPsolveNLP() macro isn't perfect with ancient MSVC */ 565 #pragma message ( "Warning: designated initializers not supported by this version of MSVC. Parameters given to NLP solves may be ignored." ) 566 #endif 567 568 /** gets solution status of current NLP 569 * 570 * @pre This method can be called if SCIP is in one of the following stages: 571 * - \ref SCIP_STAGE_INITSOLVE 572 * - \ref SCIP_STAGE_SOLVING 573 */ 574 SCIP_NLPSOLSTAT SCIPgetNLPSolstat( 575 SCIP* scip /**< SCIP data structure */ 576 ) 577 { 578 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNLPSolstat", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 579 580 if( scip->nlp == NULL ) 581 { 582 SCIPerrorMessage("NLP has not been constructed.\n"); 583 SCIPABORT(); 584 return SCIP_NLPSOLSTAT_UNKNOWN; /*lint !e527*/ 585 } 586 587 return SCIPnlpGetSolstat(scip->nlp); 588 } 589 590 /** gets termination status of last NLP solve 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 */ 596 SCIP_NLPTERMSTAT SCIPgetNLPTermstat( 597 SCIP* scip /**< SCIP data structure */ 598 ) 599 { 600 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNLPTermstat", 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 SCIPABORT(); 606 return SCIP_NLPTERMSTAT_OTHER; /*lint !e527*/ 607 } 608 609 return SCIPnlpGetTermstat(scip->nlp); 610 } 611 612 /** gives statistics (number of iterations, solving time, ...) of last NLP solve 613 * 614 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 615 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 616 * 617 * @pre This method can be called if SCIP is in one of the following stages: 618 * - \ref SCIP_STAGE_INITSOLVE 619 * - \ref SCIP_STAGE_SOLVING 620 */ 621 SCIP_RETCODE SCIPgetNLPStatistics( 622 SCIP* scip, /**< SCIP data structure */ 623 SCIP_NLPSTATISTICS* statistics /**< pointer to store statistics */ 624 ) 625 { 626 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNLPStatistics", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 627 628 if( scip->nlp == NULL ) 629 { 630 SCIPerrorMessage("NLP has not been constructed.\n"); 631 return SCIP_INVALIDCALL; 632 } 633 634 SCIP_CALL( SCIPnlpGetStatistics(scip->set, scip->nlp, statistics) ); 635 636 return SCIP_OKAY; 637 } 638 639 /** gets objective value of current NLP 640 * 641 * @pre This method can be called if SCIP is in one of the following stages: 642 * - \ref SCIP_STAGE_INITSOLVE 643 * - \ref SCIP_STAGE_SOLVING 644 */ 645 SCIP_Real SCIPgetNLPObjval( 646 SCIP* scip /**< SCIP data structure */ 647 ) 648 { 649 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNLPObjval", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 650 651 if( scip->nlp != NULL ) 652 { 653 return SCIPnlpGetObjval(scip->nlp); 654 } 655 else 656 { 657 SCIPerrorMessage("NLP has not been constructed.\n"); 658 return SCIP_INVALID; 659 } 660 } 661 662 /** indicates whether a solution for the current NLP is available 663 * 664 * The solution may be optimal, feasible, or infeasible. 665 * Thus, returns whether the NLP solution status is at most \ref SCIP_NLPSOLSTAT_LOCINFEASIBLE. 666 * 667 * @pre This method can be called if SCIP is in one of the following stages: 668 * - \ref SCIP_STAGE_INITSOLVE 669 * - \ref SCIP_STAGE_SOLVING 670 */ 671 SCIP_Bool SCIPhasNLPSolution( 672 SCIP* scip /**< SCIP data structure */ 673 ) 674 { 675 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPhasNLPSolution", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 676 677 if( scip->nlp == NULL ) 678 { 679 SCIPerrorMessage("NLP has not been constructed.\n"); 680 SCIPABORT(); 681 return FALSE; /*lint !e527*/ 682 } 683 684 return SCIPnlpHasSolution(scip->nlp); 685 } 686 687 /** gets fractional variables of last NLP solution along with solution values and fractionalities 688 * 689 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 690 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 691 * 692 * @pre This method can be called if SCIP is in one of the following stages: 693 * - \ref SCIP_STAGE_INITSOLVE 694 * - \ref SCIP_STAGE_SOLVING 695 */ 696 SCIP_RETCODE SCIPgetNLPFracVars( 697 SCIP* scip, /**< SCIP data structure */ 698 SCIP_VAR*** fracvars, /**< pointer to store the array of NLP fractional variables, or NULL */ 699 SCIP_Real** fracvarssol, /**< pointer to store the array of NLP fractional variables solution values, or NULL */ 700 SCIP_Real** fracvarsfrac, /**< pointer to store the array of NLP fractional variables fractionalities, or NULL */ 701 int* nfracvars, /**< pointer to store the number of NLP fractional variables , or NULL */ 702 int* npriofracvars /**< pointer to store the number of NLP fractional variables with maximal branching priority, or NULL */ 703 ) 704 { 705 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNLPFracVars", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 706 707 if( scip->nlp == NULL ) 708 { 709 SCIPerrorMessage("NLP has not been constructed.\n"); 710 return SCIP_INVALIDCALL; 711 } 712 713 SCIP_CALL( SCIPnlpGetFracVars(scip->nlp, SCIPblkmem(scip), scip->set, scip->stat, fracvars, fracvarssol, fracvarsfrac, nfracvars, npriofracvars) ); 714 715 return SCIP_OKAY; 716 } 717 718 /** writes current NLP to a file 719 * 720 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 721 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 722 * 723 * @pre This method can be called if SCIP is in one of the following stages: 724 * - \ref SCIP_STAGE_INITSOLVE 725 * - \ref SCIP_STAGE_SOLVING 726 */ 727 SCIP_RETCODE SCIPwriteNLP( 728 SCIP* scip, /**< SCIP data structure */ 729 const char* filename /**< file name */ 730 ) 731 { 732 SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteNLP", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 733 734 if( scip->nlp == NULL ) 735 { 736 SCIPerrorMessage("NLP has not been constructed.\n"); 737 return SCIP_INVALIDCALL; 738 } 739 740 SCIP_CALL( SCIPnlpWrite(scip->nlp, scip->mem->probmem, scip->set, scip->stat, scip->messagehdlr, filename) ); 741 742 return SCIP_OKAY; 743 } 744 745 /** gets the NLP interface and problem used by the SCIP NLP 746 * 747 * @warning With the NLPI and its problem, all methods defined in \ref scip_nlpi.h and \ref pub_nlpi.h can be used. 748 * It needs to be ensured that the full internal state of the NLPI does not change or is recovered completely 749 * after the end of the method that uses the NLPI. In particular, if the NLP or its solution is manipulated 750 * (e.g. by calling one of the SCIPaddNlpi...() or the SCIPsolveNlpi() method), one has to check in advance 751 * whether the NLP is currently solved. If this is the case, one has to make sure that the internal solution 752 * status is recovered completely again. Additionally one has to resolve the NLP with 753 * SCIPsolveNlpi() in order to reinstall the internal solution status. 754 * 755 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 756 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 757 * 758 * @pre This method can be called if SCIP is in one of the following stages: 759 * - \ref SCIP_STAGE_INITSOLVE 760 * - \ref SCIP_STAGE_SOLVING 761 */ 762 SCIP_RETCODE SCIPgetNLPI( 763 SCIP* scip, /**< SCIP data structure */ 764 SCIP_NLPI** nlpi, /**< pointer to store the NLP solver interface */ 765 SCIP_NLPIPROBLEM** nlpiproblem /**< pointer to store the NLP solver interface problem */ 766 ) 767 { 768 assert(nlpi != NULL); 769 assert(nlpiproblem != NULL); 770 771 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNLPI", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 772 773 if( scip->nlp == NULL ) 774 { 775 SCIPerrorMessage("NLP has not been constructed.\n"); 776 return SCIP_INVALIDCALL; 777 } 778 779 *nlpi = SCIPnlpGetNLPI(scip->nlp); 780 *nlpiproblem = SCIPnlpGetNLPIProblem(scip->nlp); 781 782 return SCIP_OKAY; 783 } 784 785 /** @} */ 786 787 /**@addtogroup PublicNLPDiveMethods 788 * @{ */ 789 790 /** initiates NLP diving 791 * 792 * Makes functions SCIPchgVarObjDiveNLP(), SCIPchgVarBoundsDiveNLP() and SCIPchgVarsBoundsDiveNLP() available. 793 * Further, SCIPsolveNLP() can be used to solve the diving NLP. 794 * 795 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 796 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 797 * 798 * @pre This method can be called if SCIP is in one of the following stages: 799 * - \ref SCIP_STAGE_INITSOLVE 800 * - \ref SCIP_STAGE_SOLVING 801 */ 802 SCIP_RETCODE SCIPstartDiveNLP( 803 SCIP* scip /**< SCIP data structure */ 804 ) 805 { 806 SCIP_CALL( SCIPcheckStage(scip, "SCIPstartDiveNLP", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 807 808 if( scip->nlp == NULL ) 809 { 810 SCIPerrorMessage("NLP has not been constructed.\n"); 811 return SCIP_INVALIDCALL; 812 } 813 814 SCIP_CALL( SCIPnlpStartDive(scip->nlp, SCIPblkmem(scip), scip->set, scip->stat) ); 815 816 return SCIP_OKAY; 817 } 818 819 /** ends NLP diving 820 * 821 * Resets changes made by SCIPchgVarObjDiveNLP(), SCIPchgVarBoundsDiveNLP(), and SCIPchgVarsBoundsDiveNLP(). 822 * 823 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 824 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 825 * 826 * @pre This method can be called if SCIP is in one of the following stages: 827 * - \ref SCIP_STAGE_INITSOLVE 828 * - \ref SCIP_STAGE_SOLVING 829 */ 830 SCIP_RETCODE SCIPendDiveNLP( 831 SCIP* scip /**< SCIP data structure */ 832 ) 833 { 834 SCIP_CALL( SCIPcheckStage(scip, "SCIPendDiveNLP", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 835 836 if( scip->nlp == NULL ) 837 { 838 SCIPerrorMessage("NLP has not been constructed.\n"); 839 return SCIP_INVALIDCALL; 840 } 841 842 SCIP_CALL( SCIPnlpEndDive(scip->nlp, SCIPblkmem(scip), scip->set, scip->stat) ); 843 844 return SCIP_OKAY; 845 } 846 847 /** changes linear objective coefficient of a variable in diving NLP 848 * 849 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 850 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 851 * 852 * @pre This method can be called if SCIP is in one of the following stages: 853 * - \ref SCIP_STAGE_INITSOLVE 854 * - \ref SCIP_STAGE_SOLVING 855 */ 856 SCIP_RETCODE SCIPchgVarObjDiveNLP( 857 SCIP* scip, /**< SCIP data structure */ 858 SCIP_VAR* var, /**< variable which coefficient to change */ 859 SCIP_Real coef /**< new value for coefficient */ 860 ) 861 { 862 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarObjDiveNLP", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 863 864 assert( var->scip == scip ); 865 866 if( scip->nlp == NULL ) 867 { 868 SCIPerrorMessage("NLP has not been constructed.\n"); 869 return SCIP_INVALIDCALL; 870 } 871 872 SCIP_CALL( SCIPnlpChgVarObjDive(scip->nlp, SCIPblkmem(scip), scip->set, scip->stat, var, coef) ); 873 874 return SCIP_OKAY; 875 } 876 877 /** changes bounds of a variable in diving NLP 878 * 879 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 880 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 881 * 882 * @pre This method can be called if SCIP is in one of the following stages: 883 * - \ref SCIP_STAGE_INITSOLVE 884 * - \ref SCIP_STAGE_SOLVING 885 */ 886 SCIP_RETCODE SCIPchgVarBoundsDiveNLP( 887 SCIP* scip, /**< SCIP data structure */ 888 SCIP_VAR* var, /**< variable which bounds to change */ 889 SCIP_Real lb, /**< new lower bound */ 890 SCIP_Real ub /**< new upper bound */ 891 ) 892 { 893 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarBoundsDiveNLP", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 894 895 assert( var->scip == scip ); 896 897 if( scip->nlp == NULL ) 898 { 899 SCIPerrorMessage("NLP has not been constructed.\n"); 900 return SCIP_INVALIDCALL; 901 } 902 903 SCIP_CALL( SCIPnlpChgVarBoundsDive(scip->set, scip->nlp, var, lb, ub) ); 904 905 return SCIP_OKAY; 906 } 907 908 /** changes bounds of a set of variables in diving NLP 909 * 910 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 911 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 912 * 913 * @pre This method can be called if SCIP is in one of the following stages: 914 * - \ref SCIP_STAGE_INITSOLVE 915 * - \ref SCIP_STAGE_SOLVING 916 */ 917 SCIP_RETCODE SCIPchgVarsBoundsDiveNLP( 918 SCIP* scip, /**< SCIP data structure */ 919 int nvars, /**< number of variables which bounds to changes */ 920 SCIP_VAR** vars, /**< variables which bounds to change */ 921 SCIP_Real* lbs, /**< new lower bounds */ 922 SCIP_Real* ubs /**< new upper bounds */ 923 ) 924 { 925 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarsBoundsDiveNLP", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 926 927 if( scip->nlp == NULL ) 928 { 929 SCIPerrorMessage("NLP has not been constructed.\n"); 930 return SCIP_INVALIDCALL; 931 } 932 933 SCIP_CALL( SCIPnlpChgVarsBoundsDive(scip->nlp, scip->set, nvars, vars, lbs, ubs) ); 934 935 return SCIP_OKAY; 936 } 937 938 /** @} */ 939 940 /**@addtogroup PublicNLRowMethods 941 * @{ 942 */ 943 944 /** creates and captures a nonlinear row 945 * 946 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 947 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 948 * 949 * @pre This method can be called if SCIP is in one of the following stages: 950 * - \ref SCIP_STAGE_PRESOLVED 951 * - \ref SCIP_STAGE_INITSOLVE 952 * - \ref SCIP_STAGE_SOLVING 953 */ 954 SCIP_RETCODE SCIPcreateNlRow( 955 SCIP* scip, /**< SCIP data structure */ 956 SCIP_NLROW** nlrow, /**< buffer to store pointer to nonlinear row */ 957 const char* name, /**< name of nonlinear row */ 958 SCIP_Real constant, /**< constant */ 959 int nlinvars, /**< number of linear variables */ 960 SCIP_VAR** linvars, /**< linear variables, or NULL if nlinvars == 0 */ 961 SCIP_Real* lincoefs, /**< linear coefficients, or NULL if nlinvars == 0 */ 962 SCIP_EXPR* expr, /**< nonlinear expression, or NULL */ 963 SCIP_Real lhs, /**< left hand side */ 964 SCIP_Real rhs, /**< right hand side */ 965 SCIP_EXPRCURV curvature /**< curvature of the nonlinear row */ 966 ) 967 { 968 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateNlRow", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 969 970 SCIP_CALL( SCIPnlrowCreate(nlrow, scip->mem->probmem, scip->set, scip->stat, 971 name, constant, nlinvars, linvars, lincoefs, expr, lhs, rhs, curvature) ); 972 973 return SCIP_OKAY; 974 } 975 976 /** creates and captures a nonlinear row without any coefficients 977 * 978 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 979 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 980 * 981 * @pre This method can be called if SCIP is in one of the following stages: 982 * - \ref SCIP_STAGE_PRESOLVED 983 * - \ref SCIP_STAGE_INITSOLVE 984 * - \ref SCIP_STAGE_SOLVING 985 */ 986 SCIP_RETCODE SCIPcreateEmptyNlRow( 987 SCIP* scip, /**< SCIP data structure */ 988 SCIP_NLROW** nlrow, /**< pointer to nonlinear row */ 989 const char* name, /**< name of nonlinear row */ 990 SCIP_Real lhs, /**< left hand side */ 991 SCIP_Real rhs /**< right hand side */ 992 ) 993 { 994 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateEmptyNlRow", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 995 996 SCIP_CALL( SCIPnlrowCreate(nlrow, scip->mem->probmem, scip->set, scip->stat, 997 name, 0.0, 0, NULL, NULL, NULL, lhs, rhs, SCIP_EXPRCURV_UNKNOWN) ); 998 999 return SCIP_OKAY; 1000 } 1001 1002 /** creates and captures a nonlinear row from a linear row 1003 * 1004 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1005 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1006 * 1007 * @pre This method can be called if SCIP is in one of the following stages: 1008 * - \ref SCIP_STAGE_PRESOLVED 1009 * - \ref SCIP_STAGE_INITSOLVE 1010 * - \ref SCIP_STAGE_SOLVING 1011 */ 1012 SCIP_RETCODE SCIPcreateNlRowFromRow( 1013 SCIP* scip, /**< SCIP data structure */ 1014 SCIP_NLROW** nlrow, /**< pointer to nonlinear row */ 1015 SCIP_ROW* row /**< the linear row to copy */ 1016 ) 1017 { 1018 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateNlRowFromRow", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1019 1020 SCIP_CALL( SCIPnlrowCreateFromRow(nlrow, scip->mem->probmem, scip->set, scip->stat, row) ); 1021 1022 return SCIP_OKAY; 1023 } 1024 1025 /** increases usage counter of a nonlinear row 1026 * 1027 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1028 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1029 * 1030 * @pre This method can be called if SCIP is in one of the following stages: 1031 * - \ref SCIP_STAGE_PRESOLVED 1032 * - \ref SCIP_STAGE_INITSOLVE 1033 * - \ref SCIP_STAGE_SOLVING 1034 */ 1035 SCIP_RETCODE SCIPcaptureNlRow( 1036 SCIP* scip, /**< SCIP data structure */ 1037 SCIP_NLROW* nlrow /**< nonlinear row to capture */ 1038 ) 1039 { 1040 SCIP_CALL( SCIPcheckStage(scip, "SCIPcaptureNlRow", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1041 1042 SCIPnlrowCapture(nlrow); 1043 1044 return SCIP_OKAY; 1045 } 1046 1047 /** decreases usage counter of a nonlinear row, and frees memory if necessary 1048 * 1049 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1050 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1051 * 1052 * @pre This method can be called if SCIP is in one of the following stages: 1053 * - \ref SCIP_STAGE_PRESOLVED 1054 * - \ref SCIP_STAGE_INITSOLVE 1055 * - \ref SCIP_STAGE_SOLVING 1056 * - \ref SCIP_STAGE_EXITSOLVE 1057 */ 1058 SCIP_RETCODE SCIPreleaseNlRow( 1059 SCIP* scip, /**< SCIP data structure */ 1060 SCIP_NLROW** nlrow /**< pointer to nonlinear row */ 1061 ) 1062 { 1063 SCIP_CALL( SCIPcheckStage(scip, "SCIPreleaseNlRow", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE) ); 1064 1065 SCIP_CALL( SCIPnlrowRelease(nlrow, scip->mem->probmem, scip->set, scip->stat) ); 1066 1067 return SCIP_OKAY; 1068 } 1069 1070 /** changes left hand side of a nonlinear row 1071 * 1072 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1073 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1074 * 1075 * @pre This method can be called if SCIP is in one of the following stages: 1076 * - \ref SCIP_STAGE_PRESOLVED 1077 * - \ref SCIP_STAGE_INITSOLVE 1078 * - \ref SCIP_STAGE_SOLVING 1079 */ 1080 SCIP_RETCODE SCIPchgNlRowLhs( 1081 SCIP* scip, /**< SCIP data structure */ 1082 SCIP_NLROW* nlrow, /**< NLP nonlinear row */ 1083 SCIP_Real lhs /**< new left hand side */ 1084 ) 1085 { 1086 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgNlRowLhs", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1087 1088 SCIP_CALL( SCIPnlrowChgLhs(nlrow, scip->set, scip->stat, scip->nlp, lhs) ); 1089 1090 return SCIP_OKAY; 1091 } 1092 1093 /** changes right hand side of a nonlinear row 1094 * 1095 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1096 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1097 * 1098 * @pre This method can be called if SCIP is in one of the following stages: 1099 * - \ref SCIP_STAGE_PRESOLVED 1100 * - \ref SCIP_STAGE_INITSOLVE 1101 * - \ref SCIP_STAGE_SOLVING 1102 */ 1103 SCIP_RETCODE SCIPchgNlRowRhs( 1104 SCIP* scip, /**< SCIP data structure */ 1105 SCIP_NLROW* nlrow, /**< NLP nonlinear row */ 1106 SCIP_Real rhs /**< new right hand side */ 1107 ) 1108 { 1109 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgNlRowRhs", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1110 1111 SCIP_CALL( SCIPnlrowChgRhs(nlrow, scip->set, scip->stat, scip->nlp, rhs) ); 1112 1113 return SCIP_OKAY; 1114 } 1115 1116 /** changes constant of a nonlinear row 1117 * 1118 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1119 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1120 * 1121 * @pre This method can be called if SCIP is in one of the following stages: 1122 * - \ref SCIP_STAGE_PRESOLVED 1123 * - \ref SCIP_STAGE_INITSOLVE 1124 * - \ref SCIP_STAGE_SOLVING 1125 */ 1126 SCIP_RETCODE SCIPchgNlRowConstant( 1127 SCIP* scip, /**< SCIP data structure */ 1128 SCIP_NLROW* nlrow, /**< NLP row */ 1129 SCIP_Real constant /**< new value for constant */ 1130 ) 1131 { 1132 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgNlRowConstant", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1133 1134 SCIP_CALL( SCIPnlrowChgConstant(nlrow, scip->set, scip->stat, scip->nlp, constant) ); 1135 1136 return SCIP_OKAY; 1137 } 1138 1139 /** set curvature of a nonlinear row */ 1140 void SCIPsetNlRowCurvature( 1141 SCIP* scip, /**< SCIP data structure */ 1142 SCIP_NLROW* nlrow, /**< NLP row */ 1143 SCIP_EXPRCURV curvature /**< curvature of NLP row */ 1144 ) 1145 { 1146 assert(scip != NULL); 1147 1148 SCIPnlrowSetCurvature(scip->nlp, scip->set, nlrow, curvature); 1149 } 1150 1151 /** adds variable with a linear coefficient to a nonlinear row 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_PRESOLVED 1158 * - \ref SCIP_STAGE_INITSOLVE 1159 * - \ref SCIP_STAGE_SOLVING 1160 */ 1161 SCIP_RETCODE SCIPaddLinearCoefToNlRow( 1162 SCIP* scip, /**< SCIP data structure */ 1163 SCIP_NLROW* nlrow, /**< NLP row */ 1164 SCIP_VAR* var, /**< problem variable */ 1165 SCIP_Real val /**< value of coefficient in linear part of row */ 1166 ) 1167 { 1168 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddLinearCoefToNlRow", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1169 1170 SCIP_CALL( SCIPnlrowAddLinearCoef(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->nlp, var, val) ); 1171 1172 return SCIP_OKAY; 1173 } 1174 1175 /** adds variables with linear coefficients to a row 1176 * 1177 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1178 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1179 * 1180 * @pre This method can be called if SCIP is in one of the following stages: 1181 * - \ref SCIP_STAGE_PRESOLVED 1182 * - \ref SCIP_STAGE_INITSOLVE 1183 * - \ref SCIP_STAGE_SOLVING 1184 */ 1185 SCIP_RETCODE SCIPaddLinearCoefsToNlRow( 1186 SCIP* scip, /**< SCIP data structure */ 1187 SCIP_NLROW* nlrow, /**< NLP row */ 1188 int nvars, /**< number of variables to add to the row */ 1189 SCIP_VAR** vars, /**< problem variables to add */ 1190 SCIP_Real* vals /**< values of coefficients in linear part of row */ 1191 ) 1192 { 1193 int v; 1194 1195 assert(nvars == 0 || vars != NULL); 1196 assert(nvars == 0 || vals != NULL); 1197 1198 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddLinearCoefsToNlRow", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1199 1200 /* add the variables to the row */ 1201 for( v = 0; v < nvars; ++v ) 1202 { 1203 SCIP_CALL( SCIPnlrowAddLinearCoef(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->nlp, vars[v], vals[v]) ); 1204 } 1205 1206 return SCIP_OKAY; 1207 } 1208 1209 /** changes linear coefficient of a variables in a nonlinear row 1210 * 1211 * Setting the coefficient to 0.0 means that it is removed from the row. 1212 * The variable does not need to exists before. 1213 * 1214 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1215 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1216 * 1217 * @pre This method can be called if SCIP is in one of the following stages: 1218 * - \ref SCIP_STAGE_PRESOLVED 1219 * - \ref SCIP_STAGE_INITSOLVE 1220 * - \ref SCIP_STAGE_SOLVING 1221 */ 1222 SCIP_RETCODE SCIPchgNlRowLinearCoef( 1223 SCIP* scip, /**< SCIP data structure */ 1224 SCIP_NLROW* nlrow, /**< NLP row */ 1225 SCIP_VAR* var, /**< variable */ 1226 SCIP_Real coef /**< new value of coefficient */ 1227 ) 1228 { 1229 assert(var != NULL); 1230 1231 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgNlRowLinearCoef", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1232 1233 SCIP_CALL( SCIPnlrowChgLinearCoef(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->nlp, var, coef) ); 1234 1235 return SCIP_OKAY; 1236 } 1237 1238 /** sets or deletes expression in a nonlinear row 1239 * 1240 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1241 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1242 * 1243 * @pre This method can be called if SCIP is in one of the following stages: 1244 * - \ref SCIP_STAGE_PRESOLVED 1245 * - \ref SCIP_STAGE_INITSOLVE 1246 * - \ref SCIP_STAGE_SOLVING 1247 */ 1248 SCIP_RETCODE SCIPsetNlRowExpr( 1249 SCIP* scip, /**< SCIP data structure */ 1250 SCIP_NLROW* nlrow, /**< NLP row */ 1251 SCIP_EXPR* expr /**< expression, or NULL */ 1252 ) 1253 { 1254 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetNlRowExpr", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1255 1256 SCIP_CALL( SCIPnlrowChgExpr(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->nlp, expr) ); 1257 1258 /* invalidate curvature */ 1259 SCIPnlrowSetCurvature(scip->nlp, scip->set, nlrow, SCIP_EXPRCURV_UNKNOWN); 1260 1261 return SCIP_OKAY; 1262 } 1263 1264 /** recalculates the activity of a nonlinear row in the last NLP solution 1265 * 1266 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1267 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1268 * 1269 * @pre This method can be called if SCIP is in one of the following stages: 1270 * - \ref SCIP_STAGE_PRESOLVED 1271 * - \ref SCIP_STAGE_INITSOLVE 1272 * - \ref SCIP_STAGE_SOLVING 1273 */ 1274 SCIP_RETCODE SCIPrecalcNlRowNLPActivity( 1275 SCIP* scip, /**< SCIP data structure */ 1276 SCIP_NLROW* nlrow /**< NLP nonlinear row */ 1277 ) 1278 { 1279 SCIP_CALL( SCIPcheckStage(scip, "SCIPrecalcNlRowNLPActivity", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1280 1281 if( scip->nlp == NULL ) 1282 { 1283 SCIPerrorMessage("do not have NLP for computing NLP activity\n"); 1284 return SCIP_INVALIDCALL; 1285 } 1286 1287 SCIP_CALL( SCIPnlrowRecalcNLPActivity(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->primal, scip->tree, scip->nlp) ); 1288 1289 return SCIP_OKAY; 1290 } 1291 1292 /** returns the activity of a nonlinear row in the last NLP solution 1293 * 1294 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1295 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1296 * 1297 * @pre This method can be called if SCIP is in one of the following stages: 1298 * - \ref SCIP_STAGE_INITSOLVE 1299 * - \ref SCIP_STAGE_SOLVING 1300 */ 1301 SCIP_RETCODE SCIPgetNlRowNLPActivity( 1302 SCIP* scip, /**< SCIP data structure */ 1303 SCIP_NLROW* nlrow, /**< NLP nonlinear row */ 1304 SCIP_Real* activity /**< pointer to store activity value */ 1305 ) 1306 { 1307 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNlRowNLPActivity", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1308 1309 if( scip->nlp == NULL ) 1310 { 1311 SCIPerrorMessage("do not have NLP for computing NLP activity\n"); 1312 return SCIP_INVALIDCALL; 1313 } 1314 1315 SCIP_CALL( SCIPnlrowGetNLPActivity(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->primal, scip->tree, scip->nlp, activity) ); 1316 1317 return SCIP_OKAY; 1318 } 1319 1320 /** gives the feasibility of a nonlinear row in the last NLP solution: negative value means infeasibility 1321 * 1322 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1323 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1324 * 1325 * @pre This method can be called if SCIP is in one of the following stages: 1326 * - \ref SCIP_STAGE_INITSOLVE 1327 * - \ref SCIP_STAGE_SOLVING 1328 */ 1329 SCIP_RETCODE SCIPgetNlRowNLPFeasibility( 1330 SCIP* scip, /**< SCIP data structure */ 1331 SCIP_NLROW* nlrow, /**< NLP nonlinear row */ 1332 SCIP_Real* feasibility /**< pointer to store feasibility value */ 1333 ) 1334 { 1335 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNlRowNLPFeasibility", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1336 1337 if( scip->nlp == NULL ) 1338 { 1339 SCIPerrorMessage("do not have NLP for computing NLP feasibility\n"); 1340 return SCIP_INVALIDCALL; 1341 } 1342 1343 SCIP_CALL( SCIPnlrowGetNLPFeasibility(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->primal, scip->tree, scip->nlp, feasibility) ); 1344 1345 return SCIP_OKAY; 1346 } 1347 1348 /** recalculates the activity of a nonlinear row for the current pseudo solution 1349 * 1350 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1351 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1352 * 1353 * @pre This method can be called if SCIP is in one of the following stages: 1354 * - \ref SCIP_STAGE_INITSOLVE 1355 * - \ref SCIP_STAGE_SOLVING 1356 */ 1357 SCIP_RETCODE SCIPrecalcNlRowPseudoActivity( 1358 SCIP* scip, /**< SCIP data structure */ 1359 SCIP_NLROW* nlrow /**< NLP nonlinear row */ 1360 ) 1361 { 1362 SCIP_CALL( SCIPcheckStage(scip, "SCIPrecalcNlRowPseudoActivity", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1363 1364 SCIP_CALL( SCIPnlrowRecalcPseudoActivity(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->primal, scip->tree, scip->lp) ); 1365 1366 return SCIP_OKAY; 1367 } 1368 1369 /** gives the activity of a nonlinear row for the current pseudo solution 1370 * 1371 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1372 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1373 * 1374 * @pre This method can be called if SCIP is in one of the following stages: 1375 * - \ref SCIP_STAGE_INITSOLVE 1376 * - \ref SCIP_STAGE_SOLVING 1377 */ 1378 SCIP_RETCODE SCIPgetNlRowPseudoActivity( 1379 SCIP* scip, /**< SCIP data structure */ 1380 SCIP_NLROW* nlrow, /**< NLP nonlinear row */ 1381 SCIP_Real* pseudoactivity /**< pointer to store pseudo activity value */ 1382 ) 1383 { 1384 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNlRowPseudoActivity", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1385 1386 SCIP_CALL( SCIPnlrowGetPseudoActivity(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->primal, scip->tree, scip->lp, pseudoactivity) ); 1387 1388 return SCIP_OKAY; 1389 } 1390 1391 /** gives the feasibility of a nonlinear row for the current pseudo solution: negative value means infeasibility 1392 * 1393 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1394 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1395 * 1396 * @pre This method can be called if SCIP is in one of the following stages: 1397 * - \ref SCIP_STAGE_INITSOLVE 1398 * - \ref SCIP_STAGE_SOLVING 1399 */ 1400 SCIP_RETCODE SCIPgetNlRowPseudoFeasibility( 1401 SCIP* scip, /**< SCIP data structure */ 1402 SCIP_NLROW* nlrow, /**< NLP nonlinear row */ 1403 SCIP_Real* pseudofeasibility /**< pointer to store pseudo feasibility value */ 1404 ) 1405 { 1406 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNlRowPseudoFeasibility", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1407 1408 SCIP_CALL( SCIPnlrowGetPseudoFeasibility(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->primal, scip->tree, scip->lp, pseudofeasibility) ); 1409 1410 return SCIP_OKAY; 1411 } 1412 1413 /** recalculates the activity of a nonlinear row in the last NLP or pseudo solution 1414 * 1415 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1416 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1417 * 1418 * @pre This method can be called if SCIP is in one of the following stages: 1419 * - \ref SCIP_STAGE_INITSOLVE 1420 * - \ref SCIP_STAGE_SOLVING 1421 */ 1422 SCIP_RETCODE SCIPrecalcNlRowActivity( 1423 SCIP* scip, /**< SCIP data structure */ 1424 SCIP_NLROW* nlrow /**< NLP nonlinear row */ 1425 ) 1426 { 1427 SCIP_CALL( SCIPcheckStage(scip, "SCIPrecalcNlRowActivity", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1428 1429 if( scip->nlp != NULL && SCIPnlpHasCurrentNodeNLP(scip->nlp) && SCIPnlpHasSolution(scip->nlp) ) 1430 { 1431 SCIP_CALL( SCIPnlrowRecalcNLPActivity(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->primal, scip->tree, scip->nlp) ); 1432 } 1433 else 1434 { 1435 SCIP_CALL( SCIPnlrowRecalcPseudoActivity(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->primal, scip->tree, scip->lp) ); 1436 } 1437 1438 return SCIP_OKAY; 1439 } 1440 1441 /** gives the activity of a nonlinear row in the last NLP or pseudo solution 1442 * 1443 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1444 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1445 * 1446 * @pre This method can be called if SCIP is in one of the following stages: 1447 * - \ref SCIP_STAGE_INITSOLVE 1448 * - \ref SCIP_STAGE_SOLVING 1449 */ 1450 SCIP_RETCODE SCIPgetNlRowActivity( 1451 SCIP* scip, /**< SCIP data structure */ 1452 SCIP_NLROW* nlrow, /**< NLP nonlinear row */ 1453 SCIP_Real* activity /**< pointer to store activity value */ 1454 ) 1455 { 1456 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNlRowActivity", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1457 1458 if( scip->nlp != NULL && SCIPnlpHasCurrentNodeNLP(scip->nlp) && SCIPnlpHasSolution(scip->nlp) ) 1459 { 1460 SCIP_CALL( SCIPnlrowGetNLPActivity(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->primal, scip->tree, scip->nlp, activity) ); 1461 } 1462 else 1463 { 1464 SCIP_CALL( SCIPnlrowGetPseudoActivity(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->primal, scip->tree, scip->lp, activity) ); 1465 } 1466 1467 return SCIP_OKAY; 1468 } 1469 1470 /** gives the feasibility of a nonlinear row in the last NLP or pseudo solution 1471 * 1472 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1473 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1474 * 1475 * @pre This method can be called if SCIP is in one of the following stages: 1476 * - \ref SCIP_STAGE_INITSOLVE 1477 * - \ref SCIP_STAGE_SOLVING 1478 */ 1479 SCIP_RETCODE SCIPgetNlRowFeasibility( 1480 SCIP* scip, /**< SCIP data structure */ 1481 SCIP_NLROW* nlrow, /**< NLP nonlinear row */ 1482 SCIP_Real* feasibility /**< pointer to store feasibility value */ 1483 ) 1484 { 1485 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNlRowFeasibility", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1486 1487 if( scip->nlp != NULL && SCIPnlpHasCurrentNodeNLP(scip->nlp) && SCIPnlpHasSolution(scip->nlp) ) 1488 { 1489 SCIP_CALL( SCIPnlrowGetNLPFeasibility(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->primal, scip->tree, scip->nlp, feasibility) ); 1490 } 1491 else 1492 { 1493 SCIP_CALL( SCIPnlrowGetPseudoFeasibility(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->primal, scip->tree, scip->lp, feasibility) ); 1494 } 1495 1496 return SCIP_OKAY; 1497 } 1498 1499 /** gives the activity of a nonlinear row for the given primal solution or NLP solution or pseudo solution 1500 * 1501 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1502 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1503 * 1504 * @pre This method can be called if SCIP is in one of the following stages: 1505 * - \ref SCIP_STAGE_INITSOLVE 1506 * - \ref SCIP_STAGE_SOLVING 1507 */ 1508 SCIP_RETCODE SCIPgetNlRowSolActivity( 1509 SCIP* scip, /**< SCIP data structure */ 1510 SCIP_NLROW* nlrow, /**< NLP nonlinear row */ 1511 SCIP_SOL* sol, /**< primal CIP solution, or NULL for NLP solution of pseudo solution */ 1512 SCIP_Real* activity /**< pointer to store activity value */ 1513 ) 1514 { 1515 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNlRowSolActivity", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1516 1517 if( sol != NULL ) 1518 { 1519 SCIP_CALL( SCIPnlrowGetSolActivity(nlrow, scip->mem->probmem, scip->set, scip->stat, sol, activity) ); 1520 } 1521 else if( scip->nlp != NULL && SCIPnlpHasCurrentNodeNLP(scip->nlp) && SCIPnlpHasSolution(scip->nlp) ) 1522 { 1523 SCIP_CALL( SCIPnlrowGetNLPActivity(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->primal, scip->tree, scip->nlp, activity) ); 1524 } 1525 else 1526 { 1527 SCIP_CALL( SCIPnlrowGetPseudoActivity(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->primal, scip->tree, scip->lp, activity) ); 1528 } 1529 1530 return SCIP_OKAY; 1531 } 1532 1533 /** gives the feasibility of a nonlinear row for the given primal solution 1534 * 1535 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1536 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1537 * 1538 * @pre This method can be called if SCIP is in one of the following stages: 1539 * - \ref SCIP_STAGE_INITSOLVE 1540 * - \ref SCIP_STAGE_SOLVING 1541 */ 1542 SCIP_RETCODE SCIPgetNlRowSolFeasibility( 1543 SCIP* scip, /**< SCIP data structure */ 1544 SCIP_NLROW* nlrow, /**< NLP nonlinear row */ 1545 SCIP_SOL* sol, /**< primal CIP solution */ 1546 SCIP_Real* feasibility /**< pointer to store feasibility value */ 1547 ) 1548 { 1549 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNlRowSolFeasibility", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1550 1551 if( sol != NULL ) 1552 { 1553 SCIP_CALL( SCIPnlrowGetSolFeasibility(nlrow, scip->mem->probmem, scip->set, scip->stat, sol, feasibility) ); 1554 } 1555 else if( scip->nlp != NULL && SCIPnlpHasCurrentNodeNLP(scip->nlp) && SCIPnlpHasSolution(scip->nlp) ) 1556 { 1557 SCIP_CALL( SCIPnlrowGetNLPFeasibility(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->primal, scip->tree, scip->nlp, feasibility) ); 1558 } 1559 else 1560 { 1561 SCIP_CALL( SCIPnlrowGetPseudoFeasibility(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->primal, scip->tree, scip->lp, feasibility) ); 1562 } 1563 1564 return SCIP_OKAY; 1565 } 1566 1567 /** gives the minimal and maximal activity of a nonlinear row w.r.t. the variable's bounds 1568 * 1569 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1570 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1571 * 1572 * @pre This method can be called if SCIP is in one of the following stages: 1573 * - \ref SCIP_STAGE_PRESOLVED 1574 * - \ref SCIP_STAGE_INITSOLVE 1575 * - \ref SCIP_STAGE_SOLVING 1576 */ 1577 SCIP_RETCODE SCIPgetNlRowActivityBounds( 1578 SCIP* scip, /**< SCIP data structure */ 1579 SCIP_NLROW* nlrow, /**< NLP row */ 1580 SCIP_Real* minactivity, /**< buffer to store minimal activity, or NULL */ 1581 SCIP_Real* maxactivity /**< buffer to store maximal activity, or NULL */ 1582 ) 1583 { 1584 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetNlRowActivityBounds", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1585 1586 SCIP_CALL( SCIPnlrowGetActivityBounds(nlrow, scip->mem->probmem, scip->set, scip->stat, minactivity, maxactivity) ); 1587 1588 return SCIP_OKAY; 1589 } 1590 1591 /** prints a nonlinear row to file stream 1592 * 1593 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1594 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1595 * 1596 * @pre This method can be called if SCIP is in one of the following stages: 1597 * - \ref SCIP_STAGE_PRESOLVED 1598 * - \ref SCIP_STAGE_INITSOLVE 1599 * - \ref SCIP_STAGE_SOLVING 1600 */ 1601 SCIP_RETCODE SCIPprintNlRow( 1602 SCIP* scip, /**< SCIP data structure */ 1603 SCIP_NLROW* nlrow, /**< NLP row */ 1604 FILE* file /**< output file (or NULL for standard output) */ 1605 ) 1606 { 1607 assert(nlrow != NULL); 1608 1609 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintNlRow", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1610 1611 SCIP_CALL( SCIPnlrowPrint(nlrow, scip->mem->probmem, scip->set, scip->stat, scip->messagehdlr, file) ); 1612 1613 return SCIP_OKAY; 1614 } 1615 1616 /** @} */ 1617