Scippy

SCIP

Solving Constraint Integer Programs

expr.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-2022 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scip.zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file expr.c
17  * @ingroup OTHER_CFILES
18  * @brief functions for algebraic expressions
19  * @author Ksenia Bestuzheva
20  * @author Benjamin Mueller
21  * @author Felipe Serrano
22  * @author Stefan Vigerske
23  */
24 
25 #include <assert.h>
26 #include <ctype.h>
27 
28 #include "scip/expr.h"
29 #include "scip/struct_expr.h"
30 #include "scip/pub_misc.h"
31 #include "scip/clock.h"
32 #include "scip/set.h"
33 #include "scip/pub_var.h"
34 #include "scip/sol.h"
35 #include "scip/tree.h"
36 #include "scip/struct_set.h"
37 #include "scip/struct_stat.h"
38 #include "scip/nlpi_ipopt.h" /* for LAPACK */
39 
40 /*lint -e440*/
41 /*lint -e441*/
42 /*lint -e777*/
43 
44 /*
45  * Data structures
46  */
47 
48 /** printing to file data */
49 struct SCIP_ExprPrintData
50 {
51  FILE* file; /**< file to print to */
52  SCIP_EXPRITER* iterator; /**< iterator to use */
53  SCIP_Bool closefile; /**< whether file need to be closed when finished printing */
54  SCIP_HASHMAP* leaveexprs; /**< hashmap storing leave (no children) expressions */
55  SCIP_EXPRPRINT_WHAT whattoprint; /**< flags that indicate what to print for each expression */
56 };
57 
58 /*
59  * Local methods
60  */
61 
62 /** frees an expression */
63 static
65  BMS_BLKMEM* blkmem, /**< block memory */
66  SCIP_EXPR** expr /**< pointer to free the expression */
67  )
68 {
69  assert(expr != NULL);
70  assert(*expr != NULL);
71  assert((*expr)->nuses == 1);
72  assert((*expr)->quaddata == NULL);
73  assert((*expr)->ownerdata == NULL);
74 
75  /* free children array, if any */
76  BMSfreeBlockMemoryArrayNull(blkmem, &(*expr)->children, (*expr)->childrensize);
77 
78  BMSfreeBlockMemory(blkmem, expr);
79  assert(*expr == NULL);
80 
81  return SCIP_OKAY;
82 }
83 
84 /*
85  * quadratic representation of expression
86  */
87 
88 /** first time seen quadratically and
89  * seen before linearly --> --nlinterms; assign 2; ++nquadterms
90  * not seen before linearly --> assing 1; ++nquadterms
91  *
92  * seen before --> assign += 1
93  */
94 static
96  SCIP_EXPR* expr, /**< the expression */
97  SCIP_HASHMAP* seenexpr, /**< hash map */
98  int* nquadterms, /**< number of quadratic terms */
99  int* nlinterms /**< number of linear terms */
100  )
101 {
102  if( SCIPhashmapExists(seenexpr, (void*)expr) )
103  {
104  int nseen = SCIPhashmapGetImageInt(seenexpr, (void*)expr);
105 
106  if( nseen < 0 )
107  {
108  /* only seen linearly before */
109  assert(nseen == -1);
110 
111  --*nlinterms;
112  ++*nquadterms;
113  SCIP_CALL( SCIPhashmapSetImageInt(seenexpr, (void*)expr, 2) );
114  }
115  else
116  {
117  assert(nseen > 0);
118  SCIP_CALL( SCIPhashmapSetImageInt(seenexpr, (void*)expr, nseen + 1) );
119  }
120  }
121  else
122  {
123  ++*nquadterms;
124  SCIP_CALL( SCIPhashmapInsertInt(seenexpr, (void*)expr, 1) );
125  }
126 
127  return SCIP_OKAY;
128 }
129 
130 /** returns a quadexprterm that contains the expr
131  *
132  * it either finds one that already exists or creates a new one
133  */
134 static
136  BMS_BLKMEM* blkmem, /**< block memory */
137  SCIP_EXPR* expr, /**< the expression */
138  SCIP_HASHMAP* expr2idx, /**< map: expr to index in quadexpr->quadexprterms */
139  SCIP_HASHMAP* seenexpr, /**< map: expr to number of times it was seen */
140  SCIP_QUADEXPR* quadexpr, /**< data of quadratic representation of expression */
141  SCIP_QUADEXPR_QUADTERM** quadexprterm /**< buffer to store quadexprterm */
142  )
143 {
144  assert(expr != NULL);
145  assert(expr2idx != NULL);
146  assert(quadexpr != NULL);
147  assert(quadexprterm != NULL);
148 
149  if( SCIPhashmapExists(expr2idx, (void*)expr) )
150  {
151  *quadexprterm = &quadexpr->quadexprterms[SCIPhashmapGetImageInt(expr2idx, (void*)expr)];
152  assert((*quadexprterm)->expr == expr);
153  }
154  else
155  {
156  SCIP_CALL( SCIPhashmapInsertInt(expr2idx, expr, quadexpr->nquadexprs) );
157  *quadexprterm = &quadexpr->quadexprterms[quadexpr->nquadexprs];
158  ++quadexpr->nquadexprs;
159 
160  (*quadexprterm)->expr = expr;
161  (*quadexprterm)->sqrcoef = 0.0;
162  (*quadexprterm)->sqrexpr = NULL;
163  (*quadexprterm)->lincoef = 0.0;
164  (*quadexprterm)->nadjbilin = 0;
165  (*quadexprterm)->adjbilinsize = SCIPhashmapGetImageInt(seenexpr, (void*)expr);
166  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*quadexprterm)->adjbilin, (*quadexprterm)->adjbilinsize) );
167  }
168 
169  return SCIP_OKAY;
170 }
171 
172 
173 /** evaluate and forward-differentiate expression
174  *
175  * also initializes derivative and bardot to 0.0
176  */
177 static
179  SCIP_SET* set, /**< global SCIP settings */
180  SCIP_STAT* stat, /**< dynamic problem statistics */
181  BMS_BLKMEM* blkmem, /**< block memory */
182  SCIP_EXPR* expr, /**< expression to be evaluated */
183  SCIP_SOL* sol, /**< solution to be evaluated */
184  SCIP_Longint soltag, /**< tag that uniquely identifies the solution (with its values), or 0. */
185  SCIP_SOL* direction /**< direction for directional derivative */
186  )
187 {
188  SCIP_EXPRITER* it;
189 
190  assert(set != NULL);
191  assert(stat != NULL);
192  assert(blkmem != NULL);
193  assert(expr != NULL);
194 
195  /* assume we'll get a domain error, so we don't have to get this expr back if we abort the iteration
196  * if there is no domain error, then we will overwrite the evalvalue in the last leaveexpr stage
197  */
198  expr->evalvalue = SCIP_INVALID;
199  expr->evaltag = soltag;
200  expr->dot = SCIP_INVALID;
201 
202  /* start a new difftag */
203  ++stat->exprlastdifftag;
204 
205  SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
208 
209  for( expr = SCIPexpriterGetCurrent(it); !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
210  {
211  /* evaluate expression only if necessary */
212  if( soltag == 0 || expr->evaltag != soltag )
213  {
214  SCIP_CALL( SCIPexprhdlrEvalExpr(expr->exprhdlr, set, NULL, expr, &expr->evalvalue, NULL, sol) );
215 
216  expr->evaltag = soltag;
217  }
218 
219  if( expr->evalvalue == SCIP_INVALID )
220  break;
221 
222  if( expr->difftag != stat->exprlastdifftag )
223  {
224  /* compute forward diff */
225  SCIP_CALL( SCIPexprhdlrFwDiffExpr(expr->exprhdlr, set, expr, &expr->dot, direction) );
226 
227  if( expr->dot == SCIP_INVALID )
228  break;
229 
230  expr->derivative = 0.0;
231  expr->bardot = 0.0;
232  expr->difftag = stat->exprlastdifftag;
233  }
234  }
235 
236  SCIPexpriterFree(&it);
237 
238  return SCIP_OKAY;
239 }
240 
241 
242 /*
243  * Public methods
244  */
245 
246 /* Undo the defines from pub_expr.h, which exist if NDEBUG is defined. */
247 #ifdef NDEBUG
248 #undef SCIPexprhdlrSetCopyFreeHdlr
249 #undef SCIPexprhdlrSetCopyFreeData
250 #undef SCIPexprhdlrSetPrint
251 #undef SCIPexprhdlrSetParse
252 #undef SCIPexprhdlrSetCurvature
253 #undef SCIPexprhdlrSetMonotonicity
254 #undef SCIPexprhdlrSetIntegrality
255 #undef SCIPexprhdlrSetHash
256 #undef SCIPexprhdlrSetCompare
257 #undef SCIPexprhdlrSetDiff
258 #undef SCIPexprhdlrSetIntEval
259 #undef SCIPexprhdlrSetSimplify
260 #undef SCIPexprhdlrSetReverseProp
261 #undef SCIPexprhdlrSetEstimate
262 #undef SCIPexprhdlrGetName
263 #undef SCIPexprhdlrGetDescription
264 #undef SCIPexprhdlrGetPrecedence
265 #undef SCIPexprhdlrGetData
266 #undef SCIPexprhdlrHasPrint
267 #undef SCIPexprhdlrHasBwdiff
268 #undef SCIPexprhdlrHasFwdiff
269 #undef SCIPexprhdlrHasIntEval
270 #undef SCIPexprhdlrHasEstimate
271 #undef SCIPexprhdlrHasInitEstimates
272 #undef SCIPexprhdlrHasSimplify
273 #undef SCIPexprhdlrHasCurvature
274 #undef SCIPexprhdlrHasMonotonicity
275 #undef SCIPexprhdlrHasReverseProp
276 #undef SCIPexprhdlrGetNCreated
277 #undef SCIPexprhdlrGetNIntevalCalls
278 #undef SCIPexprhdlrGetIntevalTime
279 #undef SCIPexprhdlrGetNReversepropCalls
280 #undef SCIPexprhdlrGetReversepropTime
281 #undef SCIPexprhdlrGetNCutoffs
282 #undef SCIPexprhdlrGetNDomainReductions
283 #undef SCIPexprhdlrIncrementNDomainReductions
284 #undef SCIPexprhdlrGetNEstimateCalls
285 #undef SCIPexprhdlrGetEstimateTime
286 #undef SCIPexprhdlrGetNBranchings
287 #undef SCIPexprhdlrIncrementNBranchings
288 #undef SCIPexprhdlrGetNSimplifyCalls
289 #undef SCIPexprhdlrGetSimplifyTime
290 #undef SCIPexprhdlrGetNSimplifications
291 #endif
292 
293 /** create expression handler */
295  BMS_BLKMEM* blkmem, /**< block memory */
296  SCIP_EXPRHDLR** exprhdlr, /**< buffer where to store created expression handler */
297  const char* name, /**< name of expression handler (must not be NULL) */
298  const char* desc, /**< description of expression handler (can be NULL) */
299  unsigned int precedence, /**< precedence of expression operation (used for printing) */
300  SCIP_DECL_EXPREVAL((*eval)), /**< point evaluation callback (must not be NULL) */
301  SCIP_EXPRHDLRDATA* data /**< data of expression handler (can be NULL) */
302  )
303 {
304  assert(exprhdlr != NULL);
305  assert(name != NULL);
306 
307  SCIP_ALLOC( BMSallocClearBlockMemory(blkmem, exprhdlr) );
308 
309  SCIP_ALLOC( BMSduplicateMemoryArray(&(*exprhdlr)->name, name, strlen(name)+1) );
310  if( desc != NULL )
311  {
312  SCIP_ALLOC( BMSduplicateMemoryArray(&(*exprhdlr)->desc, desc, strlen(desc)+1) );
313  }
314 
315  (*exprhdlr)->precedence = precedence;
316  (*exprhdlr)->eval = eval;
317  (*exprhdlr)->data = data;
318 
319  /* create clocks */
320  SCIP_CALL( SCIPclockCreate(&(*exprhdlr)->estimatetime, SCIP_CLOCKTYPE_DEFAULT) );
321  SCIP_CALL( SCIPclockCreate(&(*exprhdlr)->intevaltime, SCIP_CLOCKTYPE_DEFAULT) );
322  SCIP_CALL( SCIPclockCreate(&(*exprhdlr)->proptime, SCIP_CLOCKTYPE_DEFAULT) );
323  SCIP_CALL( SCIPclockCreate(&(*exprhdlr)->simplifytime, SCIP_CLOCKTYPE_DEFAULT) );
324 
325  return SCIP_OKAY;
326 }
327 
328 /** frees expression handler */
330  SCIP_EXPRHDLR** exprhdlr, /**< pointer to expression handler to be freed */
331  SCIP_SET* set, /**< global SCIP settings */
332  BMS_BLKMEM* blkmem /**< block memory */
333  )
334 {
335  if( (*exprhdlr)->freehdlr != NULL )
336  {
337  SCIP_CALL( (*exprhdlr)->freehdlr(set->scip, *exprhdlr, &(*exprhdlr)->data) );
338  }
339 
340  /* free clocks */
341  SCIPclockFree(&(*exprhdlr)->simplifytime);
342  SCIPclockFree(&(*exprhdlr)->intevaltime);
343  SCIPclockFree(&(*exprhdlr)->proptime);
344  SCIPclockFree(&(*exprhdlr)->estimatetime);
345 
346  BMSfreeMemoryArrayNull(&(*exprhdlr)->desc);
347  BMSfreeMemoryArray(&(*exprhdlr)->name);
348 
349  BMSfreeBlockMemory(blkmem, exprhdlr);
350 
351  return SCIP_OKAY;
352 }
353 
354 /**@addtogroup PublicExprHandlerMethods
355  * @{
356  */
357 
358 /** set the expression handler callbacks to copy and free an expression handler */
360  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
361  SCIP_DECL_EXPRCOPYHDLR((*copyhdlr)), /**< handler copy callback (can be NULL) */
362  SCIP_DECL_EXPRFREEHDLR((*freehdlr)) /**< handler free callback (can be NULL) */
363  )
364 {
365  assert(exprhdlr != NULL);
366 
367  exprhdlr->copyhdlr = copyhdlr;
368  exprhdlr->freehdlr = freehdlr;
369 }
370 
371 /** set the expression handler callbacks to copy and free expression data */
373  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
374  SCIP_DECL_EXPRCOPYDATA((*copydata)), /**< expression data copy callback (can be NULL for expressions
375  without data) */
376  SCIP_DECL_EXPRFREEDATA((*freedata)) /**< expression data free callback (can be NULL if data does not
377  need to be freed) */
378  )
379 { /*lint --e{715}*/
380  assert(exprhdlr != NULL);
381 
382  exprhdlr->copydata = copydata;
383  exprhdlr->freedata = freedata;
384 }
385 
386 /** set the print callback of an expression handler */
388  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
389  SCIP_DECL_EXPRPRINT((*print)) /**< print callback (can be NULL) */
390  )
391 {
392  assert(exprhdlr != NULL);
393 
394  exprhdlr->print = print;
395 }
396 
397 /** set the parse callback of an expression handler */
399  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
400  SCIP_DECL_EXPRPARSE((*parse)) /**< parse callback (can be NULL) */
401  )
402 {
403  assert(exprhdlr != NULL);
404 
405  exprhdlr->parse = parse;
406 }
407 
408 /** set the curvature detection callback of an expression handler */
410  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
411  SCIP_DECL_EXPRCURVATURE((*curvature)) /**< curvature detection callback (can be NULL) */
412  )
413 {
414  assert(exprhdlr != NULL);
415 
416  exprhdlr->curvature = curvature;
417 }
418 
419 /** set the monotonicity detection callback of an expression handler */
421  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
422  SCIP_DECL_EXPRMONOTONICITY((*monotonicity)) /**< monotonicity detection callback (can be NULL) */
423  )
424 {
425  assert(exprhdlr != NULL);
426 
427  exprhdlr->monotonicity = monotonicity;
428 }
429 
430 /** set the integrality detection callback of an expression handler */
432  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
433  SCIP_DECL_EXPRINTEGRALITY((*integrality)) /**< integrality detection callback (can be NULL) */
434  )
435 {
436  assert(exprhdlr != NULL);
437 
438  exprhdlr->integrality = integrality;
439 }
440 
441 /** set the hash callback of an expression handler */
443  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
444  SCIP_DECL_EXPRHASH((*hash)) /**< hash callback (can be NULL) */
445  )
446 {
447  assert(exprhdlr != NULL);
448 
449  exprhdlr->hash = hash;
450 }
451 
452 /** set the compare callback of an expression handler */
454  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
455  SCIP_DECL_EXPRCOMPARE((*compare)) /**< compare callback (can be NULL) */
456  )
457 {
458  assert(exprhdlr != NULL);
459 
460  exprhdlr->compare = compare;
461 }
462 
463 /** set differentiation callbacks of an expression handler */
465  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
466  SCIP_DECL_EXPRBWDIFF((*bwdiff)), /**< backward derivative evaluation callback (can be NULL) */
467  SCIP_DECL_EXPRFWDIFF((*fwdiff)), /**< forward derivative evaluation callback (can be NULL) */
468  SCIP_DECL_EXPRBWFWDIFF((*bwfwdiff)) /**< backward-forward derivative evaluation callback (can be NULL) */
469  )
470 {
471  assert(exprhdlr != NULL);
472 
473  exprhdlr->bwdiff = bwdiff;
474  exprhdlr->fwdiff = fwdiff;
475  exprhdlr->bwfwdiff = bwfwdiff;
476 }
477 
478 /** set the interval evaluation callback of an expression handler */
480  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
481  SCIP_DECL_EXPRINTEVAL((*inteval)) /**< interval evaluation callback (can be NULL) */
482  )
483 {
484  assert(exprhdlr != NULL);
485 
486  exprhdlr->inteval = inteval;
487 }
488 
489 /** set the simplify callback of an expression handler */
491  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
492  SCIP_DECL_EXPRSIMPLIFY((*simplify)) /**< simplify callback (can be NULL) */
493  )
494 {
495  assert(exprhdlr != NULL);
496 
497  exprhdlr->simplify = simplify;
498 }
499 
500 /** set the reverse propagation callback of an expression handler */
502  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
503  SCIP_DECL_EXPRREVERSEPROP((*reverseprop)) /**< reverse propagation callback (can be NULL) */
504  )
505 {
506  assert(exprhdlr != NULL);
507 
508  exprhdlr->reverseprop = reverseprop;
509 }
510 
511 /** set the estimation callbacks of an expression handler */
513  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
514  SCIP_DECL_EXPRINITESTIMATES((*initestimates)), /**< initial estimators callback (can be NULL) */
515  SCIP_DECL_EXPRESTIMATE((*estimate)) /**< estimator callback (can be NULL) */
516  )
517 {
518  assert(exprhdlr != NULL);
519 
520  exprhdlr->initestimates = initestimates;
521  exprhdlr->estimate = estimate;
522 }
523 
524 /** gives the name of an expression handler */
526  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
527  )
528 {
529  assert(exprhdlr != NULL);
530 
531  return exprhdlr->name;
532 }
533 
534 /** gives the description of an expression handler (can be NULL) */
536  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
537  )
538 {
539  assert(exprhdlr != NULL);
540 
541  return exprhdlr->desc;
542 }
543 
544 /** gives the precedence of an expression handler */
546  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
547  )
548 {
549  assert(exprhdlr != NULL);
550 
551  return exprhdlr->precedence;
552 }
553 
554 /** gives the data of an expression handler */
556  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
557  )
558 {
559  assert(exprhdlr != NULL);
560 
561  return exprhdlr->data;
562 }
563 
564 /** returns whether expression handler implements the print callback */
566  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
567  )
568 {
569  assert(exprhdlr != NULL);
570 
571  return exprhdlr->print != NULL;
572 }
573 
574 /** returns whether expression handler implements the backward differentiation callback */
576  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
577  )
578 {
579  assert(exprhdlr != NULL);
580 
581  return exprhdlr->bwdiff != NULL;
582 }
583 
584 /** returns whether expression handler implements the forward differentiation callback */
586  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
587  )
588 {
589  assert(exprhdlr != NULL);
590 
591  return exprhdlr->fwdiff != NULL;
592 }
593 
594 /** returns whether expression handler implements the interval evaluation callback */
596  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
597  )
598 {
599  assert(exprhdlr != NULL);
600 
601  return exprhdlr->inteval != NULL;
602 }
603 
604 /** returns whether expression handler implements the estimator callback */
606  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
607  )
608 {
609  assert(exprhdlr != NULL);
610 
611  return exprhdlr->estimate != NULL;
612 }
613 
614 /** returns whether expression handler implements the initial estimators callback */
616  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
617  )
618 {
619  assert(exprhdlr != NULL);
620 
621  return exprhdlr->initestimates != NULL;
622 }
623 
624 /** returns whether expression handler implements the simplification callback */
626  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
627  )
628 {
629  assert(exprhdlr != NULL);
630 
631  return exprhdlr->simplify != NULL;
632 }
633 
634 /** returns whether expression handler implements the curvature callback */
636  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
637  )
638 {
639  assert(exprhdlr != NULL);
640 
641  return exprhdlr->curvature != NULL;
642 }
643 
644 /** returns whether expression handler implements the monotonicity callback */
646  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
647  )
648 {
649  assert(exprhdlr != NULL);
650 
651  return exprhdlr->monotonicity != NULL;
652 }
653 
654 /** returns whether expression handler implements the reverse propagation callback */
656  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
657  )
658 {
659  assert(exprhdlr != NULL);
660 
661  return exprhdlr->reverseprop != NULL;
662 }
663 
664 /** compares two expression handler w.r.t. their name */
665 SCIP_DECL_SORTPTRCOMP(SCIPexprhdlrComp)
666 {
667  return strcmp(((SCIP_EXPRHDLR*)elem1)->name, ((SCIP_EXPRHDLR*)elem2)->name);
668 }
669 
670 /** gets number of times an expression has been created with given expression handler */
672  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
673  )
674 {
675  assert(exprhdlr != NULL);
676 
677  return exprhdlr->ncreated;
678 }
679 
680 /** gets number of times the interval evaluation callback was called */
682  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
683  )
684 {
685  assert(exprhdlr != NULL);
686 
687  return exprhdlr->nintevalcalls;
688 }
689 
690 /** gets time spend in interval evaluation callback */
692  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
693  )
694 {
695  assert(exprhdlr != NULL);
696 
697  return SCIPclockGetTime(exprhdlr->intevaltime);
698 }
699 
700 /** gets number of times the reverse propagation callback was called */
702  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
703  )
704 {
705  assert(exprhdlr != NULL);
706 
707  return exprhdlr->npropcalls;
708 }
709 
710 /** gets time spend in reverse propagation callback */
712  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
713  )
714 {
715  assert(exprhdlr != NULL);
716 
717  return SCIPclockGetTime(exprhdlr->proptime);
718 }
719 
720 /** gets number of times an empty interval was found in reverse propagation */
722  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
723  )
724 {
725  assert(exprhdlr != NULL);
726 
727  return exprhdlr->ncutoffs;
728 }
729 
730 /** gets number of times a bound reduction was found in reverse propagation (and accepted by caller) */
732  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
733  )
734 {
735  assert(exprhdlr != NULL);
736 
737  return exprhdlr->ndomreds;
738 }
739 
740 /** increments the domain reductions count of an expression handler */
742  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
743  int nreductions /**< number of reductions to add to counter */
744  )
745 {
746  assert(exprhdlr != NULL);
747  assert(nreductions >= 0);
748 
749  exprhdlr->ndomreds += nreductions;
750 }
751 
752 /** gets number of times the estimation callback was called */
754  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
755  )
756 {
757  assert(exprhdlr != NULL);
758 
759  return exprhdlr->nestimatecalls;
760 }
761 
762 /** gets time spend in estimation callback */
764  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
765  )
766 {
767  assert(exprhdlr != NULL);
768 
769  return SCIPclockGetTime(exprhdlr->estimatetime);
770 }
771 
772 /** gets number of times branching candidates reported by of this expression handler were used to
773  * assemble branching candidates
774  *
775  * that is, how often did we consider branching on a child of this expression
776  */
778  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
779  )
780 {
781  assert(exprhdlr != NULL);
782 
783  return exprhdlr->nbranchscores;
784 }
785 
786 /** increments the branching candidates count of an expression handler */
788  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
789  )
790 {
791  assert(exprhdlr != NULL);
792 
793  ++exprhdlr->nbranchscores;
794 }
795 
796 /** gets number of times the simplify callback was called */
798  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
799  )
800 {
801  assert(exprhdlr != NULL);
802 
803  return exprhdlr->nsimplifycalls;
804 }
805 
806 /** gets time spend in simplify callback */
808  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
809  )
810 {
811  assert(exprhdlr != NULL);
812 
813  return SCIPclockGetTime(exprhdlr->simplifytime);
814 }
815 
816 /** gets number of times the simplify callback found a simplification */
818  SCIP_EXPRHDLR* exprhdlr /**< expression handler */
819  )
820 {
821  assert(exprhdlr != NULL);
822 
823  return exprhdlr->nsimplified;
824 }
825 
826 /** @} */
827 
828 /** copies the given expression handler to a new scip */
830  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
831  SCIP_SET* targetset /**< SCIP_SET of SCIP to copy to */
832  )
833 {
834  assert(exprhdlr != NULL);
835  assert(targetset != NULL);
836  assert(targetset->scip != NULL);
837 
838  if( exprhdlr->copyhdlr != NULL )
839  {
840  SCIPsetDebugMsg(targetset, "including expression handler <%s> in subscip %p\n",
841  SCIPexprhdlrGetName(exprhdlr), (void*)targetset->scip);
842  SCIP_CALL( exprhdlr->copyhdlr(targetset->scip, exprhdlr) );
843  }
844  else
845  {
846  SCIPsetDebugMsg(targetset, "expression handler <%s> cannot be copied to subscip %p due "
847  "to missing copyhdlr callback\n", SCIPexprhdlrGetName(exprhdlr), (void*)targetset->scip);
848  }
849 
850  return SCIP_OKAY;
851 }
852 
853 /** initialization of expression handler (resets statistics) */
855  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
856  SCIP_SET* set /**< global SCIP settings */
857  )
858 {
859  assert(exprhdlr != NULL);
860 
861  if( set->misc_resetstat )
862  {
863  exprhdlr->ncreated = 0;
864  exprhdlr->nestimatecalls = 0;
865  exprhdlr->nintevalcalls = 0;
866  exprhdlr->npropcalls = 0;
867  exprhdlr->ncutoffs = 0;
868  exprhdlr->ndomreds = 0;
869  exprhdlr->nbranchscores = 0;
870  exprhdlr->nsimplifycalls = 0;
871  exprhdlr->nsimplified = 0;
872 
873  SCIPclockReset(exprhdlr->estimatetime);
874  SCIPclockReset(exprhdlr->intevaltime);
875  SCIPclockReset(exprhdlr->proptime);
876  SCIPclockReset(exprhdlr->simplifytime);
877  }
878 }
879 
880 /** calls the print callback of an expression handler
881  *
882  * The method prints an expression.
883  * It is called while iterating over the expression graph at different stages.
884  *
885  * @see SCIP_DECL_EXPRPRINT
886  */
888  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
889  SCIP_SET* set, /**< global SCIP settings */
890  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
891  SCIP_EXPR* expr, /**< expression */
892  SCIP_EXPRITER_STAGE stage, /**< stage of expression iteration */
893  int currentchild, /**< index of current child if in stage visitingchild or visitedchild */
894  unsigned int parentprecedence, /**< precedence of parent */
895  FILE* file /**< the file to print to */
896  )
897 {
898  assert(exprhdlr != NULL);
899  assert(set != NULL);
900  assert(expr != NULL);
901  assert(expr->exprhdlr == exprhdlr);
902  assert(messagehdlr != NULL);
903 
904  if( SCIPexprhdlrHasPrint(exprhdlr) )
905  {
906  SCIP_CALL( exprhdlr->print(set->scip, expr, stage, currentchild, parentprecedence, file) );
907  }
908  else
909  {
910  /* default: <hdlrname>(<child1>, <child2>, ...) */
911  switch( stage )
912  {
914  {
915  SCIPmessageFPrintInfo(messagehdlr, file, "%s", SCIPexprhdlrGetName(expr->exprhdlr));
916  if( expr->nchildren > 0 )
917  {
918  SCIPmessageFPrintInfo(messagehdlr, file, "(");
919  }
920  break;
921  }
922 
924  {
925  assert(currentchild >= 0);
926  assert(currentchild < expr->nchildren);
927  if( currentchild < expr->nchildren-1 )
928  {
929  SCIPmessageFPrintInfo(messagehdlr, file, ", ");
930  }
931  else
932  {
933  SCIPmessageFPrintInfo(messagehdlr, file, ")");
934  }
935 
936  break;
937  }
938 
941  default:
942  break;
943  }
944  }
945 
946  return SCIP_OKAY;
947 }
948 
949 /** calls the parse callback of an expression handler
950  *
951  * The method parses an expression.
952  * It should be called when parsing an expression and an operator with the expr handler name is found.
953  *
954  * @see SCIP_DECL_EXPRPARSE
955  */
957  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
958  SCIP_SET* set, /**< global SCIP settings */
959  const char* string, /**< string containing expression to be parse */
960  const char** endstring, /**< buffer to store the position of string after parsing */
961  SCIP_EXPR** expr, /**< buffer to store the parsed expression */
962  SCIP_Bool* success, /**< buffer to store whether the parsing was successful or not */
963  SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call on expression copy to create ownerdata */
964  void* ownercreatedata /**< data to pass to ownercreate */
965  )
966 {
967  assert(exprhdlr != NULL);
968  assert(set != NULL);
969  assert(expr != NULL);
970 
971  *expr = NULL;
972 
973  if( exprhdlr->parse == NULL )
974  {
975  /* TODO we could just look for a comma separated list of operands and try to initialize the expr with this one?
976  * That would be sufficient for sin, cos, exp, log, abs, for example.
977  */
978  SCIPdebugMessage("Expression handler <%s> has no parsing method.\n", SCIPexprhdlrGetName(exprhdlr));
979  *success = FALSE;
980  return SCIP_OKAY;
981  }
982 
983  /* give control to exprhdlr's parser */
984  SCIP_CALL( exprhdlr->parse(set->scip, exprhdlr, string, endstring, expr, success, ownercreate, ownercreatedata) );
985 
986  assert(*success || (*expr == NULL));
987 
988  return SCIP_OKAY;
989 }
990 
991 /** calls the curvature check callback of an expression handler
992  *
993  * @see SCIP_DECL_EXPRCURVATURE
994  */
996  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
997  SCIP_SET* set, /**< global SCIP settings */
998  SCIP_EXPR* expr, /**< expression to check the curvature for */
999  SCIP_EXPRCURV exprcurvature, /**< desired curvature of this expression */
1000  SCIP_Bool* success, /**< buffer to store whether the desired curvature be obtained */
1001  SCIP_EXPRCURV* childcurv /**< array to store required curvature for each child */
1002  )
1003 {
1004  assert(exprhdlr != NULL);
1005  assert(set != NULL);
1006  assert(expr != NULL);
1007  assert(expr->exprhdlr == exprhdlr);
1008  assert(success != NULL);
1009 
1010  *success = FALSE;
1011 
1012  if( exprhdlr->curvature != NULL )
1013  {
1014  SCIP_CALL( exprhdlr->curvature(set->scip, expr, exprcurvature, success, childcurv) );
1015  }
1016 
1017  return SCIP_OKAY;
1018 }
1019 
1020 /** calls the monotonicity check callback of an expression handler
1021  *
1022  * @see SCIP_DECL_EXPRMONOTONICITY
1023  */
1025  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1026  SCIP_SET* set, /**< global SCIP settings */
1027  SCIP_EXPR* expr, /**< expression to check the monotonicity for */
1028  int childidx, /**< index of the considered child expression */
1029  SCIP_MONOTONE* result /**< buffer to store the monotonicity */
1030  )
1031 {
1032  assert(exprhdlr != NULL);
1033  assert(set != NULL);
1034  assert(expr != NULL);
1035  assert(expr->exprhdlr == exprhdlr);
1036  assert(result != NULL);
1037 
1038  *result = SCIP_MONOTONE_UNKNOWN;
1039 
1040  /* check whether the expression handler implements the monotonicity callback */
1041  if( exprhdlr->monotonicity != NULL )
1042  {
1043  SCIP_CALL( exprhdlr->monotonicity(set->scip, expr, childidx, result) );
1044  }
1045 
1046  return SCIP_OKAY;
1047 }
1048 
1049 /** calls the integrality check callback of an expression handler
1050  *
1051  * @see SCIP_DECL_EXPRINTEGRALITY
1052  */
1054  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1055  SCIP_SET* set, /**< global SCIP settings */
1056  SCIP_EXPR* expr, /**< expression to check integrality for */
1057  SCIP_Bool* isintegral /**< buffer to store whether expression is integral */
1058  )
1059 {
1060  assert(exprhdlr != NULL);
1061  assert(set != NULL);
1062  assert(expr != NULL);
1063  assert(expr->exprhdlr == exprhdlr);
1064  assert(isintegral != NULL);
1065 
1066  *isintegral = FALSE;
1067 
1068  /* check whether the expression handler implements the monotonicity callback */
1069  if( exprhdlr->integrality != NULL )
1070  {
1071  SCIP_CALL( exprhdlr->integrality(set->scip, expr, isintegral) );
1072  }
1073 
1074  return SCIP_OKAY;
1075 }
1076 
1077 /** calls the hash callback of an expression handler
1078  *
1079  * The method hashes an expression by taking the hashes of its children into account.
1080  *
1081  * @see SCIP_DECL_EXPRHASH
1082  */
1084  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1085  SCIP_SET* set, /**< global SCIP settings */
1086  SCIP_EXPR* expr, /**< expression to be hashed */
1087  unsigned int* hashkey, /**< buffer to store the hash value */
1088  unsigned int* childrenhashes /**< array with hash values of children */
1089  )
1090 {
1091  assert(exprhdlr != NULL);
1092  assert(set != NULL);
1093  assert(expr != NULL);
1094  assert(expr->exprhdlr == exprhdlr);
1095  assert(hashkey != NULL);
1096  assert(childrenhashes != NULL || expr->nchildren == 0);
1097 
1098  if( expr->exprhdlr->hash != NULL )
1099  {
1100  SCIP_CALL( expr->exprhdlr->hash(set->scip, expr, hashkey, childrenhashes) );
1101  }
1102  else
1103  {
1104  int i;
1105 
1106  /* compute initial hash from expression handler name if callback is not implemented
1107  * this can lead to more collisions and thus a larger number of expensive expression compare calls
1108  */
1109  *hashkey = 0;
1110  for( i = 0; expr->exprhdlr->name[i] != '\0'; i++ )
1111  *hashkey += (unsigned int) expr->exprhdlr->name[i]; /*lint !e571*/
1112 
1113  *hashkey = SCIPcalcFibHash((SCIP_Real)*hashkey);
1114 
1115  /* now make use of the hashkeys of the children */
1116  for( i = 0; i < expr->nchildren; ++i )
1117  *hashkey ^= childrenhashes[i];
1118  }
1119 
1120  return SCIP_OKAY;
1121 }
1122 
1123 /** calls the compare callback of an expression handler
1124  *
1125  * The method receives two expressions, expr1 and expr2, and returns
1126  * - -1 if expr1 < expr2,
1127  * - 0 if expr1 = expr2,
1128  * - 1 if expr1 > expr2.
1129  *
1130  * @see SCIP_DECL_EXPRCOMPARE
1131  */
1133  SCIP_SET* set, /**< global SCIP settings */
1134  SCIP_EXPR* expr1, /**< first expression in comparison */
1135  SCIP_EXPR* expr2 /**< second expression in comparison */
1136  )
1137 {
1138  int i;
1139 
1140  assert(expr1 != NULL);
1141  assert(expr2 != NULL);
1142  assert(expr1->exprhdlr == expr2->exprhdlr);
1143 
1144  if( expr1->exprhdlr->compare != NULL )
1145  {
1146  /* enforces OR1-OR4 */
1147  return expr1->exprhdlr->compare(set->scip, expr1, expr2);
1148  }
1149 
1150  /* enforces OR5: default comparison method of expressions of the same type:
1151  * expr1 < expr2 if and only if expr1_i = expr2_i for all i < k and expr1_k < expr2_k.
1152  * if there is no such k, use number of children to decide
1153  * if number of children is equal, both expressions are equal
1154  * @note: Warning, this method doesn't know about expression data. So if your expressions have special data,
1155  * you must implement the compare callback: SCIP_DECL_EXPRCOMPARE
1156  */
1157  for( i = 0; i < expr1->nchildren && i < expr2->nchildren; ++i )
1158  {
1159  int compareresult = SCIPexprCompare(set, expr1->children[i], expr2->children[i]);
1160  if( compareresult != 0 )
1161  return compareresult;
1162  }
1163 
1164  return expr1->nchildren == expr2->nchildren ? 0 : expr1->nchildren < expr2->nchildren ? -1 : 1;
1165 }
1166 
1167 /** calls the evaluation callback of an expression handler
1168  *
1169  * The method evaluates an expression by taking the values of its children into account.
1170  *
1171  * Further, allows to evaluate w.r.t. given expression and children values instead of those stored in children expressions.
1172  *
1173  * @see SCIP_DECL_EXPREVAL
1174  */
1176  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1177  SCIP_SET* set, /**< global SCIP settings */
1178  BMS_BUFMEM* bufmem, /**< buffer memory, can be NULL if childrenvals is NULL */
1179  SCIP_EXPR* expr, /**< expression to be evaluated */
1180  SCIP_Real* val, /**< buffer to store value of expression */
1181  SCIP_Real* childrenvals, /**< values for children, or NULL if values stored in children should be used */
1182  SCIP_SOL* sol /**< solution that is evaluated (can be NULL) */
1183  )
1184 {
1185  SCIP_Real* origvals = NULL;
1186 
1187  assert(exprhdlr != NULL);
1188  assert(set != NULL);
1189  assert(expr != NULL);
1190  assert(expr->exprhdlr == exprhdlr);
1191  assert(exprhdlr->eval != NULL);
1192  assert(val != NULL);
1193 
1194  /* temporarily overwrite the evalvalue in all children with values from childrenvals */
1195  if( childrenvals != NULL && expr->nchildren > 0 )
1196  {
1197  int c;
1198 
1199  assert(bufmem != NULL);
1200 
1201  SCIP_ALLOC( BMSallocBufferMemoryArray(bufmem, &origvals, expr->nchildren) );
1202 
1203  for( c = 0; c < expr->nchildren; ++c )
1204  {
1205  origvals[c] = expr->children[c]->evalvalue;
1206  expr->children[c]->evalvalue = childrenvals[c];
1207  }
1208  }
1209 
1210  /* call expression eval callback */
1211  SCIP_CALL( exprhdlr->eval(set->scip, expr, val, sol) );
1212 
1213  /* if there was some evaluation error (e.g., overflow) that hasn't been caught yet, then do so now */
1214  if( !SCIPisFinite(*val) )
1215  *val = SCIP_INVALID;
1216 
1217  /* restore original evalvalues in children */
1218  if( origvals != NULL )
1219  {
1220  int c;
1221  for( c = 0; c < expr->nchildren; ++c )
1222  expr->children[c]->evalvalue = origvals[c];
1223 
1224  BMSfreeBufferMemoryArray(bufmem, &origvals);
1225  }
1226 
1227  return SCIP_OKAY;
1228 }
1229 
1230 /** calls the backward derivative evaluation callback of an expression handler
1231  *
1232  * The method should compute the partial derivative of expr w.r.t its child at childidx.
1233  * That is, it returns
1234  * \f[
1235  * \frac{\partial \text{expr}}{\partial \text{child}_{\text{childidx}}}
1236  * \f]
1237  *
1238  * Further, allows to differentiate w.r.t. given expression and children values instead of those stored in children expressions.
1239  *
1240  * @see SCIP_DECL_EXPRBWDIFF
1241  */
1243  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1244  SCIP_SET* set, /**< global SCIP settings */
1245  BMS_BUFMEM* bufmem, /**< buffer memory, can be NULL if childrenvals is NULL */
1246  SCIP_EXPR* expr, /**< expression to be differentiated */
1247  int childidx, /**< index of the child */
1248  SCIP_Real* derivative, /**< buffer to store the partial derivative w.r.t. the i-th children */
1249  SCIP_Real* childrenvals, /**< values for children, or NULL if values stored in children should be used */
1250  SCIP_Real exprval /**< value for expression, used only if childrenvals is not NULL */
1251  )
1252 {
1253  SCIP_Real* origchildrenvals;
1254  SCIP_Real origexprval;
1255  int c;
1256 
1257  assert(exprhdlr != NULL);
1258  assert(set != NULL);
1259  assert(expr != NULL);
1260  assert(expr->exprhdlr == exprhdlr);
1261  assert(derivative != NULL);
1262 
1263  if( exprhdlr->bwdiff == NULL )
1264  {
1265  *derivative = SCIP_INVALID;
1266  return SCIP_OKAY;
1267  }
1268 
1269  if( childrenvals != NULL )
1270  {
1271  /* temporarily overwrite the evalvalue in all children and expr with values from childrenvals and exprval, resp. */
1272  if( expr->nchildren > 0 )
1273  {
1274  assert(bufmem != NULL);
1275  SCIP_ALLOC( BMSallocBufferMemoryArray(bufmem, &origchildrenvals, expr->nchildren) );
1276 
1277  for( c = 0; c < expr->nchildren; ++c )
1278  {
1279  origchildrenvals[c] = expr->children[c]->evalvalue;
1280  expr->children[c]->evalvalue = childrenvals[c];
1281  }
1282  }
1283 
1284  origexprval = expr->evalvalue;
1285  expr->evalvalue = exprval;
1286  }
1287 
1288  SCIP_CALL( expr->exprhdlr->bwdiff(set->scip, expr, childidx, derivative) );
1289 
1290  /* if there was some evaluation error (e.g., overflow) that hasn't been caught yet, then do so now */
1291  if( !SCIPisFinite(*derivative) )
1292  *derivative = SCIP_INVALID;
1293 
1294  /* restore original evalvalues in children */
1295  if( childrenvals != NULL )
1296  {
1297  if( expr->nchildren > 0 )
1298  {
1299  for( c = 0; c < expr->nchildren; ++c )
1300  expr->children[c]->evalvalue = origchildrenvals[c]; /*lint !e644*/
1301 
1302  BMSfreeBufferMemoryArray(bufmem, &origchildrenvals);
1303  }
1304 
1305  expr->evalvalue = origexprval; /*lint !e644*/
1306  }
1307 
1308  return SCIP_OKAY;
1309 }
1310 
1311 /** calls the forward differentiation callback of an expression handler
1312  *
1313  * @see SCIP_DECL_EXPRFWDIFF
1314  */
1316  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1317  SCIP_SET* set, /**< global SCIP settings */
1318  SCIP_EXPR* expr, /**< expression to be differentiated */
1319  SCIP_Real* dot, /**< buffer to store derivative value */
1320  SCIP_SOL* direction /**< direction of the derivative (useful only for var expressions) */
1321  )
1322 {
1323  assert(exprhdlr != NULL);
1324  assert(set != NULL);
1325  assert(expr != NULL);
1326  assert(expr->exprhdlr == exprhdlr);
1327  assert(dot != NULL);
1328 
1329  if( exprhdlr->fwdiff == NULL )
1330  {
1331  *dot = SCIP_INVALID;
1332  return SCIP_OKAY;
1333  }
1334 
1335  SCIP_CALL( exprhdlr->fwdiff(set->scip, expr, dot, direction) );
1336 
1337  /* if there was some evaluation error (e.g., overflow) that hasn't been caught yet, then do so now */
1338  if( !SCIPisFinite(*dot) )
1339  *dot = SCIP_INVALID;
1340 
1341  return SCIP_OKAY;
1342 }
1343 
1344 /** calls the evaluation and forward-differentiation callback of an expression handler
1345  *
1346  * The method evaluates an expression by taking the values of its children into account.
1347  * The method differentiates an expression by taking the values and directional derivatives of its children into account.
1348  *
1349  * Further, allows to evaluate and differentiate w.r.t. given values for children instead of those stored in children expressions.
1350  *
1351  * It probably doesn't make sense to call this function for a variable-expression if sol and/or direction are not given.
1352  *
1353  * @see SCIP_DECL_EXPREVAL
1354  * @see SCIP_DECL_EXPRFWDIFF
1355  */
1357  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1358  SCIP_SET* set, /**< global SCIP settings */
1359  BMS_BUFMEM* bufmem, /**< buffer memory, can be NULL if childrenvals is NULL */
1360  SCIP_EXPR* expr, /**< expression to be evaluated */
1361  SCIP_Real* val, /**< buffer to store value of expression */
1362  SCIP_Real* dot, /**< buffer to store derivative value */
1363  SCIP_Real* childrenvals, /**< values for children, or NULL if values stored in children should
1364  be used */
1365  SCIP_SOL* sol, /**< solution that is evaluated (can be NULL) */
1366  SCIP_Real* childrendirs, /**< directional derivatives for children, or NULL if dot-values stored
1367  in children should be used */
1368  SCIP_SOL* direction /**< direction of the derivative (useful only for var expressions, can
1369  be NULL if childrendirs is given) */
1370  )
1371 {
1372  SCIP_Real origval;
1373  SCIP_Real* origvals = NULL;
1374  SCIP_Real* origdots = NULL;
1375 
1376  assert(exprhdlr != NULL);
1377  assert(set != NULL);
1378  assert(expr != NULL);
1379  assert(expr->exprhdlr == exprhdlr);
1380  assert(exprhdlr->eval != NULL);
1381  assert(val != NULL);
1382  assert(dot != NULL);
1383 
1384  /* temporarily overwrite the evalvalue in all children with values from childrenvals */
1385  if( childrenvals != NULL && expr->nchildren > 0 )
1386  {
1387  int c;
1388 
1389  assert(bufmem != NULL);
1390 
1391  SCIP_ALLOC( BMSallocBufferMemoryArray(bufmem, &origvals, expr->nchildren) );
1392 
1393  for( c = 0; c < expr->nchildren; ++c )
1394  {
1395  origvals[c] = expr->children[c]->evalvalue;
1396  expr->children[c]->evalvalue = childrenvals[c];
1397  }
1398  }
1399 
1400  /* temporarily overwrite the dot in all children with values from childrendirs */
1401  if( childrendirs != NULL && expr->nchildren > 0 )
1402  {
1403  int c;
1404 
1405  assert(bufmem != NULL);
1406 
1407  SCIP_ALLOC( BMSallocBufferMemoryArray(bufmem, &origdots, expr->nchildren) );
1408 
1409  for( c = 0; c < expr->nchildren; ++c )
1410  {
1411  origdots[c] = expr->children[c]->dot;
1412  expr->children[c]->dot = childrendirs[c];
1413  }
1414  }
1415 
1416  /* remember original value */
1417  origval = expr->evalvalue;
1418 
1419  /* call expression eval callback */
1420  SCIP_CALL( exprhdlr->eval(set->scip, expr, val, sol) );
1421 
1422  /* if there was some evaluation error (e.g., overflow) that hasn't been caught yet, then do so now */
1423  if( !SCIPisFinite(*val) )
1424  *val = SCIP_INVALID;
1425 
1426  /* temporarily overwrite evalvalue of expr, since some exprhdlr (e.g., product) access this value in fwdiff */
1427  expr->evalvalue = *val;
1428 
1429  /* call forward-differentiation callback (if available) */
1430  SCIP_CALL( SCIPexprhdlrFwDiffExpr(exprhdlr, set, expr, dot, direction) );
1431 
1432  /* restore original value */
1433  expr->evalvalue = origval;
1434 
1435  /* restore original dots in children */
1436  if( origdots != NULL )
1437  {
1438  int c;
1439  for( c = 0; c < expr->nchildren; ++c )
1440  expr->children[c]->dot = origdots[c];
1441 
1442  BMSfreeBufferMemoryArray(bufmem, &origdots);
1443  }
1444 
1445  /* restore original evalvalues in children */
1446  if( origvals != NULL )
1447  {
1448  int c;
1449  for( c = 0; c < expr->nchildren; ++c )
1450  expr->children[c]->evalvalue = origvals[c];
1451 
1452  BMSfreeBufferMemoryArray(bufmem, &origvals);
1453  }
1454 
1455  return SCIP_OKAY;
1456 }
1457 
1458 /** calls the evaluation callback for Hessian directions (backward over forward) of an expression handler
1459  *
1460  * @see SCIP_DECL_EXPRBWFWDIFF
1461  */
1463  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1464  SCIP_SET* set, /**< global SCIP settings */
1465  SCIP_EXPR* expr, /**< expression to be differentiated */
1466  int childidx, /**< index of the child */
1467  SCIP_Real* bardot, /**< buffer to store derivative value */
1468  SCIP_SOL* direction /**< direction of the derivative (useful only for var expressions) */
1469  )
1470 {
1471  assert(exprhdlr != NULL);
1472  assert(set != NULL);
1473  assert(expr != NULL);
1474  assert(expr->exprhdlr == exprhdlr);
1475  assert(childidx >= 0);
1476  assert(childidx < expr->nchildren);
1477  assert(bardot != NULL);
1478 
1479  if( exprhdlr->bwfwdiff == NULL )
1480  {
1481  *bardot = SCIP_INVALID;
1482  return SCIP_OKAY;
1483  }
1484 
1485  SCIP_CALL( expr->exprhdlr->bwfwdiff(set->scip, expr, childidx, bardot, direction) );
1486 
1487  /* if there was some evaluation error (e.g., overflow) that hasn't been caught yet, then do so now */
1488  if( !SCIPisFinite(*bardot) )
1489  *bardot = SCIP_INVALID;
1490 
1491  return SCIP_OKAY;
1492 }
1493 
1494 /** calls the interval evaluation callback of an expression handler
1495  *
1496  * @see SCIP_DECL_EXPRINTEVAL
1497  */
1499  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1500  SCIP_SET* set, /**< global SCIP settings */
1501  SCIP_EXPR* expr, /**< expression to be evaluated */
1502  SCIP_INTERVAL* interval, /**< buffer where to store interval */
1503  SCIP_DECL_EXPR_INTEVALVAR((*intevalvar)), /**< callback to be called when interval-evaluating a variable */
1504  void* intevalvardata /**< data to be passed to intevalvar callback */
1505  )
1506 {
1507  assert(exprhdlr != NULL);
1508  assert(set != NULL);
1509  assert(expr != NULL);
1510  assert(expr->exprhdlr == exprhdlr);
1511  assert(interval != NULL);
1512 
1513  if( exprhdlr->inteval != NULL )
1514  {
1515  SCIPclockStart(exprhdlr->intevaltime, set);
1516  SCIP_CALL( exprhdlr->inteval(set->scip, expr, interval, intevalvar, intevalvardata) );
1517  SCIPclockStop(exprhdlr->intevaltime, set);
1518 
1519  ++exprhdlr->nintevalcalls;
1520  }
1521 
1522  return SCIP_OKAY;
1523 }
1524 
1525 /** calls the estimator callback of an expression handler
1526  *
1527  * @see SCIP_DECL_EXPRESTIMATE
1528  */
1530  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1531  SCIP_SET* set, /**< global SCIP settings */
1532  SCIP_EXPR* expr, /**< expression to be estimated */
1533  SCIP_INTERVAL* localbounds, /**< current bounds for children */
1534  SCIP_INTERVAL* globalbounds, /**< global bounds for children */
1535  SCIP_Real* refpoint, /**< children values for the reference point where to estimate */
1536  SCIP_Bool overestimate, /**< whether the expression needs to be over- or underestimated */
1537  SCIP_Real targetvalue, /**< a value that the estimator shall exceed, can be +/-infinity */
1538  SCIP_Real* coefs, /**< array to store coefficients of estimator */
1539  SCIP_Real* constant, /**< buffer to store constant part of estimator */
1540  SCIP_Bool* islocal, /**< buffer to store whether estimator is valid locally only */
1541  SCIP_Bool* success, /**< buffer to indicate whether an estimator could be computed */
1542  SCIP_Bool* branchcand /**< array to indicate which children (not) to consider for branching */
1543  )
1544 {
1545  assert(exprhdlr != NULL);
1546  assert(set != NULL);
1547  assert(expr != NULL);
1548  assert(expr->exprhdlr == exprhdlr);
1549  assert(coefs != NULL);
1550  assert(islocal != NULL);
1551  assert(success != NULL);
1552 
1553  *success = FALSE;
1554 
1555  if( exprhdlr->estimate != NULL )
1556  {
1557  SCIPclockStart(exprhdlr->estimatetime, set);
1558  SCIP_CALL( exprhdlr->estimate(set->scip, expr, localbounds, globalbounds, refpoint, overestimate, targetvalue,
1559  coefs, constant, islocal, success, branchcand) );
1560  SCIPclockStop(exprhdlr->estimatetime, set);
1561 
1562  /* update statistics */
1563  ++exprhdlr->nestimatecalls;
1564  }
1565 
1566  return SCIP_OKAY;
1567 }
1568 
1569 /** calls the intitial estimators callback of an expression handler
1570  *
1571  * @see SCIP_DECL_EXPRINITESTIMATES
1572  */
1574  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1575  SCIP_SET* set, /**< global SCIP settings */
1576  SCIP_EXPR* expr, /**< expression to be estimated */
1577  SCIP_INTERVAL* bounds, /**< bounds for children */
1578  SCIP_Bool overestimate, /**< whether the expression shall be overestimated or underestimated */
1579  SCIP_Real* coefs[SCIP_EXPR_MAXINITESTIMATES], /**< buffer to store coefficients of computed estimators */
1580  SCIP_Real constant[SCIP_EXPR_MAXINITESTIMATES], /**< buffer to store constant of computed estimators */
1581  int* nreturned /**< buffer to store number of estimators that have been computed */
1582  )
1583 {
1584  assert(exprhdlr != NULL);
1585  assert(set != NULL);
1586  assert(expr != NULL);
1587  assert(expr->exprhdlr == exprhdlr);
1588  assert(nreturned != NULL);
1589 
1590  *nreturned = 0;
1591 
1592  if( exprhdlr->initestimates )
1593  {
1594  SCIPclockStart(expr->exprhdlr->estimatetime, set);
1595  SCIP_CALL( exprhdlr->initestimates(set->scip, expr, bounds, overestimate, coefs, constant, nreturned) );
1596  SCIPclockStop(expr->exprhdlr->estimatetime, set);
1597 
1598  ++exprhdlr->nestimatecalls;
1599  }
1600 
1601  return SCIP_OKAY;
1602 }
1603 
1604 /** calls the simplification callback of an expression handler
1605  *
1606  * @see SCIP_DECL_EXPRSIMPLIFY
1607  */
1609  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1610  SCIP_SET* set, /**< global SCIP settings */
1611  SCIP_EXPR* expr, /**< expression to simplify */
1612  SCIP_EXPR** simplifiedexpr, /**< buffer to store the simplified expression */
1613  SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call on expression copy to create ownerdata */
1614  void* ownercreatedata /**< data to pass to ownercreate */
1615  )
1616 {
1617  assert(exprhdlr != NULL);
1618  assert(set != NULL);
1619  assert(expr != NULL);
1620  assert(expr->exprhdlr == exprhdlr);
1621  assert(simplifiedexpr != NULL);
1622 
1623  if( exprhdlr->simplify != NULL )
1624  {
1625  SCIPclockStart(expr->exprhdlr->simplifytime, set);
1626  SCIP_CALL( exprhdlr->simplify(set->scip, expr, simplifiedexpr, ownercreate, ownercreatedata) );
1627  SCIPclockStop(expr->exprhdlr->simplifytime, set);
1628 
1629  /* update statistics */
1630  ++exprhdlr->nsimplifycalls;
1631  if( expr != *simplifiedexpr )
1632  ++exprhdlr->nsimplified;
1633  }
1634  else
1635  {
1636  *simplifiedexpr = expr;
1637 
1638  /* if an expression handler doesn't implement simplify, we assume that it is already simplified
1639  * we have to capture it, since it must simulate a "normal" simplified call in which a new expression is created
1640  */
1641  SCIPexprCapture(expr);
1642  }
1643 
1644  return SCIP_OKAY;
1645 }
1646 
1647 /** calls the reverse propagation callback of an expression handler
1648  *
1649  * The method propagates given bounds over the children of an expression.
1650  *
1651  * @see SCIP_DECL_EXPRREVERSEPROP
1652  */
1654  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1655  SCIP_SET* set, /**< global SCIP settings */
1656  SCIP_EXPR* expr, /**< expression to propagate */
1657  SCIP_INTERVAL bounds, /**< the bounds on the expression that should be propagated */
1658  SCIP_INTERVAL* childrenbounds, /**< array to store computed bounds for children, initialized with
1659  current activity */
1660  SCIP_Bool* infeasible /**< buffer to store whether a children bounds were propagated to
1661  an empty interval */
1662  )
1663 {
1664  assert(exprhdlr != NULL);
1665  assert(set != NULL);
1666  assert(expr != NULL);
1667  assert(expr->exprhdlr == exprhdlr);
1668  assert(childrenbounds != NULL || expr->nchildren == 0);
1669  assert(infeasible != NULL);
1670 
1671  *infeasible = FALSE;
1672 
1673  if( exprhdlr->reverseprop != NULL )
1674  {
1675  SCIPclockStart(exprhdlr->proptime, set);
1676  SCIP_CALL( exprhdlr->reverseprop(set->scip, expr, bounds, childrenbounds, infeasible) );
1677  SCIPclockStop(exprhdlr->proptime, set);
1678 
1679  /* update statistics */
1680  if( *infeasible )
1681  ++expr->exprhdlr->ncutoffs;
1682  ++expr->exprhdlr->npropcalls;
1683  }
1684 
1685  return SCIP_OKAY;
1686 }
1687 
1688 /**@name Expression Methods */
1689 /**@{ */
1690 
1691 /* from expr.h */
1692 
1693 #ifdef NDEBUG
1694 #undef SCIPexprCapture
1695 #undef SCIPexprIsVar
1696 #undef SCIPexprIsValue
1697 #undef SCIPexprIsSum
1698 #undef SCIPexprIsProduct
1699 #undef SCIPexprIsPower
1700 #endif
1701 
1702 /** creates and captures an expression with given expression data and children */
1704  SCIP_SET* set, /**< global SCIP settings */
1705  BMS_BLKMEM* blkmem, /**< block memory */
1706  SCIP_EXPR** expr, /**< pointer where to store expression */
1707  SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1708  SCIP_EXPRDATA* exprdata, /**< expression data (expression assumes ownership) */
1709  int nchildren, /**< number of children */
1710  SCIP_EXPR** children, /**< children (can be NULL if nchildren is 0) */
1711  SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
1712  void* ownercreatedata /**< data to pass to ownercreate */
1713  )
1714 {
1715  int c;
1716 
1717  assert(set != NULL);
1718  assert(blkmem != NULL);
1719  assert(expr != NULL);
1720  assert(exprhdlr != NULL);
1721  assert(children != NULL || nchildren == 0);
1722  assert(exprdata == NULL || exprhdlr->copydata != NULL); /* copydata must be available if there is expression data */
1723  assert(exprdata == NULL || exprhdlr->freedata != NULL); /* freedata must be available if there is expression data */
1724 
1725  SCIP_ALLOC( BMSallocClearBlockMemory(blkmem, expr) );
1726 
1727  (*expr)->exprhdlr = exprhdlr;
1728  (*expr)->exprdata = exprdata;
1729  (*expr)->activitytag = -1; /* to be less than initial domchgcount */
1730  (*expr)->curvature = SCIP_EXPRCURV_UNKNOWN;
1731 
1732  /* initialize activity to entire interval */
1733  SCIPintervalSetEntire(SCIP_INTERVAL_INFINITY, &(*expr)->activity);
1734 
1735  if( nchildren > 0 )
1736  {
1737  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*expr)->children, children, nchildren) );
1738  (*expr)->nchildren = nchildren;
1739  (*expr)->childrensize = nchildren;
1740 
1741  for( c = 0; c < nchildren; ++c )
1742  SCIPexprCapture((*expr)->children[c]);
1743  }
1744 
1745  SCIPexprCapture(*expr);
1746 
1747  ++exprhdlr->ncreated;
1748 
1749  /* initializes the ownerdata */
1750  if( ownercreate != NULL )
1751  {
1752  SCIP_CALL( ownercreate(set->scip, *expr, &(*expr)->ownerdata, &(*expr)->ownerfree, &(*expr)->ownerprint,
1753  &(*expr)->ownerevalactivity, ownercreatedata) );
1754  }
1755 
1756  return SCIP_OKAY;
1757 }
1758 
1759 /** appends child to the children list of expr */
1761  SCIP_SET* set, /**< global SCIP settings */
1762  BMS_BLKMEM* blkmem, /**< block memory */
1763  SCIP_EXPR* expr, /**< expression */
1764  SCIP_EXPR* child /**< expression to be appended */
1765  )
1766 {
1767  assert(set != NULL);
1768  assert(blkmem != NULL);
1769  assert(child != NULL);
1770  assert(expr->nchildren <= expr->childrensize);
1771 
1772  if( expr->nchildren == expr->childrensize )
1773  {
1774  expr->childrensize = SCIPsetCalcMemGrowSize(set, expr->nchildren+1);
1775  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &expr->children, expr->nchildren, expr->childrensize) );
1776  }
1777 
1778  expr->children[expr->nchildren] = child;
1779  ++expr->nchildren;
1780 
1781  /* capture child */
1782  SCIPexprCapture(child);
1783 
1784  return SCIP_OKAY;
1785 }
1786 
1787 /** overwrites/replaces a child of an expressions
1788  *
1789  * @note the old child is released and the newchild is captured, unless they are the same (=same pointer)
1790  */
1792  SCIP_SET* set, /**< global SCIP settings */
1793  SCIP_STAT* stat, /**< dynamic problem statistics */
1794  BMS_BLKMEM* blkmem, /**< block memory */
1795  SCIP_EXPR* expr, /**< expression where a child is going to be replaced */
1796  int childidx, /**< index of child being replaced */
1797  SCIP_EXPR* newchild /**< the new child */
1798  )
1799 {
1800  assert(set != NULL);
1801  assert(blkmem != NULL);
1802  assert(expr != NULL);
1803  assert(newchild != NULL);
1804  assert(childidx >= 0);
1805  assert(childidx < expr->nchildren);
1806 
1807  /* do nothing if child is not changing */
1808  if( newchild == expr->children[childidx] )
1809  return SCIP_OKAY;
1810 
1811  /* capture new child (do this before releasing the old child in case there are equal */
1812  SCIPexprCapture(newchild);
1813 
1814  SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &(expr->children[childidx])) );
1815  expr->children[childidx] = newchild;
1816 
1817  return SCIP_OKAY;
1818 }
1819 
1820 /** remove all children of expr */
1822  SCIP_SET* set, /**< global SCIP settings */
1823  SCIP_STAT* stat, /**< dynamic problem statistics */
1824  BMS_BLKMEM* blkmem, /**< block memory */
1825  SCIP_EXPR* expr /**< expression */
1826  )
1827 {
1828  int c;
1829 
1830  assert(set != NULL);
1831  assert(blkmem != NULL);
1832  assert(expr != NULL);
1833 
1834  for( c = 0; c < expr->nchildren; ++c )
1835  {
1836  assert(expr->children[c] != NULL);
1837  SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &(expr->children[c])) );
1838  }
1839 
1840  expr->nchildren = 0;
1841 
1842  return SCIP_OKAY;
1843 }
1844 
1845 /** copies an expression including subexpressions
1846  *
1847  * @note If copying fails due to an expression handler not being available in the targetscip, then *targetexpr will be set to NULL.
1848  *
1849  * For all or some expressions, a mapping to an existing expression can be specified via the mapexpr callback.
1850  * The mapped expression (including its children) will not be copied in this case and its ownerdata will not be touched.
1851  * If, however, the mapexpr callback returns NULL for the targetexpr, then the expr will be copied in the usual way.
1852  */
1854  SCIP_SET* set, /**< global SCIP settings */
1855  SCIP_STAT* stat, /**< dynamic problem statistics */
1856  BMS_BLKMEM* blkmem, /**< block memory */
1857  SCIP_SET* targetset, /**< global SCIP settings data structure where target expression will live */
1858  SCIP_STAT* targetstat, /**< dynamic problem statistics in target SCIP */
1859  BMS_BLKMEM* targetblkmem, /**< block memory in target SCIP */
1860  SCIP_EXPR* sourceexpr, /**< expression to be copied */
1861  SCIP_EXPR** targetexpr, /**< buffer to store pointer to copy of source expression */
1862  SCIP_DECL_EXPR_MAPEXPR((*mapexpr)), /**< expression mapping function, or NULL for creating new expressions */
1863  void* mapexprdata, /**< data of expression mapping function */
1864  SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call on expression copy to create ownerdata */
1865  void* ownercreatedata /**< data to pass to ownercreate */
1866  )
1867 {
1868  SCIP_EXPRITER* it;
1869  SCIP_EXPRITER_USERDATA expriteruserdata;
1870  SCIP_EXPR* expr;
1871  SCIP* sourcescip = set->scip; /* SCIP data structure corresponding to source expression */
1872  SCIP* targetscip = targetset->scip; /* SCIP data structure where target expression will live */
1873 
1874  assert(set != NULL);
1875  assert(stat != NULL);
1876  assert(blkmem != NULL);
1877  assert(targetset != NULL);
1878  assert(sourceexpr != NULL);
1879  assert(targetexpr != NULL);
1880  assert(sourcescip != NULL);
1881  assert(targetscip != NULL);
1882 
1883  SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
1884  SCIP_CALL( SCIPexpriterInit(it, sourceexpr, SCIP_EXPRITER_DFS, TRUE) ); /*TODO use FALSE, i.e., don't duplicate common subexpr? */
1886 
1887  expr = sourceexpr;
1888  while( !SCIPexpriterIsEnd(it) )
1889  {
1890  switch( SCIPexpriterGetStageDFS(it) )
1891  {
1893  {
1894  /* create expr that will hold the copy */
1895  SCIP_EXPRHDLR* targetexprhdlr;
1896  SCIP_EXPRDATA* targetexprdata;
1897  SCIP_EXPR* exprcopy = NULL;
1898 
1899  if( mapexpr != NULL )
1900  {
1901  SCIP_CALL( mapexpr(targetscip, &exprcopy, sourcescip, expr, ownercreate, ownercreatedata, mapexprdata) );
1902  if( exprcopy != NULL )
1903  {
1904  /* map callback gave us an expression to use for the copy */
1905  /* store targetexpr */
1906  expriteruserdata.ptrval = exprcopy;
1907  SCIPexpriterSetCurrentUserData(it, expriteruserdata);
1908 
1909  /* skip subexpression (assume that exprcopy is a complete copy) and continue */
1910  expr = SCIPexpriterSkipDFS(it);
1911  continue;
1912  }
1913  }
1914 
1915  /* get the exprhdlr of the target scip */
1916  if( targetscip != sourcescip )
1917  {
1918  targetexprhdlr = SCIPsetFindExprhdlr(targetset, expr->exprhdlr->name);
1919 
1920  if( targetexprhdlr == NULL )
1921  {
1922  /* expression handler not in target scip (probably did not have a copy callback) -> abort */
1923  expriteruserdata.ptrval = NULL;
1924  SCIPexpriterSetCurrentUserData(it, expriteruserdata);
1925 
1926  expr = SCIPexpriterSkipDFS(it);
1927  continue;
1928  }
1929  }
1930  else
1931  {
1932  targetexprhdlr = expr->exprhdlr;
1933  }
1934  assert(targetexprhdlr != NULL);
1935 
1936  /* copy expression data */
1937  if( expr->exprdata != NULL )
1938  {
1939  assert(expr->exprhdlr->copydata != NULL);
1940  SCIP_CALL( expr->exprhdlr->copydata(targetscip, targetexprhdlr, &targetexprdata, sourcescip, expr) );
1941  }
1942  else
1943  {
1944  targetexprdata = NULL;
1945  }
1946 
1947  /* create in targetexpr an expression of the same type as expr, but without children for now */
1948  SCIP_CALL( SCIPexprCreate(targetset, targetblkmem, &exprcopy, targetexprhdlr, targetexprdata, 0, NULL,
1949  ownercreate, ownercreatedata) );
1950 
1951  /* store targetexpr */
1952  expriteruserdata.ptrval = exprcopy;
1953  SCIPexpriterSetCurrentUserData(it, expriteruserdata);
1954 
1955  break;
1956  }
1957 
1959  {
1960  /* just visited child so a copy of himself should be available; append it */
1961  SCIP_EXPR* exprcopy;
1962  SCIP_EXPR* childcopy;
1963 
1965 
1966  /* get copy of child */
1968  if( childcopy == NULL )
1969  {
1970  /* abort */
1971  /* release exprcopy (should free also the already copied children) */
1972  SCIP_CALL( SCIPexprRelease(targetset, targetstat, targetblkmem, (SCIP_EXPR**)&exprcopy) );
1973 
1974  expriteruserdata.ptrval = NULL;
1975  SCIPexpriterSetCurrentUserData(it, expriteruserdata);
1976 
1977  expr = SCIPexpriterSkipDFS(it);
1978  continue;
1979  }
1980 
1981  /* append child to exprcopy */
1982  SCIP_CALL( SCIPexprAppendChild(targetset, targetblkmem, exprcopy, childcopy) );
1983 
1984  /* release childcopy (still captured by exprcopy) */
1985  SCIP_CALL( SCIPexprRelease(targetset, targetstat, targetblkmem, &childcopy) );
1986 
1987  break;
1988  }
1989 
1990  default:
1991  /* we should never be called in this stage */
1992  SCIPABORT();
1993  break;
1994  }
1995 
1996  expr = SCIPexpriterGetNext(it);
1997  }
1998 
1999  /* the target expression should be stored in the userdata of the sourceexpr (can be NULL if aborted) */
2000  *targetexpr = (SCIP_EXPR*)SCIPexpriterGetExprUserData(it, sourceexpr).ptrval;
2001 
2002  SCIPexpriterFree(&it);
2003 
2004  return SCIP_OKAY;
2005 }
2006 
2007 /** duplicates the given expression without its children */
2009  SCIP_SET* set, /**< global SCIP settings */
2010  BMS_BLKMEM* blkmem, /**< block memory */
2011  SCIP_EXPR* expr, /**< original expression */
2012  SCIP_EXPR** copyexpr, /**< buffer to store (shallow) duplicate of expr */
2013  SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call on expression copy to create ownerdata */
2014  void* ownercreatedata /**< data to pass to ownercreate */
2015  )
2016 {
2017  SCIP_EXPRDATA* exprdatacopy = NULL;
2018 
2019  assert(set != NULL);
2020  assert(blkmem != NULL);
2021  assert(expr != NULL);
2022  assert(copyexpr != NULL);
2023 
2024  /* copy expression data */
2025  if( expr->exprdata != NULL )
2026  {
2027  assert(expr->exprhdlr->copydata != NULL);
2028  SCIP_CALL( expr->exprhdlr->copydata(set->scip, expr->exprhdlr, &exprdatacopy, set->scip, expr) );
2029  }
2030 
2031  /* create expression with same handler and copied data, but without children */
2032  SCIP_CALL( SCIPexprCreate(set, blkmem, copyexpr, expr->exprhdlr, exprdatacopy, 0, NULL, ownercreate,
2033  ownercreatedata) );
2034 
2035  return SCIP_OKAY;
2036 }
2037 
2038 /** captures an expression (increments usage count) */
2040  SCIP_EXPR* expr /**< expression */
2041  )
2042 {
2043  assert(expr != NULL);
2044 
2045  ++expr->nuses;
2046 }
2047 
2048 /** releases an expression (decrements usage count and possibly frees expression) */
2050  SCIP_SET* set, /**< global SCIP settings */
2051  SCIP_STAT* stat, /**< dynamic problem statistics */
2052  BMS_BLKMEM* blkmem, /**< block memory */
2053  SCIP_EXPR** rootexpr /**< pointer to expression */
2054  )
2055 {
2056  SCIP_EXPRITER* it;
2057  SCIP_EXPR* expr;
2058 
2059  assert(rootexpr != NULL);
2060  assert(*rootexpr != NULL);
2061  assert((*rootexpr)->nuses > 0);
2062 
2063  if( (*rootexpr)->nuses > 1 )
2064  {
2065  --(*rootexpr)->nuses;
2066  *rootexpr = NULL;
2067 
2068  return SCIP_OKAY;
2069  }
2070 
2071  /* handle the root expr separately: free ownerdata, quaddata, and exprdata first */
2072 
2073  /* call ownerfree callback, if given
2074  * we intentially call this also if ownerdata is NULL, so owner can be notified without storing data
2075  */
2076  if( (*rootexpr)->ownerfree != NULL )
2077  {
2078  SCIP_CALL( (*rootexpr)->ownerfree(set->scip, *rootexpr, &(*rootexpr)->ownerdata) );
2079  assert((*rootexpr)->ownerdata == NULL);
2080  }
2081 
2082  /* free quadratic info */
2083  SCIPexprFreeQuadratic(blkmem, *rootexpr);
2084 
2085  /* free expression data */
2086  if( (*rootexpr)->exprdata != NULL )
2087  {
2088  assert((*rootexpr)->exprhdlr->freedata != NULL);
2089  SCIP_CALL( (*rootexpr)->exprhdlr->freedata(set->scip, *rootexpr) );
2090  }
2091 
2092  /* now release and free children, where no longer in use */
2093  SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
2094  SCIP_CALL( SCIPexpriterInit(it, *rootexpr, SCIP_EXPRITER_DFS, TRUE) );
2096  for( expr = SCIPexpriterGetCurrent(it); !SCIPexpriterIsEnd(it) ; )
2097  {
2098  /* expression should be used by its parent and maybe by the iterator (only the root!)
2099  * in VISITEDCHILD we assert that expression is only used by its parent
2100  */
2101  assert(expr != NULL);
2102  assert(0 <= expr->nuses && expr->nuses <= 2);
2103 
2104  switch( SCIPexpriterGetStageDFS(it) )
2105  {
2107  {
2108  /* check whether a child needs to be visited (nuses == 1)
2109  * if not, then we still have to release it
2110  */
2111  SCIP_EXPR* child;
2112 
2113  child = SCIPexpriterGetChildExprDFS(it);
2114  if( child->nuses > 1 )
2115  {
2116  /* child is not going to be freed: just release it */
2117  SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &child) );
2118  expr = SCIPexpriterSkipDFS(it);
2119  continue;
2120  }
2121 
2122  assert(child->nuses == 1);
2123 
2124  /* free child's quaddata, ownerdata, and exprdata when entering child */
2125  if( child->ownerfree != NULL )
2126  {
2127  SCIP_CALL( child->ownerfree(set->scip, child, &child->ownerdata) );
2128  assert(child->ownerdata == NULL);
2129  }
2130 
2131  /* free quadratic info */
2132  SCIPexprFreeQuadratic(blkmem, child);
2133 
2134  /* free expression data */
2135  if( child->exprdata != NULL )
2136  {
2137  assert(child->exprhdlr->freedata != NULL);
2138  SCIP_CALL( child->exprhdlr->freedata(set->scip, child) );
2139  assert(child->exprdata == NULL);
2140  }
2141 
2142  break;
2143  }
2144 
2146  {
2147  /* free child after visiting it */
2148  SCIP_EXPR* child;
2149 
2150  child = SCIPexpriterGetChildExprDFS(it);
2151  /* child should only be used by its parent */
2152  assert(child->nuses == 1);
2153 
2154  /* child should have no data associated */
2155  assert(child->exprdata == NULL);
2156 
2157  /* free child expression */
2158  SCIP_CALL( freeExpr(blkmem, &child) );
2160 
2161  break;
2162  }
2163 
2164  default:
2165  SCIPABORT(); /* we should never be called in this stage */
2166  break;
2167  }
2168 
2169  expr = SCIPexpriterGetNext(it);
2170  }
2171 
2172  SCIPexpriterFree(&it);
2173 
2174  /* handle the root expr separately: free its children and itself here */
2175  SCIP_CALL( freeExpr(blkmem, rootexpr) );
2176 
2177  return SCIP_OKAY;
2178 }
2179 
2180 /** returns whether an expression is a variable expression */
2182  SCIP_SET* set, /**< global SCIP settings */
2183  SCIP_EXPR* expr /**< expression */
2184  )
2185 {
2186  assert(set != NULL);
2187  assert(expr != NULL);
2188 
2189  return expr->exprhdlr == set->exprhdlrvar;
2190 }
2191 
2192 /** returns whether an expression is a value expression */
2194  SCIP_SET* set, /**< global SCIP settings */
2195  SCIP_EXPR* expr /**< expression */
2196  )
2197 {
2198  assert(set != NULL);
2199  assert(expr != NULL);
2200 
2201  return expr->exprhdlr == set->exprhdlrval;
2202 }
2203 
2204 /** returns whether an expression is a sum expression */
2206  SCIP_SET* set, /**< global SCIP settings */
2207  SCIP_EXPR* expr /**< expression */
2208  )
2209 {
2210  assert(set != NULL);
2211  assert(expr != NULL);
2212 
2213  return expr->exprhdlr == set->exprhdlrsum;
2214 }
2215 
2216 /** returns whether an expression is a product expression */
2218  SCIP_SET* set, /**< global SCIP settings */
2219  SCIP_EXPR* expr /**< expression */
2220  )
2221 {
2222  assert(set != NULL);
2223  assert(expr != NULL);
2224 
2225  return expr->exprhdlr == set->exprhdlrproduct;
2226 }
2227 
2228 /** returns whether an expression is a power expression */
2230  SCIP_SET* set, /**< global SCIP settings */
2231  SCIP_EXPR* expr /**< expression */
2232  )
2233 {
2234  assert(set != NULL);
2235  assert(expr != NULL);
2236 
2237  return expr->exprhdlr == set->exprhdlrpow;
2238 }
2239 
2240 /** print an expression as info-message */
2242  SCIP_SET* set, /**< global SCIP settings */
2243  SCIP_STAT* stat, /**< dynamic problem statistics */
2244  BMS_BLKMEM* blkmem, /**< block memory */
2245  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
2246  FILE* file, /**< file to print to, or NULL for stdout */
2247  SCIP_EXPR* expr /**< expression to be printed */
2248  )
2249 {
2250  SCIP_EXPRITER* it;
2251  SCIP_EXPRITER_STAGE stage;
2252  int currentchild;
2253  unsigned int parentprecedence;
2254 
2255  assert(set != NULL);
2256  assert(blkmem != NULL);
2257  assert(expr != NULL);
2258 
2259  SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
2262 
2263  while( !SCIPexpriterIsEnd(it) )
2264  {
2265  assert(expr->exprhdlr != NULL);
2266  stage = SCIPexpriterGetStageDFS(it);
2267 
2268  if( stage == SCIP_EXPRITER_VISITEDCHILD || stage == SCIP_EXPRITER_VISITINGCHILD )
2269  currentchild = SCIPexpriterGetChildIdxDFS(it);
2270  else
2271  currentchild = -1;
2272 
2273  if( SCIPexpriterGetParentDFS(it) != NULL )
2275  else
2276  parentprecedence = 0;
2277 
2278  SCIP_CALL( SCIPexprhdlrPrintExpr(expr->exprhdlr, set, messagehdlr, expr, stage, currentchild,
2279  parentprecedence, file) );
2280 
2281  expr = SCIPexpriterGetNext(it);
2282  }
2283 
2284  SCIPexpriterFree(&it);
2285 
2286  return SCIP_OKAY;
2287 }
2288 
2289 /** initializes printing of expressions in dot format to a give FILE* pointer */
2291  SCIP_SET* set, /**< global SCIP settings */
2292  SCIP_STAT* stat, /**< dynamic problem statistics */
2293  BMS_BLKMEM* blkmem, /**< block memory */
2294  SCIP_EXPRPRINTDATA** printdata, /**< buffer to store dot printing data */
2295  FILE* file, /**< file to print to, or NULL for stdout */
2296  SCIP_EXPRPRINT_WHAT whattoprint /**< info on what to print for each expression */
2297  )
2298 {
2299  assert(set != NULL);
2300  assert(stat != NULL);
2301  assert(blkmem != NULL);
2302  assert(printdata != NULL);
2303 
2304  if( file == NULL )
2305  file = stdout;
2306 
2307  SCIP_ALLOC( BMSallocBlockMemory(blkmem, printdata) );
2308 
2309  (*printdata)->file = file;
2310  SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &(*printdata)->iterator) );
2311  (*printdata)->closefile = FALSE;
2312  (*printdata)->whattoprint = whattoprint;
2313  SCIP_CALL( SCIPhashmapCreate(&(*printdata)->leaveexprs, blkmem, 100) );
2314 
2315  fputs("strict digraph exprgraph {\n", file);
2316  fputs("node [fontcolor=white, style=filled, rankdir=LR]\n", file);
2317 
2318  return SCIP_OKAY;
2319 }
2320 
2321 /** initializes printing of expressions in dot format to a file with given filename */
2323  SCIP_SET* set, /**< global SCIP settings */
2324  SCIP_STAT* stat, /**< dynamic problem statistics */
2325  BMS_BLKMEM* blkmem, /**< block memory */
2326  SCIP_EXPRPRINTDATA** printdata, /**< buffer to store dot printing data */
2327  const char* filename, /**< name of file to print to */
2328  SCIP_EXPRPRINT_WHAT whattoprint /**< info on what to print for each expression */
2329  )
2330 {
2331  FILE* f;
2332 
2333  assert(set != NULL);
2334  assert(stat != NULL);
2335  assert(blkmem != NULL);
2336  assert(printdata != NULL);
2337  assert(filename != NULL);
2338 
2339  f = fopen(filename, "w");
2340  if( f == NULL )
2341  {
2342  SCIPerrorMessage("could not open file <%s> for writing\n", filename); /* error code would be in errno */
2343  return SCIP_FILECREATEERROR;
2344  }
2345 
2346  SCIP_CALL( SCIPexprPrintDotInit(set, stat, blkmem, printdata, f, whattoprint) );
2347  (*printdata)->closefile = TRUE;
2348 
2349  return SCIP_OKAY;
2350 } /*lint !e429*/
2351 
2352 /** main part of printing an expression in dot format */
2354  SCIP_SET* set, /**< global SCIP settings */
2355  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
2356  SCIP_EXPRPRINTDATA* printdata, /**< data as initialized by \ref SCIPprintExprDotInit() */
2357  SCIP_EXPR* expr /**< expression to be printed */
2358  )
2359 {
2360  SCIP_Real color;
2361  int c;
2362 
2363  assert(set != NULL);
2364  assert(printdata != NULL);
2365  assert(expr != NULL);
2366  assert(expr->exprhdlr != NULL);
2367 
2368  SCIP_CALL( SCIPexpriterInit(printdata->iterator, expr, SCIP_EXPRITER_DFS, FALSE) );
2369 
2370  while( !SCIPexpriterIsEnd(printdata->iterator) )
2371  {
2372  /* print expression as dot node */
2373 
2374  if( expr->nchildren == 0 )
2375  {
2376  SCIP_CALL( SCIPhashmapInsert(printdata->leaveexprs, (void*)expr, NULL) );
2377  }
2378 
2379  /* make up some color from the expression type (it's name) */
2380  color = 0.0;
2381  for( c = 0; expr->exprhdlr->name[c] != '\0'; ++c )
2382  color += (tolower(expr->exprhdlr->name[c]) - 'a') / 26.0;
2383  color = SCIPsetFrac(set, color);
2384  fprintf(printdata->file, "n%p [fillcolor=\"%g,%g,%g\", label=\"", (void*)expr, color, color, color);
2385 
2386  if( printdata->whattoprint & SCIP_EXPRPRINT_EXPRHDLR )
2387  {
2388  fprintf(printdata->file, "%s\\n", expr->exprhdlr->name);
2389  }
2390 
2391  if( printdata->whattoprint & SCIP_EXPRPRINT_EXPRSTRING )
2392  {
2393  SCIP_CALL( SCIPexprhdlrPrintExpr(expr->exprhdlr, set, messagehdlr, expr, SCIP_EXPRITER_ENTEREXPR, -1, 0,
2394  printdata->file) );
2395  for( c = 0; c < expr->nchildren; ++c )
2396  {
2397  SCIP_CALL( SCIPexprhdlrPrintExpr(expr->exprhdlr, set, messagehdlr, expr, SCIP_EXPRITER_VISITINGCHILD,
2398  c, 0, printdata->file) );
2399  fprintf(printdata->file, "c%d", c);
2400  SCIP_CALL( SCIPexprhdlrPrintExpr(expr->exprhdlr, set, messagehdlr, expr, SCIP_EXPRITER_VISITEDCHILD,
2401  c, 0, printdata->file) );
2402  }
2403  SCIP_CALL( SCIPexprhdlrPrintExpr(expr->exprhdlr, set, messagehdlr, expr, SCIP_EXPRITER_LEAVEEXPR, -1, 0,
2404  printdata->file) );
2405 
2406  fputs("\\n", printdata->file);
2407  }
2408 
2409  if( printdata->whattoprint & SCIP_EXPRPRINT_NUSES )
2410  {
2411  /* print number of uses */
2412  fprintf(printdata->file, "%d uses\\n", expr->nuses);
2413  }
2414 
2415  if( printdata->whattoprint & SCIP_EXPRPRINT_OWNER )
2416  {
2417  /* print ownerdata */
2418  if( expr->ownerprint != NULL )
2419  {
2420  SCIP_CALL( expr->ownerprint(set->scip, printdata->file, expr, expr->ownerdata) );
2421  }
2422  else if( expr->ownerdata != NULL )
2423  {
2424  fprintf(printdata->file, "owner=%p\\n", (void*)expr->ownerdata);
2425  }
2426  }
2427 
2428  if( printdata->whattoprint & SCIP_EXPRPRINT_EVALVALUE )
2429  {
2430  /* print eval value */
2431  fprintf(printdata->file, "val=%g", expr->evalvalue);
2432 
2433  if( (printdata->whattoprint & SCIP_EXPRPRINT_EVALTAG) == SCIP_EXPRPRINT_EVALTAG )
2434  {
2435  /* print also eval tag */
2436  fprintf(printdata->file, " (%" SCIP_LONGINT_FORMAT ")", expr->evaltag);
2437  }
2438  fputs("\\n", printdata->file);
2439  }
2440 
2441  if( printdata->whattoprint & SCIP_EXPRPRINT_ACTIVITY )
2442  {
2443  /* print activity */
2444  fprintf(printdata->file, "[%g,%g]", expr->activity.inf, expr->activity.sup);
2445 
2446  if( (printdata->whattoprint & SCIP_EXPRPRINT_ACTIVITYTAG) == SCIP_EXPRPRINT_ACTIVITYTAG )
2447  {
2448  /* print also activity eval tag */
2449  fprintf(printdata->file, " (%" SCIP_LONGINT_FORMAT ")", expr->activitytag);
2450  }
2451  fputs("\\n", printdata->file);
2452  }
2453 
2454  fputs("\"]\n", printdata->file); /* end of label and end of node */
2455 
2456  /* add edges from expr to its children */
2457  for( c = 0; c < expr->nchildren; ++c )
2458  fprintf(printdata->file, "n%p -> n%p [label=\"c%d\"]\n", (void*)expr, (void*)expr->children[c], c);
2459 
2460  expr = SCIPexpriterGetNext(printdata->iterator);
2461  }
2462 
2463  return SCIP_OKAY;
2464 }
2465 
2466 /** finishes printing of expressions in dot format */
2468  SCIP_SET* set, /**< global SCIP settings */
2469  SCIP_STAT* stat, /**< dynamic problem statistics */
2470  BMS_BLKMEM* blkmem, /**< block memory */
2471  SCIP_EXPRPRINTDATA** printdata /**< buffer where dot printing data has been stored */
2472  )
2473 {
2474  SCIP_EXPR* expr;
2475  SCIP_HASHMAPENTRY* entry;
2476  FILE* file;
2477  int i;
2478 
2479  assert(set != NULL);
2480  assert(stat != NULL);
2481  assert(blkmem != NULL);
2482  assert(printdata != NULL);
2483  assert(*printdata != NULL);
2484 
2485  file = (*printdata)->file;
2486  assert(file != NULL);
2487 
2488  /* iterate through all entries of the map */
2489  fputs("{rank=same;", file);
2490  for( i = 0; i < SCIPhashmapGetNEntries((*printdata)->leaveexprs); ++i )
2491  {
2492  entry = SCIPhashmapGetEntry((*printdata)->leaveexprs, i);
2493 
2494  if( entry != NULL )
2495  {
2496  expr = (SCIP_EXPR*) SCIPhashmapEntryGetOrigin(entry);
2497  assert(expr != NULL);
2498  assert(expr->nchildren == 0);
2499 
2500  fprintf(file, " n%p", (void*)expr);
2501  }
2502  }
2503  fprintf(file, "}\n");
2504 
2505  fprintf(file, "}\n");
2506 
2507  SCIPhashmapFree(&(*printdata)->leaveexprs);
2508 
2509  SCIPexpriterFree(&(*printdata)->iterator);
2510 
2511  if( (*printdata)->closefile )
2512  fclose((*printdata)->file);
2513 
2514  BMSfreeBlockMemory(blkmem, printdata);
2515 
2516  return SCIP_OKAY;
2517 }
2518 
2519 /** prints structure of an expression a la Maple's dismantle */
2521  SCIP_SET* set, /**< global SCIP settings */
2522  SCIP_STAT* stat, /**< dynamic problem statistics */
2523  BMS_BLKMEM* blkmem, /**< block memory */
2524  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
2525  FILE* file, /**< file to print to, or NULL for stdout */
2526  SCIP_EXPR* expr /**< expression to dismantle */
2527  )
2528 {
2529  SCIP_EXPRITER* it;
2530  int depth = -1;
2531 
2532  assert(set != NULL);
2533  assert(stat != NULL);
2534  assert(blkmem != NULL);
2535  assert(messagehdlr != NULL);
2536  assert(expr != NULL);
2537 
2538  SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
2541 
2542  for( ; !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
2543  {
2544  switch( SCIPexpriterGetStageDFS(it) )
2545  {
2547  {
2548  int nspaces;
2549 
2550  ++depth;
2551  nspaces = 3 * depth;
2552 
2553  /* use depth of expression to align output */
2554  SCIPmessageFPrintInfo(messagehdlr, file, "%*s[%s]: ", nspaces, "", expr->exprhdlr->name);
2555 
2556  if( SCIPexprIsVar(set, expr) )
2557  {
2558  SCIP_VAR* var;
2559 
2560  var = SCIPgetVarExprVar(expr);
2561  SCIPmessageFPrintInfo(messagehdlr, file, "%s in [%g, %g]", SCIPvarGetName(var), SCIPvarGetLbLocal(var),
2562  SCIPvarGetUbLocal(var));
2563  }
2564  else if( SCIPexprIsSum(set, expr) )
2565  SCIPmessageFPrintInfo(messagehdlr, file, "%g", SCIPgetConstantExprSum(expr));
2566  else if( SCIPexprIsProduct(set, expr) )
2567  SCIPmessageFPrintInfo(messagehdlr, file, "%g", SCIPgetCoefExprProduct(expr));
2568  else if( SCIPexprIsValue(set, expr) )
2569  SCIPmessageFPrintInfo(messagehdlr, file, "%g", SCIPgetValueExprValue(expr));
2570  else if( SCIPexprIsPower(set, expr) || strcmp(expr->exprhdlr->name, "signpower") == 0)
2571  SCIPmessageFPrintInfo(messagehdlr, file, "%g", SCIPgetExponentExprPow(expr));
2572 
2573  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
2574 
2575  if( expr->ownerprint != NULL )
2576  {
2577  SCIPmessageFPrintInfo(messagehdlr, file, "%*s ", nspaces, "");
2578  SCIP_CALL( expr->ownerprint(set->scip, file, expr, expr->ownerdata) );
2579  }
2580 
2581  break;
2582  }
2583 
2585  {
2586  int nspaces = 3 * depth;
2587 
2588  if( SCIPexprIsSum(set, expr) )
2589  {
2590  SCIPmessageFPrintInfo(messagehdlr, file, "%*s ", nspaces, "");
2591  SCIPmessageFPrintInfo(messagehdlr, file, "[coef]: %g\n", SCIPgetCoefsExprSum(expr)[SCIPexpriterGetChildIdxDFS(it)]);
2592  }
2593 
2594  break;
2595  }
2596 
2598  {
2599  --depth;
2600  break;
2601  }
2602 
2603  default:
2604  /* shouldn't be here */
2605  SCIPABORT();
2606  break;
2607  }
2608  }
2609 
2610  SCIPexpriterFree(&it);
2611 
2612  return SCIP_OKAY;
2613 }
2614 
2615 /** evaluate an expression in a point
2616  *
2617  * Iterates over expressions to also evaluate children, if necessary.
2618  * Value can be received via SCIPexprGetEvalValue().
2619  * If an evaluation error (division by zero, ...) occurs, this value will
2620  * be set to SCIP_INVALID.
2621  *
2622  * If a nonzero \p soltag is passed, then only (sub)expressions are
2623  * reevaluated that have a different solution tag. If a soltag of 0
2624  * is passed, then subexpressions are always reevaluated.
2625  * The tag is stored together with the value and can be received via
2626  * SCIPexprGetEvalTag().
2627  */
2629  SCIP_SET* set, /**< global SCIP settings */
2630  SCIP_STAT* stat, /**< dynamic problem statistics */
2631  BMS_BLKMEM* blkmem, /**< block memory */
2632  SCIP_EXPR* expr, /**< expression to be evaluated */
2633  SCIP_SOL* sol, /**< solution to be evaluated */
2634  SCIP_Longint soltag /**< tag that uniquely identifies the solution (with its values), or 0. */
2635  )
2636 {
2637  SCIP_EXPRITER* it;
2638 
2639  assert(set != NULL);
2640  assert(stat != NULL);
2641  assert(blkmem != NULL);
2642  assert(expr != NULL);
2643 
2644  /* if value is up-to-date, then nothing to do */
2645  if( soltag != 0 && expr->evaltag == soltag )
2646  return SCIP_OKAY;
2647 
2648  /* assume we'll get a domain error, so we don't have to get this expr back if we abort the iteration
2649  * if there is no domain error, then we will overwrite the evalvalue in the last leaveexpr stage
2650  */
2651  expr->evalvalue = SCIP_INVALID;
2652  expr->evaltag = soltag;
2653 
2654  SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
2657 
2658  while( !SCIPexpriterIsEnd(it) )
2659  {
2660  switch( SCIPexpriterGetStageDFS(it) )
2661  {
2663  {
2664  SCIP_EXPR* child;
2665 
2666  if( soltag == 0 )
2667  break;
2668 
2669  /* check whether child has been evaluated for that solution already */
2670  child = SCIPexpriterGetChildExprDFS(it);
2671  if( soltag == child->evaltag )
2672  {
2673  if( child->evalvalue == SCIP_INVALID )
2674  goto TERMINATE;
2675 
2676  /* skip this child
2677  * this already returns the next one, so continue with loop
2678  */
2679  expr = SCIPexpriterSkipDFS(it);
2680  continue;
2681  }
2682 
2683  break;
2684  }
2685 
2687  {
2688  SCIP_CALL( SCIPexprhdlrEvalExpr(expr->exprhdlr, set, NULL , expr, &expr->evalvalue, NULL, sol) );
2689  expr->evaltag = soltag;
2690 
2691  if( expr->evalvalue == SCIP_INVALID )
2692  goto TERMINATE;
2693 
2694  break;
2695  }
2696 
2697  default :
2698  /* we should never be here */
2699  SCIPABORT();
2700  break;
2701  }
2702 
2703  expr = SCIPexpriterGetNext(it);
2704  }
2705 
2706 TERMINATE:
2707  SCIPexpriterFree(&it);
2708 
2709  return SCIP_OKAY;
2710 }
2711 
2712 /** evaluates gradient of an expression for a given point
2713  *
2714  * Initiates an expression walk to also evaluate children, if necessary.
2715  * Value can be received via SCIPgetExprPartialDiffNonlinear().
2716  * If an error (division by zero, ...) occurs, this value will
2717  * be set to SCIP_INVALID.
2718  */
2720  SCIP_SET* set, /**< global SCIP settings */
2721  SCIP_STAT* stat, /**< dynamic problem statistics */
2722  BMS_BLKMEM* blkmem, /**< block memory */
2723  SCIP_EXPR* rootexpr, /**< expression to be evaluated */
2724  SCIP_SOL* sol, /**< solution to be evaluated (NULL for the current LP solution) */
2725  SCIP_Longint soltag /**< tag that uniquely identifies the solution (with its values), or 0. */
2726  )
2727 {
2728  SCIP_EXPRITER* it;
2729  SCIP_EXPR* expr;
2730  SCIP_EXPR* child;
2731  SCIP_Real derivative;
2732  SCIP_Longint difftag;
2733 
2734  assert(set != NULL);
2735  assert(stat != NULL);
2736  assert(blkmem != NULL);
2737  assert(rootexpr != NULL);
2738 
2739  /* ensure expression is evaluated */
2740  SCIP_CALL( SCIPexprEval(set, stat, blkmem, rootexpr, sol, soltag) );
2741 
2742  /* check if expression could not be evaluated */
2743  if( SCIPexprGetEvalValue(rootexpr) == SCIP_INVALID )
2744  {
2745  rootexpr->derivative = SCIP_INVALID;
2746  return SCIP_OKAY;
2747  }
2748 
2749  if( SCIPexprIsValue(set, rootexpr) )
2750  {
2751  rootexpr->derivative = 0.0;
2752  return SCIP_OKAY;
2753  }
2754 
2755  difftag = ++(stat->exprlastdifftag);
2756 
2757  rootexpr->derivative = 1.0;
2758  rootexpr->difftag = difftag;
2759 
2760  SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
2761  SCIP_CALL( SCIPexpriterInit(it, rootexpr, SCIP_EXPRITER_DFS, TRUE) );
2763 
2764  for( expr = SCIPexpriterGetCurrent(it); !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
2765  {
2766  assert(expr->evalvalue != SCIP_INVALID);
2767 
2768  child = SCIPexpriterGetChildExprDFS(it);
2769  assert(child != NULL);
2770 
2771  /* reset the value of the partial derivative w.r.t. a variable expression if we see it for the first time */
2772  if( child->difftag != difftag && SCIPexprIsVar(set, child) )
2773  child->derivative = 0.0;
2774 
2775  /* update differentiation tag of the child */
2776  child->difftag = difftag;
2777 
2778  /* call backward differentiation callback */
2779  if( SCIPexprIsValue(set, child) )
2780  {
2781  derivative = 0.0;
2782  }
2783  else
2784  {
2785  derivative = SCIP_INVALID;
2787  &derivative, NULL, 0.0) );
2788 
2789  if( derivative == SCIP_INVALID )
2790  {
2791  rootexpr->derivative = SCIP_INVALID;
2792  break;
2793  }
2794  }
2795 
2796  /* update partial derivative stored in the child expression
2797  * for a variable, we have to sum up the partial derivatives of the root w.r.t. this variable over all parents
2798  * for other intermediate expressions, we only store the partial derivative of the root w.r.t. this expression
2799  */
2800  if( !SCIPexprIsVar(set, child) )
2801  child->derivative = expr->derivative * derivative;
2802  else
2803  child->derivative += expr->derivative * derivative;
2804  }
2805 
2806  SCIPexpriterFree(&it);
2807 
2808  return SCIP_OKAY;
2809 }
2810 
2811 /** evaluates Hessian-vector product of an expression for a given point and direction
2812  *
2813  * Evaluates children, if necessary.
2814  * Value can be received via SCIPgetExprPartialDiffGradientDirNonlinear()
2815  * If an error (division by zero, ...) occurs, this value will
2816  * be set to SCIP_INVALID.
2817  */
2819  SCIP_SET* set, /**< global SCIP settings */
2820  SCIP_STAT* stat, /**< dynamic problem statistics */
2821  BMS_BLKMEM* blkmem, /**< block memory */
2822  SCIP_EXPR* rootexpr, /**< expression to be evaluated */
2823  SCIP_SOL* sol, /**< solution to be evaluated (NULL for the current LP solution) */
2824  SCIP_Longint soltag, /**< tag that uniquely identifies the solution (with its values), or 0. */
2825  SCIP_SOL* direction /**< direction */
2826  )
2827 {
2828  SCIP_EXPRITER* it;
2829  SCIP_EXPR* expr;
2830  SCIP_EXPR* child;
2831  SCIP_Real derivative;
2832  SCIP_Real hessiandir;
2833 
2834  assert(set != NULL);
2835  assert(stat != NULL);
2836  assert(blkmem != NULL);
2837  assert(rootexpr != NULL);
2838 
2839  if( SCIPexprIsValue(set, rootexpr) )
2840  {
2841  rootexpr->dot = 0.0;
2842  rootexpr->bardot = 0.0;
2843  return SCIP_OKAY;
2844  }
2845 
2846  /* evaluate expression and directional derivative */
2847  SCIP_CALL( evalAndDiff(set, stat, blkmem, rootexpr, sol, soltag, direction) );
2848 
2849  if( rootexpr->evalvalue == SCIP_INVALID )
2850  {
2851  rootexpr->derivative = SCIP_INVALID;
2852  rootexpr->bardot = SCIP_INVALID;
2853  return SCIP_OKAY;
2854  }
2855 
2856  rootexpr->derivative = 1.0;
2857 
2858  SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
2859  SCIP_CALL( SCIPexpriterInit(it, rootexpr, SCIP_EXPRITER_DFS, TRUE) );
2861 
2862  /* compute reverse diff and bardots: i.e. hessian times direction */
2863  for( expr = SCIPexpriterGetCurrent(it); !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
2864  {
2865  assert(expr->evalvalue != SCIP_INVALID);
2866 
2867  child = SCIPexpriterGetChildExprDFS(it);
2868  assert(child != NULL);
2869 
2870  /* call backward and forward-backward differentiation callback */
2871  if( SCIPexprIsValue(set, child) )
2872  {
2873  derivative = 0.0;
2874  hessiandir = 0.0;
2875  }
2876  else
2877  {
2878  derivative = SCIP_INVALID;
2879  hessiandir = SCIP_INVALID;
2881  &derivative, NULL, SCIP_INVALID) );
2883  &hessiandir, NULL) );
2884 
2885  if( derivative == SCIP_INVALID || hessiandir == SCIP_INVALID )
2886  {
2887  rootexpr->derivative = SCIP_INVALID;
2888  rootexpr->bardot = SCIP_INVALID;
2889  break;
2890  }
2891  }
2892 
2893  /* update partial derivative and hessian stored in the child expression
2894  * for a variable, we have to sum up the partial derivatives of the root w.r.t. this variable over all parents
2895  * for other intermediate expressions, we only store the partial derivative of the root w.r.t. this expression
2896  */
2897  if( !SCIPexprIsVar(set, child) )
2898  {
2899  child->derivative = expr->derivative * derivative;
2900  child->bardot = expr->bardot * derivative + expr->derivative * hessiandir;
2901  }
2902  else
2903  {
2904  child->derivative += expr->derivative * derivative;
2905  child->bardot += expr->bardot * derivative + expr->derivative * hessiandir;
2906  }
2907  }
2908 
2909  SCIPexpriterFree(&it);
2910 
2911  return SCIP_OKAY;
2912 }
2913 
2914 /** possibly reevaluates and then returns the activity of the expression
2915  *
2916  * Reevaluate activity if currently stored is no longer uptodate.
2917  * If the expr owner provided a evalactivity-callback, then call this.
2918  * Otherwise, loop over descendants and compare activitytag with stat's domchgcount, i.e.,
2919  * whether some bound was changed since last evaluation, to check whether exprhdlrs INTEVAL should be called.
2920  *
2921  * @note If expression is set to be integral, then activities are tightened to integral values.
2922  * Thus, ensure that the integrality information is valid (if set to TRUE; the default (FALSE) is always ok).
2923  */
2925  SCIP_SET* set, /**< global SCIP settings */
2926  SCIP_STAT* stat, /**< dynamic problem statistics */
2927  BMS_BLKMEM* blkmem, /**< block memory */
2928  SCIP_EXPR* rootexpr /**< expression */
2929  )
2930 {
2931  SCIP_EXPRITER* it;
2932  SCIP_EXPR* expr;
2933 
2934  assert(set != NULL);
2935  assert(stat != NULL);
2936  assert(blkmem != NULL);
2937  assert(rootexpr != NULL);
2938 
2939  if( rootexpr->ownerevalactivity != NULL )
2940  {
2941  /* call owner callback for activity-eval */
2942  SCIP_CALL( rootexpr->ownerevalactivity(set->scip, rootexpr, rootexpr->ownerdata) );
2943 
2944  return SCIP_OKAY;
2945  }
2946 
2947  /* fallback if no callback is given */
2948 
2949  assert(rootexpr->activitytag <= stat->domchgcount);
2950 
2951  /* if value is up-to-date, then nothing to do */
2952  if( rootexpr->activitytag == stat->domchgcount )
2953  {
2954 #ifdef DEBUG_PROP
2955  SCIPsetDebugMsg(set, "activitytag of root expr equals domchgcount (%u), skip evalactivity\n", stat->domchgcount);
2956 #endif
2957 
2958  return SCIP_OKAY;
2959  }
2960 
2961  SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
2962  SCIP_CALL( SCIPexpriterInit(it, rootexpr, SCIP_EXPRITER_DFS, TRUE) );
2964 
2965  for( expr = SCIPexpriterGetCurrent(it); !SCIPexpriterIsEnd(it); )
2966  {
2967  switch( SCIPexpriterGetStageDFS(it) )
2968  {
2970  {
2971  /* skip child if it has been evaluated already */
2972  SCIP_EXPR* child;
2973 
2974  child = SCIPexpriterGetChildExprDFS(it);
2975  if( child->activitytag == stat->domchgcount )
2976  {
2977  expr = SCIPexpriterSkipDFS(it);
2978  continue;
2979  }
2980 
2981  break;
2982  }
2983 
2985  {
2986  /* we should not have entered this expression if its activity was already uptodate */
2987  assert(expr->activitytag < stat->domchgcount);
2988 
2989  /* reset activity to entire if invalid, so we can use it as starting point below */
2991 
2992 #ifdef DEBUG_PROP
2993  SCIPsetDebugMsg(set, "interval evaluation of expr %p ", (void*)expr);
2994  SCIP_CALL( SCIPprintExpr(set->scip, expr, NULL) );
2995  SCIPsetDebugMsgPrint(set, "\n");
2996 #endif
2997 
2998  /* call the inteval callback of the exprhdlr */
2999  SCIP_CALL( SCIPexprhdlrIntEvalExpr(expr->exprhdlr, set, expr, &expr->activity, NULL, NULL) );
3000 #ifdef DEBUG_PROP
3001  SCIPsetDebugMsg(set, " exprhdlr <%s>::inteval = [%.20g, %.20g]", expr->exprhdlr->name, expr->activity.inf,
3002  expr->activity.sup);
3003 #endif
3004 
3005  /* if expression is integral, then we try to tighten the interval bounds a bit
3006  * this should undo the addition of some unnecessary safety added by use of nextafter() in interval
3007  * arithmetics, e.g., when doing pow() it would be ok to use ceil() and floor(), but for safety we
3008  * use SCIPceil and SCIPfloor for now the default intevalVar does not relax variables, so can omit
3009  * expressions without children (constants should be ok, too)
3010  */
3011  if( expr->isintegral && expr->nchildren > 0 )
3012  {
3013  if( expr->activity.inf > -SCIP_INTERVAL_INFINITY )
3014  expr->activity.inf = SCIPsetCeil(set, expr->activity.inf);
3015  if( expr->activity.sup < SCIP_INTERVAL_INFINITY )
3016  expr->activity.sup = SCIPsetFloor(set, expr->activity.sup);
3017 #ifdef DEBUG_PROP
3018  SCIPsetDebugMsg(set, " applying integrality: [%.20g, %.20g]\n", expr->activity.inf, expr->activity.sup);
3019 #endif
3020  }
3021 
3022  /* mark activity as empty if either the lower/upper bound is above/below +/- SCIPinfinity()
3023  * TODO this is a problem if dual-presolve fixed a variable to +/- infinity
3024  */
3025  if( SCIPsetIsInfinity(set, expr->activity.inf) || SCIPsetIsInfinity(set, -expr->activity.sup) )
3026  {
3027  SCIPsetDebugMsg(set, "treat activity [%g,%g] as empty as beyond infinity\n", expr->activity.inf, expr->activity.sup);
3028  SCIPintervalSetEmpty(&expr->activity);
3029  }
3030 
3031  /* remember that activity is uptodate now */
3032  expr->activitytag = stat->domchgcount;
3033 
3034  break;
3035  }
3036 
3037  default:
3038  /* you should never be here */
3039  SCIPABORT();
3040  break;
3041  }
3042 
3043  expr = SCIPexpriterGetNext(it);
3044  }
3045 
3046  SCIPexpriterFree(&it);
3047 
3048  return SCIP_OKAY;
3049 }
3050 
3051 /** compare expressions
3052  *
3053  * @return -1, 0 or 1 if expr1 <, =, > expr2, respectively
3054  * @note The given expressions are assumed to be simplified.
3055  */
3057  SCIP_SET* set, /**< global SCIP settings */
3058  SCIP_EXPR* expr1, /**< first expression */
3059  SCIP_EXPR* expr2 /**< second expression */
3060  )
3061 {
3062  SCIP_EXPRHDLR* exprhdlr1;
3063  SCIP_EXPRHDLR* exprhdlr2;
3064  int retval;
3065 
3066  exprhdlr1 = expr1->exprhdlr;
3067  exprhdlr2 = expr2->exprhdlr;
3068 
3069  /* expressions are of the same kind/type; use compare callback or default method */
3070  if( exprhdlr1 == exprhdlr2 )
3071  return SCIPexprhdlrCompareExpr(set, expr1, expr2);
3072 
3073  /* expressions are of different kind/type */
3074  /* enforces OR6 */
3075  if( SCIPexprIsValue(set, expr1) )
3076  {
3077  return -1;
3078  }
3079  /* enforces OR12 */
3080  if( SCIPexprIsValue(set, expr2) )
3081  return -SCIPexprCompare(set, expr2, expr1);
3082 
3083  /* enforces OR7 */
3084  if( SCIPexprIsSum(set, expr1) )
3085  {
3086  int compareresult;
3087  int nchildren;
3088 
3089  nchildren = expr1->nchildren;
3090  compareresult = SCIPexprCompare(set, expr1->children[nchildren-1], expr2);
3091 
3092  if( compareresult != 0 )
3093  return compareresult;
3094 
3095  /* "base" of the largest expression of the sum is equal to expr2, coefficient might tell us that
3096  * expr2 is larger */
3097  if( SCIPgetCoefsExprSum(expr1)[nchildren-1] < 1.0 )
3098  return -1;
3099 
3100  /* largest expression of sum is larger or equal than expr2 => expr1 > expr2 */
3101  return 1;
3102  }
3103  /* enforces OR12 */
3104  if( SCIPexprIsSum(set, expr2) )
3105  return -SCIPexprCompare(set, expr2, expr1);
3106 
3107  /* enforces OR8 */
3108  if( SCIPexprIsProduct(set, expr1) )
3109  {
3110  int compareresult;
3111  int nchildren;
3112 
3113  nchildren = expr1->nchildren;
3114  compareresult = SCIPexprCompare(set, expr1->children[nchildren-1], expr2);
3115 
3116  if( compareresult != 0 )
3117  return compareresult;
3118 
3119  /* largest expression of product is larger or equal than expr2 => expr1 > expr2 */
3120  return 1;
3121  }
3122  /* enforces OR12 */
3123  if( SCIPexprIsProduct(set, expr2) )
3124  return -SCIPexprCompare(set, expr2, expr1);
3125 
3126  /* enforces OR9 */
3127  if( SCIPexprIsPower(set, expr1) )
3128  {
3129  int compareresult;
3130 
3131  compareresult = SCIPexprCompare(set, expr1->children[0], expr2);
3132 
3133  if( compareresult != 0 )
3134  return compareresult;
3135 
3136  /* base equal to expr2, exponent might tell us that expr2 is larger */
3137  if( SCIPgetExponentExprPow(expr1) < 1.0 )
3138  return -1;
3139 
3140  /* power expression is larger => expr1 > expr2 */
3141  return 1;
3142  }
3143  /* enforces OR12 */
3144  if( SCIPexprIsPower(set, expr2) )
3145  return -SCIPexprCompare(set, expr2, expr1);
3146 
3147  /* enforces OR10 */
3148  if( SCIPexprIsVar(set, expr1) )
3149  return -1;
3150  /* enforces OR12 */
3151  if( SCIPexprIsVar(set, expr2) )
3152  return -SCIPexprCompare(set, expr2, expr1);
3153 
3154  /* enforces OR11 */
3155  retval = strcmp(SCIPexprhdlrGetName(exprhdlr1), SCIPexprhdlrGetName(exprhdlr2));
3156  return retval == 0 ? 0 : retval < 0 ? -1 : 1;
3157 }
3158 
3159 /** simplifies an expression
3160  *
3161  * @see SCIPsimplifyExpr
3162  */
3164  SCIP_SET* set, /**< global SCIP settings */
3165  SCIP_STAT* stat, /**< dynamic problem statistics */
3166  BMS_BLKMEM* blkmem, /**< block memory */
3167  SCIP_EXPR* rootexpr, /**< expression to be simplified */
3168  SCIP_EXPR** simplified, /**< buffer to store simplified expression */
3169  SCIP_Bool* changed, /**< buffer to store if rootexpr actually changed */
3170  SCIP_Bool* infeasible, /**< buffer to store whether infeasibility has been detected */
3171  SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
3172  void* ownercreatedata /**< data to pass to ownercreate */
3173  )
3174 {
3175  SCIP_EXPR* expr;
3176  SCIP_EXPRITER* it;
3177 
3178  assert(rootexpr != NULL);
3179  assert(simplified != NULL);
3180  assert(changed != NULL);
3181  assert(infeasible != NULL);
3182 
3183  /* simplify bottom up
3184  * when leaving an expression it simplifies it and stores the simplified expr in its iterators expression data
3185  * after the child was visited, it is replaced with the simplified expr
3186  */
3187  SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
3188  SCIP_CALL( SCIPexpriterInit(it, rootexpr, SCIP_EXPRITER_DFS, TRUE) ); /* TODO can we set allowrevisited to FALSE?*/
3190 
3191  *changed = FALSE;
3192  *infeasible = FALSE;
3193  for( expr = SCIPexpriterGetCurrent(it); !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
3194  {
3195  switch( SCIPexpriterGetStageDFS(it) )
3196  {
3198  {
3199  SCIP_EXPR* newchild;
3200  SCIP_EXPR* child;
3201 
3203  child = SCIPexpriterGetChildExprDFS(it);
3204  assert(newchild != NULL);
3205 
3206  /* if child got simplified, replace it with the new child */
3207  if( newchild != child )
3208  {
3209  SCIP_CALL( SCIPexprReplaceChild(set, stat, blkmem, expr, SCIPexpriterGetChildIdxDFS(it), newchild) );
3210  }
3211 
3212  /* we do not need to hold newchild anymore */
3213  SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &newchild) );
3214 
3215  break;
3216  }
3217 
3219  {
3220  SCIP_EXPR* refexpr = NULL;
3221  SCIP_EXPRITER_USERDATA iterdata;
3222 
3223  /* TODO we should do constant folding (handle that all children are value-expressions) here in a generic way
3224  * instead of reimplementing it in every handler
3225  */
3226 
3227  /* use simplification of expression handlers */
3228  SCIP_CALL( SCIPexprhdlrSimplifyExpr(expr->exprhdlr, set, expr, &refexpr, ownercreate, ownercreatedata) );
3229  assert(refexpr != NULL);
3230  if( expr != refexpr )
3231  *changed = TRUE;
3232 
3233  iterdata.ptrval = (void*) refexpr;
3234  SCIPexpriterSetCurrentUserData(it, iterdata);
3235 
3236  break;
3237  }
3238 
3239  default:
3240  SCIPABORT(); /* we should never be called in this stage */
3241  break;
3242  }
3243  }
3244 
3245  *simplified = (SCIP_EXPR*)SCIPexpriterGetExprUserData(it, rootexpr).ptrval;
3246  assert(*simplified != NULL);
3247 
3248  SCIPexpriterFree(&it);
3249 
3250  return SCIP_OKAY;
3251 }
3252 
3253 /** checks whether an expression is quadratic
3254  *
3255  * An expression is quadratic if it is either a power expression with exponent 2.0, a product of two expressions,
3256  * or a sum of terms where at least one is a square or a product of two.
3257  *
3258  * Use \ref SCIPexprGetQuadraticData to get data about the representation as quadratic.
3259  */
3261  SCIP_SET* set, /**< global SCIP settings */
3262  BMS_BLKMEM* blkmem, /**< block memory */
3263  SCIP_EXPR* expr, /**< expression */
3264  SCIP_Bool* isquadratic /**< buffer to store result */
3265  )
3266 {
3267  SCIP_HASHMAP* expr2idx;
3268  SCIP_HASHMAP* seenexpr = NULL;
3269  int nquadterms = 0;
3270  int nlinterms = 0;
3271  int nbilinterms = 0;
3272  int c;
3273 
3274  assert(set != NULL);
3275  assert(blkmem != NULL);
3276  assert(expr != NULL);
3277  assert(isquadratic != NULL);
3278 
3279  if( expr->quadchecked )
3280  {
3281  *isquadratic = expr->quaddata != NULL;
3282  return SCIP_OKAY;
3283  }
3284  assert(expr->quaddata == NULL);
3285 
3286  expr->quadchecked = TRUE;
3287  *isquadratic = FALSE;
3288 
3289  /* check if expression is a quadratic expression */
3290  SCIPsetDebugMsg(set, "checking if expr %p is quadratic\n", (void*)expr);
3291 
3292  /* handle single square term */
3293  if( SCIPexprIsPower(set, expr) && SCIPgetExponentExprPow(expr) == 2.0 )
3294  {
3295  SCIPsetDebugMsg(set, "expr %p looks like square: fill data structures\n", (void*)expr);
3296  SCIP_ALLOC( BMSallocClearBlockMemory(blkmem, &expr->quaddata) );
3297 
3298  expr->quaddata->nquadexprs = 1;
3299  SCIP_ALLOC( BMSallocClearBlockMemoryArray(blkmem, &expr->quaddata->quadexprterms, 1) );
3300  expr->quaddata->quadexprterms[0].expr = expr->children[0];
3301  expr->quaddata->quadexprterms[0].sqrcoef = 1.0;
3302 
3303  expr->quaddata->allexprsarevars = SCIPexprIsVar(set, expr->quaddata->quadexprterms[0].expr);
3304 
3305  *isquadratic = TRUE;
3306  return SCIP_OKAY;
3307  }
3308 
3309  /* handle single bilinear term */
3310  if( SCIPexprIsProduct(set, expr) && SCIPexprGetNChildren(expr) == 2 )
3311  {
3312  SCIPsetDebugMsg(set, "expr %p looks like bilinear product: fill data structures\n", (void*)expr);
3313  SCIP_ALLOC( BMSallocClearBlockMemory(blkmem, &expr->quaddata) );
3314  expr->quaddata->nquadexprs = 2;
3315 
3316  SCIP_ALLOC( BMSallocClearBlockMemoryArray(blkmem, &expr->quaddata->quadexprterms, 2) );
3317  expr->quaddata->quadexprterms[0].expr = SCIPexprGetChildren(expr)[0];
3318  expr->quaddata->quadexprterms[0].nadjbilin = 1;
3319  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &expr->quaddata->quadexprterms[0].adjbilin, 1) );
3320  expr->quaddata->quadexprterms[0].adjbilin[0] = 0;
3321 
3322  expr->quaddata->quadexprterms[1].expr = SCIPexprGetChildren(expr)[1];
3323  expr->quaddata->quadexprterms[1].nadjbilin = 1;
3324  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &expr->quaddata->quadexprterms[1].adjbilin, 1) );
3325  expr->quaddata->quadexprterms[1].adjbilin[0] = 0;
3326 
3327  expr->quaddata->nbilinexprterms = 1;
3328  SCIP_ALLOC( BMSallocClearBlockMemoryArray(blkmem, &expr->quaddata->bilinexprterms, 1) );
3329  expr->quaddata->bilinexprterms[0].expr1 = SCIPexprGetChildren(expr)[1];
3330  expr->quaddata->bilinexprterms[0].expr2 = SCIPexprGetChildren(expr)[0];
3331  expr->quaddata->bilinexprterms[0].coef = 1.0;
3332 
3333  expr->quaddata->allexprsarevars = SCIPexprIsVar(set, expr->quaddata->quadexprterms[0].expr)
3334  && SCIPexprIsVar(set, expr->quaddata->quadexprterms[1].expr);
3335 
3336  *isquadratic = TRUE;
3337  return SCIP_OKAY;
3338  }
3339 
3340  /* neither a sum, nor a square, nor a bilinear term */
3341  if( !SCIPexprIsSum(set, expr) )
3342  return SCIP_OKAY;
3343 
3344  SCIP_CALL( SCIPhashmapCreate(&seenexpr, blkmem, 2*SCIPexprGetNChildren(expr)) );
3345  for( c = 0; c < SCIPexprGetNChildren(expr); ++c )
3346  {
3347  SCIP_EXPR* child;
3348 
3349  child = SCIPexprGetChildren(expr)[c];
3350  assert(child != NULL);
3351 
3352  if( SCIPexprIsPower(set, child) && SCIPgetExponentExprPow(child) == 2.0 ) /* quadratic term */
3353  {
3354  SCIP_CALL( quadDetectProcessExpr(SCIPexprGetChildren(child)[0], seenexpr, &nquadterms, &nlinterms) );
3355  }
3356  else if( SCIPexprIsProduct(set, child) && SCIPexprGetNChildren(child) == 2 ) /* bilinear term */
3357  {
3358  ++nbilinterms;
3359  SCIP_CALL( quadDetectProcessExpr(SCIPexprGetChildren(child)[0], seenexpr, &nquadterms, &nlinterms) );
3360  SCIP_CALL( quadDetectProcessExpr(SCIPexprGetChildren(child)[1], seenexpr, &nquadterms, &nlinterms) );
3361  }
3362  else
3363  {
3364  /* first time seen linearly --> assign -1; ++nlinterms
3365  * not first time --> assign +=1;
3366  */
3367  if( SCIPhashmapExists(seenexpr, (void*)child) )
3368  {
3369  assert(SCIPhashmapGetImageInt(seenexpr, (void*)child) > 0);
3370 
3371  SCIP_CALL( SCIPhashmapSetImageInt(seenexpr, (void*)child, SCIPhashmapGetImageInt(seenexpr, (void*)child) + 1) );
3372  }
3373  else
3374  {
3375  ++nlinterms;
3376  SCIP_CALL( SCIPhashmapInsertInt(seenexpr, (void*)child, -1) );
3377  }
3378  }
3379  }
3380 
3381  if( nquadterms == 0 )
3382  {
3383  /* only linear sum */
3384  SCIPhashmapFree(&seenexpr);
3385  return SCIP_OKAY;
3386  }
3387 
3388  SCIPsetDebugMsg(set, "expr %p looks quadratic: fill data structures\n", (void*)expr);
3389 
3390  /* expr2idx maps expressions to indices; if index > 0, it is its index in the linexprs array, otherwise -index-1 is
3391  * its index in the quadexprterms array
3392  */
3393  SCIP_CALL( SCIPhashmapCreate(&expr2idx, blkmem, nquadterms + nlinterms) );
3394 
3395  /* allocate memory, etc */
3396  SCIP_ALLOC( BMSallocClearBlockMemory(blkmem, &expr->quaddata) );
3397  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &expr->quaddata->quadexprterms, nquadterms) );
3398  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &expr->quaddata->linexprs, nlinterms) );
3399  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &expr->quaddata->lincoefs, nlinterms) );
3400  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &expr->quaddata->bilinexprterms, nbilinterms) );
3401 
3402  expr->quaddata->constant = SCIPgetConstantExprSum(expr);
3403 
3404  expr->quaddata->allexprsarevars = TRUE;
3405  /* for every term of the sum-expr */
3406  for( c = 0; c < SCIPexprGetNChildren(expr); ++c )
3407  {
3408  SCIP_EXPR* child;
3409  SCIP_Real coef;
3410 
3411  child = SCIPexprGetChildren(expr)[c];
3412  coef = SCIPgetCoefsExprSum(expr)[c];
3413 
3414  assert(child != NULL);
3415  assert(coef != 0.0);
3416 
3417  if( SCIPexprIsPower(set, child) && SCIPgetExponentExprPow(child) == 2.0 ) /* quadratic term */
3418  {
3419  SCIP_QUADEXPR_QUADTERM* quadexprterm;
3420  assert(SCIPexprGetNChildren(child) == 1);
3421 
3422  child = SCIPexprGetChildren(child)[0];
3423  assert(SCIPhashmapGetImageInt(seenexpr, (void *)child) > 0);
3424 
3425  SCIP_CALL( quadDetectGetQuadexprterm(blkmem, child, expr2idx, seenexpr, expr->quaddata, &quadexprterm) );
3426  assert(quadexprterm->expr == child);
3427  quadexprterm->sqrcoef = coef;
3428  quadexprterm->sqrexpr = SCIPexprGetChildren(expr)[c];
3429 
3430  if( expr->quaddata->allexprsarevars )
3431  expr->quaddata->allexprsarevars = SCIPexprIsVar(set, quadexprterm->expr);
3432  }
3433  else if( SCIPexprIsProduct(set, child) && SCIPexprGetNChildren(child) == 2 ) /* bilinear term */
3434  {
3435  SCIP_QUADEXPR_BILINTERM* bilinexprterm;
3436  SCIP_QUADEXPR_QUADTERM* quadexprterm;
3437  SCIP_EXPR* expr1;
3438  SCIP_EXPR* expr2;
3439 
3440  assert(SCIPgetCoefExprProduct(child) == 1.0);
3441 
3442  expr1 = SCIPexprGetChildren(child)[0];
3443  expr2 = SCIPexprGetChildren(child)[1];
3444  assert(expr1 != NULL && expr2 != NULL);
3445 
3446  bilinexprterm = &expr->quaddata->bilinexprterms[expr->quaddata->nbilinexprterms];
3447 
3448  bilinexprterm->coef = coef;
3449  if( SCIPhashmapGetImageInt(seenexpr, (void*)expr1) >= SCIPhashmapGetImageInt(seenexpr, (void*)expr2) )
3450  {
3451  bilinexprterm->expr1 = expr1;
3452  bilinexprterm->expr2 = expr2;
3453  }
3454  else
3455  {
3456  bilinexprterm->expr1 = expr2;
3457  bilinexprterm->expr2 = expr1;
3458  }
3459  bilinexprterm->prodexpr = child;
3460 
3461  SCIP_CALL( quadDetectGetQuadexprterm(blkmem, expr1, expr2idx, seenexpr, expr->quaddata, &quadexprterm) );
3462  assert(quadexprterm->expr == expr1);
3463  quadexprterm->adjbilin[quadexprterm->nadjbilin] = expr->quaddata->nbilinexprterms;
3464  ++quadexprterm->nadjbilin;
3465 
3466  if( expr->quaddata->allexprsarevars )
3467  expr->quaddata->allexprsarevars = SCIPexprIsVar(set, quadexprterm->expr);
3468 
3469  SCIP_CALL( quadDetectGetQuadexprterm(blkmem, expr2, expr2idx, seenexpr, expr->quaddata, &quadexprterm) );
3470  assert(quadexprterm->expr == expr2);
3471  quadexprterm->adjbilin[quadexprterm->nadjbilin] = expr->quaddata->nbilinexprterms;
3472  ++quadexprterm->nadjbilin;
3473 
3474  if( expr->quaddata->allexprsarevars )
3475  expr->quaddata->allexprsarevars = SCIPexprIsVar(set, quadexprterm->expr);
3476 
3477  ++expr->quaddata->nbilinexprterms;
3478 
3479  /* store position of second factor in quadexprterms */
3480  bilinexprterm->pos2 = SCIPhashmapGetImageInt(expr2idx, (void*)bilinexprterm->expr2);
3481  }
3482  else /* linear term */
3483  {
3484  if( SCIPhashmapGetImageInt(seenexpr, (void*)child) < 0 )
3485  {
3486  assert(SCIPhashmapGetImageInt(seenexpr, (void*)child) == -1);
3487 
3488  /* expression only appears linearly */
3489  expr->quaddata->linexprs[expr->quaddata->nlinexprs] = child;
3490  expr->quaddata->lincoefs[expr->quaddata->nlinexprs] = coef;
3491  expr->quaddata->nlinexprs++;
3492 
3493  if( expr->quaddata->allexprsarevars )
3494  expr->quaddata->allexprsarevars = SCIPexprIsVar(set, child);
3495  }
3496  else
3497  {
3498  /* expression appears non-linearly: set lin coef */
3499  SCIP_QUADEXPR_QUADTERM* quadexprterm;
3500  assert(SCIPhashmapGetImageInt(seenexpr, (void*)child) > 0);
3501 
3502  SCIP_CALL( quadDetectGetQuadexprterm(blkmem, child, expr2idx, seenexpr, expr->quaddata, &quadexprterm) );
3503  assert(quadexprterm->expr == child);
3504  quadexprterm->lincoef = coef;
3505 
3506  if( expr->quaddata->allexprsarevars )
3507  expr->quaddata->allexprsarevars = SCIPexprIsVar(set, quadexprterm->expr);
3508  }
3509  }
3510  }
3511  assert(expr->quaddata->nquadexprs == nquadterms);
3512  assert(expr->quaddata->nlinexprs == nlinterms);
3513  assert(expr->quaddata->nbilinexprterms == nbilinterms);
3514 
3515  SCIPhashmapFree(&seenexpr);
3516  SCIPhashmapFree(&expr2idx);
3517 
3518  *isquadratic = TRUE;
3519 
3520  return SCIP_OKAY;
3521 }
3522 
3523 /** frees information on quadratic representation of an expression
3524  *
3525  * Reverts SCIPexprCheckQuadratic().
3526  * Before doing changes to an expression, it can be useful to call this function.
3527  */
3529  BMS_BLKMEM* blkmem, /**< block memory */
3530  SCIP_EXPR* expr /**< expression */
3531  )
3532 {
3533  int i;
3534  int n;
3535 
3536  assert(blkmem != NULL);
3537  assert(expr != NULL);
3538 
3539  expr->quadchecked = FALSE;
3540 
3541  if( expr->quaddata == NULL )
3542  return;
3543 
3544  n = expr->quaddata->nquadexprs;
3545 
3549  BMSfreeBlockMemoryArrayNull(blkmem, &expr->quaddata->eigenvalues, n);
3550  BMSfreeBlockMemoryArrayNull(blkmem, &expr->quaddata->eigenvectors, n * n); /*lint !e647*/
3551 
3552  for( i = 0; i < n; ++i )
3553  {
3555  expr->quaddata->quadexprterms[i].adjbilinsize);
3556  }
3558 
3559  BMSfreeBlockMemory(blkmem, &expr->quaddata);
3560 }
3561 
3562 /** Checks the curvature of the quadratic function stored in quaddata
3563  *
3564  * For this, it builds the matrix Q of quadratic coefficients and computes its eigenvalues using LAPACK.
3565  * If Q is
3566  * - semidefinite positive -> curv is set to convex,
3567  * - semidefinite negative -> curv is set to concave,
3568  * - otherwise -> curv is set to unknown.
3569  *
3570  * If `assumevarfixed` is given and some expressions in quadratic terms correspond to variables present in
3571  * this hashmap, then the corresponding rows and columns are ignored in the matrix Q.
3572  */
3574  SCIP_SET* set, /**< global SCIP settings */
3575  BMS_BLKMEM* blkmem, /**< block memory */
3576  BMS_BUFMEM* bufmem, /**< buffer memory */
3577  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
3578  SCIP_EXPR* expr, /**< quadratic expression */
3579  SCIP_EXPRCURV* curv, /**< pointer to store the curvature of quadratics */
3580  SCIP_HASHMAP* assumevarfixed, /**< hashmap containing variables that should be assumed to be fixed, or NULL */
3581  SCIP_Bool storeeigeninfo /**< whether the eigenvalues and eigenvectors should be stored */
3582  )
3583 {
3584  SCIP_QUADEXPR* quaddata;
3585  SCIP_HASHMAP* expr2matrix;
3586  double* matrix;
3587  double* alleigval;
3588  int nvars;
3589  int nn;
3590  int n;
3591  int i;
3592 
3593  assert(set != NULL);
3594  assert(blkmem != NULL);
3595  assert(bufmem != NULL);
3596  assert(messagehdlr != NULL);
3597  assert(expr != NULL);
3598  assert(curv != NULL);
3599 
3600  quaddata = expr->quaddata;
3601  assert(quaddata != NULL);
3602 
3603  /* do not store eigen information if we are not considering full matrix */
3604  if( assumevarfixed != NULL )
3605  storeeigeninfo = FALSE;
3606 
3607  if( quaddata->eigeninfostored || (quaddata->curvaturechecked && !storeeigeninfo) )
3608  {
3609  *curv = quaddata->curvature;
3610  /* if we are convex or concave on the full set of variables, then we will also be so on a subset */
3611  if( assumevarfixed == NULL || quaddata->curvature != SCIP_EXPRCURV_UNKNOWN )
3612  return SCIP_OKAY;
3613  }
3614  assert(quaddata->curvature == SCIP_EXPRCURV_UNKNOWN || assumevarfixed != NULL
3615  || (storeeigeninfo && !quaddata->eigeninfostored));
3616 
3617  *curv = SCIP_EXPRCURV_UNKNOWN;
3618 
3619  n = quaddata->nquadexprs;
3620 
3621  /* do not check curvature if nn will be too large
3622  * we want nn * sizeof(real) to fit into an unsigned int, so n must be <= sqrt(unit_max/sizeof(real))
3623  * sqrt(2*214748364/8) = 7327.1475350234
3624  */
3625  if( n > 7000 )
3626  {
3627  SCIPmessageFPrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL, NULL,
3628  "number of quadratic variables is too large (%d) to check the curvature\n", n);
3629  return SCIP_OKAY;
3630  }
3631 
3632  /* TODO do some simple tests first; like diagonal entries don't change sign, etc */
3633 
3634  if( !SCIPisIpoptAvailableIpopt() )
3635  return SCIP_OKAY;
3636 
3637  nn = n * n;
3638  assert(nn > 0);
3639  assert((unsigned)nn < UINT_MAX / sizeof(SCIP_Real));
3640 
3641  if( storeeigeninfo )
3642  {
3643  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &quaddata->eigenvalues, n));
3644  SCIP_ALLOC( BMSallocClearBlockMemoryArray(blkmem, &quaddata->eigenvectors, nn));
3645 
3646  alleigval = quaddata->eigenvalues;
3647  matrix = quaddata->eigenvectors;
3648  }
3649  else
3650  {
3651  SCIP_ALLOC( BMSallocBufferMemoryArray(bufmem, &alleigval, n) );
3652  SCIP_ALLOC( BMSallocClearBufferMemoryArray(bufmem, &matrix, nn) );
3653  }
3654 
3655  SCIP_CALL( SCIPhashmapCreate(&expr2matrix, blkmem, n) );
3656 
3657  /* fill matrix's diagonal */
3658  nvars = 0;
3659  for( i = 0; i < n; ++i )
3660  {
3661  SCIP_QUADEXPR_QUADTERM quadexprterm;
3662 
3663  quadexprterm = quaddata->quadexprterms[i];
3664 
3665  assert(!SCIPhashmapExists(expr2matrix, (void*)quadexprterm.expr));
3666 
3667  /* skip expr if it is a variable mentioned in assumevarfixed */
3668  if( assumevarfixed != NULL && SCIPexprIsVar(set, quadexprterm.expr)
3669  && SCIPhashmapExists(assumevarfixed, (void*)SCIPgetVarExprVar(quadexprterm.expr)) )
3670  continue;
3671 
3672  if( quadexprterm.sqrcoef == 0.0 && ! storeeigeninfo )
3673  {
3674  assert(quadexprterm.nadjbilin > 0);
3675  /* SCIPdebugMsg(scip, "var <%s> appears in bilinear term but is not squared
3676  * --> indefinite quadratic\n", SCIPvarGetName(quadexprterm.var)); */
3677  goto CLEANUP;
3678  }
3679 
3680  matrix[nvars * n + nvars] = quadexprterm.sqrcoef;
3681 
3682  /* remember row of variable in matrix */
3683  SCIP_CALL( SCIPhashmapInsert(expr2matrix, (void *)quadexprterm.expr, (void *)(size_t)nvars) );
3684  nvars++;
3685  }
3686 
3687  /* fill matrix's upper-diagonal */
3688  for( i = 0; i < quaddata->nbilinexprterms; ++i )
3689  {
3690  SCIP_QUADEXPR_BILINTERM bilinexprterm;
3691  int col;
3692  int row;
3693 
3694  bilinexprterm = quaddata->bilinexprterms[i];
3695 
3696  /* each factor should have been added to expr2matrix unless it corresponds to a variable mentioned in assumevarfixed */
3697  assert(SCIPhashmapExists(expr2matrix, (void*)bilinexprterm.expr1)
3698  || (assumevarfixed != NULL && SCIPexprIsVar(set, bilinexprterm.expr1)
3699  && SCIPhashmapExists(assumevarfixed, (void*)SCIPgetVarExprVar(bilinexprterm.expr1))));
3700  assert(SCIPhashmapExists(expr2matrix, (void*)bilinexprterm.expr2)
3701  || (assumevarfixed != NULL && SCIPexprIsVar(set, bilinexprterm.expr2)
3702  && SCIPhashmapExists(assumevarfixed, (void*)SCIPgetVarExprVar(bilinexprterm.expr2))));
3703 
3704  /* skip bilinear terms where at least one of the factors should be assumed to be fixed
3705  * (i.e., not present in expr2matrix map) */
3706  if( !SCIPhashmapExists(expr2matrix, (void*)bilinexprterm.expr1)
3707  || !SCIPhashmapExists(expr2matrix, (void*)bilinexprterm.expr2) )
3708  continue;
3709 
3710  row = (int)(size_t)SCIPhashmapGetImage(expr2matrix, bilinexprterm.expr1);
3711  col = (int)(size_t)SCIPhashmapGetImage(expr2matrix, bilinexprterm.expr2);
3712 
3713  assert(row != col);
3714 
3715  if( row < col )
3716  matrix[row * n + col] = bilinexprterm.coef / 2.0;
3717  else
3718  matrix[col * n + row] = bilinexprterm.coef / 2.0;
3719  }
3720 
3721  /* compute eigenvalues */
3722  if( SCIPcallLapackDsyevIpopt(storeeigeninfo, n, matrix, alleigval) != SCIP_OKAY )
3723  {
3724  SCIPmessagePrintWarning(messagehdlr, "Failed to compute eigenvalues of quadratic coefficient "
3725  "matrix --> don't know curvature\n");
3726  goto CLEANUP;
3727  }
3728 
3729  /* check convexity */
3730  if( !SCIPsetIsNegative(set, alleigval[0]) )
3731  *curv = SCIP_EXPRCURV_CONVEX;
3732  else if( !SCIPsetIsPositive(set, alleigval[n-1]) )
3733  *curv = SCIP_EXPRCURV_CONCAVE;
3734 
3735 CLEANUP:
3736  SCIPhashmapFree(&expr2matrix);
3737 
3738  if( !storeeigeninfo )
3739  {
3740  BMSfreeBufferMemoryArray(bufmem, &matrix);
3741  BMSfreeBufferMemoryArray(bufmem, &alleigval);
3742  }
3743  else
3744  {
3745  assert(!quaddata->eigeninfostored);
3746  quaddata->eigeninfostored = TRUE;
3747  }
3748 
3749  /* if checked convexity on full Q matrix, then remember it
3750  * if indefinite on submatrix, then it will also be indefinite on full matrix, so can remember that, too */
3751  if( assumevarfixed == NULL || *curv == SCIP_EXPRCURV_UNKNOWN )
3752  {
3753  quaddata->curvature = *curv;
3754  quaddata->curvaturechecked = TRUE;
3755  }
3756 
3757  return SCIP_OKAY;
3758 }
3759 
3760 
3761 /* from pub_expr.h */
3762 
3763 #ifdef NDEBUG
3764 #undef SCIPexprGetNUses
3765 #undef SCIPexprGetNChildren
3766 #undef SCIPexprGetChildren
3767 #undef SCIPexprGetHdlr
3768 #undef SCIPexprGetData
3769 #undef SCIPexprSetData
3770 #undef SCIPexprGetOwnerData
3771 #undef SCIPexprGetEvalValue
3772 #undef SCIPexprGetEvalTag
3773 #undef SCIPexprGetDerivative
3774 #undef SCIPexprGetDot
3775 #undef SCIPexprGetBardot
3776 #undef SCIPexprGetDiffTag
3777 #undef SCIPexprGetActivity
3778 #undef SCIPexprGetActivityTag
3779 #undef SCIPexprSetActivity
3780 #undef SCIPexprGetCurvature
3781 #undef SCIPexprSetCurvature
3782 #undef SCIPexprIsIntegral
3783 #undef SCIPexprSetIntegrality
3784 #undef SCIPexprAreQuadraticExprsVariables
3785 #endif
3786 
3787 /** gets the number of times the expression is currently captured */
3789  SCIP_EXPR* expr /**< expression */
3790  )
3791 {
3792  assert(expr != NULL);
3793 
3794  return expr->nuses;
3795 }
3796 
3797 /** gives the number of children of an expression */
3799  SCIP_EXPR* expr /**< expression */
3800  )
3801 {
3802  assert(expr != NULL);
3803 
3804  return expr->nchildren;
3805 }
3806 
3807 /** gives the children of an expression (can be NULL if no children) */
3809  SCIP_EXPR* expr /**< expression */
3810  )
3811 {
3812  assert(expr != NULL);
3813 
3814  return expr->children;
3815 }
3816 
3817 /** gets the expression handler of an expression
3818  *
3819  * This identifies the type of the expression (sum, variable, ...).
3820  */
3822  SCIP_EXPR* expr /**< expression */
3823  )
3824 {
3825  assert(expr != NULL);
3826 
3827  return expr->exprhdlr;
3828 }
3829 
3830 /** gets the expression data of an expression */
3832  SCIP_EXPR* expr /**< expression */
3833  )
3834 {
3835  assert(expr != NULL);
3836 
3837  return expr->exprdata;
3838 }
3839 
3840 /** sets the expression data of an expression
3841  *
3842  * The pointer to possible old data is overwritten and the
3843  * freedata-callback is not called before.
3844  * This function is intended to be used by expression handler only.
3845  */
3847  SCIP_EXPR* expr, /**< expression */
3848  SCIP_EXPRDATA* exprdata /**< expression data to be set (can be NULL) */
3849  )
3850 {
3851  assert(expr != NULL);
3852  assert(exprdata == NULL || expr->exprhdlr->copydata != NULL); /* copydata must be available if there is expression data */
3853  assert(exprdata == NULL || expr->exprhdlr->freedata != NULL); /* freedata must be available if there is expression data */
3854 
3855  expr->exprdata = exprdata;
3856 }
3857 
3858 /** gets the data that the owner of an expression has stored in an expression */
3860  SCIP_EXPR* expr /**< expression */
3861  )
3862 {
3863  assert(expr != NULL);
3864 
3865  return expr->ownerdata;
3866 }
3867 
3868 /** gives the value from the last evaluation of an expression (or SCIP_INVALID if there was an eval error)
3869  *
3870  * @see SCIPevalExpr to evaluate the expression at a given solution.
3871  */
3873  SCIP_EXPR* expr /**< expression */
3874  )
3875 {
3876  assert(expr != NULL);
3877 
3878  return expr->evalvalue;
3879 }
3880 
3881 /** gives the evaluation tag from the last evaluation, or 0
3882  *
3883  * @see SCIPevalExpr
3884  */
3886  SCIP_EXPR* expr /**< expression */
3887  )
3888 {
3889  assert(expr != NULL);
3890 
3891  return expr->evaltag;
3892 }
3893 
3894 /** returns the derivative stored in an expression (or SCIP_INVALID if there was an evaluation error)
3895  *
3896  * @see SCIPevalExprGradient
3897  */
3899  SCIP_EXPR* expr /**< expression */
3900  )
3901 {
3902  assert(expr != NULL);
3903 
3904  return expr->derivative;
3905 }
3906 
3907 /** gives the value of directional derivative from the last evaluation of a directional derivative of
3908  * expression (or SCIP_INVALID if there was an error)
3909  *
3910  * @see SCIPevalExprHessianDir
3911  */
3913  SCIP_EXPR* expr /**< expression */
3914  )
3915 {
3916  assert(expr != NULL);
3917 
3918  return expr->dot;
3919 }
3920 
3921 /** gives the value of directional derivative from the last evaluation of a directional derivative of
3922  * derivative of root (or SCIP_INVALID if there was an error)
3923  *
3924  * @see SCIPevalExprHessianDir
3925  */
3927  SCIP_EXPR* expr /**< expression */
3928  )
3929 {
3930  assert(expr != NULL);
3931 
3932  return expr->bardot;
3933 }
3934 
3935 /** returns the difftag stored in an expression
3936  *
3937  * can be used to check whether partial derivative value is valid
3938  *
3939  * @see SCIPevalExprGradient
3940  */
3942  SCIP_EXPR* expr /**< expression */
3943  )
3944 {
3945  assert(expr != NULL);
3946 
3947  return expr->difftag;
3948 }
3949 
3950 /** returns the activity that is currently stored for an expression
3951  *
3952  * @see SCIPevalExprActivity
3953  */
3955  SCIP_EXPR* expr /**< expression */
3956  )
3957 {
3958  assert(expr != NULL);
3959 
3960  return expr->activity;
3961 }
3962 
3963 /** returns the tag associated with the activity of the expression
3964  *
3965  * It can depend on the owner of the expression how to interpret this tag.
3966  * SCIPevalExprActivity() compares with `stat->domchgcount`.
3967  *
3968  * @see SCIPevalExprActivity
3969  */
3971  SCIP_EXPR* expr /**< expression */
3972  )
3973 {
3974  assert(expr != NULL);
3975 
3976  return expr->activitytag;
3977 }
3978 
3979 /** set the activity with tag for an expression */
3981  SCIP_EXPR* expr, /**< expression */
3982  SCIP_INTERVAL activity, /**< new activity */
3983  SCIP_Longint activitytag /**< tag associated with activity */
3984  )
3985 {
3986  assert(expr != NULL);
3987 
3988  expr->activity = activity;
3989  expr->activitytag = activitytag;
3990 }
3991 
3992 /** returns the curvature of an expression
3993  *
3994  * @note Call SCIPcomputeExprCurvature() before calling this function.
3995  */
3997  SCIP_EXPR* expr /**< expression */
3998  )
3999 {
4000  assert(expr != NULL);
4001 
4002  return expr->curvature;
4003 }
4004 
4005 /** sets the curvature of an expression */
4007  SCIP_EXPR* expr, /**< expression */
4008  SCIP_EXPRCURV curvature /**< curvature of the expression */
4009  )
4010 {
4011  assert(expr != NULL);
4012 
4013  expr->curvature = curvature;
4014 }
4015 
4016 /** returns whether an expression is integral */
4018  SCIP_EXPR* expr /**< expression */
4019  )
4020 {
4021  assert(expr != NULL);
4022 
4023  return expr->isintegral;
4024 }
4025 
4026 /** sets the integrality flag of an expression */
4028  SCIP_EXPR* expr, /**< expression */
4029  SCIP_Bool isintegral /**< integrality of the expression */
4030  )
4031 {
4032  assert(expr != NULL);
4033 
4034  expr->isintegral = isintegral;
4035 }
4036 
4037 /** gives the coefficients and expressions that define a quadratic expression
4038  *
4039  * It can return the constant part, the number, arguments, and coefficients of the purely linear part
4040  * and the number of quadratic terms and bilinear terms.
4041  * Note that for arguments that appear in the quadratic part, a linear coefficient is
4042  * stored with the quadratic term.
4043  * Use SCIPexprGetQuadraticQuadTerm() and SCIPexprGetQuadraticBilinTerm()
4044  * to access the data for a quadratic or bilinear term.
4045  *
4046  * It can also return the eigenvalues and the eigenvectors of the matrix \f$Q\f$ when the quadratic is written
4047  * as \f$x^T Q x + b^T x + c^T y + d\f$, where \f$c^T y\f$ defines the purely linear part.
4048  * Note, however, that to have access to them one needs to call SCIPcomputeExprQuadraticCurvature()
4049  * with `storeeigeninfo=TRUE`. If the eigen information was not stored or it failed to be computed,
4050  * `eigenvalues` and `eigenvectors` will be set to NULL.
4051  *
4052  * This function returns pointers to internal data in linexprs and lincoefs.
4053  * The user must not change this data.
4054  *
4055  * @attention SCIPcheckExprQuadratic() needs to be called first to check whether expression is quadratic and initialize the data of the quadratic representation.
4056  */
4058  SCIP_EXPR* expr, /**< quadratic expression */
4059  SCIP_Real* constant, /**< buffer to store constant term, or NULL */
4060  int* nlinexprs, /**< buffer to store number of expressions that appear linearly, or NULL */
4061  SCIP_EXPR*** linexprs, /**< buffer to store pointer to array of expressions that appear linearly,
4062  or NULL */
4063  SCIP_Real** lincoefs, /**< buffer to store pointer to array of coefficients of expressions that
4064  appear linearly, or NULL */
4065  int* nquadexprs, /**< buffer to store number of expressions in quadratic terms, or NULL */
4066  int* nbilinexprs, /**< buffer to store number of bilinear expressions terms, or NULL */
4067  SCIP_Real** eigenvalues, /**< buffer to store pointer to array of eigenvalues of Q, or NULL */
4068  SCIP_Real** eigenvectors /**< buffer to store pointer to array of eigenvectors of Q, or NULL */
4069  )
4070 {
4071  SCIP_QUADEXPR* quaddata;
4072 
4073  assert(expr != NULL);
4074 
4075  quaddata = expr->quaddata;
4076  assert(quaddata != NULL);
4077 
4078  if( constant != NULL )
4079  *constant = quaddata->constant;
4080  if( nlinexprs != NULL )
4081  *nlinexprs = quaddata->nlinexprs;
4082  if( linexprs != NULL )
4083  *linexprs = quaddata->linexprs;
4084  if( lincoefs != NULL )
4085  *lincoefs = quaddata->lincoefs;
4086  if( nquadexprs != NULL )
4087  *nquadexprs = quaddata->nquadexprs;
4088  if( nbilinexprs != NULL )
4089  *nbilinexprs = quaddata->nbilinexprterms;
4090  if( eigenvalues != NULL )
4091  *eigenvalues = quaddata->eigenvalues;
4092  if( eigenvectors != NULL )
4093  *eigenvectors = quaddata->eigenvectors;
4094 }
4095 
4096 /** gives the data of a quadratic expression term
4097  *
4098  * For a term \f$a \cdot \text{expr}^2 + b \cdot \text{expr} + \sum_i (c_i \cdot \text{expr} \cdot \text{otherexpr}_i)\f$, returns
4099  * `expr`, \f$a\f$, \f$b\f$, the number of summands, and indices of bilinear terms in the quadratic expressions `bilinexprterms`.
4100  *
4101  * This function returns pointers to internal data in adjbilin.
4102  * The user must not change this data.
4103  */
4105  SCIP_EXPR* quadexpr, /**< quadratic expression */
4106  int termidx, /**< index of quadratic term */
4107  SCIP_EXPR** expr, /**< buffer to store pointer to argument expression (the 'x') of this term,
4108  or NULL */
4109  SCIP_Real* lincoef, /**< buffer to store linear coefficient of variable, or NULL */
4110  SCIP_Real* sqrcoef, /**< buffer to store square coefficient of variable, or NULL */
4111  int* nadjbilin, /**< buffer to store number of bilinear terms this variable is involved in,
4112  or NULL */
4113  int** adjbilin, /**< buffer to store pointer to indices of associated bilinear terms, or NULL */
4114  SCIP_EXPR** sqrexpr /**< buffer to store pointer to square expression (the 'x^2') of this term
4115  or NULL if no square expression, or NULL */
4116  )
4117 {
4118  SCIP_QUADEXPR_QUADTERM* quadexprterm;
4119 
4120  assert(quadexpr != NULL);
4121  assert(quadexpr->quaddata != NULL);
4122  assert(quadexpr->quaddata->quadexprterms != NULL);
4123  assert(termidx >= 0);
4124  assert(termidx < quadexpr->quaddata->nquadexprs);
4125 
4126  quadexprterm = &quadexpr->quaddata->quadexprterms[termidx];
4127 
4128  if( expr != NULL )
4129  *expr = quadexprterm->expr;
4130  if( lincoef != NULL )
4131  *lincoef = quadexprterm->lincoef;
4132  if( sqrcoef != NULL )
4133  *sqrcoef = quadexprterm->sqrcoef;
4134  if( nadjbilin != NULL )
4135  *nadjbilin = quadexprterm->nadjbilin;
4136  if( adjbilin != NULL )
4137  *adjbilin = quadexprterm->adjbilin;
4138  if( sqrexpr != NULL )
4139  *sqrexpr = quadexprterm->sqrexpr;
4140 }
4141 
4142 /** gives the data of a bilinear expression term
4143  *
4144  * For a term a*expr1*expr2, returns expr1, expr2, a, and
4145  * the position of the quadratic expression term that uses expr2 in the quadratic expressions `quadexprterms`.
4146  */
4148  SCIP_EXPR* expr, /**< quadratic expression */
4149  int termidx, /**< index of bilinear term */
4150  SCIP_EXPR** expr1, /**< buffer to store first factor, or NULL */
4151  SCIP_EXPR** expr2, /**< buffer to store second factor, or NULL */
4152  SCIP_Real* coef, /**< buffer to coefficient, or NULL */
4153  int* pos2, /**< buffer to position of expr2 in quadexprterms array of quadratic
4154  expression, or NULL */
4155  SCIP_EXPR** prodexpr /**< buffer to store pointer to expression that is product if first
4156  and second factor, or NULL */
4157  )
4158 {
4159  SCIP_QUADEXPR_BILINTERM* bilinexprterm;
4160 
4161  assert(expr != NULL);
4162  assert(expr->quaddata != NULL);
4163  assert(expr->quaddata->bilinexprterms != NULL);
4164  assert(termidx >= 0);
4165  assert(termidx < expr->quaddata->nbilinexprterms);
4166 
4167  bilinexprterm = &expr->quaddata->bilinexprterms[termidx];
4168 
4169  if( expr1 != NULL )
4170  *expr1 = bilinexprterm->expr1;
4171  if( expr2 != NULL )
4172  *expr2 = bilinexprterm->expr2;
4173  if( coef != NULL )
4174  *coef = bilinexprterm->coef;
4175  if( pos2 != NULL )
4176  *pos2 = bilinexprterm->pos2;
4177  if( prodexpr != NULL )
4178  *prodexpr = bilinexprterm->prodexpr;
4179 }
4180 
4181 /** returns whether all expressions that are used in a quadratic expression are variable expressions
4182  *
4183  * @return TRUE iff all `linexprs` and `quadexprterms[.].expr` are variable expressions
4184  */
4186  SCIP_EXPR* expr /**< quadratic expression */
4187  )
4188 {
4189  assert(expr != NULL);
4190  assert(expr->quaddata != NULL);
4191 
4192  return expr->quaddata->allexprsarevars;
4193 }
4194 
4195 /**@} */
void SCIPintervalSetEntire(SCIP_Real infinity, SCIP_INTERVAL *resultant)
SCIP_RETCODE SCIPexprhdlrHashExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, unsigned int *hashkey, unsigned int *childrenhashes)
Definition: expr.c:1083
SCIP_Longint SCIPexprhdlrGetNSimplifyCalls(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:797
int SCIPexprhdlrCompareExpr(SCIP_SET *set, SCIP_EXPR *expr1, SCIP_EXPR *expr2)
Definition: expr.c:1132
#define SCIP_EXPRITER_ALLSTAGES
Definition: type_expr.h:671
SCIP_Longint SCIPexprhdlrGetNEstimateCalls(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:753
SCIP_Bool SCIPisIpoptAvailableIpopt(void)
void SCIPexprGetQuadraticData(SCIP_EXPR *expr, SCIP_Real *constant, int *nlinexprs, SCIP_EXPR ***linexprs, SCIP_Real **lincoefs, int *nquadexprs, int *nbilinexprs, SCIP_Real **eigenvalues, SCIP_Real **eigenvectors)
Definition: expr.c:4057
static SCIP_RETCODE eval(SCIP *scip, SCIP_EXPR *expr, SCIP_EXPRINTDATA *exprintdata, const vector< Type > &x, Type &val)
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6200
SCIP_RETCODE SCIPexprhdlrEstimateExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_INTERVAL *localbounds, SCIP_INTERVAL *globalbounds, SCIP_Real *refpoint, SCIP_Bool overestimate, SCIP_Real targetvalue, SCIP_Real *coefs, SCIP_Real *constant, SCIP_Bool *islocal, SCIP_Bool *success, SCIP_Bool *branchcand)
Definition: expr.c:1529
#define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
Definition: memory.h:461
SCIP_RETCODE SCIPexpriterInit(SCIP_EXPRITER *iterator, SCIP_EXPR *expr, SCIP_EXPRITER_TYPE type, SCIP_Bool allowrevisit)
Definition: expriter.c:491
SCIP_EXPR_OWNERDATA * SCIPexprGetOwnerData(SCIP_EXPR *expr)
Definition: expr.c:3859
#define SCIP_DECL_EXPREVAL(x)
Definition: type_expr.h:414
void SCIPexprSetIntegrality(SCIP_EXPR *expr, SCIP_Bool isintegral)
Definition: expr.c:4027
#define SCIP_DECL_EXPRPRINT(x)
Definition: type_expr.h:277
internal methods for storing primal CIP solutions
SCIP_RETCODE SCIPexprEvalGradient(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *rootexpr, SCIP_SOL *sol, SCIP_Longint soltag)
Definition: expr.c:2719
SCIP_MONOTONE
Definition: type_expr.h:57
SCIP_RETCODE SCIPexprhdlrIntEvalExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_INTERVAL *interval, SCIP_DECL_EXPR_INTEVALVAR((*intevalvar)), void *intevalvardata)
Definition: expr.c:1498
#define SCIP_DECL_EXPRMONOTONICITY(x)
Definition: type_expr.h:346
#define SCIP_DECL_EXPR_INTEVALVAR(x)
Definition: type_expr.h:151
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:141
SCIP_Bool SCIPexprhdlrHasFwdiff(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:585
SCIP_Bool allexprsarevars
Definition: struct_expr.h:153
SCIP_RETCODE SCIPprintExpr(SCIP *scip, SCIP_EXPR *expr, FILE *file)
Definition: scip_expr.c:1476
internal methods for branch and bound tree
SCIP_RETCODE SCIPexprPrintDotInit2(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPRPRINTDATA **printdata, const char *filename, SCIP_EXPRPRINT_WHAT whattoprint)
Definition: expr.c:2322
void SCIPmessageFPrintVerbInfo(SCIP_MESSAGEHDLR *messagehdlr, SCIP_VERBLEVEL verblevel, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: message.c:697
SCIP_RETCODE SCIPhashmapSetImageInt(SCIP_HASHMAP *hashmap, void *origin, int image)
Definition: misc.c:3297
#define SCIP_EXPRPRINT_NUSES
Definition: type_expr.h:705
SCIP_Real SCIPsetFloor(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6387
int SCIPexprGetNChildren(SCIP_EXPR *expr)
Definition: expr.c:3798
SCIP_EXPR * SCIPexpriterGetParentDFS(SCIP_EXPRITER *iterator)
Definition: expriter.c:730
SCIP_EXPRCURV curvature
Definition: struct_expr.h:155
#define SCIP_DECL_EXPRINITESTIMATES(x)
Definition: type_expr.h:596
void SCIPexprhdlrSetDiff(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRBWDIFF((*bwdiff)), SCIP_DECL_EXPRFWDIFF((*fwdiff)), SCIP_DECL_EXPRBWFWDIFF((*bwfwdiff)))
Definition: expr.c:464
SCIP_EXPR_OWNERDATA * ownerdata
Definition: struct_expr.h:108
const char * SCIPexprhdlrGetName(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:525
internal methods for clocks and timing issues
SCIP_RETCODE SCIPexprhdlrCopyInclude(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *targetset)
Definition: expr.c:829
SCIP_Bool SCIPsetIsPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6323
SCIP_EXPR ** linexprs
Definition: struct_expr.h:144
unsigned int ncreated
Definition: struct_expr.h:64
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17966
SCIP_Real SCIPgetConstantExprSum(SCIP_EXPR *expr)
Definition: expr_sum.c:1172
SCIP_Longint evaltag
Definition: struct_expr.h:118
SCIP_EXPR * SCIPexpriterSkipDFS(SCIP_EXPRITER *iterator)
Definition: expriter.c:920
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:3163
#define SCIP_DECL_EXPRFWDIFF(x)
Definition: type_expr.h:468
SCIP_RETCODE SCIPexprhdlrBwFwDiffExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, int childidx, SCIP_Real *bardot, SCIP_SOL *direction)
Definition: expr.c:1462
#define SCIP_EXPRPRINT_EVALTAG
Definition: type_expr.h:707
void * SCIPhashmapEntryGetOrigin(SCIP_HASHMAPENTRY *entry)
Definition: misc.c:3500
SCIP_Real constant
Definition: struct_expr.h:141
SCIP_RETCODE SCIPexprEvalHessianDir(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *rootexpr, SCIP_SOL *sol, SCIP_Longint soltag, SCIP_SOL *direction)
Definition: expr.c:2818
#define SCIP_DECL_EXPRREVERSEPROP(x)
Definition: type_expr.h:645
SCIP_RETCODE SCIPexprPrintDotInit(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPRPRINTDATA **printdata, FILE *file, SCIP_EXPRPRINT_WHAT whattoprint)
Definition: expr.c:2290
SCIP_EXPRCURV curvature
Definition: struct_expr.h:128
void SCIPexprhdlrSetParse(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRPARSE((*parse)))
Definition: expr.c:398
structure definitions related to algebraic expressions
void SCIPexprhdlrInit(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set)
Definition: expr.c:854
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:351
private functions to work with algebraic expressions
SCIP_RETCODE SCIPcallLapackDsyevIpopt(SCIP_Bool computeeigenvectors, int N, SCIP_Real *a, SCIP_Real *w)
SCIP_EXPRHDLRDATA * SCIPexprhdlrGetData(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:555
#define FALSE
Definition: def.h:87
SCIP_RETCODE SCIPexprRemoveChildren(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *expr)
Definition: expr.c:1821
SCIP_Bool SCIPexprhdlrHasPrint(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:565
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:3014
void SCIPexprSetCurvature(SCIP_EXPR *expr, SCIP_EXPRCURV curvature)
Definition: expr.c:4006
SCIP_Bool SCIPexprhdlrHasBwdiff(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:575
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:281
struct SCIP_ExprData SCIP_EXPRDATA
Definition: type_expr.h:44
SCIP_Real SCIPgetExponentExprPow(SCIP_EXPR *expr)
Definition: expr_pow.c:3343
#define TRUE
Definition: def.h:86
static SCIP_RETCODE quadDetectProcessExpr(SCIP_EXPR *expr, SCIP_HASHMAP *seenexpr, int *nquadterms, int *nlinterms)
Definition: expr.c:95
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
SCIP_Longint nsimplifycalls
Definition: struct_expr.h:70
SCIP_Real SCIPexprhdlrGetEstimateTime(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:763
SCIP_RETCODE SCIPhashmapInsertInt(SCIP_HASHMAP *hashmap, void *origin, int image)
Definition: misc.c:3132
SCIP_Longint nintevalcalls
Definition: struct_expr.h:66
struct SCIP_ExprPrintData SCIP_EXPRPRINTDATA
Definition: type_expr.h:716
static SCIP_RETCODE quadDetectGetQuadexprterm(BMS_BLKMEM *blkmem, SCIP_EXPR *expr, SCIP_HASHMAP *expr2idx, SCIP_HASHMAP *seenexpr, SCIP_QUADEXPR *quadexpr, SCIP_QUADEXPR_QUADTERM **quadexprterm)
Definition: expr.c:135
#define SCIP_EXPRPRINT_EXPRSTRING
Definition: type_expr.h:703
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:5779
SCIP_RETCODE SCIPexprDismantle(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_MESSAGEHDLR *messagehdlr, FILE *file, SCIP_EXPR *expr)
Definition: expr.c:2520
void SCIPexprhdlrSetHash(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRHASH((*hash)))
Definition: expr.c:442
SCIP_Longint exprlastdifftag
Definition: struct_stat.h:119
SCIP_INTERVAL SCIPexprGetActivity(SCIP_EXPR *expr)
Definition: expr.c:3954
SCIP_EXPRITER_USERDATA SCIPexpriterGetChildUserDataDFS(SCIP_EXPRITER *iterator)
Definition: expriter.c:761
public methods for problem variables
void SCIPexprhdlrSetIntegrality(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRINTEGRALITY((*integrality)))
Definition: expr.c:431
#define SCIPdebugMessage
Definition: pub_message.h:87
SCIP_RETCODE SCIPexprPrintDotFinal(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPRPRINTDATA **printdata)
Definition: expr.c:2467
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3201
SCIP_Bool SCIPsetIsNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6334
SCIP_Real SCIPexprhdlrGetSimplifyTime(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:807
#define BMSallocClearBufferMemoryArray(mem, ptr, num)
Definition: memory.h:725
SCIP_RETCODE SCIPexprhdlrBwDiffExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, BMS_BUFMEM *bufmem, SCIP_EXPR *expr, int childidx, SCIP_Real *derivative, SCIP_Real *childrenvals, SCIP_Real exprval)
Definition: expr.c:1242
SCIP_EXPRITER_USERDATA SCIPexpriterGetCurrentUserData(SCIP_EXPRITER *iterator)
Definition: expriter.c:746
SCIP_Real SCIPexprhdlrGetIntevalTime(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:691
#define SCIP_DECL_EXPRFREEDATA(x)
Definition: type_expr.h:256
#define SCIP_EXPRITER_ENTEREXPR
Definition: type_expr.h:667
SCIP_RETCODE SCIPexprhdlrIntegralityExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_Bool *isintegral)
Definition: expr.c:1053
#define SCIP_EXPRITER_VISITEDCHILD
Definition: type_expr.h:669
SCIP_Bool SCIPexprAreQuadraticExprsVariables(SCIP_EXPR *expr)
Definition: expr.c:4185
SCIP_RETCODE SCIPexprComputeQuadraticCurvature(SCIP_SET *set, BMS_BLKMEM *blkmem, BMS_BUFMEM *bufmem, SCIP_MESSAGEHDLR *messagehdlr, SCIP_EXPR *expr, SCIP_EXPRCURV *curv, SCIP_HASHMAP *assumevarfixed, SCIP_Bool storeeigeninfo)
Definition: expr.c:3573
SCIP_EXPRHDLR * SCIPsetFindExprhdlr(SCIP_SET *set, const char *name)
Definition: set.c:5125
SCIP_Real SCIPsetCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6398
SCIP_EXPR * SCIPexpriterGetCurrent(SCIP_EXPRITER *iterator)
Definition: expriter.c:673
Definition: heur_padm.c:123
struct SCIP_Expr_OwnerData SCIP_EXPR_OWNERDATA
Definition: type_expr.h:68
SCIP_RETCODE SCIPexprPrint(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_MESSAGEHDLR *messagehdlr, FILE *file, SCIP_EXPR *expr)
Definition: expr.c:2241
unsigned int precedence
Definition: struct_expr.h:39
int nchildren
Definition: struct_expr.h:100
#define SCIP_EXPRPRINT_ACTIVITY
Definition: type_expr.h:708
SCIP * scip
Definition: struct_set.h:66
void SCIPexpriterFree(SCIP_EXPRITER **iterator)
Definition: expriter.c:436
#define SCIP_EXPRPRINT_ACTIVITYTAG
Definition: type_expr.h:709
SCIP_RETCODE SCIPexprPrintDot(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_EXPRPRINTDATA *printdata, SCIP_EXPR *expr)
Definition: expr.c:2353
SCIP_Bool isintegral
Definition: struct_expr.h:131
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3363
SCIP_EXPRITER_USERDATA SCIPexpriterGetExprUserData(SCIP_EXPRITER *iterator, SCIP_EXPR *expr)
Definition: expriter.c:780
SCIP_EXPRDATA * SCIPexprGetData(SCIP_EXPR *expr)
Definition: expr.c:3831
SCIP_EXPR ** SCIPexprGetChildren(SCIP_EXPR *expr)
Definition: expr.c:3808
SCIP_QUADEXPR_QUADTERM * quadexprterms
Definition: struct_expr.h:148
#define BMSduplicateBlockMemoryArray(mem, ptr, source, num)
Definition: memory.h:455
SCIP_Real * SCIPgetCoefsExprSum(SCIP_EXPR *expr)
Definition: expr_sum.c:1157
#define SCIP_DECL_EXPRPARSE(x)
Definition: type_expr.h:300
SCIP_Longint SCIPexprGetActivityTag(SCIP_EXPR *expr)
Definition: expr.c:3970
SCIP_Real SCIPexprGetEvalValue(SCIP_EXPR *expr)
Definition: expr.c:3872
#define BMSfreeMemoryArray(ptr)
Definition: memory.h:140
SCIP_RETCODE SCIPexprhdlrReversePropExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_INTERVAL bounds, SCIP_INTERVAL *childrenbounds, SCIP_Bool *infeasible)
Definition: expr.c:1653
#define SCIPerrorMessage
Definition: pub_message.h:55
SCIP_Real SCIPexprGetDerivative(SCIP_EXPR *expr)
Definition: expr.c:3898
int SCIPhashmapGetNEntries(SCIP_HASHMAP *hashmap)
Definition: misc.c:3481
SCIP_HASHMAPENTRY * SCIPhashmapGetEntry(SCIP_HASHMAP *hashmap, int entryidx)
Definition: misc.c:3489
SCIP_RETCODE SCIPexprhdlrInitEstimatesExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_INTERVAL *bounds, SCIP_Bool overestimate, SCIP_Real *coefs[SCIP_EXPR_MAXINITESTIMATES], SCIP_Real constant[SCIP_EXPR_MAXINITESTIMATES], int *nreturned)
Definition: expr.c:1573
SCIP_RETCODE SCIPexprhdlrSimplifyExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_EXPR **simplifiedexpr, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr.c:1608
void SCIPclockReset(SCIP_CLOCK *clck)
Definition: clock.c:200
SCIP_Bool SCIPexprhdlrHasMonotonicity(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:645
SCIP_VAR * SCIPgetVarExprVar(SCIP_EXPR *expr)
Definition: expr_var.c:407
SCIP_RETCODE SCIPexpriterCreate(SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPRITER **iterator)
Definition: expriter.c:417
SCIP_Longint SCIPexprhdlrGetNSimplifications(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:817
SCIP_Bool SCIPexprhdlrHasEstimate(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:605
SCIP_CLOCK * estimatetime
Definition: struct_expr.h:74
void SCIPintervalSetEmpty(SCIP_INTERVAL *resultant)
SCIP_CLOCK * simplifytime
Definition: struct_expr.h:77
#define BMSallocBufferMemoryArray(mem, ptr, num)
Definition: memory.h:724
void print(const Container &container, const std::string &prefix="", const std::string &suffix="", std::ostream &os=std::cout, bool negate=false, int prec=6)
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17251
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition: clock.c:429
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:3048
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:418
#define BMSallocClearBlockMemoryArray(mem, ptr, num)
Definition: memory.h:448
void SCIPexprGetQuadraticQuadTerm(SCIP_EXPR *quadexpr, int termidx, SCIP_EXPR **expr, SCIP_Real *lincoef, SCIP_Real *sqrcoef, int *nadjbilin, int **adjbilin, SCIP_EXPR **sqrexpr)
Definition: expr.c:4104
#define NULL
Definition: lpi_spx1.cpp:155
SCIP_Real SCIPsetFrac(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6420
SCIP_CLOCK * intevaltime
Definition: struct_expr.h:75
SCIP_Real SCIPexprGetBardot(SCIP_EXPR *expr)
Definition: expr.c:3926
SCIP_INTERVAL activity
Definition: struct_expr.h:124
SCIP_Longint SCIPexprGetDiffTag(SCIP_EXPR *expr)
Definition: expr.c:3941
SCIP_EXPRDATA * exprdata
Definition: struct_expr.h:98
SCIP_Real SCIPexprGetDot(SCIP_EXPR *expr)
Definition: expr.c:3912
SCIP_Longint npropcalls
Definition: struct_expr.h:67
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:384
#define SCIP_DECL_EXPRFREEHDLR(x)
Definition: type_expr.h:212
int SCIPexpriterGetChildIdxDFS(SCIP_EXPRITER *iterator)
Definition: expriter.c:697
#define SCIP_EXPRPRINT_OWNER
Definition: type_expr.h:710
SCIP_Bool SCIPexprIsVar(SCIP_SET *set, SCIP_EXPR *expr)
Definition: expr.c:2181
SCIP_Bool SCIPexprhdlrHasCurvature(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:635
SCIP_Longint SCIPexprGetEvalTag(SCIP_EXPR *expr)
Definition: expr.c:3885
SCIP_Bool SCIPexprhdlrHasIntEval(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:595
SCIP_Real * lincoefs
Definition: struct_expr.h:145
SCIP_CLOCK * proptime
Definition: struct_expr.h:76
SCIP_RETCODE SCIPexprhdlrFwDiffExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_Real *dot, SCIP_SOL *direction)
Definition: expr.c:1315
void SCIPexprhdlrSetCopyFreeHdlr(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRCOPYHDLR((*copyhdlr)), SCIP_DECL_EXPRFREEHDLR((*freehdlr)))
Definition: expr.c:359
SCIP_RETCODE SCIPexprReplaceChild(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, int childidx, SCIP_EXPR *newchild)
Definition: expr.c:1791
SCIP_RETCODE SCIPexprhdlrCreate(BMS_BLKMEM *blkmem, SCIP_EXPRHDLR **exprhdlr, const char *name, const char *desc, unsigned int precedence, SCIP_DECL_EXPREVAL((*eval)), SCIP_EXPRHDLRDATA *data)
Definition: expr.c:294
#define SCIP_INTERVAL_INFINITY
Definition: def.h:199
#define SCIP_EXPRPRINT_EVALVALUE
Definition: type_expr.h:706
SCIP_EXPRCURV SCIPexprGetCurvature(SCIP_EXPR *expr)
Definition: expr.c:3996
unsigned int SCIP_EXPRPRINT_WHAT
Definition: type_expr.h:715
SCIP_Bool eigeninfostored
Definition: struct_expr.h:159
#define BMSduplicateMemoryArray(ptr, source, num)
Definition: memory.h:136
SCIP_Real SCIPgetCoefExprProduct(SCIP_EXPR *expr)
SCIP_RETCODE SCIPclockCreate(SCIP_CLOCK **clck, SCIP_CLOCKTYPE clocktype)
Definition: clock.c:161
SCIP_RETCODE SCIPexprCreate(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_EXPR **expr, SCIP_EXPRHDLR *exprhdlr, SCIP_EXPRDATA *exprdata, int nchildren, SCIP_EXPR **children, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr.c:1703
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:458
Ipopt NLP interface.
public data structures and miscellaneous methods
#define SCIP_DECL_EXPRINTEVAL(x)
Definition: type_expr.h:527
void SCIPexprFreeQuadratic(BMS_BLKMEM *blkmem, SCIP_EXPR *expr)
Definition: expr.c:3528
int childrensize
Definition: struct_expr.h:101
#define SCIP_Bool
Definition: def.h:84
#define SCIP_EXPRPRINT_EXPRHDLR
Definition: type_expr.h:704
SCIP_Bool SCIPexprhdlrHasReverseProp(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:655
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:447
#define SCIP_DECL_EXPR_OWNERCREATE(x)
Definition: type_expr.h:131
SCIP_Longint nbranchscores
Definition: struct_expr.h:72
SCIP_EXPRCURV
Definition: type_expr.h:48
void SCIPexprhdlrSetMonotonicity(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRMONOTONICITY((*monotonicity)))
Definition: expr.c:420
SCIP_Longint SCIPexprhdlrGetNCutoffs(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:721
#define SCIP_DECL_EXPRINTEGRALITY(x)
Definition: type_expr.h:363
static SCIP_RETCODE freeExpr(BMS_BLKMEM *blkmem, SCIP_EXPR **expr)
Definition: expr.c:64
void SCIPclockFree(SCIP_CLOCK **clck)
Definition: clock.c:176
SCIP_Longint nestimatecalls
Definition: struct_expr.h:65
void SCIPexprCapture(SCIP_EXPR *expr)
Definition: expr.c:2039
#define SCIP_DECL_EXPRBWDIFF(x)
Definition: type_expr.h:437
SCIP_EXPR ** children
Definition: struct_expr.h:102
SCIP_RETCODE SCIPexprhdlrPrintExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_EXPR *expr, SCIP_EXPRITER_STAGE stage, int currentchild, unsigned int parentprecedence, FILE *file)
Definition: expr.c:887
void SCIPexprhdlrSetReverseProp(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRREVERSEPROP((*reverseprop)))
Definition: expr.c:501
#define SCIPsetDebugMsg
Definition: set.h:1761
SCIP_Longint SCIPexprhdlrGetNDomainReductions(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:731
SCIP_Bool SCIPexprIsIntegral(SCIP_EXPR *expr)
Definition: expr.c:4017
SCIP_EXPR * SCIPexpriterGetNext(SCIP_EXPRITER *iterator)
Definition: expriter.c:848
SCIP_EXPR * SCIPexpriterGetChildExprDFS(SCIP_EXPRITER *iterator)
Definition: expriter.c:711
struct SCIP_ExprhdlrData SCIP_EXPRHDLRDATA
Definition: type_expr.h:183
SCIP_EXPRHDLR * SCIPexprGetHdlr(SCIP_EXPR *expr)
Definition: expr.c:3821
datastructures for problem statistics
SCIP_Bool curvaturechecked
Definition: struct_expr.h:156
void SCIPexprhdlrSetPrint(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRPRINT((*print)))
Definition: expr.c:387
void SCIPexprhdlrSetCopyFreeData(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRCOPYDATA((*copydata)), SCIP_DECL_EXPRFREEDATA((*freedata)))
Definition: expr.c:372
SCIP_RETCODE SCIPexprEval(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, SCIP_SOL *sol, SCIP_Longint soltag)
Definition: expr.c:2628
SCIP_Longint difftag
Definition: struct_expr.h:119
SCIP_RETCODE SCIPexprDuplicateShallow(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, SCIP_EXPR **copyexpr, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr.c:2008
#define SCIP_DECL_EXPRCURVATURE(x)
Definition: type_expr.h:328
void SCIPexpriterSetStagesDFS(SCIP_EXPRITER *iterator, SCIP_EXPRITER_STAGE stopstages)
Definition: expriter.c:654
SCIP_Longint SCIPexprhdlrGetNIntevalCalls(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:681
SCIP_Longint nsimplified
Definition: struct_expr.h:71
#define SCIP_DECL_EXPRCOMPARE(x)
Definition: type_expr.h:398
SCIP_Real * eigenvectors
Definition: struct_expr.h:161
void SCIPexprhdlrSetCompare(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRCOMPARE((*compare)))
Definition: expr.c:453
#define SCIP_DECL_EXPRSIMPLIFY(x)
Definition: type_expr.h:620
SCIP_Longint ncutoffs
Definition: struct_expr.h:68
SCIP_Bool SCIPexprIsSum(SCIP_SET *set, SCIP_EXPR *expr)
Definition: expr.c:2205
static SCIP_RETCODE evalAndDiff(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, SCIP_SOL *sol, SCIP_Longint soltag, SCIP_SOL *direction)
Definition: expr.c:178
SCIP_Longint SCIPexprhdlrGetNReversepropCalls(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:701
SCIP_EXPRHDLR * exprhdlr
Definition: struct_expr.h:97
unsigned int SCIPexprhdlrGetPrecedence(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:545
SCIP_RETCODE SCIPexprCheckQuadratic(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, SCIP_Bool *isquadratic)
Definition: expr.c:3260
SCIP_Longint domchgcount
Definition: struct_stat.h:105
void SCIPexprhdlrSetCurvature(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRCURVATURE((*curvature)))
Definition: expr.c:409
void SCIPexprSetData(SCIP_EXPR *expr, SCIP_EXPRDATA *exprdata)
Definition: expr.c:3846
SCIP_QUADEXPR_BILINTERM * bilinexprterms
Definition: struct_expr.h:151
SCIP_Bool SCIPexprhdlrHasInitEstimates(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:615
void SCIPexprhdlrIncrementNDomainReductions(SCIP_EXPRHDLR *exprhdlr, int nreductions)
Definition: expr.c:741
SCIP_EXPRITER_STAGE SCIPexpriterGetStageDFS(SCIP_EXPRITER *iterator)
Definition: expriter.c:686
void SCIPexpriterSetCurrentUserData(SCIP_EXPRITER *iterator, SCIP_EXPRITER_USERDATA userdata)
Definition: expriter.c:796
SCIP_Longint SCIPexprhdlrGetNBranchings(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:777
SCIP_Bool SCIPexprIsValue(SCIP_SET *set, SCIP_EXPR *expr)
Definition: expr.c:2193
int SCIPexprCompare(SCIP_SET *set, SCIP_EXPR *expr1, SCIP_EXPR *expr2)
Definition: expr.c:3056
void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
Definition: message.c:609
void SCIPexprGetQuadraticBilinTerm(SCIP_EXPR *expr, int termidx, SCIP_EXPR **expr1, SCIP_EXPR **expr2, SCIP_Real *coef, int *pos2, SCIP_EXPR **prodexpr)
Definition: expr.c:4147
#define SCIP_DECL_EXPRESTIMATE(x)
Definition: type_expr.h:563
#define SCIP_DECL_EXPR_MAPEXPR(x)
Definition: type_expr.h:170
SCIP_Real * eigenvalues
Definition: struct_expr.h:160
SCIP_RETCODE SCIPexprhdlrParseExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, const char *string, const char **endstring, SCIP_EXPR **expr, SCIP_Bool *success, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr.c:956
#define SCIP_Real
Definition: def.h:177
SCIP_RETCODE SCIPexprhdlrFree(SCIP_EXPRHDLR **exprhdlr, SCIP_SET *set, BMS_BLKMEM *blkmem)
Definition: expr.c:329
#define SCIPsetDebugMsgPrint
Definition: set.h:1762
void SCIPexprSetActivity(SCIP_EXPR *expr, SCIP_INTERVAL activity, SCIP_Longint activitytag)
Definition: expr.c:3980
SCIP_RETCODE SCIPexprEvalActivity(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *rootexpr)
Definition: expr.c:2924
#define SCIP_EXPR_MAXINITESTIMATES
Definition: type_expr.h:186
SCIP_Real derivative
Definition: struct_expr.h:115
#define SCIP_INVALID
Definition: def.h:197
SCIP_RETCODE SCIPexprhdlrEvalExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, BMS_BUFMEM *bufmem, SCIP_EXPR *expr, SCIP_Real *val, SCIP_Real *childrenvals, SCIP_SOL *sol)
Definition: expr.c:1175
SCIP_Real SCIPgetValueExprValue(SCIP_EXPR *expr)
Definition: expr_value.c:285
unsigned int SCIPexprhdlrGetNCreated(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:671
#define SCIP_Longint
Definition: def.h:162
SCIP_RETCODE SCIPexprhdlrEvalFwDiffExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, BMS_BUFMEM *bufmem, SCIP_EXPR *expr, SCIP_Real *val, SCIP_Real *dot, SCIP_Real *childrenvals, SCIP_SOL *sol, SCIP_Real *childrendirs, SCIP_SOL *direction)
Definition: expr.c:1356
SCIP_Longint ndomreds
Definition: struct_expr.h:69
SCIP_Real SCIPexprhdlrGetReversepropTime(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:711
#define SCIPisFinite(x)
Definition: pub_misc.h:1892
SCIP_Real evalvalue
Definition: struct_expr.h:114
unsigned int SCIPcalcFibHash(SCIP_Real v)
Definition: misc.c:10242
#define SCIP_EXPRITER_LEAVEEXPR
Definition: type_expr.h:670
void SCIPexprhdlrSetEstimate(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRINITESTIMATES((*initestimates)), SCIP_DECL_EXPRESTIMATE((*estimate)))
Definition: expr.c:512
SCIP_Real bardot
Definition: struct_expr.h:117
SCIP_RETCODE SCIPexprAppendChild(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, SCIP_EXPR *child)
Definition: expr.c:1760
SCIP_QUADEXPR * quaddata
Definition: struct_expr.h:134
unsigned int SCIP_EXPRITER_STAGE
Definition: type_expr.h:674
const char * SCIPexprhdlrGetDescription(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:535
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17976
SCIP_DECL_SORTPTRCOMP(SCIPexprhdlrComp)
Definition: expr.c:665
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:444
#define SCIP_EXPRITER_VISITINGCHILD
Definition: type_expr.h:668
SCIP_RETCODE SCIPhashmapInsert(SCIP_HASHMAP *hashmap, void *origin, void *image)
Definition: misc.c:3096
SCIP_Bool SCIPexprIsProduct(SCIP_SET *set, SCIP_EXPR *expr)
Definition: expr.c:2217
SCIP_Bool SCIPexpriterIsEnd(SCIP_EXPRITER *iterator)
Definition: expriter.c:959
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:430
int SCIPhashmapGetImageInt(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3221
SCIP_EXPRHDLRDATA * data
Definition: struct_expr.h:38
SCIP_RETCODE SCIPexprRelease(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR **rootexpr)
Definition: expr.c:2049
SCIP_Bool SCIPexprhdlrHasSimplify(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:625
SCIP_RETCODE SCIPexprhdlrCurvatureExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_EXPRCURV exprcurvature, SCIP_Bool *success, SCIP_EXPRCURV *childcurv)
Definition: expr.c:995
#define SCIP_DECL_EXPRCOPYHDLR(x)
Definition: type_expr.h:198
#define SCIP_ALLOC(x)
Definition: def.h:395
#define BMSallocClearBlockMemory(mem, ptr)
Definition: memory.h:445
#define SCIPABORT()
Definition: def.h:356
#define BMSfreeBufferMemoryArray(mem, ptr)
Definition: memory.h:735
SCIP_Real dot
Definition: struct_expr.h:116
void SCIPexprhdlrIncrementNBranchings(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:787
int SCIPexprGetNUses(SCIP_EXPR *expr)
Definition: expr.c:3788
datastructures for global SCIP settings
void SCIPexprhdlrSetSimplify(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRSIMPLIFY((*simplify)))
Definition: expr.c:490
#define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
Definition: memory.h:451
void SCIPexprhdlrSetIntEval(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRINTEVAL((*inteval)))
Definition: expr.c:479
#define SCIP_DECL_EXPRCOPYDATA(x)
Definition: type_expr.h:237
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:1853
#define SCIP_DECL_EXPRHASH(x)
Definition: type_expr.h:379
SCIP_Bool SCIPexprIsPower(SCIP_SET *set, SCIP_EXPR *expr)
Definition: expr.c:2229
SCIP_Bool quadchecked
Definition: struct_expr.h:135
#define SCIP_DECL_EXPRBWFWDIFF(x)
Definition: type_expr.h:508
SCIP_RETCODE SCIPexprhdlrMonotonicityExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, int childidx, SCIP_MONOTONE *result)
Definition: expr.c:1024
SCIP_Longint activitytag
Definition: struct_expr.h:125