Scippy

SCIP

Solving Constraint Integer Programs

nlp.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (c) 2002-2024 Zuse Institute Berlin (ZIB) */
7 /* */
8 /* Licensed under the Apache License, Version 2.0 (the "License"); */
9 /* you may not use this file except in compliance with the License. */
10 /* You may obtain a copy of the License at */
11 /* */
12 /* http://www.apache.org/licenses/LICENSE-2.0 */
13 /* */
14 /* Unless required by applicable law or agreed to in writing, software */
15 /* distributed under the License is distributed on an "AS IS" BASIS, */
16 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17 /* See the License for the specific language governing permissions and */
18 /* limitations under the License. */
19 /* */
20 /* You should have received a copy of the Apache-2.0 license */
21 /* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22 /* */
23 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24 
25 /**@file nlp.c
26  * @ingroup OTHER_CFILES
27  * @brief NLP management methods
28  * @author Thorsten Gellermann
29  * @author Stefan Vigerske
30  *
31  * In NLP management, we have to distinguish between the current NLP and the NLPI problem
32  * stored in the NLP solver. All NLP methods affect the current NLP only.
33  * Before solving the current NLP with the NLP solver, the NLP solvers data
34  * has to be updated to the current NLP with a call to SCIPnlpFlush().
35  *
36  * @todo handle linear rows from LP
37  */
38 
39 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
40 
41 
42 #include "scip/nlpi.h"
43 #include "scip/pub_expr.h"
44 #include "scip/expr.h"
45 #include "scip/expr_varidx.h"
46 #include "scip/clock.h"
47 #include "scip/event.h"
48 #include "scip/nlp.h"
49 #include "scip/primal.h"
50 #include "scip/pub_event.h"
51 #include "scip/pub_lp.h"
52 #include "scip/pub_message.h"
53 #include "scip/pub_misc.h"
54 #include "scip/pub_misc_sort.h"
55 #include "scip/pub_nlp.h"
56 #include "scip/pub_var.h"
57 #include "scip/set.h"
58 #include "scip/sol.h"
59 #include "scip/struct_nlp.h"
60 /* to get nlp, set, ... in event handling and mapvar2varidx */
61 #include "scip/struct_scip.h"
62 /* to get value of parameter "nlp/solver" and nlpis array and to get access to set->lp for releasing a variable */
63 #include "scip/struct_set.h"
64 #include "scip/struct_stat.h"
65 #include "scip/var.h"
66 #include <string.h>
67 
68 /* defines */
69 
70 #define EVENTHDLR_NAME "nlpEventHdlr" /**< name of NLP event handler that catches variable events */
71 #define EVENTHDLR_DESC "handles all events necessary for maintaining NLP data" /**< description of NLP event handler */
72 #define ADDNAMESTONLPI 0 /**< whether to give variable and row names to NLPI */
73 
74 /*lint -e440*/
75 /*lint -e441*/
76 /*lint -e777*/
77 
78 #ifdef __cplusplus
79 extern "C" {
80 #endif
81 
82 /* avoid inclusion of scip.h */ /*lint -e{2701}*/
84  SCIP* scip /**< SCIP data structure */
85  );
86 
87 #ifdef __cplusplus
88 }
89 #endif
90 
91 /*
92  * forward declarations
93  */
94 
95 /** NLP event handler execution method */
96 static
97 SCIP_DECL_EVENTEXEC( eventExecNlp );
98 
99 /** announces, that a row of the NLP was modified
100  *
101  * adjusts status of current solution;
102  * calling method has to ensure that change is passed on to the NLPI!
103  */
104 static
106  SCIP_NLP* nlp, /**< current NLP data */
107  SCIP_SET* set, /**< global SCIP settings */
108  SCIP_STAT* stat, /**< problem statistics data */
109  SCIP_NLROW* nlrow /**< nonlinear row which was changed */
110  );
111 
112 /*
113  * private NLP nonlinear row methods
114  */
115 
116 /** announces, that the given linear coefficient in the constraint matrix changed */
117 static
119  SCIP_NLROW* nlrow, /**< nonlinear row */
120  SCIP_SET* set, /**< global SCIP settings */
121  SCIP_STAT* stat, /**< problem statistics data */
122  SCIP_VAR* var, /**< variable which coefficient changed */
123  SCIP_Real coef, /**< new coefficient of variable, 0.0 if deleted */
124  SCIP_NLP* nlp /**< current NLP data */
125  )
126 {
127  assert(nlrow != NULL);
128  assert(var != NULL);
129 
130  nlrow->activity = SCIP_INVALID;
131  nlrow->validactivitynlp = -1;
132  nlrow->pseudoactivity = SCIP_INVALID;
133  nlrow->validpsactivitydomchg = -1;
134  nlrow->minactivity = SCIP_INVALID;
135  nlrow->maxactivity = SCIP_INVALID;
136  nlrow->validactivitybdsdomchg = -1;
137 
138  if( nlrow->nlpindex >= 0 )
139  {
140  assert(nlp != NULL);
141 
142  /* notify NLP that row has changed */
143  SCIP_CALL( nlpRowChanged(nlp, set, stat, nlrow) );
144 
145  /* update NLPI problem, if row is in NLPI already */
146  if( nlrow->nlpiindex >= 0 )
147  {
148  int idx;
149 
150  /* get index of variable in NLPI */
151  assert(SCIPhashmapExists(nlp->varhash, var));
152  idx = SCIPhashmapGetImageInt(nlp->varhash, var);
153  assert(idx >= 0 && idx < nlp->nvars);
154 
155  idx = nlp->varmap_nlp2nlpi[idx];
156  assert(idx >= 0 && idx < nlp->nvars_solver);
157 
158  /* change coefficient in NLPI problem */
159  SCIP_CALL( SCIPnlpiChgLinearCoefs(set, nlp->solver, nlp->problem, nlrow->nlpiindex, 1, &idx, &coef) );
160  }
161  }
162 
163  return SCIP_OKAY;
164 }
165 
166 /** create varidx expression for var expression
167  *
168  * called when expr is duplicated for addition to NLPI
169  */
170 static
172 {
173  SCIP_NLP* nlp;
174  int nlpidx;
175 
176  assert(sourcescip != NULL);
177  assert(sourcescip == targetscip);
178  assert(sourceexpr != NULL);
179  assert(targetexpr != NULL);
180  assert(*targetexpr == NULL);
181  assert(mapexprdata != NULL);
182 
183  nlp = (SCIP_NLP*)mapexprdata;
184 
185  /* do not provide map if not variable */
186  if( !SCIPexprIsVar(sourcescip->set, sourceexpr) )
187  return SCIP_OKAY;
188 
189  assert(SCIPvarIsActive(SCIPgetVarExprVar(sourceexpr))); /* because we simplified exprs */
190 
191  assert(SCIPhashmapExists(nlp->varhash, SCIPgetVarExprVar(sourceexpr)));
192  nlpidx = SCIPhashmapGetImageInt(nlp->varhash, SCIPgetVarExprVar(sourceexpr));
193  assert(nlpidx < nlp->nvars);
194 
195  assert(nlp->varmap_nlp2nlpi[nlpidx] >= 0);
196  assert(nlp->varmap_nlp2nlpi[nlpidx] < nlp->nvars_solver);
197  SCIP_CALL( SCIPcreateExprVaridx(targetscip, targetexpr, nlp->varmap_nlp2nlpi[nlpidx], ownercreate, ownercreatedata) );
198 
199  return SCIP_OKAY;
200 }
201 
202 /** announces, that an expression changed */
203 static
205  SCIP_NLROW* nlrow, /**< nonlinear row */
206  BMS_BLKMEM* blkmem, /**< block memory */
207  SCIP_SET* set, /**< global SCIP settings */
208  SCIP_STAT* stat, /**< problem statistics data */
209  SCIP_NLP* nlp /**< current NLP data */
210  )
211 {
212  assert(nlrow != NULL);
213 
214  nlrow->activity = SCIP_INVALID;
215  nlrow->validactivitynlp = -1;
216  nlrow->pseudoactivity = SCIP_INVALID;
217  nlrow->validpsactivitydomchg = -1;
218  nlrow->minactivity = SCIP_INVALID;
219  nlrow->maxactivity = SCIP_INVALID;
220  nlrow->validactivitybdsdomchg = -1;
221 
222  if( nlrow->nlpindex >= 0 )
223  {
224  assert(nlp != NULL);
225 
226  /* notify NLP that row has changed */
227  SCIP_CALL( nlpRowChanged(nlp, set, stat, nlrow) );
228 
229  if( nlrow->nlpiindex >= 0 )
230  {
231  /* change expression tree in NLPI problem */
232  SCIP_EXPR* nlpiexpr;
233 
234  SCIP_CALL( SCIPexprCopy(set, stat, blkmem, set, stat, blkmem, nlrow->expr, &nlpiexpr, mapvar2varidx, (void*)nlp, NULL, NULL) );
235  SCIP_CALL( SCIPnlpiChgExpr(set, nlp->solver, nlp->problem, nlrow->nlpiindex, nlpiexpr) );
236  SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &nlpiexpr) );
237  }
238  }
239 
240  return SCIP_OKAY;
241 }
242 
243 /** notifies nonlinear row, that its sides were changed */
244 static
246  SCIP_NLROW* nlrow, /**< nonlinear row */
247  SCIP_SET* set, /**< global SCIP settings */
248  SCIP_STAT* stat, /**< problem statistics data */
249  SCIP_NLP* nlp /**< current NLP data */
250  )
251 {
252  assert(nlrow != NULL);
253 
254  if( nlrow->nlpindex >= 0 )
255  {
256  assert(nlp != NULL);
257 
258  /* notify NLP that row has changed */
259  SCIP_CALL( nlpRowChanged(nlp, set, stat, nlrow) );
260 
261  if( nlrow->nlpiindex >= 0 )
262  {
263  SCIP_Real lhs;
264  SCIP_Real rhs;
265 
266  /* change sides in NLPI problem */
267  lhs = nlrow->lhs;
268  rhs = nlrow->rhs;
269  if( !SCIPsetIsInfinity(set, -lhs) )
270  lhs -= nlrow->constant;
271  if( !SCIPsetIsInfinity(set, rhs) )
272  rhs -= nlrow->constant;
273 
274  SCIP_CALL( SCIPnlpiChgConsSides(set, nlp->solver, nlp->problem, 1, &nlrow->nlpiindex, &lhs, &rhs) );
275  }
276  }
277 
278  return SCIP_OKAY;
279 }
280 
281 /** notifies nonlinear row, that its constant was changed */
282 static
284  SCIP_NLROW* nlrow, /**< nonlinear row */
285  SCIP_SET* set, /**< global SCIP settings */
286  SCIP_STAT* stat, /**< problem statistics data */
287  SCIP_NLP* nlp /**< current NLP data */
288  )
289 {
290  assert(nlrow != NULL);
291 
292  nlrow->activity = SCIP_INVALID;
293  nlrow->validactivitynlp = -1;
294  nlrow->pseudoactivity = SCIP_INVALID;
295  nlrow->validpsactivitydomchg = -1;
296  nlrow->minactivity = SCIP_INVALID;
297  nlrow->maxactivity = SCIP_INVALID;
298  nlrow->validactivitybdsdomchg = -1;
299 
300  if( nlrow->nlpindex >= 0 )
301  {
302  assert(nlp != NULL);
303 
304  /* notify NLP that row has changed */
305  SCIP_CALL( nlpRowChanged(nlp, set, stat, nlrow) );
306 
307  if( nlrow->nlpiindex >= 0 )
308  {
309  SCIP_Real lhs;
310  SCIP_Real rhs;
311 
312  lhs = nlrow->lhs;
313  rhs = nlrow->rhs;
314  if( !SCIPsetIsInfinity(set, -lhs) )
315  lhs -= nlrow->constant;
316  if( !SCIPsetIsInfinity(set, rhs) )
317  rhs -= nlrow->constant;
318 
319  /* change sides in NLPI problem */
320  SCIP_CALL( SCIPnlpiChgConsSides(set, nlp->solver, nlp->problem, 1, &nlrow->nlpiindex, &lhs, &rhs) );
321  }
322  }
323 
324  return SCIP_OKAY;
325 }
326 
327 /** increments or decrements count of NLROW in NLP statistics
328  *
329  * Updates count on linear/convex/nonconvex NLP rows w.r.t. given NLROW.
330  */
331 static
333  SCIP_NLP* nlp, /**< NLP */
334  SCIP_SET* set, /**< global SCIP settings */
335  SCIP_NLROW* nlrow, /**< nonlinear row */
336  int incr /**< by how much to increment statistic: +1 or -1 */
337  )
338 {
339  assert(nlp != NULL);
340  assert(nlrow != NULL);
341  assert(set != NULL);
342  assert(incr == 1 || incr == -1);
343 
344  if( nlrow->expr == NULL )
345  {
346  nlp->nnlrowlinear += incr;
347  assert(nlp->nnlrowlinear >= 0);
348  return;
349  }
350 
351  if( !SCIPsetIsInfinity(set, -nlrow->lhs) && !SCIPsetIsInfinity(set, nlrow->rhs) )
352  {
353  nlp->nnlrownonlineareq += incr;
354  assert(nlp->nnlrownonlineareq >= 0);
355  return;
356  }
357 
358  if( (SCIPsetIsInfinity(set, -nlrow->lhs) && (nlrow->curvature & SCIP_EXPRCURV_CONVEX)) || /* g(x) <= rhs with g(x) convex */
359  (SCIPsetIsInfinity(set, nlrow->rhs) && (nlrow->curvature & SCIP_EXPRCURV_CONCAVE)) ) /* g(x) >= lhs with g(x) concave */
360  {
361  nlp->nnlrowconvexineq += incr;
362  assert(nlp->nnlrowconvexineq >= 0);
363  return;
364  }
365 
366  nlp->nnlrownonconvexineq += incr;
367  assert(nlp->nnlrownonconvexineq >= 0);
368 }
369 
370 /** sorts linear part of row entries such that lower variable indices precede higher ones */
371 static
373  SCIP_NLROW* nlrow /**< nonlinear row to be sorted */
374  )
375 {
376  assert(nlrow != NULL);
377 
378  /* check, if row is already sorted in the LP part, or if the sorting should be delayed */
379  if( nlrow->linvarssorted )
380  return;
381 
382  /* sort linear coefficients */
383  SCIPsortPtrReal((void**)nlrow->linvars, nlrow->lincoefs, SCIPvarComp, nlrow->nlinvars);
384 
385  nlrow->linvarssorted = TRUE;
386 }
387 
388 /** searches linear variable in nonlinear row, returns position in linvars vector or -1 if not found */
389 static
391  SCIP_NLROW* nlrow, /**< nonlinear row to be searched in */
392  SCIP_VAR* var /**< variable to be searched for */
393  )
394 {
395  int pos;
396 
397  assert(nlrow != NULL);
398  assert(var != NULL);
399 
400  if( nlrow->nlinvars == 0 )
401  return -1;
402 
403  nlrowSortLinear(nlrow);
404  if( !SCIPsortedvecFindPtr((void**)nlrow->linvars, SCIPvarComp, (void*)var, nlrow->nlinvars, &pos) )
405  return -1;
406 
407  return pos;
408 }
409 
410 /** moves a coefficient in a nonlinear row to a different place, and updates all corresponding data structures */
411 static
413  SCIP_NLROW* nlrow, /**< NLP row */
414  int oldpos, /**< old position of coefficient */
415  int newpos /**< new position of coefficient */
416  )
417 {
418  assert(nlrow != NULL);
419  assert(0 <= oldpos && oldpos < nlrow->nlinvars);
420  assert(0 <= newpos && newpos < nlrow->nlinvars);
421  assert(nlrow->linvars[oldpos] != NULL);
422 
423  if( oldpos == newpos )
424  return;
425 
426  nlrow->linvars[newpos] = nlrow->linvars[oldpos];
427  nlrow->lincoefs[newpos] = nlrow->lincoefs[oldpos];
428 
429  /* update sorted flags */
430  nlrow->linvarssorted = FALSE;
431 }
432 
433 /** adds a previously non existing linear coefficient to a nonlinear row */
434 static
436  SCIP_NLROW* nlrow, /**< nonlinear row */
437  BMS_BLKMEM* blkmem, /**< block memory */
438  SCIP_SET* set, /**< global SCIP settings */
439  SCIP_STAT* stat, /**< problem statistics data */
440  SCIP_NLP* nlp, /**< current NLP data */
441  SCIP_VAR* var, /**< variable */
442  SCIP_Real coef /**< value of coefficient */
443  )
444 {
445  int pos;
446 
447  assert(nlrow != NULL);
448  assert(blkmem != NULL);
449  assert(var != NULL);
450  assert(coef != 0.0);
451 
452  /* assert that only active variables are added once the row is in the NLP */
453  assert(nlrow->nlpindex == -1 || SCIPvarIsActive(var) );
454 
455  SCIP_CALL( SCIPnlrowEnsureLinearSize(nlrow, blkmem, set, nlrow->nlinvars+1) );
456  assert(nlrow->linvars != NULL);
457  assert(nlrow->lincoefs != NULL);
458 
459  pos = nlrow->nlinvars;
460  nlrow->nlinvars++;
461 
462  /* insert the variable */
463  nlrow->linvars [pos] = var;
464  nlrow->lincoefs[pos] = coef;
465 
466  SCIP_CALL( nlrowLinearCoefChanged(nlrow, set, stat, var, coef, nlp) );
467 
468  /* update sorted flag */
469  if( pos > 0 && SCIPvarCompare(nlrow->linvars[pos-1], nlrow->linvars[pos]) > 0 )
470  nlrow->linvarssorted = FALSE;
471 
472  SCIPsetDebugMsg(set, "added linear coefficient %g * <%s> at position %d to nonlinear row <%s>\n",
473  coef, SCIPvarGetName(var), pos, nlrow->name);
474 
475  return SCIP_OKAY;
476 }
477 
478 #ifdef SCIP_DISABLED_CODE
479 /** adds a linear coefficient to a nonlinear row
480  * if the variable exists in the linear part of the row already, the coefficients are added
481  * otherwise the variable is added to the row */
482 static
483 SCIP_RETCODE nlrowAddToLinearCoef(
484  SCIP_NLROW* nlrow, /**< nonlinear row */
485  BMS_BLKMEM* blkmem, /**< block memory */
486  SCIP_SET* set, /**< global SCIP settings */
487  SCIP_STAT* stat, /**< problem statistics data */
488  SCIP_NLP* nlp, /**< current NLP data */
489  SCIP_VAR* var, /**< variable */
490  SCIP_Real coef, /**< value of coefficient */
491  SCIP_Bool removefixed /**< whether to disaggregate var before adding */
492  )
493 {
494  int pos;
495 
496  assert(nlrow != NULL);
497  assert(blkmem != NULL);
498  assert(var != NULL);
499 
500  if( removefixed && !SCIPvarIsActive(var) )
501  {
502  SCIP_Real constant;
503 
504  constant = 0.0;
505  SCIP_CALL( SCIPvarGetProbvarSum(&var, set, &coef, &constant) );
506  if( constant != 0.0 )
507  {
508  nlrow->constant += constant;
509  SCIP_CALL( nlrowConstantChanged(nlrow, set, stat, nlp) );
510  }
511 
512  if( SCIPsetIsZero(set, coef) )
513  return SCIP_OKAY;
514 
515  if( !SCIPvarIsActive(var) )
516  {
517  int j;
518 
519  /* if var is still not active, then it is multi-aggregated */
521 
522  if( SCIPvarGetMultaggrConstant(var) != 0.0 )
523  {
524  nlrow->constant += coef * SCIPvarGetMultaggrConstant(var);
525  SCIP_CALL( nlrowConstantChanged(nlrow, set, stat, nlp) );
526  }
527 
528  for( j = 0; j < SCIPvarGetMultaggrNVars(var); ++j )
529  {
530  SCIP_CALL( nlrowAddToLinearCoef(nlrow, blkmem, set, stat, nlp, SCIPvarGetMultaggrVars(var)[j], SCIPvarGetMultaggrScalars(var)[j] * coef, TRUE) );
531  }
532 
533  return SCIP_OKAY;
534  }
535  }
536  else if( SCIPsetIsZero(set, coef) )
537  return SCIP_OKAY;
538 
539  assert(!removefixed || SCIPvarIsActive(var));
540 
541  pos = nlrowSearchLinearCoef(nlrow, var);
542 
543  if( pos == -1 )
544  {
545  /* add as new coefficient */
546  SCIP_CALL( nlrowAddLinearCoef(nlrow, blkmem, set, stat, nlp, var, coef) );
547  }
548  else
549  {
550  assert(pos >= 0);
551  assert(pos < nlrow->nlinvars);
552  assert(nlrow->linvars[pos] == var);
553 
554  /* add to previously existing coefficient */
555  nlrow->lincoefs[pos] += coef;
556  }
557 
558  return SCIP_OKAY;
559 }
560 #endif
561 
562 /** deletes coefficient at given position from row */
563 static
565  SCIP_NLROW* nlrow, /**< nonlinear row to be changed */
566  SCIP_SET* set, /**< global SCIP settings */
567  SCIP_STAT* stat, /**< problem statistics data */
568  SCIP_NLP* nlp, /**< current NLP data */
569  int pos /**< position in row vector to delete */
570  )
571 {
572  SCIP_VAR* var;
573 
574  assert(nlrow != NULL);
575  assert(set != NULL);
576  assert(0 <= pos && pos < nlrow->nlinvars);
577  assert(nlrow->linvars[pos] != NULL);
578 
579  var = nlrow->linvars[pos];
580 
581  /* move last coefficient to position of empty slot (should set sorted flag to FALSE, if not last variable was deleted) */
582  nlrowMoveLinearCoef(nlrow, nlrow->nlinvars-1, pos);
583  nlrow->nlinvars--;
584  assert(pos == nlrow->nlinvars || nlrow->linvarssorted == FALSE);
585 
586  SCIP_CALL( nlrowLinearCoefChanged(nlrow, set, stat, var, 0.0, nlp) );
587 
588  return SCIP_OKAY;
589 }
590 
591 /** changes a coefficient at given position of a nonlinear row */
592 static
594  SCIP_NLROW* nlrow, /**< NLP row */
595  SCIP_SET* set, /**< global SCIP settings */
596  SCIP_STAT* stat, /**< problem statistics data */
597  SCIP_NLP* nlp, /**< current NLP data */
598  int pos, /**< position in row vector to change */
599  SCIP_Real coef /**< new value of coefficient */
600  )
601 {
602  assert(nlrow != NULL);
603  assert(0 <= pos && pos < nlrow->nlinvars);
604  assert(nlrow->linvars != NULL);
605  assert(nlrow->linvars[pos] != NULL);
606 
607  if( SCIPsetIsZero(set, coef) )
608  {
609  /* delete existing coefficient */
610  SCIP_CALL( nlrowDelLinearCoefPos(nlrow, set, stat, nlp, pos) );
611  }
612  else if( !SCIPsetIsEQ(set, nlrow->lincoefs[pos], coef) )
613  {
614  /* change existing coefficient */
615  nlrow->lincoefs[pos] = coef;
616  SCIP_CALL( nlrowLinearCoefChanged(nlrow, set, stat, nlrow->linvars[pos], coef, nlp) );
617  }
618 
619  return SCIP_OKAY;
620 }
621 
622 /** calculates minimal and maximal activity of row w.r.t. the variable's bounds */
623 static
625  SCIP_NLROW* nlrow, /**< nonlinear row */
626  BMS_BLKMEM* blkmem, /**< block memory */
627  SCIP_SET* set, /**< global SCIP settings */
628  SCIP_STAT* stat /**< problem statistics data */
629  )
630 {
631  SCIP_Real inf;
632  SCIP_INTERVAL activity;
633  SCIP_INTERVAL bounds;
634  int i;
635 
636  assert(nlrow != NULL);
637  assert(set != NULL);
638  assert(stat != NULL);
639 
640  inf = SCIPsetInfinity(set);
641 
642  /* calculate activity bounds */
643  SCIPintervalSet(&activity, nlrow->constant);
644  for( i = 0; i < nlrow->nlinvars && !SCIPintervalIsEntire(inf, activity); ++i )
645  {
647  SCIPintervalMulScalar(inf, &bounds, bounds, nlrow->lincoefs[i]);
648  SCIPintervalAdd(inf, &activity, activity, bounds);
649  }
650 
651  if( nlrow->expr != NULL && !SCIPintervalIsEntire(inf, activity) )
652  {
653  SCIP_CALL( SCIPexprEvalActivity(set, stat, blkmem, nlrow->expr) );
654  SCIPintervalAdd(inf, &activity, activity, SCIPexprGetActivity(nlrow->expr));
655  }
656 
657  nlrow->minactivity = SCIPintervalGetInf(activity);
658  nlrow->maxactivity = SCIPintervalGetSup(activity);
659 
660  nlrow->validactivitybdsdomchg = stat->domchgcount;
661 
662  return SCIP_OKAY;
663 }
664 
665 /** makes sure that there is no fixed variable at position pos of the linear part of a nonlinear row
666  *
667  * a fixed variable is replaced with the corresponding constant or disaggregated term
668  */
669 static
671  SCIP_NLROW* nlrow, /**< nonlinear row */
672  BMS_BLKMEM* blkmem, /**< block memory */
673  SCIP_SET* set, /**< global SCIP settings */
674  SCIP_STAT* stat, /**< problem statistics data */
675  SCIP_NLP* nlp, /**< current NLP data */
676  int pos /**< position of variable in linear variables array */
677  )
678 {
679  SCIP_Real oldconstant;
680  SCIP_VAR* var;
681 
682  assert(nlrow != NULL);
683  assert(blkmem != NULL);
684  assert(pos >= 0);
685  assert(pos < nlrow->nlinvars);
686 
687  var = nlrow->linvars[pos];
688 
689  if( SCIPvarIsActive(var) )
690  return SCIP_OKAY;
691 
692  oldconstant = nlrow->constant;
693 
694  /* replace fixed, aggregated, or negated variable */
695  SCIP_CALL( SCIPvarGetProbvarSum( &nlrow->linvars[pos], set, &nlrow->lincoefs[pos], &nlrow->constant) );
696 
697  /* if var had been fixed, entry should be removed from row */
698  if( nlrow->lincoefs[pos] == 0.0 )
699  {
700  nlrowMoveLinearCoef(nlrow, nlrow->nlinvars-1, pos);
701  nlrow->nlinvars--;
702 
703  if( pos < nlrow->nlinvars )
704  {
705  SCIP_CALL( nlrowRemoveFixedLinearCoefPos(nlrow, blkmem, set, stat, nlp, pos) );
706  }
707 
708  return SCIP_OKAY;
709  }
710  nlrow->linvarssorted = FALSE;
711 
712  /* notify nlrow that coefficient of var is now 0.0 in row */
713  SCIP_CALL( nlrowLinearCoefChanged(nlrow, set, stat, var, 0.0, nlp) );
714 
715  /* notify nlrow that constant of row has changed */
716  if( oldconstant != nlrow->constant )
717  SCIP_CALL( nlrowConstantChanged(nlrow, set, stat, nlp) );
718 
719  if( SCIPvarIsActive(nlrow->linvars[pos]) )
720  {
721  /* if var was aggregated or negated, notify nlrow about new coefficient */
722  SCIP_CALL( nlrowLinearCoefChanged(nlrow, set, stat, nlrow->linvars[pos], nlrow->lincoefs[pos], nlp) );
723  }
724  else
725  {
726  SCIP_Real coef;
727  int i;
728 
729  /* if not removed or active, the new variable should be multi-aggregated */
730  assert(SCIPvarGetStatus(nlrow->linvars[pos]) == SCIP_VARSTATUS_MULTAGGR);
731 
732  var = nlrow->linvars[pos];
733  coef = nlrow->lincoefs[pos];
734 
735  /* remove the variable from the row */
736  SCIP_CALL( nlrowDelLinearCoefPos(nlrow, set, stat, nlp, pos) );
737 
738  /* add multi-aggregated term to row */
739  if( SCIPvarGetMultaggrConstant(var) != 0.0 )
740  {
741  nlrow->constant += coef * SCIPvarGetMultaggrConstant(var);
742  SCIP_CALL( nlrowConstantChanged(nlrow, set, stat, nlp) );
743  }
744  SCIP_CALL( SCIPnlrowEnsureLinearSize(nlrow, blkmem, set, nlrow->nlinvars + SCIPvarGetMultaggrNVars(var)) );
745  for( i = 0; i < SCIPvarGetMultaggrNVars(var); ++i )
746  {
747  if( SCIPsetIsZero(set, coef * SCIPvarGetMultaggrScalars(var)[i]) )
748  continue;
749  SCIP_CALL( nlrowAddLinearCoef(nlrow, blkmem, set, stat, nlp, SCIPvarGetMultaggrVars(var)[i], coef * SCIPvarGetMultaggrScalars(var)[i]) );
750  assert(SCIPvarGetMultaggrVars(var)[i] == nlrow->linvars[nlrow->nlinvars-1]);
752  {
753  /* if newly added variable is fixed, replace it now */
754  SCIP_CALL( nlrowRemoveFixedLinearCoefPos(nlrow, blkmem, set, stat, nlp, nlrow->nlinvars-1) );
755  }
756  }
757 
758  /* due to nlrowDelLinearCoefPos, an inactive variable may have moved to position pos
759  * if that is the case, call ourself recursively
760  */
761  if( pos < nlrow->nlinvars && !SCIPvarIsActive(nlrow->linvars[pos]) )
762  {
763  SCIP_CALL( nlrowRemoveFixedLinearCoefPos(nlrow, blkmem, set, stat, nlp, pos) );
764  }
765  }
766 
767  return SCIP_OKAY;
768 }
769 
770 /** removes fixed variables from the linear part of a nonlinear row */
771 static
773  SCIP_NLROW* nlrow, /**< nonlinear row */
774  BMS_BLKMEM* blkmem, /**< block memory */
775  SCIP_SET* set, /**< global SCIP settings */
776  SCIP_STAT* stat, /**< problem statistics data */
777  SCIP_NLP* nlp /**< current NLP data */
778  )
779 {
780  int i;
781  int oldlen;
782 
783  assert(nlrow != NULL);
784  assert(nlrow->linvars != NULL || nlrow->nlinvars == 0);
785 
786  oldlen = nlrow->nlinvars;
787  for( i = 0; i < MIN(oldlen, nlrow->nlinvars); ++i )
788  {
789  assert(nlrow->linvars[i] != NULL);
790  SCIP_CALL( nlrowRemoveFixedLinearCoefPos(nlrow, blkmem, set, stat, nlp, i) );
791  }
792 
793  return SCIP_OKAY;
794 }
795 
796 /** removes fixed variables from expression of a nonlinear row */
797 static
799  SCIP_NLROW* nlrow, /**< nonlinear row */
800  BMS_BLKMEM* blkmem, /**< block memory */
801  SCIP_SET* set, /**< global SCIP settings */
802  SCIP_STAT* stat, /**< problem statistics data */
803  SCIP_NLP* nlp /**< current NLP data */
804  )
805 {
806  SCIP_EXPR* simplified;
807  SCIP_Bool changed;
808  SCIP_Bool infeasible;
809 
810  if( nlrow->expr == NULL )
811  return SCIP_OKAY;
812 
813  SCIP_CALL( SCIPexprSimplify(set, stat, blkmem, nlrow->expr, &simplified, &changed, &infeasible, NULL, NULL) );
814  assert(!infeasible);
815 
816  if( !changed )
817  {
818  SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &simplified) );
819  return SCIP_OKAY;
820  }
821 
822  SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &nlrow->expr) );
823  nlrow->expr = simplified;
824 
825  if( SCIPexprIsValue(set, nlrow->expr) )
826  {
827  /* if expression tree is constant, remove it */
828  SCIP_CALL( SCIPnlrowChgConstant(nlrow, set, stat, nlp, nlrow->constant + SCIPgetValueExprValue(nlrow->expr)) );
829 
830  /* removing the expression changes statistics on rows in stat, if row is already in NLP
831  * first remove current nlrow from stat, then add again after releasing expression
832  */
833  if( nlrow->nlpindex >= 0 )
834  nlrowAddToStat(nlp, set, nlrow, -1);
835 
836  SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &nlrow->expr) );
838 
839  if( nlrow->nlpindex >= 0 )
840  nlrowAddToStat(nlp, set, nlrow, 1);
841  }
842 
843  SCIP_CALL( nlrowExprChanged(nlrow, blkmem, set, stat, nlp) );
844 
845  return SCIP_OKAY;
846 }
847 
848 /** removes fixed variable from nonlinear row */
849 static
851  SCIP_NLROW* nlrow, /**< nonlinear row */
852  BMS_BLKMEM* blkmem, /**< block memory */
853  SCIP_SET* set, /**< global SCIP settings */
854  SCIP_STAT* stat, /**< problem statistics data */
855  SCIP_NLP* nlp, /**< current NLP data */
856  SCIP_VAR* var /**< variable that had been fixed */
857  )
858 {
859  int pos;
860 
861  assert(nlrow != NULL);
862  assert(var != NULL);
863  assert(!SCIPvarIsActive(var));
864 
865  /* search for variable in linear part and remove if existing */
866  pos = nlrowSearchLinearCoef(nlrow, var);
867  if( pos >= 0 )
868  {
869  SCIP_CALL( nlrowRemoveFixedLinearCoefPos(nlrow, blkmem, set, stat, nlp, pos) );
870  }
871 
872  /* search for variable in nonlinear part and remove all fixed variables in expression if existing
873  * TODO only call simplify if var appears in expr, but currently we don't store the vars in a separate array
874  */
875  if( nlrow->expr != NULL )
876  {
877  SCIP_CALL( nlrowSimplifyExpr(nlrow, blkmem, set, stat, nlp) );
878  }
879 
880  return SCIP_OKAY;
881 }
882 
883 /*
884  * public NLP nonlinear row methods
885  */
886 /**@addtogroup PublicNLRowMethods
887  *
888  * @{
889  */
890 
891 /** create a new nonlinear row
892  *
893  * the new row is already captured
894  */
896  SCIP_NLROW** nlrow, /**< buffer to store pointer to nonlinear row */
897  BMS_BLKMEM* blkmem, /**< block memory */
898  SCIP_SET* set, /**< global SCIP settings */
899  SCIP_STAT* stat, /**< problem statistics data */
900  const char* name, /**< name of nonlinear row */
901  SCIP_Real constant, /**< constant */
902  int nlinvars, /**< number of linear variables */
903  SCIP_VAR** linvars, /**< linear variables, or NULL if nlinvars == 0 */
904  SCIP_Real* lincoefs, /**< linear coefficients, or NULL if nlinvars == 0 */
905  SCIP_EXPR* expr, /**< expression, or NULL */
906  SCIP_Real lhs, /**< left hand side */
907  SCIP_Real rhs, /**< right hand side */
908  SCIP_EXPRCURV curvature /**< curvature of the nonlinear row */
909  )
910 {
911 #ifndef NDEBUG
912  int i;
913 #endif
914 
915  assert(nlrow != NULL);
916  assert(blkmem != NULL);
917  assert(set != NULL);
918  assert(name != NULL);
919  assert(!SCIPsetIsInfinity(set, ABS(constant)));
920  assert(nlinvars == 0 || linvars != NULL);
921  assert(nlinvars == 0 || lincoefs != NULL);
922  assert(SCIPsetIsRelLE(set, lhs, rhs));
923 
924  SCIP_ALLOC( BMSallocBlockMemory(blkmem, nlrow) );
925 
926  /* constant part */
927  assert(!SCIPsetIsInfinity(set, REALABS(constant)));
928  (*nlrow)->constant = constant;
929 
930 #ifndef NDEBUG
931  for( i = 0; i < nlinvars; ++i )
932  {
933  assert(linvars[i] != NULL);
934  assert(!SCIPsetIsInfinity(set, REALABS(lincoefs[i])));
935  }
936 #endif
937 
938  /* linear part */
939  (*nlrow)->nlinvars = nlinvars;
940  (*nlrow)->linvarssize = nlinvars;
941  if( nlinvars > 0 )
942  {
943  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*nlrow)->linvars, linvars, nlinvars) );
944  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*nlrow)->lincoefs, lincoefs, nlinvars) );
945  (*nlrow)->linvarssorted = FALSE;
946  }
947  else
948  {
949  (*nlrow)->linvars = NULL;
950  (*nlrow)->lincoefs = NULL;
951  (*nlrow)->linvarssorted = TRUE;
952  }
953 
954  /* nonlinear part */
955  if( expr != NULL )
956  {
957  /* TODO preserve common subexpressions, or at least use only one varexpr per var */
958  SCIP_CALL( SCIPexprCopy(set, stat, blkmem, set, stat, blkmem, expr, &(*nlrow)->expr, NULL, NULL, NULL, NULL) );
959  }
960  else
961  {
962  (*nlrow)->expr = NULL;
963  }
964 
965  /* left and right hand sides, asserted above that lhs is relatively less equal than rhs */
966  (*nlrow)->lhs = MIN(lhs, rhs);
967  (*nlrow)->rhs = MAX(lhs, rhs);
968 
969  /* miscellaneous */
970  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*nlrow)->name, name, strlen(name)+1) );
971  (*nlrow)->activity = SCIP_INVALID;
972  (*nlrow)->validactivitynlp = FALSE;
973  (*nlrow)->pseudoactivity = SCIP_INVALID;
974  (*nlrow)->validpsactivitydomchg = FALSE;
975  (*nlrow)->minactivity = SCIP_INVALID;
976  (*nlrow)->maxactivity = SCIP_INVALID;
977  (*nlrow)->validactivitybdsdomchg = FALSE;
978  (*nlrow)->nlpindex = -1;
979  (*nlrow)->nlpiindex = -1;
980  (*nlrow)->nuses = 0;
981  (*nlrow)->dualsol = 0.0;
982  (*nlrow)->curvature = curvature;
983 
984  /* capture the nonlinear row */
985  SCIPnlrowCapture(*nlrow);
986 
987  return SCIP_OKAY;
988 }
989 
990 /** create a nonlinear row that is a copy of a given row
991  *
992  * the new row is already captured
993  */
995  SCIP_NLROW** nlrow, /**< buffer to store pointer to nonlinear row */
996  BMS_BLKMEM* blkmem, /**< block memory */
997  SCIP_SET* set, /**< global SCIP settings */
998  SCIP_STAT* stat, /**< problem statistics data */
999  SCIP_NLROW* sourcenlrow /**< nonlinear row to copy */
1000  )
1001 {
1002  assert(nlrow != NULL);
1003  assert(blkmem != NULL);
1004  assert(set != NULL);
1005  assert(sourcenlrow != NULL);
1006 
1007  SCIP_CALL( SCIPnlrowCreate(nlrow, blkmem, set, stat, sourcenlrow->name,
1008  sourcenlrow->constant,
1009  sourcenlrow->nlinvars, sourcenlrow->linvars, sourcenlrow->lincoefs,
1010  sourcenlrow->expr,
1011  sourcenlrow->lhs, sourcenlrow->rhs, sourcenlrow->curvature) );
1012 
1013  (*nlrow)->linvarssorted = sourcenlrow->linvarssorted;
1014  (*nlrow)->activity = sourcenlrow->activity;
1015  (*nlrow)->validactivitynlp = sourcenlrow->validactivitynlp;
1016  (*nlrow)->pseudoactivity = sourcenlrow->pseudoactivity;
1017  (*nlrow)->validpsactivitydomchg = sourcenlrow->validpsactivitydomchg;
1018  (*nlrow)->minactivity = sourcenlrow->minactivity;
1019  (*nlrow)->maxactivity = sourcenlrow->maxactivity;
1020  (*nlrow)->validactivitybdsdomchg = sourcenlrow->validactivitybdsdomchg;
1021 
1022  return SCIP_OKAY;
1023 }
1024 
1025 /** create a new nonlinear row from a linear row
1026  *
1027  * the new row is already captured
1028  */
1030  SCIP_NLROW** nlrow, /**< buffer to store pointer to nonlinear row */
1031  BMS_BLKMEM* blkmem, /**< block memory */
1032  SCIP_SET* set, /**< global SCIP settings */
1033  SCIP_STAT* stat, /**< problem statistics data */
1034  SCIP_ROW* row /**< the linear row to copy */
1035  )
1036 {
1037  int rownz;
1038 
1039  assert(nlrow != NULL);
1040  assert(blkmem != NULL);
1041  assert(set != NULL);
1042  assert(row != NULL);
1043 
1044  rownz = SCIProwGetNNonz(row);
1045 
1046  if( rownz > 1 )
1047  {
1048  SCIP_VAR** rowvars;
1049  int i;
1050 
1051  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowvars, rownz) );
1052 
1053  for( i = 0; i < rownz; ++i )
1054  {
1055  rowvars[i] = SCIPcolGetVar(SCIProwGetCols(row)[i]);
1056  assert(rowvars[i] != NULL);
1057  }
1058 
1059  SCIP_CALL( SCIPnlrowCreate(nlrow, blkmem, set, stat, SCIProwGetName(row),
1060  SCIProwGetConstant(row),
1061  rownz, rowvars, SCIProwGetVals(row), NULL,
1062  SCIProwGetLhs(row), SCIProwGetRhs(row),
1064 
1065  SCIPsetFreeBufferArray(set, &rowvars);
1066  }
1067  else if( rownz == 1 )
1068  {
1069  SCIP_VAR* rowvar;
1070 
1071  rowvar = SCIPcolGetVar(SCIProwGetCols(row)[0]);
1072 
1073  SCIP_CALL( SCIPnlrowCreate(nlrow, blkmem, set, stat, SCIProwGetName(row),
1074  SCIProwGetConstant(row),
1075  1, &rowvar, SCIProwGetVals(row), NULL,
1076  SCIProwGetLhs(row), SCIProwGetRhs(row),
1078  }
1079  else
1080  {
1081  SCIP_CALL( SCIPnlrowCreate(nlrow, blkmem, set, stat, SCIProwGetName(row),
1082  SCIProwGetConstant(row),
1083  0, NULL, NULL, NULL,
1084  SCIProwGetLhs(row), SCIProwGetRhs(row),
1086  }
1087 
1088  return SCIP_OKAY;
1089 }
1090 
1091 /** output nonlinear row to file stream */
1093  SCIP_NLROW* nlrow, /**< NLP row */
1094  BMS_BLKMEM* blkmem, /**< block memory */
1095  SCIP_SET* set, /**< global SCIP settings */
1096  SCIP_STAT* stat, /**< problem statistics data */
1097  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1098  FILE* file /**< output file (or NULL for standard output) */
1099  )
1100 {
1101  int i;
1102 
1103  assert(nlrow != NULL);
1104 
1105  /* print row name */
1106  if( nlrow->name != NULL && nlrow->name[0] != '\0' )
1107  {
1108  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", nlrow->name);
1109  }
1110 
1111  /* print left hand side */
1112  SCIPmessageFPrintInfo(messagehdlr, file, "%.15g <= ", nlrow->lhs);
1113 
1114  /* print constant */
1115  SCIPmessageFPrintInfo(messagehdlr, file, "%.15g ", nlrow->constant);
1116 
1117  /* print linear coefficients */
1118  for( i = 0; i < nlrow->nlinvars; ++i )
1119  {
1120  assert(nlrow->linvars[i] != NULL);
1121  assert(SCIPvarGetName(nlrow->linvars[i]) != NULL);
1122  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g<%s> ", nlrow->lincoefs[i], SCIPvarGetName(nlrow->linvars[i]));
1123  }
1124 
1125  /* print nonlinear part */
1126  if( nlrow->expr != NULL )
1127  {
1128  SCIPmessageFPrintInfo(messagehdlr, file, " + ");
1129  SCIP_CALL( SCIPexprPrint(set, stat, blkmem, messagehdlr, file, nlrow->expr) );
1130  }
1131 
1132  /* print right hand side */
1133  SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g", nlrow->rhs);
1134 
1135  /* print convexity */
1136  SCIPmessageFPrintInfo(messagehdlr, file, " [%s]\n", SCIPexprcurvGetName(nlrow->curvature));
1137 
1138  return SCIP_OKAY;
1139 }
1140 
1141 /** increases usage counter of nonlinear row */
1143  SCIP_NLROW* nlrow /**< nonlinear row to capture */
1144  )
1145 {
1146  assert(nlrow != NULL);
1147  assert(nlrow->nuses >= 0);
1148 
1149  SCIPdebugMessage("capture nonlinear row <%s> with nuses=%d\n", nlrow->name, nlrow->nuses);
1150  nlrow->nuses++;
1151 }
1152 
1153 /** decreases usage counter of nonlinear row */
1155  SCIP_NLROW** nlrow, /**< nonlinear row to free */
1156  BMS_BLKMEM* blkmem, /**< block memory */
1157  SCIP_SET* set, /**< global SCIP settings */
1158  SCIP_STAT* stat /**< problem statistics data */
1159  )
1160 {
1161  assert(blkmem != NULL);
1162  assert(nlrow != NULL);
1163  assert(*nlrow != NULL);
1164  assert((*nlrow)->nuses >= 1);
1165 
1166  SCIPsetDebugMsg(set, "release nonlinear row <%s> with nuses=%d\n", (*nlrow)->name, (*nlrow)->nuses);
1167  (*nlrow)->nuses--;
1168  if( (*nlrow)->nuses > 0 )
1169  {
1170  *nlrow = NULL;
1171  return SCIP_OKAY;
1172  }
1173 
1174  /* free row */
1175 
1176  assert((*nlrow)->nuses == 0);
1177  assert((*nlrow)->nlpindex == -1);
1178  assert((*nlrow)->nlpiindex == -1);
1179 
1180  /* linear part */
1181  BMSfreeBlockMemoryArrayNull(blkmem, &(*nlrow)->linvars, (*nlrow)->linvarssize);
1182  BMSfreeBlockMemoryArrayNull(blkmem, &(*nlrow)->lincoefs, (*nlrow)->linvarssize);
1183 
1184  /* nonlinear part */
1185  if( (*nlrow)->expr != NULL )
1186  {
1187  SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &(*nlrow)->expr) );
1188  }
1189 
1190  /* miscellaneous */
1191  BMSfreeBlockMemoryArray(blkmem, &(*nlrow)->name, strlen((*nlrow)->name)+1);
1192 
1193  BMSfreeBlockMemory(blkmem, nlrow);
1194 
1195  return SCIP_OKAY;
1196 }
1197 
1198 /** ensures, that linear coefficient array of nonlinear row can store at least num entries */
1200  SCIP_NLROW* nlrow, /**< NLP row */
1201  BMS_BLKMEM* blkmem, /**< block memory */
1202  SCIP_SET* set, /**< global SCIP settings */
1203  int num /**< minimum number of entries to store */
1204  )
1205 {
1206  assert(nlrow != NULL);
1207  assert(nlrow->nlinvars <= nlrow->linvarssize);
1208 
1209  if( num > nlrow->linvarssize )
1210  {
1211  int newsize;
1212 
1213  newsize = SCIPsetCalcMemGrowSize(set, num);
1214  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &nlrow->linvars, nlrow->linvarssize, newsize) );
1215  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &nlrow->lincoefs, nlrow->linvarssize, newsize) );
1216  nlrow->linvarssize = newsize;
1217  }
1218  assert(num <= nlrow->linvarssize);
1219 
1220  return SCIP_OKAY;
1221 }
1222 
1223 /** adds a previously non existing linear coefficient to a nonlinear row */
1225  SCIP_NLROW* nlrow, /**< NLP nonlinear row */
1226  BMS_BLKMEM* blkmem, /**< block memory */
1227  SCIP_SET* set, /**< global SCIP settings */
1228  SCIP_STAT* stat, /**< problem statistics data */
1229  SCIP_NLP* nlp, /**< current NLP data */
1230  SCIP_VAR* var, /**< variable */
1231  SCIP_Real val /**< value of coefficient */
1232  )
1233 {
1234  /* if row is in NLP already, make sure that only active variables are added */
1235  if( nlrow->nlpindex >= 0 )
1236  {
1237  SCIP_Real constant;
1238 
1239  /* get corresponding active or multi-aggregated variable */
1240  constant = 0.0;
1241  SCIP_CALL( SCIPvarGetProbvarSum(&var, set, &val, &constant) );
1242 
1243  /* add constant */
1244  SCIP_CALL( SCIPnlrowChgConstant(nlrow, set, stat, nlp, nlrow->constant + constant) );
1245 
1246  if( val == 0.0 )
1247  /* var has been fixed */
1248  return SCIP_OKAY;
1249 
1250  if( !SCIPvarIsActive(var) )
1251  {
1252  /* var should be multi-aggregated, so call this function recursively */
1253  int i;
1254 
1255  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
1256  for( i = 0; i < SCIPvarGetMultaggrNVars(var); ++i )
1257  {
1258  SCIP_CALL( SCIPnlrowAddLinearCoef(nlrow, blkmem, set, stat, nlp, SCIPvarGetMultaggrVars(var)[i], SCIPvarGetMultaggrScalars(var)[i] * val) );
1259  }
1260  return SCIP_OKAY;
1261  }
1262 
1263  /* var is active, so can go on like normal */
1264  }
1265 
1266  SCIP_CALL( nlrowAddLinearCoef(nlrow, blkmem, set, stat, nlp, var, val) );
1267 
1268  return SCIP_OKAY;
1269 }
1270 
1271 /** deletes linear coefficient from nonlinear row */
1273  SCIP_NLROW* nlrow, /**< nonlinear row to be changed */
1274  SCIP_SET* set, /**< global SCIP settings */
1275  SCIP_STAT* stat, /**< problem statistics data */
1276  SCIP_NLP* nlp, /**< current NLP data */
1277  SCIP_VAR* var /**< coefficient to be deleted */
1278  )
1279 {
1280  int pos;
1281 
1282  assert(nlrow != NULL);
1283  assert(var != NULL);
1284 
1285  /* if the row is in the NLP already, we can only have active variables, so var should also be active; in non-debug mode, one gets an error below */
1286  assert(nlrow->nlpindex == -1 || SCIPvarIsActive(var) );
1287 
1288  /* search the position of the variable in the row's variable vector */
1289  pos = nlrowSearchLinearCoef(nlrow, var);
1290  if( pos == -1 )
1291  {
1292  SCIPerrorMessage("coefficient for variable <%s> doesn't exist in nonlinear row <%s>\n", SCIPvarGetName(var), nlrow->name);
1293  return SCIP_INVALIDDATA;
1294  }
1295  assert(0 <= pos && pos < nlrow->nlinvars);
1296  assert(nlrow->linvars[pos] == var);
1297 
1298  /* delete the variable from the row's variable vector */
1299  SCIP_CALL( nlrowDelLinearCoefPos(nlrow, set, stat, nlp, pos) );
1300 
1301  return SCIP_OKAY;
1302 }
1303 
1304 /** changes or adds a linear coefficient to a nonlinear row */
1306  SCIP_NLROW* nlrow, /**< nonlinear row */
1307  BMS_BLKMEM* blkmem, /**< block memory */
1308  SCIP_SET* set, /**< global SCIP settings */
1309  SCIP_STAT* stat, /**< problem statistics data */
1310  SCIP_NLP* nlp, /**< current NLP data */
1311  SCIP_VAR* var, /**< variable */
1312  SCIP_Real coef /**< new value of coefficient */
1313  )
1314 {
1315  int pos;
1316 
1317  assert(nlrow != NULL);
1318  assert(nlp != NULL);
1319  assert(var != NULL);
1320 
1321  /* search the position of the variable in the row's linvars vector */
1322  pos = nlrowSearchLinearCoef(nlrow, var);
1323 
1324  /* check, if column already exists in the row's linear variables vector */
1325  if( pos == -1 )
1326  {
1327  if( !SCIPsetIsZero(set, coef) )
1328  {
1329  /* add previously not existing coefficient */
1330  SCIP_CALL( nlrowAddLinearCoef(nlrow, blkmem, set, stat, nlp, var, coef) );
1331  }
1332  }
1333  else
1334  {
1335  /* change the coefficient in the row */
1336  SCIP_CALL( nlrowChgLinearCoefPos(nlrow, set, stat, nlp, pos, coef) );
1337  }
1338 
1339  return SCIP_OKAY;
1340 }
1341 
1342 /** replaces or deletes an expression in a nonlinear row */
1344  SCIP_NLROW* nlrow, /**< nonlinear row */
1345  BMS_BLKMEM* blkmem, /**< block memory */
1346  SCIP_SET* set, /**< global SCIP settings */
1347  SCIP_STAT* stat, /**< problem statistics data */
1348  SCIP_NLP* nlp, /**< current NLP data */
1349  SCIP_EXPR* expr /**< new expression */
1350  )
1351 {
1352  assert(nlrow != NULL);
1353  assert(blkmem != NULL);
1354 
1355  /* if row in NLP, then remove it from statistics on NLP rows */
1356  if( nlrow->nlpindex >= 0 )
1357  nlrowAddToStat(nlp, set, nlrow, -1);
1358 
1359  /* free previous expression tree */
1360  if( nlrow->expr != NULL )
1361  {
1362  SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &nlrow->expr) );
1363  assert(nlrow->expr == NULL);
1364  }
1365 
1366  /* adds new expression tree */
1367  if( expr != NULL )
1368  {
1369  /* TODO preserve common subexpressions, or at least use only one varexpr per var */
1370  SCIP_CALL( SCIPexprCopy(set, stat, blkmem, set, stat, blkmem, expr, &nlrow->expr, NULL, NULL, NULL, NULL) );
1371 
1372  /* if row is already in NLP, ensure that expr has only active variables */
1373  if( nlrow->nlpindex >= 0 )
1374  {
1375  SCIP_EXPR* simplified;
1376  SCIP_Bool changed;
1377  SCIP_Bool infeasible;
1378 
1379  SCIP_CALL( SCIPexprSimplify(set, stat, blkmem, nlrow->expr, &simplified, &changed, &infeasible, NULL, NULL) );
1380  assert(!infeasible);
1381 
1382  SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &nlrow->expr) );
1383  nlrow->expr = simplified;
1384  }
1385  }
1386 
1387  /* notify row about the change */
1388  SCIP_CALL( nlrowExprChanged(nlrow, blkmem, set, stat, nlp) );
1389 
1390  /* if row in NLP, then add it again to statistics on NLP rows */
1391  if( nlrow->nlpindex >= 0 )
1392  nlrowAddToStat(nlp, set, nlrow, 1);
1393 
1394  return SCIP_OKAY;
1395 }
1396 
1397 /** changes constant of nonlinear row */
1399  SCIP_NLROW* nlrow, /**< nonlinear row */
1400  SCIP_SET* set, /**< global SCIP settings */
1401  SCIP_STAT* stat, /**< problem statistics data */
1402  SCIP_NLP* nlp, /**< current NLP data */
1403  SCIP_Real constant /**< new constant */
1404  )
1405 {
1406  assert(nlrow != NULL);
1407 
1408  if( !SCIPsetIsEQ(set, nlrow->constant, constant) )
1409  {
1410  nlrow->constant = constant;
1411  SCIP_CALL( nlrowConstantChanged(nlrow, set, stat, nlp) );
1412  }
1413 
1414  return SCIP_OKAY;
1415 }
1416 
1417 /** changes left hand side of nonlinear row */
1419  SCIP_NLROW* nlrow, /**< nonlinear row */
1420  SCIP_SET* set, /**< global SCIP settings */
1421  SCIP_STAT* stat, /**< problem statistics data */
1422  SCIP_NLP* nlp, /**< current NLP data */
1423  SCIP_Real lhs /**< new left hand side */
1424  )
1425 {
1426  assert(nlrow != NULL);
1427 
1428  if( !SCIPsetIsEQ(set, nlrow->lhs, lhs) )
1429  {
1430  if( nlrow->nlpindex >= 0 )
1431  nlrowAddToStat(nlp, set, nlrow, -1);
1432 
1433  nlrow->lhs = lhs;
1434  SCIP_CALL( nlrowSideChanged(nlrow, set, stat, nlp) );
1435 
1436  if( nlrow->nlpindex >= 0 )
1437  nlrowAddToStat(nlp, set, nlrow, 1);
1438  }
1439 
1440  return SCIP_OKAY;
1441 }
1442 
1443 /** changes right hand side of nonlinear row */
1445  SCIP_NLROW* nlrow, /**< nonlinear row */
1446  SCIP_SET* set, /**< global SCIP settings */
1447  SCIP_STAT* stat, /**< problem statistics data */
1448  SCIP_NLP* nlp, /**< current NLP data */
1449  SCIP_Real rhs /**< new right hand side */
1450  )
1451 {
1452  assert(nlrow != NULL);
1453 
1454  if( !SCIPsetIsEQ(set, nlrow->rhs, rhs) )
1455  {
1456  if( nlrow->nlpindex >= 0 )
1457  nlrowAddToStat(nlp, set, nlrow, -1);
1458 
1459  nlrow->rhs = rhs;
1460  SCIP_CALL( nlrowSideChanged(nlrow, set, stat, nlp) );
1461 
1462  if( nlrow->nlpindex >= 0 )
1463  nlrowAddToStat(nlp, set, nlrow, 1);
1464  }
1465 
1466  return SCIP_OKAY;
1467 }
1468 
1469 /** sets the curvature of a nonlinear row */
1471  SCIP_NLP* nlp, /**< NLP */
1472  SCIP_SET* set, /**< global SCIP settings */
1473  SCIP_NLROW* nlrow, /**< NLP row */
1474  SCIP_EXPRCURV curvature /**< curvature of NLP row */
1475  )
1476 {
1477  assert(nlrow != NULL);
1478 
1479  if( nlrow->nlpindex >= 0 )
1480  nlrowAddToStat(nlp, set, nlrow, -1);
1481 
1482  nlrow->curvature = curvature;
1483 
1484  if( nlrow->nlpindex >= 0 )
1485  nlrowAddToStat(nlp, set, nlrow, 1);
1486 }
1487 
1488 /** removes (or substitutes) all fixed, negated, aggregated, multi-aggregated variables from the linear and nonlinear part of a nonlinear row and simplifies its expression */
1490  SCIP_NLROW* nlrow, /**< nonlinear row */
1491  BMS_BLKMEM* blkmem, /**< block memory */
1492  SCIP_SET* set, /**< global SCIP settings */
1493  SCIP_STAT* stat, /**< problem statistics data */
1494  SCIP_NLP* nlp /**< current NLP data */
1495  )
1496 {
1497  SCIP_CALL( nlrowRemoveFixedLinearCoefs(nlrow, blkmem, set, stat, nlp) );
1498  SCIP_CALL( nlrowSimplifyExpr(nlrow, blkmem, set, stat, nlp) );
1499 
1500  return SCIP_OKAY;
1501 }
1502 
1503 /** recalculates the current activity of a nonlinear row in the current NLP solution */
1505  SCIP_NLROW* nlrow, /**< nonlinear row */
1506  BMS_BLKMEM* blkmem, /**< block memory */
1507  SCIP_SET* set, /**< global SCIP settings */
1508  SCIP_STAT* stat, /**< problem statistics data */
1509  SCIP_PRIMAL* primal, /**< primal data */
1510  SCIP_TREE* tree, /**< branch and bound tree */
1511  SCIP_NLP* nlp /**< current NLP data */
1512  )
1513 {
1514  int i;
1515 
1516  assert(nlrow != NULL);
1517  assert(stat != NULL);
1518  assert(nlp != NULL);
1519 
1521  {
1522  SCIPerrorMessage("do not have NLP solution for computing NLP activity\n");
1523  return SCIP_ERROR;
1524  }
1525 
1526  nlrow->activity = nlrow->constant;
1527  for( i = 0; i < nlrow->nlinvars; ++i )
1528  {
1529  assert(nlrow->linvars[i] != NULL);
1530  assert(SCIPvarGetNLPSol(nlrow->linvars[i]) < SCIP_INVALID);
1531 
1532  nlrow->activity += nlrow->lincoefs[i] * SCIPvarGetNLPSol(nlrow->linvars[i]);
1533  }
1534 
1535  if( nlrow->expr != NULL )
1536  {
1537  SCIP_SOL* sol;
1538 
1539  SCIP_CALL( SCIPsolCreateNLPSol(&sol, blkmem, set, stat, primal, tree, nlp, NULL) );
1540 
1541  SCIP_CALL( SCIPexprEval(set, stat, blkmem, nlrow->expr, sol, 0L) );
1542  if( SCIPexprGetEvalValue(nlrow->expr) == SCIP_INVALID )
1543  nlrow->activity = SCIP_INVALID;
1544  else
1545  nlrow->activity += SCIPexprGetEvalValue(nlrow->expr);
1546 
1547  SCIP_CALL( SCIPsolFree(&sol, blkmem, primal) );
1548  }
1549 
1550  nlrow->validactivitynlp = stat->nnlps;
1551 
1552  return SCIP_OKAY;
1553 }
1554 
1555 /** gives the activity of a nonlinear row in the current NLP solution */
1557  SCIP_NLROW* nlrow, /**< nonlinear row */
1558  BMS_BLKMEM* blkmem, /**< block memory */
1559  SCIP_SET* set, /**< global SCIP settings */
1560  SCIP_STAT* stat, /**< problem statistics data */
1561  SCIP_PRIMAL* primal, /**< primal data */
1562  SCIP_TREE* tree, /**< branch and bound tree */
1563  SCIP_NLP* nlp, /**< current NLP data */
1564  SCIP_Real* activity /**< buffer to store activity value */
1565  )
1566 {
1567  assert(nlrow != NULL);
1568  assert(stat != NULL);
1569  assert(activity != NULL);
1570 
1571  assert(nlrow->validactivitynlp <= stat->nnlps);
1572 
1573  if( nlrow->validactivitynlp != stat->nnlps )
1574  {
1575  SCIP_CALL( SCIPnlrowRecalcNLPActivity(nlrow, blkmem, set, stat, primal, tree, nlp) );
1576  }
1577  assert(nlrow->validactivitynlp == stat->nnlps);
1578  assert(nlrow->activity < SCIP_INVALID);
1579 
1580  *activity = nlrow->activity;
1581 
1582  return SCIP_OKAY;
1583 }
1584 
1585 /** gives the feasibility of a nonlinear row in the current NLP solution: negative value means infeasibility */
1587  SCIP_NLROW* nlrow, /**< nonlinear row */
1588  BMS_BLKMEM* blkmem, /**< block memory */
1589  SCIP_SET* set, /**< global SCIP settings */
1590  SCIP_STAT* stat, /**< problem statistics data */
1591  SCIP_PRIMAL* primal, /**< primal data */
1592  SCIP_TREE* tree, /**< branch and bound tree */
1593  SCIP_NLP* nlp, /**< current NLP data */
1594  SCIP_Real* feasibility /**< buffer to store feasibility value */
1595  )
1596 {
1597  SCIP_Real activity;
1598 
1599  assert(nlrow != NULL);
1600  assert(feasibility != NULL);
1601 
1602  SCIP_CALL( SCIPnlrowGetNLPActivity(nlrow, blkmem, set, stat, primal, tree, nlp, &activity) );
1603  *feasibility = MIN(nlrow->rhs - activity, activity - nlrow->lhs);
1604 
1605  return SCIP_OKAY;
1606 }
1607 
1608 /** calculates the current pseudo activity of a nonlinear row */
1610  SCIP_NLROW* nlrow, /**< nonlinear row */
1611  BMS_BLKMEM* blkmem, /**< block memory */
1612  SCIP_SET* set, /**< global SCIP settings */
1613  SCIP_STAT* stat, /**< problem statistics data */
1614  SCIP_PROB* prob, /**< SCIP problem */
1615  SCIP_PRIMAL* primal, /**< primal data */
1616  SCIP_TREE* tree, /**< branch and bound tree */
1617  SCIP_LP* lp /**< SCIP LP */
1618  )
1619 {
1620  SCIP_Real val1;
1621  int i;
1622 
1623  assert(nlrow != NULL);
1624  assert(stat != NULL);
1625 
1626  nlrow->pseudoactivity = nlrow->constant;
1627  for( i = 0; i < nlrow->nlinvars; ++i )
1628  {
1629  assert(nlrow->linvars[i] != NULL);
1630 
1631  val1 = SCIPvarGetBestBoundLocal(nlrow->linvars[i]);
1632  nlrow->pseudoactivity += nlrow->lincoefs[i] * val1;
1633  }
1634 
1635  if( nlrow->expr != NULL )
1636  {
1637  SCIP_SOL* sol;
1638 
1639  SCIP_CALL( SCIPsolCreatePseudoSol(&sol, blkmem, set, stat, prob, primal, tree, lp, NULL) );
1640 
1641  SCIP_CALL( SCIPexprEval(set, stat, blkmem, nlrow->expr, sol, 0L) );
1642  if( SCIPexprGetEvalValue(nlrow->expr) == SCIP_INVALID )
1643  nlrow->pseudoactivity = SCIP_INVALID;
1644  else
1645  nlrow->pseudoactivity += SCIPexprGetEvalValue(nlrow->expr);
1646 
1647  SCIP_CALL( SCIPsolFree(&sol, blkmem, primal) );
1648  }
1649 
1650  nlrow->validpsactivitydomchg = stat->domchgcount;
1651 
1652  return SCIP_OKAY;
1653 }
1654 
1655 /** returns the pseudo activity of a nonlinear row in the current pseudo solution */
1657  SCIP_NLROW* nlrow, /**< nonlinear row */
1658  BMS_BLKMEM* blkmem, /**< block memory */
1659  SCIP_SET* set, /**< global SCIP settings */
1660  SCIP_STAT* stat, /**< problem statistics data */
1661  SCIP_PROB* prob, /**< SCIP problem */
1662  SCIP_PRIMAL* primal, /**< primal data */
1663  SCIP_TREE* tree, /**< branch and bound tree */
1664  SCIP_LP* lp, /**< SCIP LP */
1665  SCIP_Real* pseudoactivity /**< buffer to store pseudo activity value */
1666  )
1667 {
1668  assert(nlrow != NULL);
1669  assert(stat != NULL);
1670  assert(pseudoactivity != NULL);
1671  assert(nlrow->validpsactivitydomchg <= stat->domchgcount);
1672 
1673  /* check, if pseudo activity has to be calculated */
1674  if( nlrow->validpsactivitydomchg != stat->domchgcount )
1675  {
1676  SCIP_CALL( SCIPnlrowRecalcPseudoActivity(nlrow, blkmem, set, stat, prob, primal, tree, lp) );
1677  }
1678  assert(nlrow->validpsactivitydomchg == stat->domchgcount);
1679  assert(nlrow->pseudoactivity < SCIP_INVALID);
1680 
1681  *pseudoactivity = nlrow->pseudoactivity;
1682 
1683  return SCIP_OKAY;
1684 }
1685 
1686 /** returns the pseudo feasibility of a nonlinear row in the current pseudo solution: negative value means infeasibility */
1688  SCIP_NLROW* nlrow, /**< nonlinear row */
1689  BMS_BLKMEM* blkmem, /**< block memory */
1690  SCIP_SET* set, /**< global SCIP settings */
1691  SCIP_STAT* stat, /**< problem statistics data */
1692  SCIP_PROB* prob, /**< SCIP problem */
1693  SCIP_PRIMAL* primal, /**< primal data */
1694  SCIP_TREE* tree, /**< branch and bound tree */
1695  SCIP_LP* lp, /**< SCIP LP */
1696  SCIP_Real* pseudofeasibility /**< buffer to store pseudo feasibility value */
1697  )
1698 {
1699  SCIP_Real pseudoactivity;
1700 
1701  assert(nlrow != NULL);
1702  assert(stat != NULL);
1703  assert(pseudofeasibility != NULL);
1704 
1705  SCIP_CALL( SCIPnlrowGetPseudoActivity(nlrow, blkmem, set, stat, prob, primal, tree, lp, &pseudoactivity) );
1706  *pseudofeasibility = MIN(nlrow->rhs - pseudoactivity, pseudoactivity - nlrow->lhs);
1707 
1708  return SCIP_OKAY;
1709 }
1710 
1711 /** returns the activity of a nonlinear row for a given solution */
1713  SCIP_NLROW* nlrow, /**< nonlinear row */
1714  BMS_BLKMEM* blkmem, /**< block memory */
1715  SCIP_SET* set, /**< global SCIP settings */
1716  SCIP_STAT* stat, /**< problem statistics data */
1717  SCIP_SOL* sol, /**< primal CIP solution */
1718  SCIP_Real* activity /**< buffer to store activity value */
1719  )
1720 {
1721  SCIP_Real inf;
1722  SCIP_Real val1;
1723  int i;
1724 
1725  assert(nlrow != NULL);
1726  assert(set != NULL);
1727  assert(stat != NULL);
1728  assert(activity != NULL);
1729 
1730  *activity = nlrow->constant;
1731  for( i = 0; i < nlrow->nlinvars; ++i )
1732  {
1733  assert(nlrow->linvars[i] != NULL);
1734 
1735  val1 = SCIPsolGetVal(sol, set, stat, nlrow->linvars[i]);
1736  if( val1 == SCIP_UNKNOWN )
1737  {
1738  *activity = SCIP_INVALID;
1739  return SCIP_OKAY;
1740  }
1741  *activity += nlrow->lincoefs[i] * val1;
1742  }
1743 
1744  if( nlrow->expr != NULL )
1745  {
1746  SCIP_CALL( SCIPexprEval(set, stat, blkmem, nlrow->expr, sol, 0L) );
1747  if( SCIPexprGetEvalValue(nlrow->expr) == SCIP_INVALID )
1748  *activity = SCIP_INVALID;
1749  else
1750  *activity += SCIPexprGetEvalValue(nlrow->expr);
1751  }
1752 
1753  inf = SCIPsetInfinity(set);
1754  *activity = MAX(*activity, -inf);
1755  *activity = MIN(*activity, +inf);
1756 
1757  return SCIP_OKAY;
1758 }
1759 
1760 /** returns the feasibility of a nonlinear row for the given solution */
1762  SCIP_NLROW* nlrow, /**< nonlinear row */
1763  BMS_BLKMEM* blkmem, /**< block memory */
1764  SCIP_SET* set, /**< global SCIP settings */
1765  SCIP_STAT* stat, /**< problem statistics data */
1766  SCIP_SOL* sol, /**< primal CIP solution */
1767  SCIP_Real* feasibility /**< buffer to store feasibility value */
1768  )
1769 {
1770  SCIP_Real activity;
1771 
1772  assert(nlrow != NULL);
1773  assert(feasibility != NULL);
1774 
1775  SCIP_CALL( SCIPnlrowGetSolActivity(nlrow, blkmem, set, stat, sol, &activity) );
1776 
1777  *feasibility = MIN(nlrow->rhs - activity, activity - nlrow->lhs);
1778 
1779  return SCIP_OKAY;
1780 }
1781 
1782 /** returns the minimal activity of a nonlinear row w.r.t. the variables' bounds */
1784  SCIP_NLROW* nlrow, /**< nonlinear row */
1785  BMS_BLKMEM* blkmem, /**< block memory */
1786  SCIP_SET* set, /**< global SCIP settings */
1787  SCIP_STAT* stat, /**< problem statistics data */
1788  SCIP_Real* minactivity, /**< buffer to store minimal activity, or NULL */
1789  SCIP_Real* maxactivity /**< buffer to store maximal activity, or NULL */
1790  )
1791 {
1792  assert(nlrow != NULL);
1793  assert(set != NULL);
1794  assert(stat != NULL);
1795  assert(nlrow->validactivitybdsdomchg <= stat->domchgcount);
1796 
1797  /* check, if activity bounds has to be calculated */
1798  if( nlrow->validactivitybdsdomchg != stat->domchgcount )
1799  {
1800  SCIP_CALL( nlrowCalcActivityBounds(nlrow, blkmem, set, stat) );
1801  }
1802  assert(nlrow->validactivitybdsdomchg == stat->domchgcount);
1803  assert(nlrow->minactivity < SCIP_INVALID);
1804  assert(nlrow->maxactivity < SCIP_INVALID);
1805 
1806  if( minactivity != NULL )
1807  *minactivity = nlrow->minactivity;
1808  if( maxactivity != NULL )
1809  *maxactivity = nlrow->maxactivity;
1810 
1811  return SCIP_OKAY;
1812 }
1813 
1814 /** returns whether the nonlinear row is redundant w.r.t. the variables' bounds */
1816  SCIP_NLROW* nlrow, /**< nonlinear row */
1817  BMS_BLKMEM* blkmem, /**< block memory */
1818  SCIP_SET* set, /**< global SCIP settings */
1819  SCIP_STAT* stat, /**< problem statistics data */
1820  SCIP_Bool* isredundant /**< buffer to store whether row is redundant */
1821  )
1822 {
1823  SCIP_Real minactivity;
1824  SCIP_Real maxactivity;
1825 
1826  assert(nlrow != NULL);
1827  assert(set != NULL);
1828  assert(isredundant != NULL);
1829 
1830  SCIP_CALL( SCIPnlrowGetActivityBounds(nlrow, blkmem, set, stat, &minactivity, &maxactivity) );
1831 
1832  *isredundant = TRUE;
1833  if( (!SCIPsetIsInfinity(set, -nlrow->lhs) && SCIPsetIsFeasLT(set, minactivity, nlrow->lhs)) ||
1834  ( !SCIPsetIsInfinity(set, nlrow->rhs) && SCIPsetIsFeasGT(set, maxactivity, nlrow->rhs)) )
1835  *isredundant = FALSE;
1836 
1837  return SCIP_OKAY;
1838 }
1839 
1840 #ifdef NDEBUG
1841 /* Undo the defines from pub_nlhdlr.h, which exist if NDEBUG is defined. */
1842 #undef SCIPnlrowGetConstant
1843 #undef SCIPnlrowGetNLinearVars
1844 #undef SCIPnlrowGetLinearVars
1845 #undef SCIPnlrowGetLinearCoefs
1846 #undef SCIPnlrowGetExpr
1847 #undef SCIPnlrowGetLhs
1848 #undef SCIPnlrowGetRhs
1849 #undef SCIPnlrowGetCurvature
1850 #undef SCIPnlrowGetName
1851 #undef SCIPnlrowGetNLPPos
1852 #undef SCIPnlrowIsInNLP
1853 #undef SCIPnlrowGetDualsol
1854 #endif
1855 
1856 /** gets constant */
1858  SCIP_NLROW* nlrow /**< NLP row */
1859  )
1860 {
1861  assert(nlrow != NULL);
1862 
1863  return nlrow->constant;
1864 }
1865 
1866 /** gets number of variables of linear part */
1868  SCIP_NLROW* nlrow /**< NLP row */
1869  )
1870 {
1871  assert(nlrow != NULL);
1872 
1873  return nlrow->nlinvars;
1874 }
1875 
1876 /** gets array with variables of linear part */
1878  SCIP_NLROW* nlrow /**< NLP row */
1879  )
1880 {
1881  assert(nlrow != NULL);
1882 
1883  return nlrow->linvars;
1884 }
1885 
1886 /** gets array with coefficients in linear part */
1888  SCIP_NLROW* nlrow /**< NLP row */
1889  )
1890 {
1891  assert(nlrow != NULL);
1892 
1893  return nlrow->lincoefs;
1894 }
1895 
1896 /** gets expression */
1898  SCIP_NLROW* nlrow /**< NLP row */
1899  )
1900 {
1901  assert(nlrow != NULL);
1902 
1903  return nlrow->expr;
1904 }
1905 
1906 /** returns the left hand side of a nonlinear row */
1908  SCIP_NLROW* nlrow /**< NLP row */
1909  )
1910 {
1911  assert(nlrow != NULL);
1912 
1913  return nlrow->lhs;
1914 }
1915 
1916 /** returns the right hand side of a nonlinear row */
1918  SCIP_NLROW* nlrow /**< NLP row */
1919  )
1920 {
1921  assert(nlrow != NULL);
1922 
1923  return nlrow->rhs;
1924 }
1925 
1926 /** returns the curvature of a nonlinear row */
1928  SCIP_NLROW* nlrow /**< NLP row */
1929  )
1930 {
1931  assert(nlrow != NULL);
1932  return nlrow->curvature;
1933 }
1934 
1935 /** returns the name of a nonlinear row */
1936 const char* SCIPnlrowGetName(
1937  SCIP_NLROW* nlrow /**< NLP row */
1938  )
1939 {
1940  assert(nlrow != NULL);
1941 
1942  return nlrow->name;
1943 }
1944 
1945 /** gets position of a nonlinear row in current NLP, or -1 if not in NLP */
1947  SCIP_NLROW* nlrow /**< NLP row */
1948  )
1949 {
1950  assert(nlrow != NULL);
1951 
1952  return nlrow->nlpindex;
1953 }
1954 
1955 /** returns TRUE iff row is member of current NLP */
1957  SCIP_NLROW* nlrow /**< NLP row */
1958  )
1959 {
1960  assert(nlrow != NULL);
1961 
1962  return nlrow->nlpindex != -1;
1963 }
1964 
1965 /** gets the dual NLP solution of a nlrow
1966  *
1967  * for a ranged constraint, the dual value is positive if the right hand side is active and negative if the left hand side is active
1968  */
1970  SCIP_NLROW* nlrow /**< NLP row */
1971  )
1972 {
1973  assert(nlrow != NULL);
1974 
1975  return nlrow->nlpiindex >= 0 ? nlrow->dualsol : 0.0;
1976 }
1977 
1978 /** @} */
1979 
1980 /*
1981  * local NLP methods
1982  */
1983 
1984 /** announces, that a row of the NLP was modified
1985  * adjusts status of current solution
1986  * calling method has to ensure that change is passed to the NLPI!
1987  */ /*lint -e{715}*/
1988 static
1990  SCIP_NLP* nlp, /**< current NLP data */
1991  SCIP_SET* set, /**< global SCIP settings */
1992  SCIP_STAT* stat, /**< problem statistics data */
1993  SCIP_NLROW* nlrow /**< nonlinear row which was changed */
1994  )
1995 { /*lint --e{715}*/
1996  assert(nlp != NULL);
1997  assert(nlrow != NULL);
1998  assert(!nlp->indiving);
1999  assert(nlrow->nlpindex >= 0);
2000 
2001  /* nlrow is a row in the NLP, so changes effect feasibility */
2002  /* if we have a feasible NLP solution and it satisfies the modified row, then it is still feasible
2003  * if the NLP was globally or locally infeasible or unbounded, then this may not be the case anymore
2004  */
2005  if( nlp->solstat <= SCIP_NLPSOLSTAT_FEASIBLE )
2006  {
2007  /* TODO bring this back? then everything that may call nlpRowChanged will need to pass on blkmem, primal, tree as well
2008  SCIP_Real feasibility;
2009  SCIP_CALL( SCIPnlrowGetNLPFeasibility(nlrow, blkmem, set, stat, primal, tree, nlp, &feasibility) );
2010  if( !SCIPsetIsFeasNegative(set, feasibility) )
2011  nlp->solstat = SCIP_NLPSOLSTAT_FEASIBLE;
2012  else */
2014  }
2015  else
2016  {
2018  }
2019 
2020  return SCIP_OKAY;
2021 }
2022 
2023 /** adds a set of nonlinear rows to the NLP and captures them */
2024 static
2026  SCIP_NLP* nlp, /**< NLP data */
2027  BMS_BLKMEM* blkmem, /**< block memory */
2028  SCIP_SET* set, /**< global SCIP settings */
2029  SCIP_STAT* stat, /**< problem statistics data */
2030  int nnlrows, /**< number of nonlinear rows to add */
2031  SCIP_NLROW** nlrows /**< nonlinear rows to add */
2032  )
2033 {
2034 #ifndef NDEBUG
2035  int i;
2036 #endif
2037  int j;
2038  SCIP_NLROW* nlrow;
2039 
2040  assert(nlp != NULL);
2041  assert(blkmem != NULL);
2042  assert(set != NULL);
2043  assert(nlrows != NULL || nnlrows == 0);
2044  assert(!nlp->indiving);
2045 
2046  SCIP_CALL( SCIPnlpEnsureNlRowsSize(nlp, blkmem, set, nlp->nnlrows + nnlrows) );
2047 
2048  for( j = 0; j < nnlrows; ++j )
2049  {
2050  nlrow = nlrows[j]; /*lint !e613*/
2051 
2052  /* assert that row is not in NLP (or even NLPI) yet */
2053  assert(nlrow->nlpindex == -1);
2054  assert(nlrow->nlpiindex == -1);
2055 
2056  /* make sure there are only active variables in row */
2057  SCIP_CALL( SCIPnlrowSimplify(nlrow, blkmem, set, stat, nlp) );
2058 
2059 #ifndef NDEBUG
2060  /* assert that variables of row are in NLP */
2061  for( i = 0; i < nlrow->nlinvars; ++i )
2062  assert(SCIPhashmapExists(nlp->varhash, nlrow->linvars[i]));
2063 
2064  if( nlrow->expr != NULL )
2065  {
2066  SCIP_EXPRITER* it;
2067  SCIP_EXPR* expr;
2068 
2069  SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
2071  for( expr = nlrow->expr; !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
2072  assert(!SCIPexprIsVar(set, expr) || SCIPhashmapExists(nlp->varhash, SCIPgetVarExprVar(expr)));
2073  SCIPexpriterFree(&it);
2074  }
2075 #endif
2076 
2077  /* add row to NLP and capture it */
2078  nlp->nlrows[nlp->nnlrows + j] = nlrow;
2079  nlrow->nlpindex = nlp->nnlrows + j;
2080 
2081  nlrowAddToStat(nlp, set, nlrow, 1);
2082 
2083  SCIPnlrowCapture(nlrow);
2084 
2085  /* if we have a feasible NLP solution and it satisfies the new solution, then it is still feasible
2086  * if the NLP was globally or locally infeasible, then it stays that way
2087  * if the NLP was unbounded, then this may not be the case anymore
2088  */
2089  if( nlp->solstat <= SCIP_NLPSOLSTAT_FEASIBLE )
2090  {
2091  /* TODO bring this back? then everything that may call nlpAddNlRows will need to pass on primal, tree as well
2092  SCIP_Real feasibility;
2093  SCIP_CALL( SCIPnlrowGetNLPFeasibility(nlrow, blkmem, set, stat, primal, tree, nlp, &feasibility) );
2094  if( !SCIPsetIsFeasNegative(set, feasibility) )
2095  nlp->solstat = SCIP_NLPSOLSTAT_FEASIBLE;
2096  else
2097  */
2099  }
2100  else if( nlp->solstat == SCIP_NLPSOLSTAT_UNBOUNDED )
2101  {
2103  }
2104  }
2105 
2106  nlp->nnlrows += nnlrows;
2107  nlp->nunflushednlrowadd += nnlrows;
2108 
2109  return SCIP_OKAY;
2110 }
2111 
2112 /** moves a nonlinear row to a different place, and updates all corresponding data structures */
2113 static
2115  SCIP_NLP* nlp, /**< NLP data structure */
2116  int oldpos, /**< old position of nonlinear row */
2117  int newpos /**< new position of nonlinear row */
2118  )
2119 {
2120  assert(nlp != NULL);
2121  assert(0 <= oldpos && oldpos < nlp->nnlrows);
2122  assert(0 <= newpos && newpos < nlp->nnlrows);
2123  assert(nlp->nlrows[oldpos] != NULL);
2124 
2125  if( oldpos == newpos )
2126  return;
2127 
2128  nlp->nlrows[newpos] = nlp->nlrows[oldpos];
2129  nlp->nlrows[newpos]->nlpindex = newpos;
2130 
2131  /* update nlpi to nlp row index mapping */
2132  if( nlp->nlrows[newpos]->nlpiindex >= 0 )
2133  {
2134  assert(nlp->nlrowmap_nlpi2nlp != NULL);
2135  assert(nlp->nlrows[newpos]->nlpiindex < nlp->sizenlrows_solver);
2136  nlp->nlrowmap_nlpi2nlp[nlp->nlrows[newpos]->nlpiindex] = newpos;
2137  }
2138 }
2139 
2140 /** deletes nonlinear row with given position from NLP */
2141 static
2143  SCIP_NLP* nlp, /**< NLP data structure */
2144  BMS_BLKMEM* blkmem, /**< block memory */
2145  SCIP_SET* set, /**< global SCIP settings */
2146  SCIP_STAT* stat, /**< problem statistics data */
2147  int pos /**< position of nonlinear row that is to be removed */
2148  )
2149 {
2150  SCIP_NLROW* nlrow;
2151 
2152  assert(nlp != NULL);
2153  assert(blkmem != NULL);
2154  assert(set != NULL);
2155  assert(pos >= 0);
2156  assert(pos < nlp->nnlrows);
2157  assert(!nlp->indiving);
2158  assert(nlp->nlrows != NULL);
2159 
2160  nlrow = nlp->nlrows[pos];
2161  assert(nlrow != NULL);
2162  assert(nlrow->nlpindex == pos);
2163 
2164  /* if row is in NLPI, then mark that it has to be removed in the next flush
2165  * if row was not in NLPI yet, then we have one unflushed nlrow addition less */
2166  if( nlrow->nlpiindex >= 0 )
2167  {
2168  assert(nlrow->nlpiindex < nlp->nnlrows_solver);
2169  nlp->nlrowmap_nlpi2nlp[nlrow->nlpiindex] = -1;
2170  nlrow->nlpiindex = -1;
2171  ++nlp->nunflushednlrowdel;
2172  }
2173  else
2174  {
2175  assert(nlrow->nlpiindex == -1);
2176  --nlp->nunflushednlrowadd;
2177  }
2178 
2179  /* move NLP row from the end to pos and mark nlrow to be not in NLP anymore */
2180  nlpMoveNlrow(nlp, nlp->nnlrows-1, pos);
2181  nlrow->nlpindex = -1;
2182 
2183  /* do no longer count nlrow in NLP row statistics */
2184  nlrowAddToStat(nlp, set, nlrow, -1);
2185 
2186  /* forget about restriction */
2187  SCIP_CALL( SCIPnlrowRelease(&nlrow, blkmem, set, stat) );
2188  --nlp->nnlrows;
2189 
2190  if( nlp->solstat < SCIP_NLPSOLSTAT_LOCOPT )
2192  else if( nlp->solstat == SCIP_NLPSOLSTAT_GLOBINFEASIBLE )
2194 
2195  return SCIP_OKAY; /*lint !e438*/
2196 }
2197 
2198 /** updates bounds on a variable in the NLPI problem */
2199 static
2201  SCIP_NLP* nlp, /**< NLP data */
2202  SCIP_SET* set, /**< global SCIP settings */
2203  SCIP_VAR* var, /**< variable which bounds have changed */
2204  SCIP_Bool tightened /**< whether the bound change was a bound tightening */
2205  )
2206 {
2207  int pos;
2208  SCIP_Real lb;
2209  SCIP_Real ub;
2210 
2211  assert(nlp != NULL);
2212  assert(var != NULL);
2213  assert(SCIPhashmapExists(nlp->varhash, var));
2214 
2215  /* original variable bounds are ignored during diving
2216  * (all variable bounds are reset to their current value in exitDiving) */
2217  if( nlp->indiving )
2218  return SCIP_OKAY;
2219 
2220  /* get position of variable in NLP */
2221  pos = SCIPhashmapGetImageInt(nlp->varhash, var);
2222 
2223  /* if variable not in NLPI yet, nothing to do */
2224  if( nlp->varmap_nlp2nlpi[pos] == -1 )
2225  return SCIP_OKAY;
2226 
2227  /* update bounds in NLPI problem */
2228  assert(nlp->solver != NULL);
2229  assert(nlp->problem != NULL);
2230 
2231  pos = nlp->varmap_nlp2nlpi[pos];
2232  lb = SCIPvarGetLbLocal(var);
2233  ub = SCIPvarGetUbLocal(var);
2234  SCIP_CALL( SCIPnlpiChgVarBounds(set, nlp->solver, nlp->problem, 1, &pos, &lb, &ub) );
2235 
2236  /* if we have a feasible NLP solution and it satisfies the new bounds, then it is still feasible
2237  * if the NLP was globally or locally infeasible and we tightened a bound, then it stays that way
2238  * if the NLP was unbounded and we tightened a bound, then this may not be the case anymore
2239  */
2240  if( nlp->solstat <= SCIP_NLPSOLSTAT_FEASIBLE )
2241  {
2242  if( !tightened ||
2243  ((SCIPsetIsInfinity(set, -lb) || SCIPsetIsFeasLE(set, lb, SCIPvarGetNLPSol(var))) &&
2244  (SCIPsetIsInfinity(set, ub) || SCIPsetIsFeasGE(set, ub, SCIPvarGetNLPSol(var)))) )
2246  else
2248  }
2249  else if( !tightened || nlp->solstat == SCIP_NLPSOLSTAT_UNBOUNDED )
2250  {
2252  }
2253 
2254  return SCIP_OKAY;
2255 }
2256 
2257 /** updates coefficient of a variable in the objective */
2258 static
2260  SCIP_SET* set, /**< global SCIP settings */
2261  SCIP_NLP* nlp, /**< NLP data */
2262  SCIP_VAR* var /**< variable which bounds have changed */
2263  )
2264 {
2265  int pos;
2266  int objidx;
2267  SCIP_Real coef;
2268 
2269  assert(nlp != NULL);
2270  assert(var != NULL);
2271  assert(SCIPhashmapExists(nlp->varhash, var));
2272 
2273  /* if the objective in the NLPI is not up to date, then we do not need to do something here */
2274  if( !nlp->objflushed )
2275  return SCIP_OKAY;
2276 
2277  /* original objective is ignored during diving
2278  * we just need to remember that at end of diving we have to flush the objective */
2279  if( nlp->indiving )
2280  {
2281  nlp->objflushed = FALSE;
2282  return SCIP_OKAY;
2283  }
2284 
2285  /* get position of variable in NLP and objective coefficient */
2286  pos = SCIPhashmapGetImageInt(nlp->varhash, var);
2287  assert(nlp->varmap_nlp2nlpi[pos] == -1 || nlp->solver != NULL);
2288 
2289  /* actually we only need to remember flushing the objective if we also have an NLPI */
2290  if( nlp->solver == NULL )
2291  return SCIP_OKAY;
2292 
2293  coef = SCIPvarGetObj(var);
2294 
2295  /* if variable not in NLPI yet, then we only need to remember to update the objective after variable additions were flushed */
2296  if( nlp->varmap_nlp2nlpi[pos] == -1 && coef != 0.0 )
2297  {
2298  nlp->objflushed = FALSE;
2299 
2300  return SCIP_OKAY;
2301  }
2302 
2303  /* if we are here, then the objective in the NLPI is up to date,
2304  * we keep it this way by changing the coefficient of var in the NLPI problem objective */
2305  assert(nlp->solver != NULL);
2306  assert(nlp->problem != NULL);
2307 
2308  pos = nlp->varmap_nlp2nlpi[pos];
2309  objidx = -1;
2310  SCIP_CALL( SCIPnlpiChgLinearCoefs(set, nlp->solver, nlp->problem, objidx, 1, &pos, &coef) );
2311 
2312  /* if we had a solution and it was locally (or globally) optimal, then now we can only be sure that it is still feasible */
2313  if( nlp->solstat < SCIP_NLPSOLSTAT_FEASIBLE )
2315 
2316  return SCIP_OKAY;
2317 }
2318 
2319 /** adds new variables to the NLP */
2320 static
2322  SCIP_NLP* nlp, /**< NLP data structure */
2323  BMS_BLKMEM* blkmem, /**< block memory */
2324  SCIP_SET* set, /**< global SCIP settings */
2325  int nvars, /**< number of variables to add */
2326  SCIP_VAR** vars /**< variable to add to NLP */
2327  )
2328 {
2329  int i;
2330  SCIP_VAR* var;
2331 
2332  assert(nlp != NULL);
2333  assert(blkmem != NULL);
2334  assert(set != NULL);
2335  assert(vars != NULL || nvars == 0);
2336  assert(!nlp->indiving || nvars == 0);
2337 
2338  if( nvars == 0 )
2339  return SCIP_OKAY;
2340 
2341  SCIP_CALL( SCIPnlpEnsureVarsSize(nlp, blkmem, set, nlp->nvars + nvars) );
2342  assert(nlp->sizevars >= nlp->nvars + nvars);
2343 
2344  for( i = 0; i < nvars; ++i )
2345  {
2346  var = vars[i]; /*lint !e613*/
2347 
2348  assert(SCIPvarIsTransformed(var));
2349  assert(SCIPvarIsActive(var));
2350  assert(!SCIPhashmapExists(nlp->varhash, var));
2351 
2352  SCIPvarCapture(var);
2353 
2354  nlp->vars[nlp->nvars+i] = var;
2355  nlp->varmap_nlp2nlpi[nlp->nvars+i] = -1;
2356  SCIP_CALL( SCIPhashmapInsertInt(nlp->varhash, var, nlp->nvars+i) );
2357 
2358  nlp->varlbdualvals[nlp->nvars+i] = 0.0;
2359  nlp->varubdualvals[nlp->nvars+i] = 0.0;
2360 
2361  /* update objective, if necessary (new variables have coefficient 0.0 anyway) */
2362  if( SCIPvarGetObj(var) != 0.0 )
2363  {
2364  SCIP_CALL( nlpUpdateObjCoef(set, nlp, var) );
2365  }
2366 
2367  /* let's keep the previous initial guess and set it for the new variable to the best bound
2368  * (since there can be no row that uses this variable yet, this seems a good guess) */
2369  if( nlp->haveinitguess )
2370  {
2371  assert(nlp->initialguess != NULL);
2372 
2373  nlp->initialguess[nlp->nvars+i] = SCIPvarGetBestBoundLocal(var);
2374  }
2375 
2376  /* if we have a feasible NLP solution, then it remains feasible
2377  * but we have to update the objective function
2378  */
2379  if( nlp->solstat <= SCIP_NLPSOLSTAT_FEASIBLE )
2380  {
2384  }
2385 
2386  /* catch events on variable */
2387  SCIP_CALL( SCIPvarCatchEvent(var, blkmem, set, \
2389  nlp->eventhdlr, (SCIP_EVENTDATA*)nlp, NULL) ); /* @todo should store event filter position in nlp? */
2390  }
2391 
2392  nlp->nvars += nvars;
2393  nlp->nunflushedvaradd += nvars;
2394 
2395  return SCIP_OKAY;
2396 }
2397 
2398 /** moves a variable to a different place, and updates all corresponding data structures */
2399 static
2401  SCIP_NLP* nlp, /**< NLP data structure */
2402  int oldpos, /**< old position of variable */
2403  int newpos /**< new position of variable */
2404  )
2405 {
2406  int nlpipos;
2407 
2408  assert(nlp != NULL);
2409  assert(0 <= oldpos && oldpos < nlp->nvars);
2410  assert(0 <= newpos && newpos < nlp->nvars);
2411  assert(nlp->vars[oldpos] != NULL);
2412 
2413  if( oldpos == newpos )
2414  return SCIP_OKAY;
2415 
2416  SCIP_CALL( SCIPhashmapSetImageInt(nlp->varhash, nlp->vars[oldpos], newpos) );
2417  nlp->vars[newpos] = nlp->vars[oldpos];
2418  nlp->varmap_nlp2nlpi[newpos] = nlp->varmap_nlp2nlpi[oldpos];
2419  nlp->varlbdualvals[newpos] = nlp->varlbdualvals[oldpos];
2420  nlp->varubdualvals[newpos] = nlp->varubdualvals[oldpos];
2421  if( nlp->initialguess != NULL )
2422  nlp->initialguess[newpos] = nlp->initialguess[oldpos];
2423 
2424  nlpipos = nlp->varmap_nlp2nlpi[newpos];
2425  if( nlpipos > 0 )
2426  nlp->varmap_nlpi2nlp[nlpipos] = newpos;
2427 
2428  return SCIP_OKAY;
2429 }
2430 
2431 /** deletes variable with given position from NLP */
2432 static
2434  SCIP_NLP* nlp, /**< NLP data structure */
2435  BMS_BLKMEM* blkmem, /**< block memory */
2436  SCIP_SET* set, /**< global SCIP settings */
2437  SCIP_STAT* stat, /**< problem statistics data */
2438  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2439  SCIP_LP* lp, /**< SCIP LP, needed if a column-variable is freed */
2440  int pos /**< position of nonlinear row that is to be removed */
2441  )
2442 {
2443  SCIP_VAR* var;
2444 #ifndef NDEBUG
2445  int i;
2446 #endif
2447  int nlpipos;
2448 
2449  assert(nlp != NULL);
2450  assert(blkmem != NULL);
2451  assert(set != NULL);
2452  assert(pos >= 0);
2453  assert(pos < nlp->nvars);
2454  assert(!nlp->indiving);
2455 
2456  var = nlp->vars[pos];
2457  assert(var != NULL);
2458 
2459 #ifndef NDEBUG
2460  /* assert that variable is not used by any nonlinear row */
2461  for( i = 0; i < nlp->nnlrows; ++i )
2462  {
2463  int j;
2464  SCIP_NLROW* nlrow;
2465 
2466  nlrow = nlp->nlrows[i];
2467  assert(nlrow != NULL);
2468 
2469  /* use nlrowSearchLinearCoef only if already sorted, since otherwise we may change the solving process slightly */
2470  if( nlrow->linvarssorted )
2471  assert( nlrowSearchLinearCoef(nlrow, var) == -1 );
2472  else
2473  for( j = 0; j < nlrow->nlinvars; ++j )
2474  assert( nlrow->linvars[j] != var );
2475 
2476  if( nlrow->expr != NULL )
2477  {
2478  SCIP_EXPRITER* it;
2479  SCIP_EXPR* expr;
2480  SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
2482  for( expr = nlrow->expr; !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
2483  assert(!SCIPexprIsVar(set, expr) || SCIPgetVarExprVar(expr) != var);
2484  SCIPexpriterFree(&it);
2485  }
2486  }
2487 #endif
2488 
2489  /* if we had a feasible solution, then adjust objective function value
2490  * if NLP was unbounded before, then maybe it is not anymore */
2491  if( nlp->solstat <= SCIP_NLPSOLSTAT_FEASIBLE )
2492  nlp->primalsolobjval -= SCIPvarGetObj(var) * SCIPvarGetNLPSol(var);
2493  else if( nlp->solstat == SCIP_NLPSOLSTAT_UNBOUNDED )
2495 
2496  /* if variable is in NLPI problem, mark that we have to remember to delete it there
2497  * if it was not in the NLPI yet, then we have one unflushed var addition less now */
2498  nlpipos = nlp->varmap_nlp2nlpi[pos];
2499  if( nlpipos >= 0 )
2500  {
2501  assert(nlpipos < nlp->nvars_solver);
2502 
2503  nlp->varmap_nlpi2nlp[nlpipos] = -1;
2504  ++nlp->nunflushedvardel;
2505  }
2506  else
2507  --nlp->nunflushedvaradd;
2508 
2509  /* drop events on variable */
2510  SCIP_CALL( SCIPvarDropEvent(var, blkmem, set, \
2512  nlp->eventhdlr, (SCIP_EVENTDATA*)nlp, -1) );
2513 
2514  /* move variable from end to pos */
2515  SCIP_CALL( nlpMoveVar(nlp, nlp->nvars-1, pos) );
2516 
2517  /* forget about variable */
2518  SCIP_CALL( SCIPhashmapRemove(nlp->varhash, var) );
2519  SCIP_CALL( SCIPvarRelease(&var, blkmem, set, eventqueue, lp) );
2520  --nlp->nvars;
2521 
2522  return SCIP_OKAY;
2523 }
2524 
2525 /** notifies NLP that a variable was fixed, so it is removed from objective, all rows, and the NLP variables */
2526 static
2528  SCIP_NLP* nlp, /**< NLP data */
2529  BMS_BLKMEM* blkmem, /**< block memory */
2530  SCIP_SET* set, /**< global SCIP settings */
2531  SCIP_STAT* stat, /**< problem statistics data */
2532  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2533  SCIP_LP* lp, /**< SCIP LP, needed to release variable */
2534  SCIP_VAR* var /**< variable that has been fixed */
2535  )
2536 {
2537  int i;
2538 
2539  assert(nlp != NULL);
2540  assert(var != NULL);
2541  assert(!SCIPvarIsActive(var));
2542  assert(!nlp->indiving);
2543  assert(SCIPhashmapExists(nlp->varhash, var));
2544 
2545  /* remove var from all rows */
2546  for( i = 0; i < nlp->nnlrows; ++i )
2547  {
2548  SCIP_CALL( nlrowRemoveFixedVar(nlp->nlrows[i], blkmem, set, stat, nlp, var) );
2549  }
2550 
2551  /* remove variable from NLP */
2552  SCIP_CALL( SCIPnlpDelVar(nlp, blkmem, set, stat, eventqueue, lp, var) );
2553 
2554  return SCIP_OKAY;
2555 }
2556 
2557 /** creates arrays with NLPI variable indices of linear variables in a nonlinear row */
2558 static
2560  SCIP_NLP* nlp, /**< NLP data */
2561  SCIP_SET* set, /**< global SCIP settings */
2562  SCIP_NLROW* nlrow, /**< nonlinear row */
2563  int** linidxs /**< buffer to store pointer to NLPI indices of linear variables */
2564  )
2565 {
2566  int i;
2567  SCIP_VAR* var;
2568 
2569  assert(nlp != NULL);
2570  assert(set != NULL);
2571  assert(nlrow != NULL);
2572  assert(linidxs != NULL);
2573 
2574  /* get indices of variables in linear part of row */
2575  if( nlrow->nlinvars > 0 )
2576  {
2577  assert(nlrow->linvars != NULL);
2578  assert(nlrow->lincoefs != NULL);
2579 
2580  SCIP_CALL( SCIPsetAllocBufferArray(set, linidxs, nlrow->nlinvars) );
2581 
2582  for( i = 0; i < nlrow->nlinvars; ++i )
2583  {
2584  var = nlrow->linvars[i];
2585  assert(var != NULL);
2586  assert(SCIPvarIsActive(var)); /* at this point, there should be only active variables in the row */
2587 
2588  assert(SCIPhashmapExists(nlp->varhash, var));
2589  (*linidxs)[i] = nlp->varmap_nlp2nlpi[SCIPhashmapGetImageInt(nlp->varhash, var)];
2590  assert((*linidxs)[i] >= 0);
2591  }
2592  }
2593  else
2594  *linidxs = NULL;
2595 
2596  return SCIP_OKAY;
2597 }
2598 
2599 /** ensures, that NLPI variables array of NLP can store at least num entries */
2600 static
2602  SCIP_NLP* nlp, /**< NLP data */
2603  BMS_BLKMEM* blkmem, /**< block memory */
2604  SCIP_SET* set, /**< global SCIP settings */
2605  int num /**< minimum number of entries to store */
2606  )
2607 {
2608  assert(nlp != NULL);
2609  assert(blkmem != NULL);
2610  assert(set != NULL);
2611  assert(nlp->nvars_solver <= nlp->sizevars_solver);
2612 
2613  if( num > nlp->sizevars_solver )
2614  {
2615  int newsize;
2616 
2617  newsize = SCIPsetCalcMemGrowSize(set, num);
2618  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &nlp->varmap_nlpi2nlp, nlp->sizevars_solver, newsize) );
2619 
2620  nlp->sizevars_solver = newsize;
2621  }
2622  assert(num <= nlp->sizevars_solver);
2623 
2624  return SCIP_OKAY;
2625 }
2626 
2627 /** ensures, that NLPI nonlinear rows array of NLP can store at least num entries */
2628 static
2630  SCIP_NLP* nlp, /**< NLP data */
2631  BMS_BLKMEM* blkmem, /**< block memory */
2632  SCIP_SET* set, /**< global SCIP settings */
2633  int num /**< minimum number of entries to store */
2634  )
2635 {
2636  assert(nlp != NULL);
2637  assert(blkmem != NULL);
2638  assert(set != NULL);
2639  assert(nlp->nnlrows_solver <= nlp->sizenlrows_solver);
2640 
2641  if( num > nlp->sizenlrows_solver )
2642  {
2643  int newsize;
2644 
2645  newsize = SCIPsetCalcMemGrowSize(set, num);
2647 
2648  nlp->sizenlrows_solver = newsize;
2649  }
2650  assert(num <= nlp->sizenlrows_solver);
2651 
2652  return SCIP_OKAY;
2653 }
2654 
2655 /** deletes rows from the NLPI problem that have been marked as to remove */
2656 static
2658  SCIP_NLP* nlp, /**< NLP data */
2659  BMS_BLKMEM* blkmem, /**< block memory */
2660  SCIP_SET* set /**< global SCIP settings */
2661  )
2662 {
2663  int j;
2664  int c; /* counts the number of rows to delete */
2665  int* rowset; /* marks which rows to delete and stores new indices */
2666  SCIP_NLROW* nlrow;
2667 
2668  assert(nlp != NULL);
2669  assert(blkmem != NULL);
2670  assert(set != NULL);
2671  assert(nlp->nunflushednlrowdel >= 0);
2672  assert(!nlp->indiving);
2673 
2674  if( nlp->nunflushednlrowdel == 0 )
2675  {
2676 #ifndef NDEBUG
2677  /* check that there are really no pending removals of nonlinear rows */
2678  for( j = 0; j < nlp->nnlrows_solver; ++j )
2679  assert(nlp->nlrowmap_nlpi2nlp[j] >= 0);
2680 #endif
2681  return SCIP_OKAY;
2682  }
2683 
2684  assert(nlp->solver != NULL);
2685  assert(nlp->problem != NULL);
2686 
2687  /* create marker which rows have to be deleted */
2688  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowset, nlp->nnlrows_solver) );
2689  c = 0;
2690  for( j = 0; j < nlp->nnlrows_solver; ++j )
2691  {
2692  if( nlp->nlrowmap_nlpi2nlp[j] == -1 )
2693  {
2694  rowset[j] = 1;
2695  ++c;
2696  }
2697  else
2698  rowset[j] = 0;
2699  }
2700  assert(c == nlp->nunflushednlrowdel);
2701 
2702  /* remove rows from NLPI problem */
2703  SCIP_CALL( SCIPnlpiDelConsSet(set, nlp->solver, nlp->problem, rowset, nlp->nnlrows_solver) );
2704 
2705  /* update NLPI row indices */
2706  for( j = 0; j < nlp->nnlrows_solver; ++j )
2707  {
2708  assert(rowset[j] <= j); /* we assume that the NLP solver did not move a row behind its previous position!! */
2709  if( rowset[j] < 0 )
2710  {
2711  /* assert that row was marked as deleted */
2712  assert(nlp->nlrowmap_nlpi2nlp[j] == -1);
2713  }
2714  else if( rowset[j] < j )
2715  {
2716  /* nlrow at position j moved (forward) to position rowset[j] */
2717  assert(nlp->nlrowmap_nlpi2nlp[j] >= 0);
2718  assert(nlp->nlrowmap_nlpi2nlp[j] < nlp->nnlrows);
2719 
2720  nlrow = nlp->nlrows[nlp->nlrowmap_nlpi2nlp[j]];
2721  assert(nlrow->nlpiindex == j);
2722 
2723  /* there should be no row at the new position already */
2724  assert(nlp->nlrowmap_nlpi2nlp[rowset[j]] == -1);
2725 
2726  nlrow->nlpiindex = rowset[j];
2727  nlp->nlrowmap_nlpi2nlp[rowset[j]] = nlrow->nlpindex;
2728  }
2729  else
2730  {
2731  /* row j stays at position j */
2732  assert(nlp->nlrowmap_nlpi2nlp[j] >= 0);
2733  assert(nlp->nlrowmap_nlpi2nlp[j] < nlp->nnlrows);
2734  assert(nlp->nlrows[nlp->nlrowmap_nlpi2nlp[j]]->nlpiindex == j);
2735  }
2736  }
2737  nlp->nnlrows_solver -= c;
2738  nlp->nunflushednlrowdel = 0;
2739 
2740  /* cleanup */
2741  SCIPsetFreeBufferArray(set, &rowset);
2742 
2743  return SCIP_OKAY;
2744 }
2745 
2746 /** deletes variables from the NLPI problem that have been marked as to remove
2747  *
2748  * assumes that there are no pending row deletions (nlpFlushNlRowDeletions() should be called first)
2749  */
2750 static
2752  SCIP_NLP* nlp, /**< NLP data */
2753  BMS_BLKMEM* blkmem, /**< block memory */
2754  SCIP_SET* set /**< global SCIP settings */
2755  )
2756 {
2757  int i;
2758  int c; /* counter on number of variables to remove in solver */
2759  int* colset; /* marks which variables to delete and stores new indices */
2760 
2761  assert(nlp != NULL);
2762  assert(blkmem != NULL);
2763  assert(set != NULL);
2764  assert(nlp->nunflushedvardel >= 0);
2765  assert(nlp->nunflushednlrowdel == 0);
2766  assert(!nlp->indiving);
2767 
2768  if( nlp->nunflushedvardel == 0 )
2769  {
2770 #ifndef NDEBUG
2771  /* check that there are really no pending removals of variables */
2772  for( i = 0; i < nlp->nvars_solver; ++i )
2773  assert(nlp->varmap_nlpi2nlp[i] >= 0);
2774 #endif
2775  return SCIP_OKAY;
2776  }
2777 
2778  assert(nlp->solver != NULL);
2779  assert(nlp->problem != NULL);
2780 
2781  /* create marker which variables have to be deleted */
2782  SCIP_CALL( SCIPsetAllocBufferArray(set, &colset, nlp->nvars_solver) );
2783  c = 0;
2784  for( i = 0; i < nlp->nvars_solver; ++i )
2785  {
2786  if( nlp->varmap_nlpi2nlp[i] == -1 )
2787  {
2788  colset[i] = 1;
2789  ++c;
2790  }
2791  else
2792  colset[i] = 0;
2793  }
2794  assert(c == nlp->nunflushedvardel);
2795 
2796  /* delete variables from NLPI problem */
2797  SCIP_CALL( SCIPnlpiDelVarSet(set, nlp->solver, nlp->problem, colset, nlp->nvars_solver) );
2798 
2799  /* update NLPI variable indices */
2800  for( i = 0; i < nlp->nvars_solver; ++i )
2801  {
2802  assert(colset[i] <= i); /* we assume that the NLP solver did not move a variable behind its previous position!! */
2803  if( colset[i] < 0 )
2804  {
2805  /* assert that variable was marked as deleted */
2806  assert(nlp->varmap_nlpi2nlp[i] == -1);
2807  }
2808  else if( colset[i] < i)
2809  {
2810  /* variable at position i moved (forward) to position colset[i] */
2811  int varpos;
2812 
2813  varpos = nlp->varmap_nlpi2nlp[i]; /* position of variable i in NLP */
2814  assert(varpos >= 0);
2815  assert(varpos < nlp->nvars);
2816  assert(nlp->varmap_nlp2nlpi[varpos] == i);
2817 
2818  /* there should be no variable at the new position already */
2819  assert(nlp->varmap_nlpi2nlp[colset[i]] == -1);
2820 
2821  nlp->varmap_nlp2nlpi[varpos] = colset[i];
2822  nlp->varmap_nlpi2nlp[colset[i]] = varpos;
2823  }
2824  else
2825  {
2826  /* variable i stays at position i */
2827  assert(nlp->varmap_nlpi2nlp[i] >= 0);
2828  assert(nlp->varmap_nlpi2nlp[i] < nlp->nvars);
2829  assert(nlp->varmap_nlp2nlpi[nlp->varmap_nlpi2nlp[i]] == i);
2830  }
2831  }
2832 
2833  nlp->nvars_solver -= c;
2834  nlp->nunflushedvardel = 0;
2835 
2836  /* cleanup */
2837  SCIPsetFreeBufferArray(set, &colset);
2838 
2839  return SCIP_OKAY;
2840 }
2841 
2842 /** adds nonlinear rows to NLPI problem that have been added to NLP before
2843  *
2844  * assumes that there are no pending variable additions or deletions (nlpFlushVarDeletions() and nlpFlushVarAdditions() should be called first)
2845  */
2846 static
2848  SCIP_NLP* nlp, /**< NLP data */
2849  BMS_BLKMEM* blkmem, /**< block memory */
2850  SCIP_SET* set, /**< global SCIP settings */
2851  SCIP_STAT* stat /**< problem statistics */
2852  )
2853 {
2854  int c, i;
2855  SCIP_NLROW* nlrow;
2856  SCIP_Real* lhss;
2857  SCIP_Real* rhss;
2858  int* nlinvars;
2859  int** linidxs;
2860  SCIP_Real** lincoefs;
2861  SCIP_EXPR** exprs;
2862  const char** names;
2863 
2864  assert(nlp != NULL);
2865  assert(blkmem != NULL);
2866  assert(set != NULL);
2867  assert(nlp->nunflushednlrowadd >= 0);
2868  assert(nlp->nunflushedvaradd == 0);
2869  assert(nlp->nunflushedvardel == 0);
2870  assert(!nlp->indiving);
2871 
2872  if( nlp->nunflushednlrowadd == 0 )
2873  {
2874 #ifndef NDEBUG
2875  /* check that there are really no pending additions of variables */
2876  for( i = 0; i < nlp->nnlrows; ++i )
2877  assert(nlp->nlrows[i]->nlpiindex >= 0);
2878 #endif
2879  return SCIP_OKAY;
2880  }
2881 
2882  assert(nlp->solver != NULL);
2883  assert(nlp->problem != NULL);
2884 
2885  SCIP_CALL( nlpEnsureNlRowsSolverSize(nlp, blkmem, set, nlp->nnlrows_solver + nlp->nunflushednlrowadd) );
2886 
2889  SCIP_CALL( SCIPsetAllocBufferArray(set, &nlinvars, nlp->nunflushednlrowadd) );
2890  SCIP_CALL( SCIPsetAllocBufferArray(set, &linidxs, nlp->nunflushednlrowadd) );
2891  SCIP_CALL( SCIPsetAllocBufferArray(set, &lincoefs, nlp->nunflushednlrowadd) );
2893 #if ADDNAMESTONLPI
2895 #else
2896  names = NULL;
2897 #endif
2898 
2899  c = 0;
2900  for( i = 0; i < nlp->nnlrows; ++i )
2901  {
2902  nlrow = nlp->nlrows[i];
2903  assert(nlrow != NULL);
2904 
2905  /* skip nonlinear rows already in NLPI problem */
2906  if( nlrow->nlpiindex >= 0 )
2907  continue;
2908  assert(c < nlp->nunflushednlrowadd);
2909 
2910  /* get indices in NLPI */
2911  SCIP_CALL( nlpSetupNlpiIndices(nlp, set, nlrow, &linidxs[c]) );
2912  assert(linidxs[c] != NULL || nlrow->nlinvars == 0);
2913 
2914  nlp->nlrowmap_nlpi2nlp[nlp->nnlrows_solver+c] = i;
2915  nlrow->nlpiindex = nlp->nnlrows_solver+c;
2916 
2917  lhss[c] = nlrow->lhs;
2918  rhss[c] = nlrow->rhs;
2919  if( nlrow->constant != 0.0 )
2920  {
2921  if( !SCIPsetIsInfinity(set, -nlrow->lhs) )
2922  lhss[c] -= nlrow->constant;
2923  if( !SCIPsetIsInfinity(set, nlrow->rhs) )
2924  rhss[c] -= nlrow->constant;
2925  }
2926  if( rhss[c] < lhss[c] )
2927  {
2928  assert(SCIPsetIsEQ(set, lhss[c], rhss[c]));
2929  rhss[c] = lhss[c];
2930  }
2931 
2932  nlinvars[c] = nlrow->nlinvars;
2933  lincoefs[c] = nlrow->lincoefs;
2934 
2935  if( nlrow->expr != NULL )
2936  {
2937  /* create copy of expr that uses varidx expressions corresponding to variables indices in NLPI */
2938  SCIP_CALL( SCIPexprCopy(set, stat, blkmem, set, stat, blkmem, nlrow->expr, &exprs[c], mapvar2varidx, (void*)nlp, NULL, NULL) );
2939  }
2940  else
2941  exprs[c] = NULL;
2942 
2943 #if ADDNAMESTONLPI
2944  names[c] = nlrow->name;
2945 #endif
2946 
2947  ++c;
2948 
2949 #ifdef NDEBUG
2950  /* have c vars to add already, there can be no more */
2951  if( c == nlp->nunflushednlrowadd )
2952  break;
2953 #endif
2954  }
2955  assert(c == nlp->nunflushednlrowadd);
2956 
2957  nlp->nnlrows_solver += c;
2958 
2959  SCIP_CALL( SCIPnlpiAddConstraints(set, nlp->solver, nlp->problem, c, lhss, rhss,
2960  nlinvars, linidxs, lincoefs,
2961  exprs,
2962  names) );
2963 
2964  for( c = nlp->nunflushednlrowadd - 1; c >= 0 ; --c )
2965  {
2966  if( linidxs[c] != NULL )
2967  SCIPsetFreeBufferArray(set, &linidxs[c]);
2968  if( exprs[c] != NULL )
2969  {
2970  SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &exprs[c]) );
2971  }
2972  }
2973 
2974 #if ADDNAMESTONLPI
2975  SCIPsetFreeBufferArray(set, &names);
2976 #endif
2977  SCIPsetFreeBufferArray(set, &exprs);
2978  SCIPsetFreeBufferArray(set, &lincoefs);
2979  SCIPsetFreeBufferArray(set, &linidxs);
2980  SCIPsetFreeBufferArray(set, &nlinvars);
2981  SCIPsetFreeBufferArray(set, &rhss);
2982  SCIPsetFreeBufferArray(set, &lhss);
2983 
2984  nlp->nunflushednlrowadd = 0;
2985 
2986  return SCIP_OKAY;
2987 }
2988 
2989 
2990 /** adds variables to NLPI problem that have been added to NLP before
2991  *
2992  * may set nlp->objflushed to FALSE if a variable with nonzero objective coefficient is added to the NLPI problem
2993  */
2994 static
2996  SCIP_NLP* nlp, /**< NLP data */
2997  BMS_BLKMEM* blkmem, /**< block memory */
2998  SCIP_SET* set /**< global SCIP settings */
2999  )
3000 {
3001  int i, c;
3002  SCIP_Real* lbs;
3003  SCIP_Real* ubs;
3004  const char** names;
3005 
3006  assert(nlp != NULL);
3007  assert(blkmem != NULL);
3008  assert(set != NULL);
3009  assert(nlp->nunflushedvaradd >= 0);
3010  assert(!nlp->indiving);
3011 
3012  if( nlp->nunflushedvaradd == 0 )
3013  {
3014 #ifndef NDEBUG
3015  /* check that there are really no pending additions of variables */
3016  for( i = 0; i < nlp->nvars; ++i )
3017  assert(nlp->varmap_nlp2nlpi[i] >= 0);
3018 #endif
3019  return SCIP_OKAY;
3020  }
3021 
3022  assert(nlp->solver != NULL);
3023  assert(nlp->problem != NULL);
3024 
3025  SCIP_CALL( nlpEnsureVarsSolverSize(nlp, blkmem, set, nlp->nvars_solver + nlp->nunflushedvaradd) );
3026 
3029 #if ADDNAMESTONLPI
3030  SCIP_CALL( SCIPsetAllocBufferArray(set, &names, nlp->nunflushedvaradd) );
3031 #else
3032  names = NULL;
3033 #endif
3034 
3035  c = 0;
3036  for( i = 0; i < nlp->nvars; ++i )
3037  {
3038  /* skip variables already in NLPI problem */
3039  if( nlp->varmap_nlp2nlpi[i] >= 0 )
3040  continue;
3041  assert(c < nlp->nunflushedvaradd);
3042 
3043  nlp->varmap_nlpi2nlp[nlp->nvars_solver+c] = i;
3044  nlp->varmap_nlp2nlpi[i] = nlp->nvars_solver+c;
3045  lbs[c] = SCIPvarGetLbLocal(nlp->vars[i]);
3046  ubs[c] = SCIPvarGetUbLocal(nlp->vars[i]);
3047 #if ADDNAMESTONLPI
3048  names[c] = SCIPvarGetName(nlp->vars[i]);
3049 #endif
3050  ++c;
3051 
3052  /* if the new variable has a nonzero objective coefficient, then the objective need to be updated */
3053  if( !SCIPsetIsZero(set, SCIPvarGetObj(nlp->vars[i])) )
3054  nlp->objflushed = FALSE;
3055 
3056 #ifdef NDEBUG
3057  /* have c vars to add already, there can be no more */
3058  if( c == nlp->nunflushedvaradd )
3059  break;
3060 #endif
3061  }
3062  assert(c == nlp->nunflushedvaradd);
3063 
3064  nlp->nvars_solver += c;
3065 
3066  SCIP_CALL( SCIPnlpiAddVars(set, nlp->solver, nlp->problem, c, lbs, ubs, names) );
3067 
3068 #if ADDNAMESTONLPI
3069  SCIPsetFreeBufferArray(set, &names);
3070 #endif
3071  SCIPsetFreeBufferArray(set, &ubs);
3072  SCIPsetFreeBufferArray(set, &lbs);
3073 
3074  nlp->nunflushedvaradd = 0;
3075 
3076  return SCIP_OKAY;
3077 }
3078 
3079 /** updates the objective in the NLPI problem, if necessary
3080  *
3081  * assumes that there are no unflushed variable additions or deletions (nlpFlushVarDeletions() and nlpFlushVarAdditions() should be called first)
3082  */
3083 static
3085  SCIP_NLP* nlp, /**< NLP data */
3086  BMS_BLKMEM* blkmem, /**< block memory */
3087  SCIP_SET* set /**< global SCIP settings */
3088  )
3089 {
3090  int* linindices;
3091  SCIP_Real* lincoefs;
3092  SCIP_Real coef;
3093  int i;
3094  int nz;
3095 
3096  assert(nlp != NULL);
3097  assert(blkmem != NULL);
3098  assert(set != NULL);
3099  assert(nlp->nunflushedvaradd == 0);
3100  assert(nlp->nunflushedvardel == 0);
3101  assert(!nlp->indiving);
3102 
3103  if( nlp->objflushed )
3104  return SCIP_OKAY;
3105 
3106  assert(nlp->solver != NULL);
3107  assert(nlp->problem != NULL);
3108 
3109  /* assemble coefficients */
3110  SCIP_CALL( SCIPsetAllocBufferArray(set, &linindices, nlp->nvars_solver) );
3111  SCIP_CALL( SCIPsetAllocBufferArray(set, &lincoefs, nlp->nvars_solver) );
3112 
3113  nz = 0;
3114  for( i = 0; i < nlp->nvars_solver; ++i )
3115  {
3116  assert(nlp->varmap_nlpi2nlp[i] >= 0); /* there should be no variable deletions pending */
3117 
3118  coef = SCIPvarGetObj(nlp->vars[nlp->varmap_nlpi2nlp[i]]);
3119  if( SCIPsetIsZero(set, coef) )
3120  continue;
3121 
3122  linindices[nz] = i;
3123  lincoefs[nz] = coef;
3124  ++nz;
3125  }
3126 
3127  SCIP_CALL( SCIPnlpiSetObjective(set, nlp->solver, nlp->problem,
3128  nz, linindices, lincoefs,
3129  NULL,
3130  0.0) );
3131 
3132  SCIPsetFreeBufferArray(set, &lincoefs);
3133  SCIPsetFreeBufferArray(set, &linindices);
3134 
3135  nlp->objflushed = TRUE;
3136 
3137  return SCIP_OKAY;
3138 }
3139 
3140 /** solves the NLP (or diving NLP), assuming it has been flushed already */
3141 static
3143  SCIP_NLP* nlp, /**< NLP data */
3144  BMS_BLKMEM* blkmem, /**< block memory buffers */
3145  SCIP_SET* set, /**< global SCIP settings */
3146  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
3147  SCIP_STAT* stat, /**< problem statistics */
3148  SCIP_PRIMAL* primal, /**< primal data */
3149  SCIP_TREE* tree, /**< branch and bound tree */
3150  SCIP_NLPPARAM* nlpparam /**< NLP solve parameters */
3151  )
3152 {
3153  int i;
3154 
3155  assert(nlp != NULL);
3156  assert(blkmem != NULL);
3157  assert(set != NULL);
3158  assert(stat != NULL);
3159 
3160  if( nlp->solver == NULL )
3161  {
3162  SCIPmessagePrintWarning(messagehdlr, "Attempted to solve NLP, but no solver available.\n");
3163 
3166 
3167  return SCIP_OKAY;
3168  }
3169 
3170  assert(nlp->solver != NULL);
3171  assert(nlp->problem != NULL);
3172 
3173  /* set initial guess, if available and warmstart hasn't been enabled
3174  * when using the NLP, passing a dual solution with the initguess is not available at the moment (TODO),
3175  * so a warmstart has to start from the last solution stored in the NLPI
3176  */
3177  if( nlp->haveinitguess && !nlpparam->warmstart )
3178  {
3179  /* @todo should we not set it if we had set it already? (initguessflushed...) */
3180  SCIP_Real* initialguess_solver;
3181  int nlpidx;
3182 
3183  assert(nlp->initialguess != NULL);
3184 
3185  SCIP_CALL( SCIPsetAllocBufferArray(set, &initialguess_solver, nlp->nvars_solver) );
3186 
3187  for( i = 0; i < nlp->nvars_solver; ++i )
3188  {
3189  nlpidx = nlp->varmap_nlpi2nlp[i];
3190  assert(nlpidx >= 0);
3191  assert(nlpidx < nlp->nvars);
3192 
3193  initialguess_solver[i] = nlp->initialguess[nlpidx];
3194  }
3195  SCIP_CALL( SCIPnlpiSetInitialGuess(set, nlp->solver, nlp->problem, initialguess_solver, NULL, NULL, NULL) );
3196 
3197  SCIPsetFreeBufferArray(set, &initialguess_solver);
3198  }
3199 
3200  /* let NLP solver do his work */
3201  SCIPclockStart(stat->nlpsoltime, set);
3202 
3203  SCIP_CALL( SCIPnlpiSolve(set, stat, nlp->solver, nlp->problem, nlpparam) );
3204 
3205  SCIPclockStop(stat->nlpsoltime, set);
3206  ++stat->nnlps;
3207 
3208  nlp->termstat = SCIPnlpiGetTermstat(set, nlp->solver, nlp->problem);
3209  nlp->solstat = SCIPnlpiGetSolstat(set, nlp->solver, nlp->problem);
3210  switch( nlp->solstat )
3211  {
3216  {
3217  SCIP_Real* primalvals;
3218  SCIP_Real* nlrowdualvals;
3219  SCIP_Real* varlbdualvals;
3220  SCIP_Real* varubdualvals;
3221 
3222  primalvals = NULL;
3223  nlrowdualvals = NULL;
3224  varlbdualvals = NULL;
3225  varubdualvals = NULL;
3226 
3227  /* get NLP solution */
3228  SCIP_CALL( SCIPnlpiGetSolution(set, nlp->solver, nlp->problem, &primalvals, &nlrowdualvals, &varlbdualvals, &varubdualvals, NULL) );
3229  assert(primalvals != NULL || nlp->nvars == 0);
3230  assert((varlbdualvals != NULL) == (varubdualvals != NULL)); /* if there are duals for one bound, then there should also be duals for the other bound */
3231 
3232  /* store solution primal values in variable and evaluate objective function */
3233  if( nlp->indiving && nlp->divingobj != NULL )
3234  {
3235  for( i = 0; i < nlp->nvars; ++i )
3236  {
3237  SCIP_CALL( SCIPvarSetNLPSol(nlp->vars[i], set, primalvals[nlp->varmap_nlp2nlpi[i]]) ); /*lint !e613 */
3238  }
3239 
3240  /* evaluate modified diving objective */
3241  SCIP_CALL( SCIPnlrowGetNLPActivity(nlp->divingobj, blkmem, set, stat, primal, tree, nlp, &nlp->primalsolobjval) );
3242  }
3243  else
3244  {
3245  /* evaluate SCIP objective function */
3246  nlp->primalsolobjval = 0.0;
3247  for( i = 0; i < nlp->nvars; ++i )
3248  {
3249  SCIP_Real solval = primalvals[nlp->varmap_nlp2nlpi[i]]; /*lint !e613 */
3250 
3251  /* do a quick assert that variable bounds are satisfied, if feasibility is claimed */
3252  assert(SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(nlp->vars[i])) ||
3253  SCIPsetIsFeasGE(set, solval, SCIPvarGetLbLocal(nlp->vars[i])) || nlp->solstat > SCIP_NLPSOLSTAT_FEASIBLE);
3254  assert(SCIPsetIsInfinity(set, SCIPvarGetUbLocal(nlp->vars[i])) ||
3255  SCIPsetIsFeasLE(set, solval, SCIPvarGetUbLocal(nlp->vars[i])) || nlp->solstat > SCIP_NLPSOLSTAT_FEASIBLE);
3256 
3257  SCIP_CALL( SCIPvarSetNLPSol(nlp->vars[i], set, solval) ); /*lint !e613 */
3258  nlp->primalsolobjval += SCIPvarGetObj(nlp->vars[i]) * solval; /*lint !e613 */
3259  }
3260  }
3261 
3262  /* store solution dual values in nlrows and variables */
3263  for( i = 0; i < nlp->nnlrows; ++i )
3264  {
3265  assert(nlp->nlrows[i]->nlpiindex >= 0); /* NLP was flushed before solve, so all nlrows should be in there */
3266 
3267  nlp->nlrows[i]->dualsol = nlrowdualvals != NULL ? nlrowdualvals[nlp->nlrows[i]->nlpiindex] : 0.0;
3268 
3269  /* SCIPsetDebugMsg(set, "dual of nlrow <%s> = %g\n", nlp->nlrows[i]->name, nlp->nlrows[i]->dualsol); */
3270  }
3271  assert(nlp->varlbdualvals != NULL || nlp->nvars == 0);
3272  assert(nlp->varubdualvals != NULL || nlp->nvars == 0);
3273  if( varlbdualvals != NULL )
3274  {
3275  for( i = 0; i < nlp->nvars; ++i )
3276  {
3277  assert(nlp->varmap_nlp2nlpi[i] >= 0); /* NLP was flushed before solve, so all vars should be in there */
3278 
3279  nlp->varlbdualvals[i] = varlbdualvals[nlp->varmap_nlp2nlpi[i]];
3280  nlp->varubdualvals[i] = varubdualvals[nlp->varmap_nlp2nlpi[i]];
3281 
3282  /* SCIPsetDebugMsg(set, "duals of var <%s> = %g %g\n", SCIPvarGetName(nlp->vars[i]), nlp->varlbdualvals[i], nlp->varubdualvals[i]); */
3283  }
3284  }
3285  else if( nlp->nvars > 0 )
3286  {
3289  }
3290 
3291  break;
3292  }
3293  default:
3295  break;
3296  } /*lint !e788*/
3297 
3298  return SCIP_OKAY;
3299 }
3300 
3301 /** assembles list of fractional variables in last NLP solution */
3302 static
3304  SCIP_NLP* nlp, /**< NLP data */
3305  BMS_BLKMEM* blkmem, /**< block memory buffers */
3306  SCIP_SET* set, /**< global SCIP settings */
3307  SCIP_STAT* stat /**< problem statistics */
3308  )
3309 {
3310  assert(nlp != NULL);
3311  assert(blkmem != NULL);
3312  assert(set != NULL);
3313  assert(stat != NULL);
3314  assert(nlp->validfracvars <= stat->nnlps);
3315  assert(SCIPnlpHasSolution(nlp));
3316 
3317  SCIPsetDebugMsg(set, "calculating NLP fractional variables: validfracvars=%" SCIP_LONGINT_FORMAT ", nnlps=%" SCIP_LONGINT_FORMAT "\n", nlp->validfracvars, stat->nnlps);
3318 
3320  {
3321  nlp->nfracvars = 0;
3322  nlp->npriofracvars = 0;
3323  nlp->validfracvars = stat->nnlps;
3324 
3325  SCIPsetDebugMsg(set, "NLP globally infeasible, unbounded, or worse -> no solution values -> no fractional variables\n");
3326  return SCIP_OKAY;
3327  }
3328 
3329  /* check, if the current NLP fractional variables array is invalid */
3330  if( nlp->validfracvars < stat->nnlps )
3331  {
3332  SCIP_VAR* var;
3333  SCIP_Real primsol;
3334  SCIP_Real frac;
3335  int branchpriority;
3336  int insertpos;
3337  int maxpriority;
3338  int i;
3339 
3340  SCIPsetDebugMsg(set, " -> recalculating NLP fractional variables\n");
3341 
3342  if( nlp->fracvarssize == 0 )
3343  {
3344  assert(nlp->fracvars == NULL);
3345  assert(nlp->fracvarssol == NULL);
3346  assert(nlp->fracvarsfrac == NULL);
3347  nlp->fracvarssize = 5;
3348  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &nlp->fracvars, nlp->fracvarssize) );
3351  }
3352 
3353  maxpriority = INT_MIN;
3354  nlp->nfracvars = 0;
3355  nlp->npriofracvars = 0;
3356  for( i = 0; i < nlp->nvars; ++i )
3357  {
3358  var = nlp->vars[i];
3359  assert(var != NULL);
3360 
3361  primsol = SCIPvarGetNLPSol(var);
3362  assert(primsol < SCIP_INVALID);
3363 
3364  /* consider only binary and integer variables */
3366  continue;
3367 
3368  /* ignore fixed variables (due to numerics, it is possible, that the NLP solution of a fixed integer variable
3369  * (with large fixed value) is fractional in terms of absolute feasibility measure)
3370  */
3371  if( SCIPvarGetLbLocal(var) >= SCIPvarGetUbLocal(var) - 0.5 )
3372  continue;
3373 
3374  /* check, if the LP solution value is fractional */
3375  frac = SCIPsetFeasFrac(set, primsol);
3376 
3377  /* The fractionality should not be smaller than -feastol, however, if the primsol is large enough
3378  * and close to an integer, fixed precision floating point arithmetic might give us values slightly
3379  * smaller than -feastol. Originally, the "frac >= -feastol"-check was within SCIPsetIsFeasFracIntegral(),
3380  * however, we relaxed it to "frac >= -2*feastol" and have the stricter check here for small-enough primsols.
3381  */
3382  assert(SCIPsetIsGE(set, frac, -SCIPsetFeastol(set)) || (primsol > 1e14 * SCIPsetFeastol(set)));
3383 
3384  if( SCIPsetIsFeasFracIntegral(set, frac) )
3385  continue;
3386 
3387  /* ensure enough space in fracvars arrays */
3388  if( nlp->fracvarssize <= nlp->nfracvars )
3389  {
3390  int newsize;
3391 
3392  newsize = SCIPsetCalcMemGrowSize(set, nlp->nfracvars + 1);
3393  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &nlp->fracvars, nlp->fracvarssize, newsize) );
3394  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &nlp->fracvarssol, nlp->fracvarssize, newsize) );
3395  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &nlp->fracvarsfrac, nlp->fracvarssize, newsize) );
3396  nlp->fracvarssize = newsize;
3397  }
3398  assert(nlp->nfracvars < nlp->fracvarssize);
3399  assert(nlp->fracvars != NULL);
3400  assert(nlp->fracvarssol != NULL);
3401  assert(nlp->fracvarsfrac != NULL);
3402 
3403  /* insert candidate in candidate list */
3404  branchpriority = SCIPvarGetBranchPriority(var);
3405  insertpos = nlp->nfracvars;
3406  nlp->nfracvars++;
3407  if( branchpriority > maxpriority )
3408  {
3409  /* candidate has higher priority than the current maximum:
3410  * move it to the front and declare it to be the single best candidate
3411  */
3412  if( insertpos != 0 )
3413  {
3414  nlp->fracvars[insertpos] = nlp->fracvars[0];
3415  nlp->fracvarssol[insertpos] = nlp->fracvarssol[0];
3416  nlp->fracvarsfrac[insertpos] = nlp->fracvarsfrac[0];
3417  insertpos = 0;
3418  }
3419  nlp->npriofracvars = 1;
3420  maxpriority = branchpriority;
3421  }
3422  else if( branchpriority == maxpriority )
3423  {
3424  /* candidate has equal priority as the current maximum:
3425  * move away the first non-maximal priority candidate, move the current candidate to the correct
3426  * slot (binaries first) and increase the number of maximal priority candidates
3427  */
3428  if( insertpos != nlp->npriofracvars )
3429  {
3430  nlp->fracvars[insertpos] = nlp->fracvars[nlp->npriofracvars];
3431  nlp->fracvarssol[insertpos] = nlp->fracvarssol[nlp->npriofracvars];
3432  nlp->fracvarsfrac[insertpos] = nlp->fracvarsfrac[nlp->npriofracvars];
3433  insertpos = nlp->npriofracvars;
3434  }
3435  ++nlp->npriofracvars;
3436  }
3437  nlp->fracvars[insertpos] = var;
3438  nlp->fracvarssol[insertpos] = primsol;
3439  nlp->fracvarsfrac[insertpos] = frac;
3440 
3441  SCIPsetDebugMsg(set, " -> candidate %d: var=<%s>, sol=%g, frac=%g, prio=%d (max: %d) -> pos %d\n",
3442  nlp->nfracvars, SCIPvarGetName(var), primsol, frac, branchpriority, maxpriority, insertpos);
3443  }
3444 
3445  nlp->validfracvars = stat->nnlps;
3446  }
3447  assert(0 <= nlp->npriofracvars);
3448  assert(nlp->npriofracvars <= nlp->nfracvars);
3449 
3450  SCIPsetDebugMsg(set, " -> %d fractional variables (%d of maximal priority)\n", nlp->nfracvars, nlp->npriofracvars);
3451 
3452  return SCIP_OKAY;
3453 }
3454 
3455 /** event handling for variable events */
3456 static
3457 SCIP_DECL_EVENTEXEC(eventExecNlp)
3458 {
3459  SCIP_EVENTTYPE etype;
3460  SCIP_VAR* var;
3461 
3462  assert(scip != NULL);
3463  assert(eventhdlr != NULL);
3464  assert(event != NULL);
3465  assert(eventdata != NULL);
3466 
3467  assert((SCIP_NLP*)eventdata == scip->nlp);
3468 
3469  etype = SCIPeventGetType(event);
3470  var = SCIPeventGetVar(event);
3471 
3472  if( SCIP_EVENTTYPE_VARADDED & etype )
3473  {
3474  SCIPdebugMessage("-> handling varadd event, variable <%s>\n", SCIPvarGetName(var) );
3475  SCIP_CALL( SCIPnlpAddVar(scip->nlp, SCIPblkmem(scip), scip->set, var) );
3476  }
3477  else if( SCIP_EVENTTYPE_VARDELETED & etype )
3478  {
3479  SCIPdebugMessage("-> handling vardel event, variable <%s>\n", SCIPvarGetName(var) );
3480  SCIP_CALL( SCIPnlpDelVar(scip->nlp, SCIPblkmem(scip), scip->set, scip->stat, scip->eventqueue, scip->lp, var) );
3481  }
3482  else if( SCIP_EVENTTYPE_VARFIXED & etype )
3483  {
3484  /* variable was fixed, aggregated, or multi-aggregated */
3485  /* TODO is this ever happening? that is, can we have changes in a variable status during solve? */
3486  SCIPdebugMessage("-> handling variable fixation event, variable <%s>\n", SCIPvarGetName(var) );
3487  SCIP_CALL( nlpRemoveFixedVar(scip->nlp, SCIPblkmem(scip), scip->set, scip->stat, scip->eventqueue, scip->lp, var) );
3488  }
3489  else if( SCIP_EVENTTYPE_BOUNDCHANGED & etype )
3490  {
3491  SCIPdebugMessage("-> handling bound changed event %" SCIP_EVENTTYPE_FORMAT ", variable <%s>\n", etype, SCIPvarGetName(var) );
3493  }
3494  else if( SCIP_EVENTTYPE_OBJCHANGED & etype )
3495  {
3496  SCIPdebugMessage("-> handling objchg event, variable <%s>\n", SCIPvarGetName(var) );
3497  SCIP_CALL( nlpUpdateObjCoef(scip->set, scip->nlp, var) );
3498  }
3499  else
3500  {
3501  SCIPerrorMessage("unexpected event %" SCIP_EVENTTYPE_FORMAT " on variable <%s>\n", etype, SCIPvarGetName(var) );
3502  return SCIP_ERROR;
3503  }
3504 
3505  return SCIP_OKAY;
3506 }
3507 
3508 
3509 /*
3510  * public NLP methods
3511  */
3512 
3513 /** includes event handler that is used by NLP */
3515  SCIP_SET* set, /**< global SCIP settings */
3516  BMS_BLKMEM* blkmem /**< block memory */
3517  )
3518 {
3519  SCIP_EVENTHDLR* eventhdlr;
3520 
3521  assert(set != NULL);
3522  assert(blkmem != NULL);
3523  assert(set->stage == SCIP_STAGE_INIT);
3524 
3525  /* check whether event handler is already present */
3527  {
3528  SCIPerrorMessage("event handler <" EVENTHDLR_NAME "> already included.\n");
3529  return SCIP_INVALIDDATA;
3530  }
3531 
3533  NULL, NULL, NULL, NULL, NULL, NULL, NULL, eventExecNlp, NULL) );
3534  SCIP_CALL( SCIPsetIncludeEventhdlr(set, eventhdlr) );
3535 
3536  return SCIP_OKAY;
3537 } /*lint !e715*/
3538 
3539 /** construct a new empty NLP */
3541  SCIP_NLP** nlp, /**< NLP handler, call by reference */
3542  BMS_BLKMEM* blkmem, /**< block memory */
3543  SCIP_SET* set, /**< global SCIP settings */
3544  SCIP_STAT* stat, /**< problem statistics */
3545  const char* name, /**< problem name */
3546  int nvars_estimate /**< an estimate on the number of variables that may be added to the NLP later */
3547  )
3548 {
3549  assert(nlp != NULL);
3550  assert(blkmem != NULL);
3551  assert(set != NULL);
3552  assert(stat != NULL);
3553  assert(name != NULL);
3554 
3555  SCIP_ALLOC( BMSallocMemory(nlp) );
3556 
3557  /* select NLP solver (if any available) and setup problem */
3558  if( set->nnlpis > 0 )
3559  {
3560  assert(set->nlp_solver != NULL);
3561  if( set->nlp_solver[0] == '\0' )
3562  { /* take solver with highest priority */
3563  assert(set->nlpis != NULL);
3564 
3565  /* sort the NLPIs if necessary */
3566  if( !set->nlpissorted )
3567  SCIPsetSortNlpis(set);
3568 
3569  (*nlp)->solver = set->nlpis[0];
3570  }
3571  else
3572  { /* find user specified NLP solver */
3573  (*nlp)->solver = SCIPsetFindNlpi(set, set->nlp_solver);
3574  if( (*nlp)->solver == NULL )
3575  {
3576  SCIPerrorMessage("Selected NLP solver <%s> not available.\n", set->nlp_solver);
3577  return SCIP_PLUGINNOTFOUND;
3578  }
3579  }
3580  assert((*nlp)->solver != NULL);
3581  SCIP_CALL( SCIPnlpiCreateProblem(set, (*nlp)->solver, &(*nlp)->problem, name) );
3582  }
3583  else
3584  {
3585  /* maybe someone wanna use the NLP just to collect nonlinearities, but is not necessarily interesting on solving
3586  * so we allow this and just continue */
3587  (*nlp)->solver = NULL;
3588  (*nlp)->problem = NULL;
3589  }
3590 
3591  /* status */
3592  (*nlp)->nunflushedvaradd = 0;
3593  (*nlp)->nunflushedvardel = 0;
3594  (*nlp)->nunflushednlrowadd = 0;
3595  (*nlp)->nunflushednlrowdel = 0;
3596  (*nlp)->indiving = FALSE;
3597 
3598  /* variables in problem and NLPI problem */
3599  (*nlp)->nvars = 0;
3600  (*nlp)->sizevars = 0;
3601  (*nlp)->vars = NULL;
3602  SCIP_CALL( SCIPhashmapCreate(&(*nlp)->varhash, blkmem, nvars_estimate) );
3603 
3604  (*nlp)->nvars_solver = 0;
3605  (*nlp)->sizevars_solver = 0;
3606  (*nlp)->varmap_nlp2nlpi = NULL;
3607  (*nlp)->varmap_nlpi2nlp = NULL;
3608 
3609  /* nonlinear rows in problem and NLPI problem */
3610  (*nlp)->nnlrows = 0;
3611  (*nlp)->sizenlrows = 0;
3612  (*nlp)->nlrows = NULL;
3613  (*nlp)->nnlrowlinear = 0;
3614  (*nlp)->nnlrowconvexineq = 0;
3615  (*nlp)->nnlrownonconvexineq = 0;
3616  (*nlp)->nnlrownonlineareq = 0;
3617 
3618  (*nlp)->nnlrows_solver = 0;
3619  (*nlp)->sizenlrows_solver = 0;
3620  (*nlp)->nlrowmap_nlpi2nlp = NULL;
3621 
3622  /* objective function */
3623  (*nlp)->objflushed = TRUE;
3624  (*nlp)->divingobj = NULL;
3625 
3626  /* initial guess */
3627  (*nlp)->haveinitguess = FALSE;
3628  (*nlp)->initialguess = NULL;
3629 
3630  /* solution of NLP */
3631  (*nlp)->primalsolobjval = SCIP_INVALID;
3632  (*nlp)->solstat = SCIP_NLPSOLSTAT_UNKNOWN;
3633  (*nlp)->termstat = SCIP_NLPTERMSTAT_OTHER;
3634  (*nlp)->varlbdualvals = NULL;
3635  (*nlp)->varubdualvals = NULL;
3636 
3637  /* event handling: catch variable addition and deletion events */
3638  (*nlp)->eventhdlr = SCIPsetFindEventhdlr(set, EVENTHDLR_NAME);
3639  if( (*nlp)->eventhdlr == NULL )
3640  {
3641  SCIPerrorMessage("NLP eventhandler <" EVENTHDLR_NAME "> not found.\n");
3642  return SCIP_PLUGINNOTFOUND;
3643  }
3644  SCIP_CALL( SCIPeventfilterAdd(set->scip->eventfilter, blkmem, set,
3646  (*nlp)->eventhdlr, (SCIP_EVENTDATA*)(*nlp), &(*nlp)->globalfilterpos) );
3647 
3648  /* fractional variables in last NLP solution */
3649  (*nlp)->fracvars = NULL;
3650  (*nlp)->fracvarssol = NULL;
3651  (*nlp)->fracvarsfrac = NULL;
3652  (*nlp)->nfracvars = 0;
3653  (*nlp)->npriofracvars = 0;
3654  (*nlp)->fracvarssize = 0;
3655  (*nlp)->validfracvars = -1;
3656 
3657  /* miscellaneous */
3658  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*nlp)->name, name, strlen(name)+1) );
3659 
3660  return SCIP_OKAY;
3661 }
3662 
3663 /** frees NLP data object */
3665  SCIP_NLP** nlp, /**< pointer to NLP data object */
3666  BMS_BLKMEM* blkmem, /**< block memory */
3667  SCIP_SET* set, /**< global SCIP settings */
3668  SCIP_STAT* stat, /**< problem statistics */
3669  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3670  SCIP_LP* lp /**< SCIP LP, needed for releasing variables */
3671  )
3672 {
3673  assert(nlp != NULL);
3674  assert(*nlp != NULL);
3675  assert(blkmem != NULL);
3676  assert(set != NULL);
3677 
3678  /* drop fractional variables */
3679  BMSfreeBlockMemoryArrayNull(blkmem, &(*nlp)->fracvars, (*nlp)->fracvarssize);
3680  BMSfreeBlockMemoryArrayNull(blkmem, &(*nlp)->fracvarssol, (*nlp)->fracvarssize);
3681  BMSfreeBlockMemoryArrayNull(blkmem, &(*nlp)->fracvarsfrac, (*nlp)->fracvarssize);
3682 
3683  /* drop global events (variable addition and deletion) */
3684  SCIP_CALL( SCIPeventfilterDel(set->scip->eventfilter, blkmem, set,
3686  (*nlp)->eventhdlr, (SCIP_EVENTDATA*)(*nlp), (*nlp)->globalfilterpos) );
3687 
3688  SCIP_CALL( SCIPnlpReset(*nlp, blkmem, set, stat, eventqueue, lp) );
3689  assert((*nlp)->nnlrows == 0);
3690  assert((*nlp)->nnlrows_solver == 0);
3691  assert((*nlp)->nvars == 0);
3692  assert((*nlp)->nvars_solver == 0);
3693  assert((*nlp)->initialguess == NULL);
3694 
3695  BMSfreeBlockMemoryArray(blkmem, &(*nlp)->name, strlen((*nlp)->name)+1);
3696 
3697  /* free nonlinear rows arrays */
3698  BMSfreeBlockMemoryArrayNull(blkmem, &(*nlp)->nlrowmap_nlpi2nlp, (*nlp)->sizenlrows_solver);
3699  BMSfreeBlockMemoryArrayNull(blkmem, &(*nlp)->nlrows, (*nlp)->sizenlrows);
3700 
3701  /* free variables arrays */
3702  BMSfreeBlockMemoryArrayNull(blkmem, &(*nlp)->varmap_nlp2nlpi, (*nlp)->sizevars);
3703  BMSfreeBlockMemoryArrayNull(blkmem, &(*nlp)->varmap_nlpi2nlp, (*nlp)->sizevars_solver);
3704  SCIPhashmapFree(&(*nlp)->varhash);
3705  BMSfreeBlockMemoryArrayNull(blkmem, &(*nlp)->vars, (*nlp)->sizevars);
3706  BMSfreeBlockMemoryArrayNull(blkmem, &(*nlp)->varlbdualvals, (*nlp)->sizevars);
3707  BMSfreeBlockMemoryArrayNull(blkmem, &(*nlp)->varubdualvals, (*nlp)->sizevars);
3708 
3709  /* free NLPI problem */
3710  if( (*nlp)->problem != NULL )
3711  {
3712  SCIP_CALL( SCIPnlpiFreeProblem(set, (*nlp)->solver, &(*nlp)->problem) );
3713  }
3714 
3715  /* free NLP data structure */
3716  BMSfreeMemory(nlp);
3717 
3718  return SCIP_OKAY;
3719 }
3720 
3721 /** resets the NLP to the empty NLP by removing all variables and rows from NLP,
3722  * releasing all rows, and flushing the changes to the NLP solver
3723  */
3725  SCIP_NLP* nlp, /**< NLP data */
3726  BMS_BLKMEM* blkmem, /**< block memory */
3727  SCIP_SET* set, /**< global SCIP settings */
3728  SCIP_STAT* stat, /**< problem statistics data */
3729  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3730  SCIP_LP* lp /**< SCIP LP, needed for releasing variables */
3731  )
3732 {
3733  int i;
3734 
3735  assert(nlp != NULL);
3736  assert(blkmem != NULL);
3737  assert(set != NULL);
3738 
3739  if( nlp->indiving )
3740  {
3741  SCIP_CALL( SCIPnlpEndDive(nlp, blkmem, set, stat) );
3742  }
3743 
3746 
3747  BMSfreeBlockMemoryArrayNull(blkmem, &nlp->initialguess, nlp->sizevars);
3748  nlp->haveinitguess = FALSE;
3749 
3750  for(i = nlp->nnlrows - 1; i >= 0; --i)
3751  {
3752  SCIP_CALL( nlpDelNlRowPos(nlp, blkmem, set, stat, i) );
3753  }
3754 
3755  for(i = nlp->nvars - 1; i >= 0; --i)
3756  {
3757  SCIP_CALL( nlpDelVarPos(nlp, blkmem, set, stat, eventqueue, lp, i) );
3758  }
3759 
3760  SCIP_CALL( SCIPnlpFlush(nlp, blkmem, set, stat) );
3761 
3762  return SCIP_OKAY;
3763 }
3764 
3765 /** currently a dummy function that always returns TRUE */
3767  SCIP_NLP* nlp /**< NLP data */
3768  )
3769 {
3770  assert(nlp != NULL);
3771  return TRUE;
3772 } /*lint !e715*/
3773 
3774 /** ensures, that variables array of NLP can store at least num entries */
3776  SCIP_NLP* nlp, /**< NLP data */
3777  BMS_BLKMEM* blkmem, /**< block memory */
3778  SCIP_SET* set, /**< global SCIP settings */
3779  int num /**< minimum number of entries to store */
3780  )
3781 {
3782  assert(nlp != NULL);
3783  assert(blkmem != NULL);
3784  assert(set != NULL);
3785  assert(nlp->nvars <= nlp->sizevars);
3786 
3787  if( num > nlp->sizevars )
3788  {
3789  int newsize;
3790 
3791  newsize = SCIPsetCalcMemGrowSize(set, num);
3792  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &nlp->vars, nlp->sizevars, newsize) );
3793  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &nlp->varmap_nlp2nlpi, nlp->sizevars, newsize) );
3794  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &nlp->varlbdualvals, nlp->sizevars, newsize) );
3795  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &nlp->varubdualvals, nlp->sizevars, newsize) );
3796  if( nlp->initialguess != NULL )
3797  {
3798  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &nlp->initialguess, nlp->sizevars, newsize) );
3799  }
3800 
3801  nlp->sizevars = newsize;
3802  }
3803  assert(num <= nlp->sizevars);
3804 
3805  return SCIP_OKAY;
3806 }
3807 
3808 /** adds a variable to the NLP and captures the variable */
3810  SCIP_NLP* nlp, /**< NLP data */
3811  BMS_BLKMEM* blkmem, /**< block memory */
3812  SCIP_SET* set, /**< global SCIP settings */
3813  SCIP_VAR* var /**< variable */
3814  )
3815 {
3816  assert(nlp != NULL);
3817  assert(blkmem != NULL);
3818  assert(set != NULL);
3819  assert(var != NULL);
3820  assert(SCIPvarIsTransformed(var));
3821  assert(!SCIPhashmapExists(nlp->varhash, var));
3822 
3823  if( nlp->indiving )
3824  {
3825  SCIPerrorMessage("cannot add variable during NLP diving\n");
3826  return SCIP_ERROR;
3827  }
3828 
3829  SCIP_CALL( nlpAddVars(nlp, blkmem, set, 1, &var) );
3830 
3831  return SCIP_OKAY;
3832 }
3833 
3834 /** adds a set of variables to the NLP and captures the variables */
3836  SCIP_NLP* nlp, /**< NLP data */
3837  BMS_BLKMEM* blkmem, /**< block memory */
3838  SCIP_SET* set, /**< global SCIP settings */
3839  int nvars, /**< number of variables to add */
3840  SCIP_VAR** vars /**< variables to add */
3841  )
3842 {
3843  assert(nlp != NULL);
3844  assert(blkmem != NULL);
3845  assert(set != NULL);
3846  assert(vars != NULL || nvars == 0);
3847 
3848  if( nlp->indiving && nvars > 0)
3849  {
3850  SCIPerrorMessage("cannot add variables during NLP diving\n");
3851  return SCIP_ERROR;
3852  }
3853 
3854  SCIP_CALL( nlpAddVars(nlp, blkmem, set, nvars, vars) );
3855 
3856  return SCIP_OKAY;
3857 }
3858 
3859 /** deletes a variable from the NLP and releases the variable */
3861  SCIP_NLP* nlp, /**< NLP data */
3862  BMS_BLKMEM* blkmem, /**< block memory */
3863  SCIP_SET* set, /**< global SCIP settings */
3864  SCIP_STAT* stat, /**< problem statistics data */
3865  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3866  SCIP_LP* lp, /**< SCIP LP, needed to release variable */
3867  SCIP_VAR* var /**< variable */
3868  )
3869 {
3870  int varpos;
3871 
3872  assert(nlp != NULL);
3873  assert(blkmem != NULL);
3874  assert(set != NULL);
3875  assert(var != NULL);
3876 
3877  if( !SCIPhashmapExists(nlp->varhash, var) )
3878  {
3879  SCIPerrorMessage("variable <%s> not found in NLP, cannot delete\n", SCIPvarGetName(var));
3880  return SCIP_ERROR;
3881  }
3882 
3883  if( nlp->indiving )
3884  {
3885  SCIPerrorMessage("cannot delete variable during NLP diving\n");
3886  return SCIP_ERROR;
3887  }
3888 
3889  varpos = SCIPhashmapGetImageInt(nlp->varhash, var);
3890 
3891  SCIP_CALL( nlpDelVarPos(nlp, blkmem, set, stat, eventqueue, lp, varpos) );
3892 
3893  return SCIP_OKAY;
3894 }
3895 
3896 /** ensures, that nonlinear rows array of NLP can store at least num entries */
3898  SCIP_NLP* nlp, /**< NLP data */
3899  BMS_BLKMEM* blkmem, /**< block memory */
3900  SCIP_SET* set, /**< global SCIP settings */
3901  int num /**< minimum number of entries to store */
3902  )
3903 {
3904  assert(nlp != NULL);
3905  assert(blkmem != NULL);
3906  assert(set != NULL);
3907  assert(nlp->nnlrows <= nlp->sizenlrows);
3908 
3909  if( num > nlp->sizenlrows )
3910  {
3911  int newsize;
3912 
3913  newsize = SCIPsetCalcMemGrowSize(set, num);
3914  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &nlp->nlrows, nlp->sizenlrows, newsize) );
3915 
3916  nlp->sizenlrows = newsize;
3917  }
3918  assert(num <= nlp->sizenlrows);
3919 
3920  return SCIP_OKAY;
3921 }
3922 
3923 /** adds a nonlinear row to the NLP and captures it
3924  *
3925  * all variables of the row need to be present in the NLP
3926  */
3928  SCIP_NLP* nlp, /**< NLP data */
3929  BMS_BLKMEM* blkmem, /**< block memory */
3930  SCIP_SET* set, /**< global SCIP settings */
3931  SCIP_STAT* stat, /**< problem statistics data */
3932  SCIP_NLROW* nlrow /**< nonlinear row */
3933  )
3934 {
3935  assert(nlp != NULL);
3936  assert(nlrow != NULL);
3937 
3938  if( nlp->indiving )
3939  {
3940  SCIPerrorMessage("cannot add row during NLP diving\n");
3941  return SCIP_ERROR;
3942  }
3943 
3944  SCIP_CALL( nlpAddNlRows(nlp, blkmem, set, stat, 1, &nlrow) );
3945 
3946  return SCIP_OKAY;
3947 }
3948 
3949 /** adds nonlinear rows to the NLP and captures them
3950  *
3951  * all variables of the row need to be present in the NLP
3952  */
3954  SCIP_NLP* nlp, /**< NLP data */
3955  BMS_BLKMEM* blkmem, /**< block memory */
3956  SCIP_SET* set, /**< global SCIP settings */
3957  SCIP_STAT* stat, /**< problem statistics data */
3958  int nnlrows, /**< number of rows to add */
3959  SCIP_NLROW** nlrows /**< rows to add */
3960  )
3961 {
3962  assert(nlp != NULL);
3963  assert(nlrows != NULL || nnlrows == 0);
3964 
3965  if( nnlrows == 0 )
3966  return SCIP_OKAY;
3967 
3968  if( nlp->indiving )
3969  {
3970  SCIPerrorMessage("cannot add rows during NLP diving\n");
3971  return SCIP_ERROR;
3972  }
3973 
3974  SCIP_CALL( nlpAddNlRows(nlp, blkmem, set, stat, nnlrows, nlrows) );
3975 
3976  return SCIP_OKAY;
3977 }
3978 
3979 /** deletes a nonlinear row from the NLP
3980  *
3981  * does nothing if nonlinear row is not in NLP
3982  */
3984  SCIP_NLP* nlp, /**< NLP data */
3985  BMS_BLKMEM* blkmem, /**< block memory */
3986  SCIP_SET* set, /**< global SCIP settings */
3987  SCIP_STAT* stat, /**< problem statistics data */
3988  SCIP_NLROW* nlrow /**< nonlinear row */
3989  )
3990 {
3991  assert(nlp != NULL);
3992  assert(blkmem != NULL);
3993  assert(set != NULL);
3994  assert(nlrow != NULL);
3995 
3996  /* if row not in NLP, nothing to do */
3997  if( nlrow->nlpindex == -1 )
3998  return SCIP_OKAY;
3999 
4000  assert(nlrow->nlpindex >= 0);
4001  assert(nlrow->nlpindex < nlp->nnlrows);
4002 
4003  if( nlp->indiving )
4004  {
4005  SCIPerrorMessage("cannot delete row during NLP diving\n");
4006  return SCIP_ERROR;
4007  }
4008 
4009  SCIP_CALL( nlpDelNlRowPos(nlp, blkmem, set, stat, nlrow->nlpindex) );
4010 
4011  return SCIP_OKAY;
4012 }
4013 
4014 /** applies all cached changes to the NLP solver */
4016  SCIP_NLP* nlp, /**< current NLP data */
4017  BMS_BLKMEM* blkmem, /**< block memory */
4018  SCIP_SET* set, /**< global SCIP settings */
4019  SCIP_STAT* stat /**< problem statistics */
4020  )
4021 {
4022  assert(nlp != NULL);
4023  assert(blkmem != NULL);
4024  assert(set != NULL);
4025 
4026  if( nlp->indiving )
4027  {
4028  SCIPerrorMessage("cannot flush NLP during NLP diving\n");
4029  return SCIP_ERROR;
4030  }
4031 
4032  /* flush removals of nonlinear rows and variables */
4033  SCIP_CALL( nlpFlushNlRowDeletions(nlp, blkmem, set) );
4034  SCIP_CALL( nlpFlushVarDeletions(nlp, blkmem, set) );
4035  assert(nlp->nunflushednlrowdel == 0);
4036  assert(nlp->nunflushedvardel == 0);
4037 
4038  /* flush addition of variables, objective, and addition of rows */
4039  SCIP_CALL( nlpFlushVarAdditions(nlp, blkmem, set) );
4040  SCIP_CALL( nlpFlushObjective(nlp, blkmem, set) );
4041  SCIP_CALL( nlpFlushNlRowAdditions(nlp, blkmem, set, stat) );
4042  assert(nlp->nunflushedvaradd == 0);
4043  assert(nlp->objflushed == TRUE);
4044  assert(nlp->nunflushednlrowadd == 0);
4045 
4046  assert(nlp->nvars == nlp->nvars_solver);
4047  assert(nlp->nnlrows == nlp->nnlrows_solver);
4048 
4049  return SCIP_OKAY;
4050 }
4051 
4052 /** solves the NLP or diving NLP */
4054  SCIP_NLP* nlp, /**< NLP data */
4055  BMS_BLKMEM* blkmem, /**< block memory buffers */
4056  SCIP_SET* set, /**< global SCIP settings */
4057  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
4058  SCIP_STAT* stat, /**< problem statistics */
4059  SCIP_PRIMAL* primal, /**< primal data */
4060  SCIP_TREE* tree, /**< branch and bound tree */
4061  SCIP_NLPPARAM* nlpparam /**< NLP solve parameters */
4062  )
4063 {
4064  assert(nlp != NULL);
4065  assert(blkmem != NULL);
4066  assert(set != NULL);
4067  assert(stat != NULL);
4068 
4069  if( !nlp->indiving )
4070  {
4071  SCIP_CALL( SCIPnlpFlush(nlp, blkmem, set, stat) );
4072  }
4073 
4074  SCIP_CALL( nlpSolve(nlp, blkmem, set, messagehdlr, stat, primal, tree, nlpparam) );
4075 
4076  return SCIP_OKAY;
4077 }
4078 
4079 /** gets objective value of current NLP */
4081  SCIP_NLP* nlp /**< current NLP data */
4082  )
4083 {
4084  assert(nlp != NULL);
4085 
4086  return nlp->primalsolobjval;
4087 }
4088 
4089 /** gives current pseudo objective value */
4091  SCIP_NLP* nlp, /**< current NLP data */
4092  BMS_BLKMEM* blkmem, /**< block memory */
4093  SCIP_SET* set, /**< global SCIP settings */
4094  SCIP_STAT* stat, /**< problem statistics data */
4095  SCIP_PROB* prob, /**< SCIP problem */
4096  SCIP_PRIMAL* primal, /**< primal data */
4097  SCIP_TREE* tree, /**< branch and bound tree */
4098  SCIP_LP* lp, /**< SCIP LP */
4099  SCIP_Real* pseudoobjval /**< buffer to store pseudo objective value */
4100  )
4101 {
4102  assert(nlp != NULL);
4103  assert(pseudoobjval != NULL);
4104 
4105  if( nlp->divingobj != NULL )
4106  {
4107  assert(nlp->indiving);
4108  SCIP_CALL( SCIPnlrowGetPseudoActivity(nlp->divingobj, blkmem, set, stat, prob, primal, tree, lp, pseudoobjval) );
4109  }
4110  else
4111  {
4112  int i;
4113 
4114  *pseudoobjval = 0.0;
4115  for( i = 0; i < nlp->nvars; ++i )
4116  *pseudoobjval += SCIPvarGetObj(nlp->vars[i]) * SCIPvarGetBestBoundLocal(nlp->vars[i]);
4117  }
4118 
4119  return SCIP_OKAY;
4120 }
4121 
4122 /** gets fractional variables of last NLP solution along with solution values and fractionalities
4123  */
4125  SCIP_NLP* nlp, /**< NLP data structure */
4126  BMS_BLKMEM* blkmem, /**< block memory */
4127  SCIP_SET* set, /**< global SCIP settings */
4128  SCIP_STAT* stat, /**< problem statistics */
4129  SCIP_VAR*** fracvars, /**< pointer to store the array of NLP fractional variables, or NULL */
4130  SCIP_Real** fracvarssol, /**< pointer to store the array of NLP fractional variables solution values, or NULL */
4131  SCIP_Real** fracvarsfrac, /**< pointer to store the array of NLP fractional variables fractionalities, or NULL */
4132  int* nfracvars, /**< pointer to store the number of NLP fractional variables , or NULL */
4133  int* npriofracvars /**< pointer to store the number of NLP fractional variables with maximal branching priority, or NULL */
4134  )
4135 {
4136  assert(nlp != NULL);
4137 
4138  SCIP_CALL( nlpCalcFracVars(nlp, blkmem, set, stat) );
4139  assert(nlp->fracvars != NULL);
4140  assert(nlp->fracvarssol != NULL);
4141  assert(nlp->fracvarsfrac != NULL);
4142 
4143  if( fracvars != NULL )
4144  *fracvars = nlp->fracvars;
4145  if( fracvarssol != NULL )
4146  *fracvarssol = nlp->fracvarssol;
4147  if( fracvarsfrac != NULL )
4148  *fracvarsfrac = nlp->fracvarsfrac;
4149  if( nfracvars != NULL )
4150  *nfracvars = nlp->nfracvars;
4151  if( npriofracvars != NULL )
4152  *npriofracvars = nlp->npriofracvars;
4153 
4154  return SCIP_OKAY;
4155 }
4156 
4157 /** removes all redundant nonlinear rows */
4159  SCIP_NLP* nlp, /**< current NLP data */
4160  BMS_BLKMEM* blkmem, /**< block memory buffers */
4161  SCIP_SET* set, /**< global SCIP settings */
4162  SCIP_STAT* stat /**< problem statistics */
4163  )
4164 {
4165  SCIP_NLPSOLSTAT solstatus;
4166  SCIP_Bool isredundant;
4167  int i;
4168 
4169  assert(nlp != NULL);
4170  assert(blkmem != NULL);
4171  assert(set != NULL);
4172  assert(stat != NULL);
4173 
4174  if( nlp->nnlrows == 0 )
4175  return SCIP_OKAY;
4176 
4177  if( nlp->indiving )
4178  {
4179  SCIPerrorMessage("cannot remove redundant rows during NLP diving\n");
4180  return SCIP_ERROR;
4181  }
4182 
4183  /* removing redundant rows should not change the solution status, so we reset it at the end */
4184  solstatus = nlp->solstat;
4185 
4186  for( i = 0; i < nlp->nnlrows; ++i )
4187  {
4188  SCIP_CALL( SCIPnlrowIsRedundant(nlp->nlrows[i], blkmem, set, stat, &isredundant) );
4189  if( isredundant )
4190  {
4191  SCIP_CALL( nlpDelNlRowPos(nlp, blkmem, set, stat, i) );
4192  }
4193  }
4194 
4195  nlp->solstat = solstatus;
4196 
4197  return SCIP_OKAY;
4198 }
4199 
4200 /** set initial guess (approximate primal solution) for next solve
4201  *
4202  * array initguess must be NULL or have length at least SCIPnlpGetNVars()
4203  */
4205  SCIP_SET* set, /**< global SCIP settings */
4206  SCIP_NLP* nlp, /**< current NLP data */
4207  BMS_BLKMEM* blkmem, /**< block memory buffers */
4208  SCIP_Real* initguess /**< new initial guess, or NULL to clear previous one */
4209  )
4210 {
4211  assert(nlp != NULL);
4212  assert(blkmem != NULL);
4213  assert(nlp->solver != NULL);
4214  assert(nlp->problem != NULL);
4215 
4216  /* if user wants to let NLP solver choose start point, then invalidate current initial guess both in NLP and in NLPI */
4217  if( initguess == NULL )
4218  {
4219  nlp->haveinitguess = FALSE;
4221  return SCIP_OKAY;
4222  }
4223 
4224  if( nlp->initialguess != NULL )
4225  {
4226  BMScopyMemoryArray(nlp->initialguess, initguess, nlp->nvars);
4227  }
4228  else
4229  {
4230  assert( nlp->sizevars >= nlp->nvars );
4231  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &nlp->initialguess, nlp->sizevars) );
4232  BMScopyMemoryArray(nlp->initialguess, initguess, nlp->nvars);
4233  }
4234  nlp->haveinitguess = TRUE;
4235 
4236  return SCIP_OKAY;
4237 }
4238 
4239 /** writes NLP to a file */
4241  SCIP_NLP* nlp, /**< current NLP data */
4242  BMS_BLKMEM* blkmem, /**< block memory buffers */
4243  SCIP_SET* set, /**< global SCIP settings */
4244  SCIP_STAT* stat, /**< problem statistics */
4245  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
4246  const char* fname /**< file name */
4247  )
4248 {
4249  SCIP_RETCODE retcode = SCIP_OKAY;
4250  FILE* file;
4251  int i;
4252 
4253  assert(nlp != NULL);
4254 
4255  if( fname != NULL )
4256  {
4257  file = fopen(fname, "w");
4258  if( file == NULL )
4259  {
4260  SCIPerrorMessage("could not open file <%s> for writing\n", fname);
4261  return SCIP_FILECREATEERROR;
4262  }
4263  }
4264  else
4265  file = stdout;
4266 
4267  SCIPmessageFPrintInfo(messagehdlr, file, "STATISTICS\n");
4268  SCIPmessageFPrintInfo(messagehdlr, file, " NLP name: %s\n", nlp->name);
4269  SCIPmessageFPrintInfo(messagehdlr, file, " Variables: %d\n", nlp->nvars);
4270  SCIPmessageFPrintInfo(messagehdlr, file, " Rows: %d\n", nlp->nnlrows);
4271 
4272  SCIPmessageFPrintInfo(messagehdlr, file, "VARIABLES\n");
4273  for( i = 0; i < nlp->nvars; ++i )
4274  {
4275  SCIP_CALL( SCIPvarPrint(nlp->vars[i], set, messagehdlr, file) );
4276  }
4277 
4278  SCIPmessageFPrintInfo(messagehdlr, file, "NONLINEAR ROWS\n");
4279  for( i = 0; i < nlp->nnlrows; ++i )
4280  {
4281  SCIPmessageFPrintInfo(messagehdlr, file, " ");
4282  SCIP_CALL_TERMINATE( retcode, SCIPnlrowPrint(nlp->nlrows[i], blkmem, set, stat, messagehdlr, file), TERMINATE );
4283  }
4284 
4285  TERMINATE:
4286  if( fname != NULL )
4287  {
4288  fclose(file);
4289  }
4290 
4291  return retcode;
4292 }
4293 
4294 /** gets array with variables of the NLP */
4296  SCIP_NLP* nlp /**< current NLP data */
4297  )
4298 {
4299  assert(nlp != NULL);
4300 
4301  return nlp->vars;
4302 }
4303 
4304 /** gets current number of variables in NLP */
4306  SCIP_NLP* nlp /**< current NLP data */
4307  )
4308 {
4309  assert(nlp != NULL);
4310 
4311  return nlp->nvars;
4312 }
4313 
4314 /** computes for each variables the number of NLP rows in which the variable appears in a nonlinear var */
4316  SCIP_NLP* nlp, /**< current NLP data */
4317  BMS_BLKMEM* blkmem, /**< block memory buffers */
4318  SCIP_SET* set, /**< global SCIP settings */
4319  SCIP_STAT* stat, /**< problem statistics */
4320  int* nlcount /**< an array of length at least SCIPnlpGetNVars() to store nonlinearity counts of variables */
4321  )
4322 {
4323  SCIP_NLROW* nlrow;
4324  SCIP_EXPRITER* it;
4325  SCIP_EXPR* expr;
4326  int varidx;
4327  int c;
4328 
4329  assert(nlp != NULL);
4330  assert(nlcount != NULL || nlp->nvars == 0);
4331 
4332  BMSclearMemoryArray(nlcount, nlp->nvars);
4333 
4334  SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
4335 
4336  for( c = 0; c < nlp->nnlrows; ++c )
4337  {
4338  nlrow = nlp->nlrows[c];
4339  assert(nlrow != NULL);
4340 
4341  if( nlrow->expr == NULL )
4342  continue;
4343 
4345  for( expr = nlrow->expr; !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
4346  {
4347  if( !SCIPexprIsVar(set, expr) )
4348  continue;
4349 
4350  assert(SCIPhashmapExists(nlp->varhash, SCIPgetVarExprVar(expr)));
4351 
4352  varidx = SCIPhashmapGetImageInt(nlp->varhash, SCIPgetVarExprVar(expr));
4353  assert(varidx < nlp->nvars);
4354  assert(nlcount != NULL);
4355  ++nlcount[varidx];
4356  }
4357  }
4358 
4359  SCIPexpriterFree(&it);
4360 
4361  return SCIP_OKAY;
4362 }
4363 
4364 
4365 /** indicates whether there exists a row that contains a continuous variable in a nonlinear term
4366  *
4367  * @note The method may have to touch every row and nonlinear term to compute its result.
4368  */
4370  SCIP_NLP* nlp, /**< current NLP data */
4371  BMS_BLKMEM* blkmem, /**< block memory buffers */
4372  SCIP_SET* set, /**< global SCIP settings */
4373  SCIP_STAT* stat, /**< problem statistics */
4374  SCIP_Bool* result /**< buffer to store whether continuous variable present in an expression of any row */
4375  )
4376 {
4377  SCIP_NLROW* nlrow;
4378  SCIP_EXPRITER* it;
4379  SCIP_EXPR* expr;
4380  int c;
4381 
4382  assert(nlp != NULL);
4383 
4384  SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
4386 
4387  *result = FALSE;
4388  for( c = 0; c < nlp->nnlrows && !*result; ++c )
4389  {
4390  nlrow = nlp->nlrows[c];
4391  assert(nlrow != NULL);
4392 
4393  if( nlrow->expr == NULL )
4394  continue;
4395 
4396  for( expr = SCIPexpriterRestartDFS(it, nlrow->expr); !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
4397  {
4399  {
4400  *result = TRUE;
4401  break;
4402  }
4403  }
4404  }
4405 
4406  SCIPexpriterFree(&it);
4407 
4408  return SCIP_OKAY;
4409 }
4410 
4411 /** gives dual solution values associated with lower bounds of NLP variables */
4413  SCIP_NLP* nlp /**< current NLP data */
4414  )
4415 {
4416  assert(nlp != NULL);
4417 
4418  return nlp->varlbdualvals;
4419 }
4420 
4421 /** gives dual solution values associated with upper bounds of NLP variables */
4423  SCIP_NLP* nlp /**< current NLP data */
4424  )
4425 {
4426  assert(nlp != NULL);
4427 
4428  return nlp->varubdualvals;
4429 }
4430 
4431 /** gets array with nonlinear rows of the NLP */
4433  SCIP_NLP* nlp /**< current NLP data */
4434  )
4435 {
4436  assert(nlp != NULL);
4437 
4438  return nlp->nlrows;
4439 }
4440 
4441 /** gets current number of nonlinear rows in NLP */
4443  SCIP_NLP* nlp /**< current NLP data */
4444  )
4445 {
4446  assert(nlp != NULL);
4447 
4448  return nlp->nnlrows;
4449 }
4450 
4451 /** gets statistics on convexity of nonlinear rows in NLP */
4453  SCIP_NLP* nlp, /**< current NLP data */
4454  int* nlinear, /**< buffer to store number of linear rows in NLP, or NULL */
4455  int* nconvexineq, /**< buffer to store number of convex inequalities in NLP, or NULL */
4456  int* nnonconvexineq, /**< buffer to store number of nonconvex inequalities in NLP, or NULL */
4457  int* nnonlineareq /**< buffer to store number of nonlinear equalities or ranged rows in NLP, or NULL */
4458  )
4459 {
4460  assert(nlp != NULL);
4461 
4462  if( nlinear != NULL )
4463  *nlinear = nlp->nnlrowlinear;
4464 
4465  if( nconvexineq != NULL )
4466  *nconvexineq = nlp->nnlrowconvexineq;
4467 
4468  if( nnonconvexineq != NULL )
4469  *nnonconvexineq = nlp->nnlrownonconvexineq;
4470 
4471  if( nnonlineareq )
4472  *nnonlineareq = nlp->nnlrownonlineareq;
4473 }
4474 
4475 /** gets the NLP solver interface */
4477  SCIP_NLP* nlp /**< current NLP data */
4478  )
4479 {
4480  assert(nlp != NULL);
4481 
4482  return nlp->solver;
4483 }
4484 
4485 /** gets the NLP problem in the solver interface */
4487  SCIP_NLP* nlp /**< current NLP data */
4488  )
4489 {
4490  assert(nlp != NULL);
4491 
4492  return nlp->problem;
4493 }
4494 
4495 /** indicates whether NLP is currently in diving mode */
4497  SCIP_NLP* nlp /**< current NLP data */
4498  )
4499 {
4500  assert(nlp != NULL);
4501 
4502  return nlp->indiving;
4503 }
4504 
4505 /** gets solution status of current NLP */
4507  SCIP_NLP* nlp /**< current NLP data */
4508  )
4509 {
4510  assert(nlp != NULL);
4511 
4512  return nlp->solstat;
4513 }
4514 
4515 /** gets termination status of last NLP solve */
4517  SCIP_NLP* nlp /**< current NLP data */
4518  )
4519 {
4520  assert(nlp != NULL);
4521 
4522  return nlp->termstat;
4523 }
4524 
4525 /** gives statistics (number of iterations, solving time, ...) of last NLP solve */
4527  SCIP_SET* set, /**< global SCIP settings */
4528  SCIP_NLP* nlp, /**< pointer to NLP datastructure */
4529  SCIP_NLPSTATISTICS* statistics /**< pointer to store statistics */
4530  )
4531 {
4532  assert(nlp != NULL);
4533  assert(nlp->solver != NULL);
4534  assert(nlp->problem != NULL);
4535  assert(statistics != NULL);
4536 
4537  SCIP_CALL( SCIPnlpiGetStatistics(set, nlp->solver, nlp->problem, statistics) );
4538 
4539  return SCIP_OKAY;
4540 }
4541 
4542 /** indicates whether a solution for the current NLP is available
4543  *
4544  * The solution may be optimal, feasible, or infeasible.
4545  * Thus, returns whether the NLP solution status is at most \ref SCIP_NLPSOLSTAT_LOCINFEASIBLE.
4546  */
4548  SCIP_NLP* nlp /**< current NLP data */
4549  )
4550 {
4551  assert(nlp != NULL);
4552 
4553  return nlp->solstat <= SCIP_NLPSOLSTAT_LOCINFEASIBLE;
4554 }
4555 
4556 /*
4557  * NLP diving methods
4558  */
4559 
4560 /** signals start of diving */
4562  SCIP_NLP* nlp, /**< current NLP data */
4563  BMS_BLKMEM* blkmem, /**< block memory buffers */
4564  SCIP_SET* set, /**< global SCIP settings */
4565  SCIP_STAT* stat /**< problem statistics */
4566  )
4567 {
4568  assert(nlp != NULL);
4569 
4570  if( nlp->indiving )
4571  {
4572  SCIPerrorMessage("NLP is already in diving mode\n");
4573  return SCIP_ERROR;
4574  }
4575 
4576  if( nlp->solver == NULL )
4577  {
4578  /* In diving mode we do not cache changes but put them directly in the NLPI problem, which does not exist if there is no solver.
4579  * So we forbid diving of no solver is available. */
4580  SCIPerrorMessage("Cannot start diving if no NLP solver is available\n");
4581  return SCIP_ERROR;
4582  }
4583 
4584  SCIP_CALL( SCIPnlpFlush(nlp, blkmem, set, stat) );
4585 
4586  nlp->indiving = TRUE;
4587 
4588  return SCIP_OKAY;
4589 }
4590 
4591 /** resets the bound and objective changes made during diving and disables diving mode */
4593  SCIP_NLP* nlp, /**< current NLP data */
4594  BMS_BLKMEM* blkmem, /**< block memory */
4595  SCIP_SET* set, /**< global SCIP settings */
4596  SCIP_STAT* stat /**< problem statistics data */
4597  )
4598 {
4599  int i;
4600  int* varidx;
4601  SCIP_Real* varlb;
4602  SCIP_Real* varub;
4603 
4604  assert(nlp != NULL);
4605  assert(set != NULL);
4606  assert(nlp->nvars == nlp->nvars_solver);
4607 
4608  if( !nlp->indiving )
4609  {
4610  SCIPerrorMessage("NLP not in diving mode, cannot end dive\n");
4611  return SCIP_ERROR;
4612  }
4613 
4614  assert(nlp->solver != NULL);
4615  assert(nlp->problem != NULL);
4616 
4617  /* reset variable bounds in NLPI problem to their current values */
4618  SCIP_CALL( SCIPsetAllocBufferArray(set, &varidx, nlp->nvars) );
4619  SCIP_CALL( SCIPsetAllocBufferArray(set, &varlb, nlp->nvars) );
4620  SCIP_CALL( SCIPsetAllocBufferArray(set, &varub, nlp->nvars) );
4621  for( i = 0; i < nlp->nvars; ++i )
4622  {
4623  varidx[i] = i;
4624  varlb[i] = SCIPvarGetLbLocal(nlp->vars[nlp->varmap_nlpi2nlp[i]]);
4625  varub[i] = SCIPvarGetUbLocal(nlp->vars[nlp->varmap_nlpi2nlp[i]]);
4626  }
4627 
4628  SCIP_CALL( SCIPnlpiChgVarBounds(set, nlp->solver, nlp->problem, nlp->nvars, varidx, varlb, varub) );
4629 
4630  SCIPsetFreeBufferArray(set, &varidx);
4631  SCIPsetFreeBufferArray(set, &varlb);
4632  SCIPsetFreeBufferArray(set, &varub);
4633 
4634  /* clear diving objective, if one was used (i.e., if SCIPnlpChgVarObjDive had been called)
4635  * the objective in the NLPI will be reset in the next flush */
4636  if( nlp->divingobj != NULL )
4637  {
4638  SCIP_CALL( SCIPnlrowRelease(&nlp->divingobj, blkmem, set, stat) );
4639  assert(nlp->divingobj == NULL);
4640  assert(nlp->objflushed == FALSE);
4641  }
4642 
4643  /* we do not have a valid solution anymore */
4647 
4648  nlp->indiving = FALSE;
4649 
4650  return SCIP_OKAY;
4651 }
4652 
4653 /** changes coefficient of variable in diving NLP */
4655  SCIP_NLP* nlp, /**< current NLP data */
4656  BMS_BLKMEM* blkmem, /**< block memory */
4657  SCIP_SET* set, /**< global SCIP settings */
4658  SCIP_STAT* stat, /**< problem statistics data */
4659  SCIP_VAR* var, /**< variable which coefficient to change */
4660  SCIP_Real coef /**< new linear coefficient of variable in objective */
4661  )
4662 {
4663  int pos;
4664  int objidx;
4665 
4666  assert(nlp != NULL);
4667  assert(var != NULL);
4668  assert(SCIPhashmapExists(nlp->varhash, var));
4669  assert(nlp->indiving);
4670  assert(nlp->solver != NULL);
4671  assert(nlp->problem != NULL);
4672 
4673  /* get position of variable in NLPI problem */
4674  pos = SCIPhashmapGetImageInt(nlp->varhash, var);
4675  pos = nlp->varmap_nlp2nlpi[pos];
4676  assert(pos >= 0);
4677 
4678  /* set coefficient in NLPI problem objective */
4679  objidx = -1;
4680  SCIP_CALL( SCIPnlpiChgLinearCoefs(set, nlp->solver, nlp->problem, objidx, 1, &pos, &coef) );
4681 
4682  /* create an nlrow that holds the diving objective, if not done yet */
4683  if( nlp->divingobj == NULL )
4684  {
4685  SCIP_Real* coefs;
4686  int i;
4687 
4688  SCIP_CALL( SCIPsetAllocBufferArray(set, &coefs, nlp->nvars) );
4689  for( i = 0; i < nlp->nvars; ++i )
4690  coefs[i] = SCIPvarGetObj(nlp->vars[i]);
4691 
4692  SCIP_CALL( SCIPnlrowCreate(&nlp->divingobj, blkmem, set, stat, "divingobj",
4693  0.0, nlp->nvars, nlp->vars, coefs, NULL,
4694  -SCIPsetInfinity(set), SCIPsetInfinity(set),
4696 
4697  SCIPsetFreeBufferArray(set, &coefs);
4698  }
4699  assert(nlp->divingobj != NULL);
4700 
4701  /* modify coefficient in diving objective */
4702  SCIP_CALL( SCIPnlrowChgLinearCoef(nlp->divingobj, blkmem, set, stat, nlp, var, coef) );
4703 
4704  /* remember that we have to store objective after diving ended */
4705  nlp->objflushed = FALSE;
4706 
4707  return SCIP_OKAY;
4708 }
4709 
4710 /** changes bounds of variable in diving NLP */
4712  SCIP_SET* set, /**< global SCIP settings */
4713  SCIP_NLP* nlp, /**< current NLP data */
4714  SCIP_VAR* var, /**< variable which coefficient to change */
4715  SCIP_Real lb, /**< new lower bound of variable */
4716  SCIP_Real ub /**< new upper bound of variable */
4717  )
4718 {
4719  int pos;
4720 
4721  assert(nlp != NULL);
4722  assert(var != NULL);
4723  assert(SCIPhashmapExists(nlp->varhash, var));
4724  assert(nlp->indiving);
4725  assert(nlp->solver != NULL);
4726  assert(nlp->problem != NULL);
4727 
4728  /* get position of variable in NLPI problem */
4729  pos = SCIPhashmapGetImageInt(nlp->varhash, var);
4730  pos = nlp->varmap_nlp2nlpi[pos];
4731  assert(pos >= 0);
4732 
4733  /* set new bounds in NLPI */
4734  SCIP_CALL( SCIPnlpiChgVarBounds(set, nlp->solver, nlp->problem, 1, &pos, &lb, &ub) );
4735 
4736  return SCIP_OKAY;
4737 }
4738 
4739 /** changes bounds of a set of variables in diving NLP */
4741  SCIP_NLP* nlp, /**< current NLP data */
4742  SCIP_SET* set, /**< global SCIP settings */
4743  int nvars, /**< number of variables which bounds to change */
4744  SCIP_VAR** vars, /**< variables which bounds to change */
4745  SCIP_Real* lbs, /**< new lower bounds of variables */
4746  SCIP_Real* ubs /**< new upper bounds of variables */
4747  )
4748 {
4749  int i;
4750  int* poss;
4751 
4752  assert(nlp != NULL);
4753  assert(vars != NULL || nvars == 0);
4754  assert(nlp->indiving);
4755  assert(lbs != NULL || nvars == 0);
4756  assert(ubs != NULL || nvars == 0);
4757  assert(nlp->solver != NULL);
4758  assert(nlp->problem != NULL);
4759 
4760  if( nvars == 0 )
4761  return SCIP_OKAY;
4762 
4763  SCIP_CALL( SCIPsetAllocBufferArray(set, &poss, nvars) );
4764 
4765  for( i = 0; i < nvars; ++i )
4766  {
4767  assert(SCIPhashmapExists(nlp->varhash, vars[i])); /*lint !e613*/
4768 
4769  /* get position of variable in NLPI problem */
4770  poss[i] = SCIPhashmapGetImageInt(nlp->varhash, vars[i]); /*lint !e613*/
4771  poss[i] = nlp->varmap_nlp2nlpi[poss[i]];
4772  assert(poss[i] >= 0);
4773  }
4774 
4775  /* set new bounds in NLPI */
4776  SCIP_CALL( SCIPnlpiChgVarBounds(set, nlp->solver, nlp->problem, nvars, poss, lbs, ubs) );
4777 
4778  SCIPsetFreeBufferArray(set, &poss);
4779 
4780  return SCIP_OKAY;
4781 }
4782 
4783 /** returns whether the objective function has been changed during diving */
4785  SCIP_NLP* nlp /**< current NLP data */
4786  )
4787 {
4788  return nlp->divingobj != NULL;
4789 }
static SCIP_RETCODE nlrowRemoveFixedLinearCoefs(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp)
Definition: nlp.c:772
static SCIP_RETCODE nlrowLinearCoefChanged(SCIP_NLROW *nlrow, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var, SCIP_Real coef, SCIP_NLP *nlp)
Definition: nlp.c:118
SCIP_RETCODE SCIPnlpEndDive(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition: nlp.c:4592
int nfracvars
Definition: struct_nlp.h:160
SCIP_RETCODE SCIPnlpEnsureNlRowsSize(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition: nlp.c:3897
SCIP_Real * fracvarssol
Definition: struct_nlp.h:158
static SCIP_RETCODE nlpEnsureVarsSolverSize(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition: nlp.c:2601
SCIP_Longint validpsactivitydomchg
Definition: struct_nlp.h:89
int * varmap_nlpi2nlp
Definition: struct_nlp.h:122
SCIP_RETCODE SCIPsetIncludeEventhdlr(SCIP_SET *set, SCIP_EVENTHDLR *eventhdlr)
Definition: set.c:4799
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6269
const char * SCIPexprcurvGetName(SCIP_EXPRCURV curv)
Definition: exprcurv.c:586
#define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
Definition: memory.h:468
#define NULL
Definition: def.h:267
internal methods for managing events
SCIP_RETCODE SCIPexpriterInit(SCIP_EXPRITER *iterator, SCIP_EXPR *expr, SCIP_EXPRITER_TYPE type, SCIP_Bool allowrevisit)
Definition: expriter.c:501
enum SCIP_NlpTermStat SCIP_NLPTERMSTAT
Definition: type_nlpi.h:194
internal methods for storing primal CIP solutions
#define SCIP_EVENTTYPE_OBJCHANGED
Definition: type_event.h:74
SCIP_Real * SCIPnlpGetVarsLbDualsol(SCIP_NLP *nlp)
Definition: nlp.c:4412
SCIP_RETCODE SCIPvarSetNLPSol(SCIP_VAR *var, SCIP_SET *set, SCIP_Real solval)
Definition: var.c:14007
SCIP_RETCODE SCIPnlrowDelLinearCoef(SCIP_NLROW *nlrow, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp, SCIP_VAR *var)
Definition: nlp.c:1272
#define SCIP_EVENTTYPE_VARFIXED
Definition: type_event.h:72
SCIP_Real * SCIPvarGetMultaggrScalars(SCIP_VAR *var)
Definition: var.c:17871
static int nlrowSearchLinearCoef(SCIP_NLROW *nlrow, SCIP_VAR *var)
Definition: nlp.c:390
SCIP_RETCODE SCIPnlpDelVar(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_VAR *var)
Definition: nlp.c:3860
SCIP_NLPI * SCIPsetFindNlpi(SCIP_SET *set, const char *name)
Definition: set.c:5235
static SCIP_RETCODE nlpUpdateVarBounds(SCIP_NLP *nlp, SCIP_SET *set, SCIP_VAR *var, SCIP_Bool tightened)
Definition: nlp.c:2200
SCIP_RETCODE SCIPhashmapSetImageInt(SCIP_HASHMAP *hashmap, void *origin, int image)
Definition: misc.c:3357
SCIP_Real SCIPsetFeastol(SCIP_SET *set)
Definition: set.c:6176
SCIP_Bool SCIPintervalIsEntire(SCIP_Real infinity, SCIP_INTERVAL operand)
int linvarssize
Definition: struct_nlp.h:75
SCIP_RETCODE SCIPnlpChgVarBoundsDive(SCIP_SET *set, SCIP_NLP *nlp, SCIP_VAR *var, SCIP_Real lb, SCIP_Real ub)
Definition: nlp.c:4711
SCIP_RETCODE SCIPnlrowEnsureLinearSize(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition: nlp.c:1199
SCIP_NLROW * divingobj
Definition: struct_nlp.h:139
SCIP_Bool warmstart
Definition: type_nlpi.h:77
SCIP_RETCODE SCIPnlrowIsRedundant(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *isredundant)
Definition: nlp.c:1815
SCIP_Bool SCIPnlpIsDiving(SCIP_NLP *nlp)
Definition: nlp.c:4496
SCIP_VAR ** linvars
Definition: struct_nlp.h:76
static SCIP_RETCODE nlrowSimplifyExpr(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp)
Definition: nlp.c:798
internal methods for clocks and timing issues
SCIP_RETCODE SCIPnlpDelNlRow(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLROW *nlrow)
Definition: nlp.c:3983
SCIP_EVENTHDLR * SCIPsetFindEventhdlr(SCIP_SET *set, const char *name)
Definition: set.c:4822
SCIP_VAR ** SCIPvarGetMultaggrVars(SCIP_VAR *var)
Definition: var.c:17859
int SCIProwGetNNonz(SCIP_ROW *row)
Definition: lp.c:17213
#define EVENTHDLR_NAME
Definition: nlp.c:70
SCIP_VAR ** fracvars
Definition: struct_nlp.h:157
SCIP_RETCODE SCIPeventfilterDel(SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition: event.c:1979
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:18135
SCIP_RETCODE SCIPnlrowRecalcPseudoActivity(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_LP *lp)
Definition: nlp.c:1609
int nnlrows
Definition: struct_nlp.h:125
internal methods for NLP solver interfaces
SCIP_RETCODE SCIPexprSimplify(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *rootexpr, SCIP_EXPR **simplified, SCIP_Bool *changed, SCIP_Bool *infeasible, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr.c:3189
int nnlrownonconvexineq
Definition: struct_nlp.h:130
const char * SCIProwGetName(SCIP_ROW *row)
Definition: lp.c:17351
SCIP_RETCODE SCIPnlrowAddLinearCoef(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp, SCIP_VAR *var, SCIP_Real val)
Definition: nlp.c:1224
static SCIP_RETCODE nlpDelNlRowPos(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, int pos)
Definition: nlp.c:2142
SCIP_VAR ** SCIPnlrowGetLinearVars(SCIP_NLROW *nlrow)
Definition: nlp.c:1877
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition: set.c:6134
SCIP_Real SCIPvarGetBestBoundLocal(SCIP_VAR *var)
Definition: var.c:18165
SCIP_NLPSOLSTAT solstat
Definition: struct_nlp.h:147
SCIP_Real * initialguess
Definition: struct_nlp.h:143
SCIP_RETCODE SCIPvarCatchEvent(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: var.c:18559
static SCIP_DECL_EXPR_MAPEXPR(mapvar2varidx)
Definition: nlp.c:171
SCIP_NLPIPROBLEM * problem
Definition: struct_nlp.h:104
SCIP_RETCODE SCIPnlrowChgExpr(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp, SCIP_EXPR *expr)
Definition: nlp.c:1343
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:360
static SCIP_RETCODE nlpFlushVarDeletions(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: nlp.c:2751
private functions to work with algebraic expressions
SCIP_RETCODE SCIPnlrowGetNLPFeasibility(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_NLP *nlp, SCIP_Real *feasibility)
Definition: nlp.c:1586
SCIP_RETCODE SCIPnlrowCreate(SCIP_NLROW **nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, const char *name, SCIP_Real constant, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, SCIP_EXPR *expr, SCIP_Real lhs, SCIP_Real rhs, SCIP_EXPRCURV curvature)
Definition: nlp.c:895
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition: lp.c:17292
#define FALSE
Definition: def.h:94
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:3074
const char * SCIPnlrowGetName(SCIP_NLROW *nlrow)
Definition: nlp.c:1936
SCIP_RETCODE SCIPnlpSetInitialGuess(SCIP_SET *set, SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_Real *initguess)
Definition: nlp.c:4204
SCIP_RETCODE SCIPnlrowRecalcNLPActivity(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_NLP *nlp)
Definition: nlp.c:1504
static SCIP_RETCODE nlpDelVarPos(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, int pos)
Definition: nlp.c:2433
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:290
static SCIP_RETCODE nlrowRemoveFixedVar(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp, SCIP_VAR *var)
Definition: nlp.c:850
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6381
SCIP_Real pseudoactivity
Definition: struct_nlp.h:88
static SCIP_RETCODE nlpCalcFracVars(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition: nlp.c:3303
#define TRUE
Definition: def.h:93
int nvars_solver
Definition: struct_nlp.h:119
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
SCIP_RETCODE SCIPnlpCreate(SCIP_NLP **nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, const char *name, int nvars_estimate)
Definition: nlp.c:3540
int nnlrows_solver
Definition: struct_nlp.h:133
SCIP_Real dualsol
Definition: struct_nlp.h:95
SCIP_RETCODE SCIPhashmapInsertInt(SCIP_HASHMAP *hashmap, void *origin, int image)
Definition: misc.c:3192
SCIP_RETCODE SCIPnlpiGetSolution(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, SCIP_Real **primalvalues, SCIP_Real **consdualvalues, SCIP_Real **varlbdualvalues, SCIP_Real **varubdualvalues, SCIP_Real *objval)
Definition: nlpi.c:653
SCIP_Longint nnlps
Definition: struct_stat.h:214
SCIP_RETCODE SCIPnlpChgVarsBoundsDive(SCIP_NLP *nlp, SCIP_SET *set, int nvars, SCIP_VAR **vars, SCIP_Real *lbs, SCIP_Real *ubs)
Definition: nlp.c:4740
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition: set.h:1748
SCIP_Real SCIPnlrowGetRhs(SCIP_NLROW *nlrow)
Definition: nlp.c:1917
datastructures for NLP management
#define EVENTHDLR_DESC
Definition: nlp.c:71
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:5834
SCIP_RETCODE SCIPnlpiAddConstraints(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, int nconss, const SCIP_Real *lhss, const SCIP_Real *rhss, const int *nlininds, int *const *lininds, SCIP_Real *const *linvals, SCIP_EXPR **exprs, const char **names)
Definition: nlpi.c:325
int SCIPnlrowGetNLinearVars(SCIP_NLROW *nlrow)
Definition: nlp.c:1867
SCIP_NLPTERMSTAT SCIPnlpGetTermstat(SCIP_NLP *nlp)
Definition: nlp.c:4516
SCIP_INTERVAL SCIPexprGetActivity(SCIP_EXPR *expr)
Definition: expr.c:4010
public methods for problem variables
void SCIPintervalSet(SCIP_INTERVAL *resultant, SCIP_Real value)
#define SCIPdebugMessage
Definition: pub_message.h:96
static SCIP_RETCODE nlrowConstantChanged(SCIP_NLROW *nlrow, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp)
Definition: nlp.c:283
int nunflushedvaradd
Definition: struct_nlp.h:107
SCIP_EXPRCURV SCIPnlrowGetCurvature(SCIP_NLROW *nlrow)
Definition: nlp.c:1927
void SCIPintervalAdd(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
SCIP_NLPI * solver
Definition: struct_nlp.h:103
char * name
Definition: struct_nlp.h:84
#define SCIPsetFreeBufferArray(set, ptr)
Definition: set.h:1755
#define BMSfreeMemory(ptr)
Definition: memory.h:145
SCIP_RETCODE SCIPnlrowChgLhs(SCIP_NLROW *nlrow, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp, SCIP_Real lhs)
Definition: nlp.c:1418
SCIP_RETCODE SCIPnlpGetStatistics(SCIP_SET *set, SCIP_NLP *nlp, SCIP_NLPSTATISTICS *statistics)
Definition: nlp.c:4526
#define SCIP_EVENTTYPE_BOUNDCHANGED
Definition: type_event.h:125
int SCIPnlrowGetNLPPos(SCIP_NLROW *nlrow)
Definition: nlp.c:1946
SCIP_CLOCK * nlpsoltime
Definition: struct_stat.h:177
SCIP_Real minactivity
Definition: struct_nlp.h:90
SCIP_NLPTERMSTAT SCIPnlpiGetTermstat(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem)
Definition: nlpi.c:636
SCIP_Bool SCIPsetIsFeasFracIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6821
SCIP_RETCODE SCIPnlrowChgRhs(SCIP_NLROW *nlrow, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp, SCIP_Real rhs)
Definition: nlp.c:1444
int fracvarssize
Definition: struct_nlp.h:162
Definition: heur_padm.c:134
SCIP_RETCODE SCIPnlpiChgVarBounds(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, const int nvars, const int *indices, const SCIP_Real *lbs, const SCIP_Real *ubs)
Definition: nlpi.c:376
SCIP_RETCODE SCIPexprPrint(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_MESSAGEHDLR *messagehdlr, FILE *file, SCIP_EXPR *expr)
Definition: expr.c:2266
SCIP_Longint validfracvars
Definition: struct_nlp.h:163
SCIP_RETCODE SCIPnlpiAddVars(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, int nvars, const SCIP_Real *lbs, const SCIP_Real *ubs, const char **varnames)
Definition: nlpi.c:302
internal methods for collecting primal CIP solutions and primal informations
SCIP_Real SCIPsolGetVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var)
Definition: sol.c:1372
void SCIPexpriterFree(SCIP_EXPRITER **iterator)
Definition: expriter.c:446
public functions to work with algebraic expressions
int sizenlrows
Definition: struct_nlp.h:126
SCIP_Longint validactivitybdsdomchg
Definition: struct_nlp.h:92
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6363
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3423
static SCIP_RETCODE nlrowChgLinearCoefPos(SCIP_NLROW *nlrow, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp, int pos, SCIP_Real coef)
Definition: nlp.c:593
SCIP_RETCODE SCIPnlrowChgConstant(SCIP_NLROW *nlrow, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp, SCIP_Real constant)
Definition: nlp.c:1398
SCIP_Real * varubdualvals
Definition: struct_nlp.h:150
SCIP_RETCODE SCIPnlpiGetStatistics(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, SCIP_NLPSTATISTICS *statistics)
Definition: nlpi.c:675
SCIP_Real rhs
Definition: struct_nlp.h:68
SCIP_RETCODE SCIPnlrowGetActivityBounds(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real *minactivity, SCIP_Real *maxactivity)
Definition: nlp.c:1783
SCIP_Real lhs
Definition: struct_nlp.h:67
static SCIP_RETCODE nlpFlushVarAdditions(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: nlp.c:2995
SCIP_RETCODE SCIPnlrowCreateCopy(SCIP_NLROW **nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLROW *sourcenlrow)
Definition: nlp.c:994
SCIP_Bool SCIPnlpIsDivingObjChanged(SCIP_NLP *nlp)
Definition: nlp.c:4784
SCIP_Bool objflushed
Definition: struct_nlp.h:138
SCIP_Bool SCIPnlrowIsInNLP(SCIP_NLROW *nlrow)
Definition: nlp.c:1956
static SCIP_RETCODE nlpMoveVar(SCIP_NLP *nlp, int oldpos, int newpos)
Definition: nlp.c:2400
SCIP_RETCODE SCIPnlpAddVars(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, int nvars, SCIP_VAR **vars)
Definition: nlp.c:3835
SCIP_Real maxactivity
Definition: struct_nlp.h:91
SCIP_Real * fracvarsfrac
Definition: struct_nlp.h:159
#define BMSduplicateBlockMemoryArray(mem, ptr, source, num)
Definition: memory.h:462
void SCIPnlrowCapture(SCIP_NLROW *nlrow)
Definition: nlp.c:1142
SCIP_RETCODE SCIPnlpiSetInitialGuess(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, SCIP_Real *primalvalues, SCIP_Real *consdualvalues, SCIP_Real *varlbdualvalues, SCIP_Real *varubdualvalues)
Definition: nlpi.c:528
SCIP_RETCODE SCIPeventfilterAdd(SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: event.c:1886
SCIP_Real SCIPexprGetEvalValue(SCIP_EXPR *expr)
Definition: expr.c:3928
handler for variable index expressions
#define SCIPerrorMessage
Definition: pub_message.h:64
SCIP_HASHMAP * varhash
Definition: struct_nlp.h:117
enum SCIP_NlpSolStat SCIP_NLPSOLSTAT
Definition: type_nlpi.h:168
int nlpiindex
Definition: struct_nlp.h:94
SCIP_VAR * SCIPgetVarExprVar(SCIP_EXPR *expr)
Definition: expr_var.c:416
SCIP_EVENTHDLR * eventhdlr
Definition: struct_nlp.h:153
SCIP_RETCODE SCIPvarRelease(SCIP_VAR **var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: var.c:2873
SCIP_RETCODE SCIPexpriterCreate(SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPRITER **iterator)
Definition: expriter.c:427
SCIP_Real * varlbdualvals
Definition: struct_nlp.h:149
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:57
int SCIPnlpGetNNlRows(SCIP_NLP *nlp)
Definition: nlp.c:4442
SCIP_Bool SCIPsortedvecFindPtr(void **ptrarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), void *val, int len, int *pos)
static SCIP_RETCODE nlpFlushObjective(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: nlp.c:3084
SCIP_RETCODE SCIPnlpGetPseudoObjval(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_LP *lp, SCIP_Real *pseudoobjval)
Definition: nlp.c:4090
SCIP_Real SCIPnlpGetObjval(SCIP_NLP *nlp)
Definition: nlp.c:4080
static void nlpMoveNlrow(SCIP_NLP *nlp, int oldpos, int newpos)
Definition: nlp.c:2114
SCIP_NLROW ** SCIPnlpGetNlRows(SCIP_NLP *nlp)
Definition: nlp.c:4432
void SCIPnlrowSetCurvature(SCIP_NLP *nlp, SCIP_SET *set, SCIP_NLROW *nlrow, SCIP_EXPRCURV curvature)
Definition: nlp.c:1470
struct SCIP_EventData SCIP_EVENTDATA
Definition: type_event.h:173
SCIP_EXPRCURV curvature
Definition: struct_nlp.h:96
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17420
SCIP_Real SCIPnlrowGetDualsol(SCIP_NLROW *nlrow)
Definition: nlp.c:1969
static SCIP_RETCODE nlpSetupNlpiIndices(SCIP_NLP *nlp, SCIP_SET *set, SCIP_NLROW *nlrow, int **linidxs)
Definition: nlp.c:2559
internal methods for NLP management
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:3108
static SCIP_RETCODE nlpRowChanged(SCIP_NLP *nlp, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLROW *nlrow)
Definition: nlp.c:1989
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:427
SCIP_Bool SCIPsetIsRelLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:7190
SCIP_Real SCIPintervalGetInf(SCIP_INTERVAL interval)
SCIP_Real SCIPintervalGetSup(SCIP_INTERVAL interval)
void SCIPintervalMulScalar(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_Real operand2)
SCIP_EXPR * expr
Definition: struct_nlp.h:81
SCIP_RETCODE SCIPnlpEnsureVarsSize(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition: nlp.c:3775
#define REALABS(x)
Definition: def.h:197
static SCIP_RETCODE nlpEnsureNlRowsSolverSize(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition: nlp.c:2629
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:380
SCIP_VAR ** vars
Definition: struct_nlp.h:116
SCIP main data structure.
SCIP_Bool SCIPsetIsFeasGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6755
SCIP_Bool SCIPexprIsVar(SCIP_SET *set, SCIP_EXPR *expr)
Definition: expr.c:2206
SCIP_Real SCIPvarGetMultaggrConstant(SCIP_VAR *var)
Definition: var.c:17883
static SCIP_RETCODE nlrowRemoveFixedLinearCoefPos(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp, int pos)
Definition: nlp.c:670
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
Definition: lp.c:17302
SCIP_RETCODE SCIPnlpSolve(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_NLPPARAM *nlpparam)
Definition: nlp.c:4053
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6291
SCIP_RETCODE SCIPnlrowChgLinearCoef(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp, SCIP_VAR *var, SCIP_Real coef)
Definition: nlp.c:1305
static void nlrowAddToStat(SCIP_NLP *nlp, SCIP_SET *set, SCIP_NLROW *nlrow, int incr)
Definition: nlp.c:332
SCIP_RETCODE SCIPnlpChgVarObjDive(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var, SCIP_Real coef)
Definition: nlp.c:4654
SCIP_RETCODE SCIPvarPrint(SCIP_VAR *var, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: var.c:3007
SCIP_RETCODE SCIPnlrowGetPseudoActivity(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_LP *lp, SCIP_Real *pseudoactivity)
Definition: nlp.c:1656
#define SCIP_EVENTTYPE_BOUNDTIGHTENED
Definition: type_event.h:123
SCIP_NLPTERMSTAT termstat
Definition: struct_nlp.h:148
SCIP_Bool SCIPsetIsFeasLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6711
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
Definition: lp.c:17238
SCIP_RETCODE SCIPnlpReset(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: nlp.c:3724
static SCIP_RETCODE nlpAddVars(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, int nvars, SCIP_VAR **vars)
Definition: nlp.c:2321
public methods for NLP management
static SCIP_RETCODE nlrowSideChanged(SCIP_NLROW *nlrow, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp)
Definition: nlp.c:245
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:465
internal methods for problem variables
SCIP_RETCODE SCIPnlpiFreeProblem(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM **problem)
Definition: nlpi.c:266
static SCIP_DECL_EVENTEXEC(eventExecNlp)
Definition: nlp.c:3457
#define SCIP_UNKNOWN
Definition: def.h:194
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
Definition: lp.c:17248
public data structures and miscellaneous methods
SCIP_VAR * SCIPeventGetVar(SCIP_EVENT *event)
Definition: event.c:1053
SCIP_RETCODE SCIPnlpFree(SCIP_NLP **nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: nlp.c:3664
#define SCIP_Bool
Definition: def.h:91
SCIP_EXPR * SCIPexpriterRestartDFS(SCIP_EXPRITER *iterator, SCIP_EXPR *expr)
Definition: expriter.c:630
void SCIPvarCapture(SCIP_VAR *var)
Definition: var.c:2848
SCIP_RETCODE SCIPnlpHasContinuousNonlinearity(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *result)
Definition: nlp.c:4369
static SCIP_RETCODE nlrowAddLinearCoef(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp, SCIP_VAR *var, SCIP_Real coef)
Definition: nlp.c:435
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:454
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
Definition: event.c:1030
static void nlrowSortLinear(SCIP_NLROW *nlrow)
Definition: nlp.c:372
int nnlrowlinear
Definition: struct_nlp.h:128
SCIP_RETCODE SCIPnlrowGetNLPActivity(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_NLP *nlp, SCIP_Real *activity)
Definition: nlp.c:1556
SCIP_Bool SCIPnlpHasCurrentNodeNLP(SCIP_NLP *nlp)
Definition: nlp.c:3766
SCIP_RETCODE SCIPnlpiChgExpr(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, int idxcons, SCIP_EXPR *expr)
Definition: nlpi.c:487
SCIP_NLPSOLSTAT SCIPnlpGetSolstat(SCIP_NLP *nlp)
Definition: nlp.c:4506
SCIP_EXPRCURV
Definition: type_expr.h:60
char * name
Definition: struct_nlp.h:166
SCIP_Real SCIPvarGetNLPSol(SCIP_VAR *var)
Definition: var.c:18466
int SCIPvarGetBranchPriority(SCIP_VAR *var)
Definition: var.c:18251
SCIP_RETCODE SCIPnlpAddNlRow(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLROW *nlrow)
Definition: nlp.c:3927
SCIP_RETCODE SCIPnlrowGetPseudoFeasibility(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_LP *lp, SCIP_Real *pseudofeasibility)
Definition: nlp.c:1687
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition: memory.h:467
int nnlrownonlineareq
Definition: struct_nlp.h:131
void SCIPsetSortNlpis(SCIP_SET *set)
Definition: set.c:5255
int SCIPvarCompare(SCIP_VAR *var1, SCIP_VAR *var2)
Definition: var.c:11943
#define MIN(x, y)
Definition: def.h:243
public methods for LP management
#define SCIPsetDebugMsg
Definition: set.h:1784
SCIP_RETCODE SCIPnlpStartDive(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition: nlp.c:4561
SCIP_RETCODE SCIPnlpiChgLinearCoefs(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, int idx, int nvals, const int *varidxs, const SCIP_Real *vals)
Definition: nlpi.c:464
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17927
SCIP_EXPR * SCIPexpriterGetNext(SCIP_EXPRITER *iterator)
Definition: expriter.c:858
SCIP_RETCODE SCIPnlpiDelVarSet(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, int *dstats, int dstatssize)
Definition: nlpi.c:422
SCIP_RETCODE SCIPnlpiCreateProblem(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM **problem, const char *name)
Definition: nlpi.c:244
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:134
int SCIPnlpGetNVars(SCIP_NLP *nlp)
Definition: nlp.c:4305
SCIP_NLROW ** nlrows
Definition: struct_nlp.h:127
SCIP_RETCODE SCIPnlpGetFracVars(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR ***fracvars, SCIP_Real **fracvarssol, SCIP_Real **fracvarsfrac, int *nfracvars, int *npriofracvars)
Definition: nlp.c:4124
datastructures for problem statistics
SCIP_RETCODE SCIPnlrowCreateFromRow(SCIP_NLROW **nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_ROW *row)
Definition: nlp.c:1029
int SCIPvarGetMultaggrNVars(SCIP_VAR *var)
Definition: var.c:17847
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6689
int nunflushedvardel
Definition: struct_nlp.h:108
SCIP_Bool haveinitguess
Definition: struct_nlp.h:142
SCIP_RETCODE SCIPexprEval(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, SCIP_SOL *sol, SCIP_Longint soltag)
Definition: expr.c:2654
static SCIP_RETCODE nlpUpdateObjCoef(SCIP_SET *set, SCIP_NLP *nlp, SCIP_VAR *var)
Definition: nlp.c:2259
SCIP_Real SCIPsetFeasFrac(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6867
int nunflushednlrowadd
Definition: struct_nlp.h:109
static SCIP_RETCODE nlpFlushNlRowDeletions(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: nlp.c:2657
static SCIP_RETCODE nlpFlushNlRowAdditions(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition: nlp.c:2847
SCIP_Real * SCIPnlrowGetLinearCoefs(SCIP_NLROW *nlrow)
Definition: nlp.c:1887
methods for sorting joint arrays of various types
int nvars
Definition: struct_nlp.h:114
#define SCIP_LONGINT_FORMAT
Definition: def.h:165
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
Definition: lp.c:17258
public methods for managing events
SCIP_RETCODE SCIPhashmapRemove(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3439
#define MAX(x, y)
Definition: def.h:239
SCIP_RETCODE SCIPnlpFlush(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition: nlp.c:4015
static SCIP_RETCODE nlrowDelLinearCoefPos(SCIP_NLROW *nlrow, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp, int pos)
Definition: nlp.c:564
SCIP_NLPIPROBLEM * SCIPnlpGetNLPIProblem(SCIP_NLP *nlp)
Definition: nlp.c:4486
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition: lp.c:17042
SCIP_RETCODE SCIPnlpiChgConsSides(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, int nconss, const int *indices, const SCIP_Real *lhss, const SCIP_Real *rhss)
Definition: nlpi.c:399
int sizevars
Definition: struct_nlp.h:115
SCIP_Longint domchgcount
Definition: struct_stat.h:114
SCIP_Bool indiving
Definition: struct_nlp.h:111
int * varmap_nlp2nlpi
Definition: struct_nlp.h:121
SCIP_NLPSOLSTAT SCIPnlpiGetSolstat(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem)
Definition: nlpi.c:621
static SCIP_RETCODE nlrowCalcActivityBounds(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition: nlp.c:624
#define SCIP_EVENTTYPE_FORMAT
Definition: type_event.h:152
SCIP_RETCODE SCIPnlpGetVarsNonlinearity(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, int *nlcount)
Definition: nlp.c:4315
public methods for message output
SCIP_Bool SCIPexprIsValue(SCIP_SET *set, SCIP_EXPR *expr)
Definition: expr.c:2218
void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
Definition: message.c:618
SCIP_RETCODE SCIPnlpWrite(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_MESSAGEHDLR *messagehdlr, const char *fname)
Definition: nlp.c:4240
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17539
void SCIPintervalSetBounds(SCIP_INTERVAL *resultant, SCIP_Real inf, SCIP_Real sup)
SCIP_RETCODE SCIPnlpiSolve(SCIP_SET *set, SCIP_STAT *stat, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, SCIP_NLPPARAM *param)
Definition: nlpi.c:551
#define SCIP_Real
Definition: def.h:173
static SCIP_RETCODE nlpRemoveFixedVar(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_VAR *var)
Definition: nlp.c:2527
int nunflushednlrowdel
Definition: struct_nlp.h:110
#define SCIP_CALL_TERMINATE(retcode, x, TERM)
Definition: def.h:401
SCIP_Real activity
Definition: struct_nlp.h:86
SCIP_RETCODE SCIPexprEvalActivity(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *rootexpr)
Definition: expr.c:2950
#define BMSallocMemory(ptr)
Definition: memory.h:118
#define SCIP_INVALID
Definition: def.h:193
SCIP_RETCODE SCIPnlpAddNlRows(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, int nnlrows, SCIP_NLROW **nlrows)
Definition: nlp.c:3953
SCIP_NLPI * SCIPnlpGetNLPI(SCIP_NLP *nlp)
Definition: nlp.c:4476
void SCIPsortPtrReal(void **ptrarray, SCIP_Real *realarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
SCIP_Real SCIPgetValueExprValue(SCIP_EXPR *expr)
Definition: expr_value.c:294
int nlinvars
Definition: struct_nlp.h:74
SCIP_RETCODE SCIPnlrowRelease(SCIP_NLROW **nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition: nlp.c:1154
SCIP_VAR ** SCIPnlpGetVars(SCIP_NLP *nlp)
Definition: nlp.c:4295
SCIP_RETCODE SCIPsolCreateNLPSol(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_NLP *nlp, SCIP_HEUR *heur)
Definition: sol.c:631
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6733
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17585
int sizevars_solver
Definition: struct_nlp.h:120
SCIP_RETCODE SCIPnlrowGetSolActivity(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_Real *activity)
Definition: nlp.c:1712
int nlpindex
Definition: struct_nlp.h:93
static SCIP_RETCODE nlpAddNlRows(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, int nnlrows, SCIP_NLROW **nlrows)
Definition: nlp.c:2025
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:18145
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition: var.c:17562
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:451
SCIP_RETCODE SCIPvarDropEvent(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition: var.c:18586
SCIP_RETCODE SCIPsolCreatePseudoSol(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_LP *lp, SCIP_HEUR *heur)
Definition: sol.c:678
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:130
SCIP_Real * SCIPnlpGetVarsUbDualsol(SCIP_NLP *nlp)
Definition: nlp.c:4422
SCIP_RETCODE SCIPnlpiDelConsSet(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, int *dstats, int dstatssize)
Definition: nlpi.c:443
SCIP_Bool SCIPexpriterIsEnd(SCIP_EXPRITER *iterator)
Definition: expriter.c:969
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:437
SCIP_Real SCIPnlrowGetConstant(SCIP_NLROW *nlrow)
Definition: nlp.c:1857
SCIP_RETCODE SCIPnlpInclude(SCIP_SET *set, BMS_BLKMEM *blkmem)
Definition: nlp.c:3514
SCIP_RETCODE SCIPvarGetProbvarSum(SCIP_VAR **var, SCIP_SET *set, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12648
SCIP_RETCODE SCIPnlpRemoveRedundantNlRows(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition: nlp.c:4158
int nnlrowconvexineq
Definition: struct_nlp.h:129
int SCIPhashmapGetImageInt(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3281
SCIP_RETCODE SCIPexprRelease(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR **rootexpr)
Definition: expr.c:2074
static SCIP_RETCODE nlpSolve(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_NLPPARAM *nlpparam)
Definition: nlp.c:3142
int * nlrowmap_nlpi2nlp
Definition: struct_nlp.h:135
SCIP_Real SCIPnlrowGetLhs(SCIP_NLROW *nlrow)
Definition: nlp.c:1907
#define SCIP_ALLOC(x)
Definition: def.h:391
SCIP_Real constant
Definition: struct_nlp.h:71
SCIP_RETCODE SCIPeventhdlrCreate(SCIP_EVENTHDLR **eventhdlr, SCIP_SET *set, const char *name, const char *desc, SCIP_DECL_EVENTCOPY((*eventcopy)), SCIP_DECL_EVENTFREE((*eventfree)), SCIP_DECL_EVENTINIT((*eventinit)), SCIP_DECL_EVENTEXIT((*eventexit)), SCIP_DECL_EVENTINITSOL((*eventinitsol)), SCIP_DECL_EVENTEXITSOL((*eventexitsol)), SCIP_DECL_EVENTDELETE((*eventdelete)), SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition: event.c:123
SCIP_Real primalsolobjval
Definition: struct_nlp.h:146
static void nlrowMoveLinearCoef(SCIP_NLROW *nlrow, int oldpos, int newpos)
Definition: nlp.c:412
double * lincoefs
Definition: struct_nlp.h:77
static SCIP_RETCODE nlrowExprChanged(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp)
Definition: nlp.c:204
SCIP_RETCODE SCIPcreateExprVaridx(SCIP *scip, SCIP_EXPR **expr, int varidx, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_varidx.c:220
SCIP_RETCODE SCIPnlpAddVar(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_VAR *var)
Definition: nlp.c:3809
#define SCIP_EVENTTYPE_VARADDED
Definition: type_event.h:70
SCIP_Bool SCIPnlpHasSolution(SCIP_NLP *nlp)
Definition: nlp.c:4547
datastructures for global SCIP settings
SCIP_RETCODE SCIPnlpiSetObjective(SCIP_SET *set, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *problem, int nlins, const int *lininds, const SCIP_Real *linvals, SCIP_EXPR *expr, const SCIP_Real constant)
Definition: nlpi.c:352
SCIP_Bool linvarssorted
Definition: struct_nlp.h:78
SCIP_RETCODE SCIPnlrowGetSolFeasibility(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_Real *feasibility)
Definition: nlp.c:1761
#define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
Definition: memory.h:458
void SCIPnlpGetNlRowsStat(SCIP_NLP *nlp, int *nlinear, int *nconvexineq, int *nnonconvexineq, int *nnonlineareq)
Definition: nlp.c:4452
int npriofracvars
Definition: struct_nlp.h:161
#define ABS(x)
Definition: def.h:235
SCIP_RETCODE SCIPnlrowPrint(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: nlp.c:1092
#define SCIP_EVENTTYPE_VARDELETED
Definition: type_event.h:71
SCIP_Longint validactivitynlp
Definition: struct_nlp.h:87
SCIP_EXPR * SCIPnlrowGetExpr(SCIP_NLROW *nlrow)
Definition: nlp.c:1897
SCIP_RETCODE SCIPexprCopy(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_SET *targetset, SCIP_STAT *targetstat, BMS_BLKMEM *targetblkmem, SCIP_EXPR *sourceexpr, SCIP_EXPR **targetexpr, SCIP_DECL_EXPR_MAPEXPR((*mapexpr)), void *mapexprdata, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr.c:1878
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:17749
int sizenlrows_solver
Definition: struct_nlp.h:134
SCIP_RETCODE SCIPnlrowSimplify(SCIP_NLROW *nlrow, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_NLP *nlp)
Definition: nlp.c:1489
SCIP_RETCODE SCIPsolFree(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_PRIMAL *primal)
Definition: sol.c:801
uint64_t SCIP_EVENTTYPE
Definition: type_event.h:151