Scippy

SCIP

Solving Constraint Integer Programs

expr_sum.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2022 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scip.zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file expr_sum.c
17  * @ingroup DEFPLUGINS_EXPR
18  * @brief sum expression handler
19  * @author Stefan Vigerske
20  * @author Benjamin Mueller
21  * @author Felipe Serrano
22  */
23 
24 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
25 
26 #include <string.h>
27 #include <stddef.h>
28 
29 #include "scip/expr_sum.h"
30 #include "scip/expr_value.h"
31 #include "scip/expr_product.h"
32 #include "scip/expr_exp.h"
33 
34 #define EXPRHDLR_NAME "sum"
35 #define EXPRHDLR_DESC "summation with coefficients and a constant"
36 #define EXPRHDLR_PRECEDENCE 40000
37 #define EXPRHDLR_HASHKEY SCIPcalcFibHash(47161.0)
38 
39 /** macro to activate/deactivate debugging information of simplify method */
40 /*lint -emacro(774,debugSimplify) */
41 #ifdef SIMPLIFY_DEBUG
42 #define debugSimplify printf
43 #else
44 #define debugSimplify while( FALSE ) printf
45 #endif
46 
47 /*
48  * Data structures
49  */
50 
51 /** expression data */
52 struct SCIP_ExprData
53 {
54  SCIP_Real constant; /**< constant coefficient */
55  SCIP_Real* coefficients; /**< coefficients of children */
56  int coefssize; /**< size of the coefficients array */
57 };
58 
59 /*
60  * Local methods
61  */
62 
63 /** creates expression data */
64 static
66  SCIP* scip, /**< SCIP data structure */
67  SCIP_EXPRDATA** exprdata, /**< pointer where to store expression data */
68  int ncoefficients, /**< number of coefficients (i.e., number of children) */
69  SCIP_Real* coefficients, /**< array with coefficients for all children (or NULL if all 1.0) */
70  SCIP_Real constant /**< constant term of sum */
71  )
72 {
73  assert(exprdata != NULL);
74  assert(ncoefficients >= 0);
75 
76  SCIP_CALL( SCIPallocBlockMemory(scip, exprdata) );
77 
78  if( coefficients != NULL )
79  {
80  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*exprdata)->coefficients, coefficients, ncoefficients) );
81  }
82  else
83  {
84  int i;
85 
86  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(*exprdata)->coefficients, ncoefficients) );
87  for( i = 0; i < ncoefficients; ++i )
88  (*exprdata)->coefficients[i] = 1.0;
89  }
90 
91  (*exprdata)->coefssize = ncoefficients;
92  (*exprdata)->constant = constant;
93 
94  return SCIP_OKAY;
95 }
96 
97 /** simplifies the `idx`-th child of the sum expression `duplicate` in order for it to be able to be a child of a simplified sum
98  *
99  * for example, this means that the `idx`-th child cannot be itself a sum
100  * if it is, we have to flatten it, i.e., take all its children and make them children of `duplicate`
101  */
102 static
104  SCIP* scip, /**< SCIP data structure */
105  SCIP_EXPR* duplicate, /**< expression to be simplified */
106  int idx, /**< idx of children to be simplified */
107  SCIP_Bool* changed, /**< pointer to store if some term actually got simplified */
108  SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
109  void* ownercreatedata /**< data to pass to ownercreate */
110  )
111 {
112  SCIP_EXPR** children;
113  SCIP_EXPR* expr;
114  SCIP_Real* coefs;
115  SCIP_Real constant ;
116  SCIP_Real coef;
117 
118  assert(duplicate != NULL);
119  assert(idx >= 0);
120  assert(idx < SCIPexprGetNChildren(duplicate));
121  assert(changed != NULL);
122 
123  children = SCIPexprGetChildren(duplicate);
124  coefs = SCIPgetCoefsExprSum(duplicate);
125  constant = SCIPgetConstantExprSum(duplicate);
126 
127  coef = coefs[idx];
128  expr = children[idx];
129  assert(expr != NULL);
130 
131  /* enforces SS3 */
132  if( SCIPisExprValue(scip, expr) )
133  {
134  *changed = TRUE;
135  constant += coef * SCIPgetValueExprValue(expr);
136  SCIPsetConstantExprSum(duplicate, constant);
137 
138  /* TODO: remove child? */
139  coefs[idx] = 0.0;
140 
141  return SCIP_OKAY;
142  }
143 
144  /* enforces SS2 */
145  if( SCIPisExprSum(scip, expr) )
146  {
147  *changed = TRUE;
148 
149  /* pass constant to parent */
150  constant += coef * SCIPgetConstantExprSum(expr);
151  SCIPsetConstantExprSum(duplicate, constant);
152 
153  /* append all children of expr on parent except the first one */
154  if( SCIPexprGetNChildren(expr) > 1 )
155  {
156  int i;
157 
158  for( i = 1; i < SCIPexprGetNChildren(expr); ++i )
159  {
160  assert(!SCIPisExprSum(scip, SCIPexprGetChildren(expr)[i]));
161  SCIP_CALL( SCIPappendExprSumExpr(scip, duplicate, SCIPexprGetChildren(expr)[i],
162  coef * SCIPgetCoefsExprSum(expr)[i]) );
163  }
164  }
165 
166  /* replace expr with first child; need to get data again since it might be re-allocated */
167  assert(!SCIPisExprSum(scip, SCIPexprGetChildren(expr)[0]));
168 
169  coefs = SCIPgetCoefsExprSum(duplicate);
170 
171  coefs[idx] = coef * SCIPgetCoefsExprSum(expr)[0];
172  SCIP_CALL( SCIPreplaceExprChild(scip, duplicate, idx, SCIPexprGetChildren(expr)[0]) );
173 
174  return SCIP_OKAY;
175  }
176 
177  /* enforce SS9 */
178  if( REALABS(coef) != 1.0 && SCIPisExprProduct(scip, expr) )
179  {
180  SCIP_EXPR* expchild = NULL;
181  int i;
182 
183  for( i = 0; i < SCIPexprGetNChildren(expr); ++i )
184  {
185  SCIP_EXPR* child = SCIPexprGetChildren(expr)[i];
186  assert(child != NULL);
187 
188  if( SCIPisExprExp(scip, child) )
189  {
190  expchild = child;
191  break;
192  }
193  }
194 
195  /* coef != +- 1, term is product and one factor is an exponential -> enforce SS9 */
196  if( expchild != NULL )
197  {
198  SCIP_EXPR* sum;
199  SCIP_EXPR* prod;
200  SCIP_EXPR* simplifiedprod;
201  SCIP_EXPR* simplifiedsum;
202  SCIP_EXPR* exponential;
203  SCIP_EXPR* simplifiedexp;
204  SCIP_Real expconstant;
205 
206  /* inform that expression will change */
207  *changed = TRUE;
208 
209  /* compute expchild's coefficient as +- 1.0 * exp(log(abs(coef))) */
210  if( coef > 0.0 )
211  {
212  expconstant = log(coef);
213  coefs[idx] = 1.0;
214  }
215  else
216  {
217  expconstant = log(-coef);
218  coefs[idx] = -1.0;
219  }
220 
221  /* add constant to exponential's child */
222  SCIP_CALL( SCIPcreateExprSum(scip, &sum, 1, SCIPexprGetChildren(expchild), NULL, expconstant, ownercreate,
223  ownercreatedata) );
224 
225  /* simplify sum */
226  SCIP_CALL( SCIPcallExprSimplify(scip, sum, &simplifiedsum, ownercreate, ownercreatedata) );
227  SCIP_CALL( SCIPreleaseExpr(scip, &sum) );
228 
229  /* create exponential with new child */
230  SCIP_CALL( SCIPcreateExprExp(scip, &exponential, simplifiedsum, ownercreate, ownercreatedata) );
231  SCIP_CALL( SCIPreleaseExpr(scip, &simplifiedsum) );
232 
233  /* simplify exponential */
234  SCIP_CALL( SCIPcallExprSimplify(scip, exponential, &simplifiedexp, ownercreate, ownercreatedata) );
235  SCIP_CALL( SCIPreleaseExpr(scip, &exponential) );
236 
237  /* create product with new child */
238  SCIP_CALL( SCIPcreateExprProduct(scip, &prod, 0, NULL, 1.0, ownercreate, ownercreatedata) );
239 
240  for( i = 0; i < SCIPexprGetNChildren(expr); ++i )
241  {
242  if( SCIPexprGetChildren(expr)[i] == expchild )
243  {
244  SCIP_CALL( SCIPappendExprChild(scip, prod, simplifiedexp) );
245  }
246  else
247  {
248  SCIP_CALL( SCIPappendExprChild(scip, prod, SCIPexprGetChildren(expr)[i]) );
249  }
250  }
251  SCIP_CALL( SCIPreleaseExpr(scip, &simplifiedexp) );
252 
253  /* simplify product */
254  SCIP_CALL( SCIPcallExprSimplify(scip, prod, &simplifiedprod, ownercreate, ownercreatedata) );
255  SCIP_CALL( SCIPreleaseExpr(scip, &prod) );
256 
257  /* replace current child with simplified product */
258  SCIP_CALL( SCIPreplaceExprChild(scip, duplicate, idx, simplifiedprod) );
259  SCIP_CALL( SCIPreleaseExpr(scip, &simplifiedprod) );
260 
261  /* since the simplified product can be a sum ( exp(-1)*exp(log(x+y)+1) -> x+y ),
262  * we call the function we are in again
263  * this is no endless recursion, since the coef is now +- 1
264  */
265  SCIP_CALL( simplifyTerm(scip, duplicate, idx, changed, ownercreate, ownercreatedata) );
266 
267  return SCIP_OKAY;
268  }
269  }
270 
271  /* enforce SS10 */
272  if( REALABS(coef) != 1.0 && SCIPisExprExp(scip, expr) )
273  {
274  /* coef != +- 1, term is exponential -> enforce SS10 by moving |coef| into argument of exponential */
275 
276  SCIP_EXPR* sum;
277  SCIP_EXPR* simplifiedsum;
278  SCIP_EXPR* exponential;
279  SCIP_EXPR* simplifiedexp;
280  SCIP_Real expconstant;
281 
282  /* inform that expression will change */
283  *changed = TRUE;
284 
285  /* compute expchild's coefficient as +- 1.0 * exp(log(abs(coef))) */
286  if( coef > 0.0 )
287  {
288  expconstant = log(coef);
289  coefs[idx] = 1.0;
290  }
291  else
292  {
293  expconstant = log(-coef);
294  coefs[idx] = -1.0;
295  }
296 
297  /* add constant to exponential's child */
298  SCIP_CALL( SCIPcreateExprSum(scip, &sum, 1, SCIPexprGetChildren(expr), NULL, expconstant, ownercreate,
299  ownercreatedata) ); /* expconstant+expchild */
300 
301  /* simplify sum */
302  SCIP_CALL( SCIPcallExprSimplify(scip, sum, &simplifiedsum, ownercreate, ownercreatedata) );
303  SCIP_CALL( SCIPreleaseExpr(scip, &sum) );
304 
305  /* create exponential with new child */
306  SCIP_CALL( SCIPcreateExprExp(scip, &exponential, simplifiedsum, ownercreate, ownercreatedata) );
307  SCIP_CALL( SCIPreleaseExpr(scip, &simplifiedsum) );
308 
309  /* simplify exponential */
310  SCIP_CALL( SCIPcallExprSimplify(scip, exponential, &simplifiedexp, ownercreate, ownercreatedata) );
311  SCIP_CALL( SCIPreleaseExpr(scip, &exponential) );
312 
313  /* replace current child with simplified exponential */
314  SCIP_CALL( SCIPreplaceExprChild(scip, duplicate, idx, simplifiedexp) );
315  SCIP_CALL( SCIPreleaseExpr(scip, &simplifiedexp) );
316 
317  return SCIP_OKAY;
318  }
319 
320  /* other types of (simplified) expressions can be a child of a simplified sum */
321  assert(!SCIPisExprSum(scip, expr));
322  assert(!SCIPisExprValue(scip, expr));
323 
324  return SCIP_OKAY;
325 }
326 
327 /** helper struct for expressions sort */
328 typedef struct
329 {
330  SCIP* scip; /**< SCIP data structure */
331  SCIP_EXPR** exprs; /**< expressions */
332 } SORTEXPRDATA;
333 
334 static
336 {
337  SORTEXPRDATA* data = (SORTEXPRDATA*)dataptr;
338 
339  return SCIPcompareExpr(data->scip, data->exprs[ind1], data->exprs[ind2]);
340 }
341 
342 /*
343  * Callback methods of expression handler
344  */
345 
346 /** simplifies a sum expression
347  *
348  * goes through each child and simplifies it; then sorts the simplified children; then sum the children that are equal;
349  * finally creates a sum expression with all the children that do not have a 0 coefficient and post-process so that SS6
350  * and SS7 are satisfied
351  */
352 static
354 { /*lint --e{715}*/
355  SCIP_EXPR** children;
356  SCIP_EXPR* duplicate = NULL;
357  SCIP_EXPR** newchildren = NULL;
358  SCIP_Real* newcoefs = NULL;
359  int nnewchildren;
360  SCIP_Real newconstant;
361  SCIP_Real* coefs;
362  int i;
363  int nchildren;
364  SCIP_Bool changed;
365  SORTEXPRDATA sortdata;
366  int* order = NULL;
367 
368  assert(expr != NULL);
369  assert(simplifiedexpr != NULL);
370  assert(SCIPexprGetHdlr(expr) == SCIPgetExprhdlrSum(scip));
371 
372  changed = FALSE;
373 
374  /* TODO: maybe have a flag to know if it is simplified ? */
375  /* TODO: can we do this with a shallow duplicate + copy of children pointer? currently simplifyTerm may modify children,
376  * so one would need to be careful
377  */
378  SCIP_CALL( SCIPduplicateExpr(scip, expr, &duplicate, NULL, NULL, ownercreate, ownercreatedata) );
379  assert(duplicate != NULL);
380 
381  nchildren = SCIPexprGetNChildren(duplicate);
382  for( i = 0; i < nchildren; i++ )
383  {
384  /* enforces SS8 TODO: remove child? */
385  /* we have to ask for the coefs everytime, since it might get realloced in simpifyTerm */
386  if( SCIPgetCoefsExprSum(duplicate)[i] == 0.0 )
387  {
388  changed = TRUE;
389  continue;
390  }
391 
392  /* enforces SS2, SS3, SS9, and SS10 */
393  SCIP_CALL( simplifyTerm(scip, duplicate, i, &changed, ownercreate, ownercreatedata) );
394  }
395 
396  /* simplifyTerm can add new children to duplicate and realloc them; so get them again */
397  nchildren = SCIPexprGetNChildren(duplicate);
398  children = SCIPexprGetChildren(duplicate);
399  coefs = SCIPgetCoefsExprSum(duplicate);
400 
401  /* treat zero term case */
402  if( nchildren == 0 )
403  {
404  SCIP_CALL( SCIPcreateExprValue(scip, simplifiedexpr, SCIPgetConstantExprSum(duplicate), ownercreate, ownercreatedata) );
405  goto CLEANUP;
406  }
407 
408  /* treat one term case */
409  if( nchildren == 1 )
410  {
411  if( coefs[0] == 0.0 )
412  {
413  SCIP_CALL( SCIPcreateExprValue(scip, simplifiedexpr, SCIPgetConstantExprSum(duplicate), ownercreate, ownercreatedata) );
414  goto CLEANUP;
415  }
416 
417  if( coefs[0] == 1.0 && SCIPgetConstantExprSum(duplicate) == 0.0 )
418  *simplifiedexpr = children[0]; /* SS7 */
419  else
420  *simplifiedexpr = changed ? duplicate : expr;
421 
422  SCIPcaptureExpr(*simplifiedexpr);
423 
424  goto CLEANUP;
425  }
426 
427  /* enforces SS5: sort children */
428  SCIP_CALL( SCIPallocBufferArray(scip, &order, nchildren) );
429  for( i = 0; i < nchildren; i++ )
430  order[i] = i;
431  sortdata.scip = scip;
432  sortdata.exprs = children;
433  SCIPsortInd(order, sortExprComp, (void*)&sortdata, nchildren);
434 
435  /* create sorted variant of children and coefs */
436  SCIP_CALL( SCIPallocBufferArray(scip, &newchildren, nchildren) );
437  SCIP_CALL( SCIPallocBufferArray(scip, &newcoefs, nchildren) );
438  for( i = 0; i < nchildren; ++i )
439  {
440  newchildren[i] = children[order[i]];
441  newcoefs[i] = coefs[order[i]];
442  if( order[i] != i )
443  changed = TRUE;
444  }
445 
446  /* post-process */
447 
448  /* enforces SS4 */
449  nnewchildren = 0;
450  for( i = 0; i < nchildren; i++ )
451  {
452  /* eliminate zero-coefficients */
453  if( newcoefs[i] == 0.0 )
454  {
455  changed = TRUE;
456  continue;
457  }
458 
459  /* sum equal expressions */
460  if( i < nchildren-1 && SCIPcompareExpr(scip, newchildren[i], newchildren[i+1]) == 0 )
461  {
462  changed = TRUE;
463  /* if we substract two almost equal not-so-small numbers, then set new coefficient to 0.0
464  * instead of some tiny value that is likely the result of some random round-off error
465  * E.g., on instance ex1221, we have x1^2 + b3 = 1.25.
466  * Probing finds an aggregation x1 = 1.11803 - 0.618034 b3.
467  * Simplify would then produce 1.25 + 1e-16 x1 = 1.25.
468  */
469  if( SCIPisEQ(scip, newcoefs[i], -newcoefs[i+1]) && REALABS(newcoefs[i]) >= 1.0 )
470  newcoefs[i+1] = 0.0;
471  else
472  newcoefs[i+1] += newcoefs[i];
473  continue;
474  }
475 
476  /* move i-th child to new position */
477  newchildren[nnewchildren] = newchildren[i];
478  newcoefs[nnewchildren] = newcoefs[i];
479  nnewchildren++;
480  }
481 
482  /* build sum expression from finalchildren and post-simplify */
483  newconstant = SCIPgetConstantExprSum(duplicate);
484 
485  debugSimplify("what to do? finalchildren has length %d\n", nnewchildren); /*lint !e506 !e681*/
486 
487  /* enforces SS6: if they are no children, return value */
488  if( nnewchildren == 0 )
489  {
490  debugSimplify("[sum] got empty list, return value %g\n", newconstant); /*lint !e506 !e681*/
491  SCIP_CALL( SCIPcreateExprValue(scip, simplifiedexpr, newconstant, ownercreate, ownercreatedata) );
492 
493  goto CLEANUP;
494  }
495 
496  /* enforces SS7: if list consists of one expr with coef 1.0 and constant is 0, return that expr */
497  if( nnewchildren == 1 && newcoefs[0] == 1.0 && newconstant == 0.0 )
498  {
499  *simplifiedexpr = newchildren[0];
500  SCIPcaptureExpr(*simplifiedexpr);
501 
502  goto CLEANUP;
503  }
504 
505  /* build sum expression from children */
506  if( changed )
507  {
508  SCIP_CALL( SCIPcreateExprSum(scip, simplifiedexpr, nnewchildren, newchildren, newcoefs, newconstant,
509  ownercreate, ownercreatedata) );
510 
511  goto CLEANUP;
512  }
513 
514  *simplifiedexpr = expr;
515 
516  /* we have to capture it, since it must simulate a "normal" simplified call in which a new expression is created */
517  SCIPcaptureExpr(*simplifiedexpr);
518 
519  /* free memory */
520  CLEANUP:
521  SCIPfreeBufferArrayNull(scip, &newcoefs);
522  SCIPfreeBufferArrayNull(scip, &newchildren);
523  SCIPfreeBufferArrayNull(scip, &order);
524  SCIP_CALL( SCIPreleaseExpr(scip, &duplicate) );
525 
526  return SCIP_OKAY;
527 }
528 
529 /** compares two sum expressions
530  *
531  * The order of two sum expressions is a lexicographical order on the terms.
532  *
533  * Starting from the *last*, we find the first child where they differ, say, the i-th.
534  * Then u < v <=> u_i < v_i.
535  * If there are no such children and they have different number of children, then u < v <=> nchildren(u) < nchildren(v).
536  * If there are no such children and they have the same number of children, then u < v <=> const(u) < const(v).
537  * Otherwise, they are the same.
538  *
539  * Note: we are assuming expression are simplified, so within u, we have u_1 < u_2, etc
540  *
541  * Example: y + z < x + y + z, 2*x + 3*y < 3*x + 3*y
542  */
543 static
545 { /*lint --e{715}*/
546  SCIP_Real const1;
547  SCIP_Real* coefs1;
548  SCIP_EXPR** children1;
549  int nchildren1;
550  SCIP_Real const2;
551  SCIP_Real* coefs2;
552  SCIP_EXPR** children2;
553  int nchildren2;
554  int compareresult;
555  int i;
556  int j;
557 
558  nchildren1 = SCIPexprGetNChildren(expr1);
559  nchildren2 = SCIPexprGetNChildren(expr2);
560  children1 = SCIPexprGetChildren(expr1);
561  children2 = SCIPexprGetChildren(expr2);
562  coefs1 = SCIPgetCoefsExprSum(expr1);
563  coefs2 = SCIPgetCoefsExprSum(expr2);
564  const1 = SCIPgetConstantExprSum(expr1);
565  const2 = SCIPgetConstantExprSum(expr2);
566 
567  for( i = nchildren1 - 1, j = nchildren2 - 1; i >= 0 && j >= 0; --i, --j )
568  {
569  compareresult = SCIPcompareExpr(scip, children1[i], children2[j]);
570  if( compareresult != 0 )
571  return compareresult;
572  else
573  {
574  /* expressions are equal, compare coefficient */
575  if( (coefs1 ? coefs1[i] : 1.0) < (coefs2 ? coefs2[j] : 1.0) )
576  return -1;
577  if( (coefs1 ? coefs1[i] : 1.0) > (coefs2 ? coefs2[j] : 1.0) )
578  return 1;
579 
580  /* coefficients are equal, continue */
581  }
582  }
583 
584  /* all children of one expression are children of the other expression, use number of children as a tie-breaker */
585  if( i < j )
586  {
587  assert(i == -1);
588  /* expr1 has less elements, hence expr1 < expr2 */
589  return -1;
590  }
591  if( i > j )
592  {
593  assert(j == -1);
594  /* expr1 has more elements, hence expr1 > expr2 */
595  return 1;
596  }
597 
598  /* everything is equal, use constant/coefficient as tie-breaker */
599  assert(i == -1 && j == -1);
600  if( const1 < const2 )
601  return -1;
602  if( const1 > const2 )
603  return 1;
604 
605  /* they are equal */
606  return 0;
607 }
608 
609 /** expression handler copy callback */
610 static
612 { /*lint --e{715}*/
614 
615  return SCIP_OKAY;
616 }
617 
618 /** expression data copy callback */
619 static
621 { /*lint --e{715}*/
622  SCIP_EXPRDATA* sourceexprdata;
623 
624  assert(targetexprdata != NULL);
625  assert(sourceexpr != NULL);
626 
627  sourceexprdata = SCIPexprGetData(sourceexpr);
628  assert(sourceexprdata != NULL);
629 
630  SCIP_CALL( createData(targetscip, targetexprdata, SCIPexprGetNChildren(sourceexpr),
631  sourceexprdata->coefficients, sourceexprdata->constant) );
632 
633  return SCIP_OKAY;
634 }
635 
636 /** expression data free callback */
637 static
639 { /*lint --e{715}*/
640  SCIP_EXPRDATA* exprdata;
641 
642  assert(expr != NULL);
643 
644  exprdata = SCIPexprGetData(expr);
645  assert(exprdata != NULL);
646 
647  SCIPfreeBlockMemoryArray(scip, &(exprdata->coefficients), exprdata->coefssize);
648  SCIPfreeBlockMemory(scip, &exprdata);
649 
650  SCIPexprSetData(expr, NULL);
651 
652  return SCIP_OKAY;
653 }
654 
655 /** expression print callback */
656 static
658 { /*lint --e{715}*/
659  SCIP_EXPRDATA* exprdata;
660 
661  assert(expr != NULL);
662 
663  exprdata = SCIPexprGetData(expr);
664  assert(exprdata != NULL);
665 
666  /**! [SnippetExprPrintSum] */
667  switch( stage )
668  {
670  {
671  /* print opening parenthesis, if necessary */
672  if( EXPRHDLR_PRECEDENCE <= parentprecedence )
673  {
674  SCIPinfoMessage(scip, file, "(");
675  }
676 
677  /* print constant, if nonzero */
678  if( exprdata->constant != 0.0 )
679  {
680  SCIPinfoMessage(scip, file, "%g", exprdata->constant);
681  }
682  break;
683  }
684 
686  {
687  SCIP_Real coef;
688 
689  coef = exprdata->coefficients[currentchild];
690 
691  /* print coefficient, if necessary */
692  if( coef == 1.0 )
693  {
694  /* if coefficient is 1.0, then print only "+" if not the first term */
695  if( exprdata->constant != 0.0 || currentchild > 0 )
696  {
697  SCIPinfoMessage(scip, file, "+");
698  }
699  }
700  else if( coef == -1.0 )
701  {
702  /* if coefficient is -1.0, then print only "-" */
703  SCIPinfoMessage(scip, file, "-");
704  }
705  else
706  {
707  /* force "+" sign on positive coefficient if not the first term */
708  SCIPinfoMessage(scip, file, (exprdata->constant != 0.0 || currentchild > 0) ? "%+g*" : "%g*", coef);
709  }
710 
711  break;
712  }
713 
715  {
716  /* print closing parenthesis, if necessary */
717  if( EXPRHDLR_PRECEDENCE <= parentprecedence )
718  {
719  SCIPinfoMessage(scip, file, ")");
720  }
721  break;
722  }
723 
725  default: ;
726  }
727  /**! [SnippetExprPrintSum] */
728 
729  return SCIP_OKAY;
730 }
731 
732 /** expression point evaluation callback */
733 static
735 { /*lint --e{715}*/
736  SCIP_EXPRDATA* exprdata;
737  int c;
738 
739  assert(expr != NULL);
740 
741  exprdata = SCIPexprGetData(expr);
742  assert(exprdata != NULL);
743 
744  /**! [SnippetExprEvalSum] */
745  *val = exprdata->constant;
746  for( c = 0; c < SCIPexprGetNChildren(expr); ++c )
747  {
748  assert(SCIPexprGetEvalValue(SCIPexprGetChildren(expr)[c]) != SCIP_INVALID); /*lint !e777*/
749 
750  *val += exprdata->coefficients[c] * SCIPexprGetEvalValue(SCIPexprGetChildren(expr)[c]);
751  }
752  /**! [SnippetExprEvalSum] */
753 
754  return SCIP_OKAY;
755 }
756 
757 /** expression forward derivative evaluation callback */
758 static
760 { /*lint --e{715}*/
761  SCIP_EXPRDATA* exprdata;
762  int c;
763 
764  assert(expr != NULL);
765  assert(dot != NULL);
766 
767  exprdata = SCIPexprGetData(expr);
768  assert(exprdata != NULL);
769 
770  *dot = 0.0;
771  for( c = 0; c < SCIPexprGetNChildren(expr); ++c )
772  {
773  assert(SCIPexprGetDot(SCIPexprGetChildren(expr)[c]) != SCIP_INVALID); /*lint !e777*/
774 
775  *dot += exprdata->coefficients[c] * SCIPexprGetDot(SCIPexprGetChildren(expr)[c]);
776  }
777 
778  return SCIP_OKAY;
779 }
780 
781 /** expression derivative evaluation callback */
782 static
784 { /*lint --e{715}*/
785  assert(expr != NULL);
786  assert(SCIPexprGetData(expr) != NULL);
787  assert(childidx >= 0 && childidx < SCIPexprGetNChildren(expr));
788  assert(SCIPexprGetChildren(expr)[childidx] != NULL);
789  assert(!SCIPisExprValue(scip, SCIPexprGetChildren(expr)[childidx]));
790 
791  *val = SCIPgetCoefsExprSum(expr)[childidx];
792 
793  return SCIP_OKAY;
794 }
795 
796 /** expression backward forward derivative evaluation callback */
797 static
799 { /*lint --e{715}*/
800  assert(bardot != NULL);
801 
802  *bardot = 0.0;
803 
804  return SCIP_OKAY;
805 }
806 
807 /** expression interval evaluation callback */
808 static
810 { /*lint --e{715}*/
811  SCIP_EXPRDATA* exprdata;
812  SCIP_INTERVAL suminterval;
813  int c;
814 
815  assert(expr != NULL);
816 
817  exprdata = SCIPexprGetData(expr);
818  assert(exprdata != NULL);
819 
820  SCIPintervalSet(interval, exprdata->constant);
821 
822  SCIPdebugMsg(scip, "inteval %p with %d children: %.20g", (void*)expr, SCIPexprGetNChildren(expr), exprdata->constant);
823 
824  for( c = 0; c < SCIPexprGetNChildren(expr); ++c )
825  {
826  SCIP_INTERVAL childinterval;
827 
828  childinterval = SCIPexprGetActivity(SCIPexprGetChildren(expr)[c]);
829  if( SCIPintervalIsEmpty(SCIP_INTERVAL_INFINITY, childinterval) )
830  {
831  SCIPintervalSetEmpty(interval);
832  break;
833  }
834 
835  /* compute coefficients[c] * childinterval and add the result to the so far computed interval */
836  if( exprdata->coefficients[c] == 1.0 )
837  {
838  SCIPintervalAdd(SCIP_INTERVAL_INFINITY, interval, *interval, childinterval);
839  }
840  else
841  {
842  SCIPintervalMulScalar(SCIP_INTERVAL_INFINITY, &suminterval, childinterval, exprdata->coefficients[c]);
843  SCIPintervalAdd(SCIP_INTERVAL_INFINITY, interval, *interval, suminterval);
844  }
845 
846  SCIPdebugMsgPrint(scip, " %+.20g*[%.20g,%.20g]", exprdata->coefficients[c], childinterval.inf, childinterval.sup);
847  }
848  SCIPdebugMsgPrint(scip, " = [%.20g,%.20g]\n", interval->inf, interval->sup);
849 
850  return SCIP_OKAY;
851 }
852 
853 /** initial estimators callback */
854 static
856 { /*lint --e{715}*/
857  SCIP_EXPRDATA* exprdata;
858 
859 #ifdef SCIP_DEBUG
860  SCIPinfoMessage(scip, NULL, "initEstimatesSum %d children: ", SCIPexprGetNChildren(expr));
861  SCIPprintExpr(scip, expr, NULL);
862  SCIPinfoMessage(scip, NULL, "\n");
863 #endif
864  assert(scip != NULL);
865  assert(expr != NULL);
866  assert(strcmp(SCIPexprhdlrGetName(SCIPexprGetHdlr(expr)), EXPRHDLR_NAME) == 0);
867 
868  assert(coefs[0] != NULL);
869  assert(constant != NULL);
870  assert(nreturned != NULL);
871 
872  exprdata = SCIPexprGetData(expr);
873  assert(exprdata != NULL);
874 
875  BMScopyMemoryArray(coefs[0], exprdata->coefficients, SCIPexprGetNChildren(expr));
876  *constant = exprdata->constant;
877  *nreturned = 1;
878 
879  return SCIP_OKAY;
880 }
881 
882 /** expression estimate callback */
883 static
885 { /*lint --e{715}*/
886  SCIP_EXPRDATA* exprdata;
887 
888  assert(scip != NULL);
889  assert(expr != NULL);
890  assert(strcmp(SCIPexprhdlrGetName(SCIPexprGetHdlr(expr)), EXPRHDLR_NAME) == 0);
891  assert(islocal != NULL);
892  assert(success != NULL);
893  assert(branchcand != NULL);
894 
895  exprdata = SCIPexprGetData(expr);
896  assert(exprdata != NULL);
897 
898  /* NOTE: nlhdlr_default assumes in nlhdlrInitSepaDefault that this estimator can be used for both under- and overestimation */
899 
900  BMScopyMemoryArray(coefs, exprdata->coefficients, SCIPexprGetNChildren(expr));
901  *constant = exprdata->constant;
902  *islocal = FALSE;
903  *success = TRUE;
904 
905  /* for none of our children, branching would improve the underestimator, so set branchcand[i]=FALSE everywhere
906  * if we branch for numerical reasons, then cons-expr-core should figure out what the candidates are
907  */
908  BMSclearMemoryArray(branchcand, SCIPexprGetNChildren(expr));
909 
910  return SCIP_OKAY;
911 }
912 
913 /** expression reverse propagation callback */
914 static
916 { /*lint --e{715}*/
917  SCIP_EXPRDATA* exprdata;
918  SCIP_INTERVAL* newbounds;
919  int nchildren;
920  int nreductions;
921 
922  assert(scip != NULL);
923  assert(expr != NULL);
924  assert(infeasible != NULL);
925 
926  nchildren = SCIPexprGetNChildren(expr);
927  assert(nchildren > 0);
928 
929  exprdata = SCIPexprGetData(expr);
930  assert(exprdata != NULL);
931 
932  SCIP_CALL( SCIPallocBufferArray(scip, &newbounds, nchildren) );
933 
934  nreductions = SCIPintervalPropagateWeightedSum(SCIP_INTERVAL_INFINITY, nchildren, childrenbounds,
935  exprdata->coefficients, exprdata->constant, bounds, newbounds, infeasible);
936 
937  if( !*infeasible && nreductions > 0 )
938  BMScopyMemoryArray(childrenbounds, newbounds, nchildren);
939 
940  SCIPfreeBufferArray(scip, &newbounds);
941 
942  return SCIP_OKAY;
943 }
944 
945 /** sum hash callback */
946 static
948 { /*lint --e{715}*/
949  SCIP_EXPRDATA* exprdata;
950  int c;
951 
952  assert(scip != NULL);
953  assert(expr != NULL);
954  assert(hashkey != NULL);
955  assert(childrenhashes != NULL);
956 
957  exprdata = SCIPexprGetData(expr);
958  assert(exprdata != NULL);
959 
960  /**! [SnippetExprHashSum] */
961  *hashkey = EXPRHDLR_HASHKEY;
962  *hashkey ^= SCIPcalcFibHash(exprdata->constant);
963 
964  for( c = 0; c < SCIPexprGetNChildren(expr); ++c )
965  *hashkey ^= SCIPcalcFibHash(exprdata->coefficients[c]) ^ childrenhashes[c];
966  /**! [SnippetExprHashSum] */
967 
968  return SCIP_OKAY;
969 }
970 
971 /** expression curvature detection callback */
972 static
974 { /*lint --e{715}*/
975  SCIP_EXPRDATA* exprdata;
976  int i;
977 
978  assert(scip != NULL);
979  assert(expr != NULL);
980  assert(childcurv != NULL);
981  assert(success != NULL);
982 
983  exprdata = SCIPexprGetData(expr);
984  assert(exprdata != NULL);
985 
986  for( i = 0; i < SCIPexprGetNChildren(expr); ++i )
987  childcurv[i] = SCIPexprcurvMultiply(exprdata->coefficients[i], exprcurvature);
988 
989  *success = TRUE;
990 
991  return SCIP_OKAY;
992 }
993 
994 /** expression monotonicity detection callback */
995 static
997 { /*lint --e{715}*/
998  SCIP_EXPRDATA* exprdata;
999 
1000  assert(scip != NULL);
1001  assert(expr != NULL);
1002  assert(result != NULL);
1003  assert(childidx >= 0 && childidx < SCIPexprGetNChildren(expr));
1004 
1005  exprdata = SCIPexprGetData(expr);
1006  assert(exprdata != NULL);
1007 
1008  *result = exprdata->coefficients[childidx] >= 0.0 ? SCIP_MONOTONE_INC : SCIP_MONOTONE_DEC;
1009 
1010  return SCIP_OKAY;
1011 }
1012 
1013 /** expression integrality detection callback */
1014 static
1016 { /*lint --e{715}*/
1017  SCIP_EXPRDATA* exprdata;
1018  int i;
1019 
1020  assert(scip != NULL);
1021  assert(expr != NULL);
1022  assert(isintegral != NULL);
1023 
1024  exprdata = SCIPexprGetData(expr);
1025  assert(exprdata != NULL);
1026 
1027  /**! [SnippetExprIntegralitySum] */
1028  *isintegral = EPSISINT(exprdata->constant, 0.0); /*lint !e835*/
1029 
1030  for( i = 0; i < SCIPexprGetNChildren(expr) && *isintegral; ++i )
1031  {
1032  SCIP_EXPR* child = SCIPexprGetChildren(expr)[i];
1033  assert(child != NULL);
1034 
1035  *isintegral = EPSISINT(exprdata->coefficients[i], 0.0) && SCIPexprIsIntegral(child); /*lint !e835*/
1036  }
1037  /**! [SnippetExprIntegralitySum] */
1038 
1039  return SCIP_OKAY;
1040 }
1041 
1042 /** creates the handler for sum expressions and includes it into SCIP */
1044  SCIP* scip /**< SCIP data structure */
1045  )
1046 {
1047  SCIP_EXPRHDLR* exprhdlr;
1048 
1050  assert(exprhdlr != NULL);
1051 
1052  SCIPexprhdlrSetCopyFreeHdlr(exprhdlr, copyhdlrSum, NULL);
1053  SCIPexprhdlrSetCopyFreeData(exprhdlr, copydataSum, freedataSum);
1054  SCIPexprhdlrSetSimplify(exprhdlr, simplifySum);
1055  SCIPexprhdlrSetCompare(exprhdlr, compareSum);
1056  SCIPexprhdlrSetPrint(exprhdlr, printSum);
1057  SCIPexprhdlrSetIntEval(exprhdlr, intevalSum);
1058  SCIPexprhdlrSetEstimate(exprhdlr, initEstimatesSum, estimateSum);
1059  SCIPexprhdlrSetReverseProp(exprhdlr, reversepropSum);
1060  SCIPexprhdlrSetHash(exprhdlr, hashSum);
1061  SCIPexprhdlrSetDiff(exprhdlr, bwdiffSum, fwdiffSum, bwfwdiffSum);
1062  SCIPexprhdlrSetCurvature(exprhdlr, curvatureSum);
1063  SCIPexprhdlrSetMonotonicity(exprhdlr, monotonicitySum);
1064  SCIPexprhdlrSetIntegrality(exprhdlr, integralitySum);
1065 
1066  return SCIP_OKAY;
1067 }
1068 
1069 /** creates a sum expression */
1071  SCIP* scip, /**< SCIP data structure */
1072  SCIP_EXPR** expr, /**< pointer where to store expression */
1073  int nchildren, /**< number of children */
1074  SCIP_EXPR** children, /**< children */
1075  SCIP_Real* coefficients, /**< array with coefficients for all children (or NULL if all 1.0) */
1076  SCIP_Real constant, /**< constant term of sum */
1077  SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
1078  void* ownercreatedata /**< data to pass to ownercreate */
1079  )
1080 {
1081  SCIP_EXPRDATA* exprdata;
1082 
1083  SCIP_CALL( createData(scip, &exprdata, nchildren, coefficients, constant) );
1084 
1085  SCIP_CALL( SCIPcreateExpr(scip, expr, SCIPgetExprhdlrSum(scip), exprdata, nchildren, children, ownercreate, ownercreatedata) );
1086 
1087  return SCIP_OKAY;
1088 }
1089 
1090 /** sets the constant of a summation expression */
1092  SCIP_EXPR* expr, /**< sum expression */
1093  SCIP_Real constant /**< constant */
1094  )
1095 {
1096  SCIP_EXPRDATA* exprdata;
1097 
1098  assert(expr != NULL);
1099 
1100  exprdata = SCIPexprGetData(expr);
1101  assert(exprdata != NULL);
1102 
1103  exprdata->constant = constant;
1104 }
1105 
1106 /** appends an expression to a sum expression */
1108  SCIP* scip, /**< SCIP data structure */
1109  SCIP_EXPR* expr, /**< sum expression */
1110  SCIP_EXPR* child, /**< expression to be appended */
1111  SCIP_Real childcoef /**< child's coefficient */
1112  )
1113 {
1114  SCIP_EXPRDATA* exprdata;
1115  int nchildren;
1116 
1117  assert(expr != NULL);
1118  assert(SCIPisExprSum(scip, expr));
1119 
1120  exprdata = SCIPexprGetData(expr);
1121  assert(exprdata != NULL);
1122 
1123  nchildren = SCIPexprGetNChildren(expr);
1124 
1125  SCIP_CALL( SCIPensureBlockMemoryArray(scip, &exprdata->coefficients, &exprdata->coefssize, nchildren + 1) );
1126 
1127  assert(exprdata->coefssize > nchildren);
1128  exprdata->coefficients[nchildren] = childcoef;
1129 
1130  SCIP_CALL( SCIPappendExprChild(scip, expr, child) );
1131 
1132  return SCIP_OKAY;
1133 }
1134 
1135 /** multiplies given sum expression by a constant */
1137  SCIP_EXPR* expr, /**< sum expression */
1138  SCIP_Real constant /**< constant that multiplies sum expression */
1139  )
1140 {
1141  int i;
1142  SCIP_EXPRDATA* exprdata;
1143 
1144  assert(expr != NULL);
1145 
1146  exprdata = SCIPexprGetData(expr);
1147  assert(exprdata != NULL);
1148 
1149  for( i = 0; i < SCIPexprGetNChildren(expr); ++i )
1150  exprdata->coefficients[i] *= constant;
1151  exprdata->constant *= constant;
1152 }
1153 
1154 /* from pub_expr.h */
1155 
1156 /** gets the coefficients of a summation expression */
1158  SCIP_EXPR* expr /**< sum expression */
1159  )
1160 {
1161  SCIP_EXPRDATA* exprdata;
1162 
1163  assert(expr != NULL);
1164 
1165  exprdata = SCIPexprGetData(expr);
1166  assert(exprdata != NULL);
1167 
1168  return exprdata->coefficients;
1169 }
1170 
1171 /** gets the constant of a summation expression */
1173  SCIP_EXPR* expr /**< sum expression */
1174  )
1175 {
1176  SCIP_EXPRDATA* exprdata;
1177 
1178  assert(expr != NULL);
1179 
1180  exprdata = SCIPexprGetData(expr);
1181  assert(exprdata != NULL);
1182 
1183  return exprdata->constant;
1184 }
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:101
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:84
SCIP_RETCODE SCIPprintExpr(SCIP *scip, SCIP_EXPR *expr, FILE *file)
Definition: scip_expr.c:1476
static SCIP_DECL_EXPRMONOTONICITY(monotonicitySum)
Definition: expr_sum.c:996
void SCIPsortInd(int *indarray, SCIP_DECL_SORTINDCOMP((*indcomp)), void *dataptr, int len)
int SCIPexprGetNChildren(SCIP_EXPR *expr)
Definition: expr.c:3798
static SCIP_DECL_EXPRFREEDATA(freedataSum)
Definition: expr_sum.c:638
void SCIPexprhdlrSetDiff(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRBWDIFF((*bwdiff)), SCIP_DECL_EXPRFWDIFF((*fwdiff)), SCIP_DECL_EXPRBWFWDIFF((*bwfwdiff)))
Definition: expr.c:464
const char * SCIPexprhdlrGetName(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:525
static SCIP_DECL_EXPRINITESTIMATES(initEstimatesSum)
Definition: expr_sum.c:855
SCIP_Real SCIPgetConstantExprSum(SCIP_EXPR *expr)
Definition: expr_sum.c:1172
#define EXPRHDLR_HASHKEY
Definition: expr_sum.c:37
#define FALSE
Definition: def.h:87
#define EPSISINT(x, eps)
Definition: def.h:214
static SCIP_DECL_EXPRINTEGRALITY(integralitySum)
Definition: expr_sum.c:1015
SCIP_RETCODE SCIPduplicateExpr(SCIP *scip, SCIP_EXPR *expr, SCIP_EXPR **copyexpr, SCIP_DECL_EXPR_MAPEXPR((*mapexpr)), void *mapexprdata, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: scip_expr.c:1271
struct SCIP_ExprData SCIP_EXPRDATA
Definition: type_expr.h:44
#define TRUE
Definition: def.h:86
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
#define debugSimplify
Definition: expr_sum.c:44
void SCIPexprhdlrSetHash(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRHASH((*hash)))
Definition: expr.c:442
SCIP_INTERVAL SCIPexprGetActivity(SCIP_EXPR *expr)
Definition: expr.c:3954
void SCIPintervalSet(SCIP_INTERVAL *resultant, SCIP_Real value)
void SCIPexprhdlrSetIntegrality(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRINTEGRALITY((*integrality)))
Definition: expr.c:431
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:99
SCIP_RETCODE SCIPcreateExprExp(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPR *child, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_exp.c:500
void SCIPintervalAdd(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
#define EXPRHDLR_NAME
Definition: expr_sum.c:34
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:127
SCIP_EXPRHDLR * SCIPgetExprhdlrSum(SCIP *scip)
Definition: scip_expr.c:893
void SCIPcaptureExpr(SCIP_EXPR *expr)
Definition: scip_expr.c:1399
SCIP_RETCODE SCIPappendExprSumExpr(SCIP *scip, SCIP_EXPR *expr, SCIP_EXPR *child, SCIP_Real childcoef)
Definition: expr_sum.c:1107
#define SCIP_EXPRITER_ENTEREXPR
Definition: type_expr.h:667
#define SCIP_EXPRITER_VISITEDCHILD
Definition: type_expr.h:669
#define SCIPdebugMsgPrint
Definition: scip_message.h:70
#define SCIPdebugMsg
Definition: scip_message.h:69
static SCIP_DECL_EXPRCURVATURE(curvatureSum)
Definition: expr_sum.c:973
SCIP_RETCODE SCIPcreateExprSum(SCIP *scip, SCIP_EXPR **expr, int nchildren, SCIP_EXPR **children, SCIP_Real *coefficients, SCIP_Real constant, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_sum.c:1070
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:199
SCIP_Bool SCIPisExprProduct(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1454
static SCIP_DECL_EXPREVAL(evalSum)
Definition: expr_sum.c:734
int SCIPcompareExpr(SCIP *scip, SCIP_EXPR *expr1, SCIP_EXPR *expr2)
Definition: scip_expr.c:1723
static SCIP_DECL_EXPRPRINT(printSum)
Definition: expr_sum.c:657
SCIP_EXPRDATA * SCIPexprGetData(SCIP_EXPR *expr)
Definition: expr.c:3831
SCIP_EXPR ** SCIPexprGetChildren(SCIP_EXPR *expr)
Definition: expr.c:3808
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip_mem.h:96
SCIP_Real inf
Definition: intervalarith.h:46
static SCIP_DECL_EXPRBWDIFF(bwdiffSum)
Definition: expr_sum.c:783
SCIP_Real * SCIPgetCoefsExprSum(SCIP_EXPR *expr)
Definition: expr_sum.c:1157
SCIP_Real SCIPexprGetEvalValue(SCIP_EXPR *expr)
Definition: expr.c:3872
SCIP_RETCODE SCIPcreateExpr(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPRHDLR *exprhdlr, SCIP_EXPRDATA *exprdata, int nchildren, SCIP_EXPR **children, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: scip_expr.c:964
SCIP_Bool SCIPintervalIsEmpty(SCIP_Real infinity, SCIP_INTERVAL operand)
static SCIP_DECL_EXPRFWDIFF(fwdiffSum)
Definition: expr_sum.c:759
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition: scip_mem.h:128
void SCIPintervalSetEmpty(SCIP_INTERVAL *resultant)
SCIP_Bool SCIPisExprValue(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1432
static SCIP_DECL_EXPRCOPYHDLR(copyhdlrSum)
Definition: expr_sum.c:611
#define NULL
Definition: lpi_spx1.cpp:155
SCIP_RETCODE SCIPcreateExprProduct(SCIP *scip, SCIP_EXPR **expr, int nchildren, SCIP_EXPR **children, SCIP_Real coefficient, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
void SCIPintervalMulScalar(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_Real operand2)
#define REALABS(x)
Definition: def.h:201
int SCIPintervalPropagateWeightedSum(SCIP_Real infinity, int noperands, SCIP_INTERVAL *operands, SCIP_Real *weights, SCIP_Real constant, SCIP_INTERVAL rhs, SCIP_INTERVAL *resultants, SCIP_Bool *infeasible)
SCIP_RETCODE SCIPreplaceExprChild(SCIP *scip, SCIP_EXPR *expr, int childidx, SCIP_EXPR *newchild)
Definition: scip_expr.c:1238
SCIP_Real SCIPexprGetDot(SCIP_EXPR *expr)
Definition: expr.c:3912
SCIP_Bool SCIPisExprSum(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1443
#define SCIP_CALL(x)
Definition: def.h:384
#define SCIPensureBlockMemoryArray(scip, ptr, arraysizeptr, minsize)
Definition: scip_mem.h:98
SCIP_Real sup
Definition: intervalarith.h:47
SCIP_RETCODE SCIPcreateExprValue(SCIP *scip, SCIP_EXPR **expr, SCIP_Real value, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_value.c:261
void SCIPexprhdlrSetCopyFreeHdlr(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRCOPYHDLR((*copyhdlr)), SCIP_DECL_EXPRFREEHDLR((*freehdlr)))
Definition: expr.c:359
#define SCIP_INTERVAL_INFINITY
Definition: def.h:199
SCIP * scip
Definition: expr_sum.c:330
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:115
#define SCIP_Bool
Definition: def.h:84
#define SCIP_DECL_EXPR_OWNERCREATE(x)
Definition: type_expr.h:131
void SCIPexprhdlrSetMonotonicity(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRMONOTONICITY((*monotonicity)))
Definition: expr.c:420
static SCIP_RETCODE createData(SCIP *scip, SCIP_EXPRDATA **exprdata, int ncoefficients, SCIP_Real *coefficients, SCIP_Real constant)
Definition: expr_sum.c:65
SCIP_RETCODE SCIPreleaseExpr(SCIP *scip, SCIP_EXPR **expr)
Definition: scip_expr.c:1407
static SCIP_DECL_EXPRCOPYDATA(copydataSum)
Definition: expr_sum.c:620
SCIP_RETCODE SCIPappendExprChild(SCIP *scip, SCIP_EXPR *expr, SCIP_EXPR *child)
Definition: scip_expr.c:1220
void SCIPexprhdlrSetReverseProp(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRREVERSEPROP((*reverseprop)))
Definition: expr.c:501
SCIP_EXPR ** exprs
Definition: expr_sum.c:331
SCIP_Bool SCIPexprIsIntegral(SCIP_EXPR *expr)
Definition: expr.c:4017
#define EXPRHDLR_DESC
Definition: expr_sum.c:35
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:127
SCIP_EXPRHDLR * SCIPexprGetHdlr(SCIP_EXPR *expr)
Definition: expr.c:3821
void SCIPexprhdlrSetPrint(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRPRINT((*print)))
Definition: expr.c:387
void SCIPexprhdlrSetCopyFreeData(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRCOPYDATA((*copydata)), SCIP_DECL_EXPRFREEDATA((*freedata)))
Definition: expr.c:372
constant value expression handler
static SCIP_DECL_EXPRINTEVAL(intevalSum)
Definition: expr_sum.c:809
product expression handler
static SCIP_DECL_EXPRESTIMATE(estimateSum)
Definition: expr_sum.c:884
void SCIPexprhdlrSetCompare(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRCOMPARE((*compare)))
Definition: expr.c:453
static SCIP_DECL_EXPRHASH(hashSum)
Definition: expr_sum.c:947
void SCIPexprhdlrSetCurvature(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRCURVATURE((*curvature)))
Definition: expr.c:409
void SCIPexprSetData(SCIP_EXPR *expr, SCIP_EXPRDATA *exprdata)
Definition: expr.c:3846
#define EXPRHDLR_PRECEDENCE
Definition: expr_sum.c:36
static SCIP_DECL_EXPRBWFWDIFF(bwfwdiffSum)
Definition: expr_sum.c:798
static SCIP_RETCODE simplifyTerm(SCIP *scip, SCIP_EXPR *duplicate, int idx, SCIP_Bool *changed, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_sum.c:103
SCIP_Bool SCIPisExprExp(SCIP *scip, SCIP_EXPR *expr)
Definition: expr_exp.c:518
void SCIPmultiplyByConstantExprSum(SCIP_EXPR *expr, SCIP_Real constant)
Definition: expr_sum.c:1136
#define SCIP_Real
Definition: def.h:177
#define SCIP_INVALID
Definition: def.h:197
SCIP_Real SCIPgetValueExprValue(SCIP_EXPR *expr)
Definition: expr_value.c:285
static SCIP_DECL_SORTINDCOMP(sortExprComp)
Definition: expr_sum.c:335
unsigned int SCIPcalcFibHash(SCIP_Real v)
Definition: misc.c:10242
#define SCIP_EXPRITER_LEAVEEXPR
Definition: type_expr.h:670
void SCIPexprhdlrSetEstimate(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRINITESTIMATES((*initestimates)), SCIP_DECL_EXPRESTIMATE((*estimate)))
Definition: expr.c:512
sum expression handler
SCIP_EXPRCURV SCIPexprcurvMultiply(SCIP_Real factor, SCIP_EXPRCURV curvature)
Definition: exprcurv.c:78
static SCIP_DECL_EXPRSIMPLIFY(simplifySum)
Definition: expr_sum.c:353
#define SCIP_EXPRITER_VISITINGCHILD
Definition: type_expr.h:668
static SCIP_DECL_EXPRREVERSEPROP(reversepropSum)
Definition: expr_sum.c:915
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:123
SCIPallocBlockMemory(scip, subsol))
SCIP_RETCODE SCIPincludeExprhdlr(SCIP *scip, SCIP_EXPRHDLR **exprhdlr, const char *name, const char *desc, unsigned int precedence, SCIP_DECL_EXPREVAL((*eval)), SCIP_EXPRHDLRDATA *data)
Definition: scip_expr.c:814
void SCIPexprhdlrSetSimplify(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRSIMPLIFY((*simplify)))
Definition: expr.c:490
void SCIPexprhdlrSetIntEval(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRINTEVAL((*inteval)))
Definition: expr.c:479
void SCIPsetConstantExprSum(SCIP_EXPR *expr, SCIP_Real constant)
Definition: expr_sum.c:1091
exponential expression handler
SCIP_RETCODE SCIPincludeExprhdlrSum(SCIP *scip)
Definition: expr_sum.c:1043
static SCIP_DECL_EXPRCOMPARE(compareSum)
Definition: expr_sum.c:544