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