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