Scippy

SCIP

Solving Constraint Integer Programs

exprcurv.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 exprcurv.c
17  * @ingroup OTHER_CFILES
18  * @brief functions to work with curvature (convex, concave, etc)
19  * @author Stefan Vigerske
20  *
21  * Declarations are in pub_expr.h
22  */
23 
24 #include "scip/pub_expr.h"
25 
26 /** curvature names as strings */
27 static
28 const char* curvnames[4] =
29  {
30  "unknown",
31  "convex",
32  "concave",
33  "linear"
34  };
35 
36 #ifdef NDEBUG
37 #undef SCIPexprcurvAdd
38 #undef SCIPexprcurvNegate
39 #undef SCIPexprcurvMultiply
40 #endif
41 
42 /** gives curvature for a sum of two functions with given curvature */
44  SCIP_EXPRCURV curv1, /**< curvature of first summand */
45  SCIP_EXPRCURV curv2 /**< curvature of second summand */
46  )
47 {
48  return (SCIP_EXPRCURV) (curv1 & curv2);
49 }
50 
51 /** gives the curvature for the negation of a function with given curvature */
53  SCIP_EXPRCURV curvature /**< curvature of function */
54  )
55 {
56  switch( curvature )
57  {
59  return SCIP_EXPRCURV_CONVEX;
60 
62  return SCIP_EXPRCURV_CONCAVE;
63 
66  /* can return curvature, do this below */
67  break;
68 
69  default:
70  SCIPerrorMessage("unknown curvature status.\n");
71  SCIPABORT();
72  }
73 
74  return curvature;
75 }
76 
77 /** gives curvature for a functions with given curvature multiplied by a constant factor */
79  SCIP_Real factor, /**< constant factor */
80  SCIP_EXPRCURV curvature /**< curvature of other factor */
81  )
82 {
83  if( factor == 0.0 )
84  return SCIP_EXPRCURV_LINEAR;
85  if( factor > 0.0 )
86  return curvature;
87  return SCIPexprcurvNegate(curvature);
88 }
89 
90 /** gives curvature for base^exponent for given bounds and curvature of base-function and constant exponent */
92  SCIP_INTERVAL basebounds, /**< bounds on base function */
93  SCIP_EXPRCURV basecurv, /**< curvature of base function */
94  SCIP_Real exponent /**< exponent */
95  )
96 {
97  SCIP_Bool expisint;
98 
99  assert(basebounds.inf <= basebounds.sup);
100 
101  if( exponent == 0.0 )
102  return SCIP_EXPRCURV_LINEAR;
103 
104  if( exponent == 1.0 )
105  return basecurv;
106 
107  expisint = EPSISINT(exponent, 0.0); /*lint !e835*/
108 
109  /* if exponent is fractional, then power is not defined for a negative base
110  * thus, consider only positive part of basebounds
111  */
112  if( !expisint && basebounds.inf < 0.0 )
113  {
114  basebounds.inf = 0.0;
115  if( basebounds.sup < 0.0 )
116  return SCIP_EXPRCURV_LINEAR;
117  }
118 
119  /* if basebounds contains 0.0, consider negative and positive interval separately, if possible */
120  if( basebounds.inf < 0.0 && basebounds.sup > 0.0 )
121  {
122  SCIP_INTERVAL leftbounds;
123  SCIP_INTERVAL rightbounds;
124 
125  /* something like x^(-2) may look convex on each side of zero, but is not convex on the whole interval
126  * due to the singularity at 0.0 */
127  if( exponent < 0.0 )
128  return SCIP_EXPRCURV_UNKNOWN;
129 
130  SCIPintervalSetBounds(&leftbounds, basebounds.inf, 0.0);
131  SCIPintervalSetBounds(&rightbounds, 0.0, basebounds.sup);
132 
133  return (SCIP_EXPRCURV) (SCIPexprcurvPower(leftbounds, basecurv, exponent) & SCIPexprcurvPower(rightbounds, basecurv, exponent));
134  }
135  assert(basebounds.inf >= 0.0 || basebounds.sup <= 0.0);
136 
137  /* (base^exponent)'' = exponent * ( (exponent-1) base^(exponent-2) (base')^2 + base^(exponent-1) base'' )
138  *
139  * if base'' is positive, i.e., base is convex, then
140  * - for base > 0.0 and exponent > 1.0, the second deriv. is positive -> convex
141  * - for base < 0.0 and exponent > 1.0, we can't say (first and second summand opposite signs)
142  * - for base > 0.0 and 0.0 < exponent < 1.0, we can't say (first sommand negative, second summand positive)
143  * - for base > 0.0 and exponent < 0.0, we can't say (first and second summand opposite signs)
144  * - for base < 0.0 and exponent < 0.0 and even, the second deriv. is positive -> convex
145  * - for base < 0.0 and exponent < 0.0 and odd, the second deriv. is negative -> concave
146  *
147  * if base'' is negative, i.e., base is concave, then
148  * - for base > 0.0 and exponent > 1.0, we can't say (first summand positive, second summand negative)
149  * - for base < 0.0 and exponent > 1.0 and even, the second deriv. is positive -> convex
150  * - for base < 0.0 and exponent > 1.0 and odd, the second deriv. is negative -> concave
151  * - for base > 0.0 and 0.0 < exponent < 1.0, the second deriv. is negative -> concave
152  * - for base > 0.0 and exponent < 0.0, the second deriv. is positive -> convex
153  * - for base < 0.0 and exponent < 0.0, we can't say (first and second summand opposite signs)
154  *
155  * if base'' is zero, i.e., base is linear, then
156  * (base^exponent)'' = exponent * (exponent-1) base^(exponent-2) (base')^2
157  * - just multiply signs
158  */
159 
160  if( basecurv == SCIP_EXPRCURV_LINEAR )
161  {
162  SCIP_Real sign;
163 
164  /* base^(exponent-2) is negative, if base < 0.0 and exponent is odd */
165  sign = exponent * (exponent - 1.0);
166  assert(basebounds.inf >= 0.0 || expisint);
167  if( basebounds.inf < 0.0 && ((int)exponent)%2 != 0 )
168  sign *= -1.0;
169  assert(sign != 0.0);
170 
171  return sign > 0.0 ? SCIP_EXPRCURV_CONVEX : SCIP_EXPRCURV_CONCAVE;
172  }
173 
174  if( basecurv == SCIP_EXPRCURV_CONVEX )
175  {
176  if( basebounds.sup <= 0.0 && exponent < 0.0 && expisint )
177  return ((int)exponent)%2 == 0 ? SCIP_EXPRCURV_CONVEX : SCIP_EXPRCURV_CONCAVE;
178  if( basebounds.inf >= 0.0 && exponent > 1.0 )
179  return SCIP_EXPRCURV_CONVEX ;
180  return SCIP_EXPRCURV_UNKNOWN;
181  }
182 
183  if( basecurv == SCIP_EXPRCURV_CONCAVE )
184  {
185  if( basebounds.sup <= 0.0 && exponent > 1.0 && expisint )
186  return ((int)exponent)%2 == 0 ? SCIP_EXPRCURV_CONVEX : SCIP_EXPRCURV_CONCAVE;
187  if( basebounds.inf >= 0.0 && exponent < 1.0 )
188  return exponent < 0.0 ? SCIP_EXPRCURV_CONVEX : SCIP_EXPRCURV_CONCAVE;
189  return SCIP_EXPRCURV_UNKNOWN;
190  }
191 
192  return SCIP_EXPRCURV_UNKNOWN;
193 }
194 
195 /** gives required curvature for base so that base^exponent has given curvature under given bounds on base and constant exponent
196  *
197  * returns curvature unknown if expected curvature cannot be obtained
198  */
200  SCIP_INTERVAL basebounds, /**< bounds on base function */
201  SCIP_Real exponent, /**< exponent, must not be 0 */
202  SCIP_EXPRCURV powercurv /**< expected curvature for power */
203  )
204 {
205  SCIP_Bool expisint;
206 
207  assert(basebounds.inf <= basebounds.sup);
208  assert(exponent != 0.0);
209  assert(powercurv != SCIP_EXPRCURV_UNKNOWN);
210 
211  if( exponent == 1.0 )
212  return powercurv;
213 
214  /* power is usually never linear, now that exponent != 1 */
215  if( powercurv == SCIP_EXPRCURV_LINEAR )
216  return SCIP_EXPRCURV_UNKNOWN;
217 
218  expisint = EPSISINT(exponent, 0.0); /*lint !e835*/
219 
220  /* if exponent is fractional, then power is only defined for a non-negative base
221  * boundtightening should have ensured this before calling this function,
222  * but sometimes this does not work and so we correct this here for us
223  */
224  if( !expisint && basebounds.inf < 0.0 )
225  {
226  basebounds.inf = 0.0;
227  if( basebounds.sup < 0.0 )
228  return SCIP_EXPRCURV_UNKNOWN;
229  }
230 
231  /* if basebounds contains 0.0, consider negative and positive interval separately, if possible */
232  if( basebounds.inf < 0.0 && basebounds.sup > 0.0 )
233  {
234  SCIP_INTERVAL leftbounds;
235  SCIP_INTERVAL rightbounds;
236  SCIP_EXPRCURV leftcurv;
237  SCIP_EXPRCURV rightcurv;
238 
239  /* something like x^(-2) may look convex on each side of zero, but is not convex on the whole
240  * interval due to the singularity at 0.0 */
241  if( exponent < 0.0 )
242  return SCIP_EXPRCURV_UNKNOWN;
243 
244  SCIPintervalSetBounds(&leftbounds, basebounds.inf, 0.0);
245  SCIPintervalSetBounds(&rightbounds, 0.0, basebounds.sup);
246 
247  leftcurv = SCIPexprcurvPowerInv(leftbounds, exponent, powercurv);
248  rightcurv = SCIPexprcurvPowerInv(rightbounds, exponent, powercurv);
249 
250  /* now need to intersect */
251  if( leftcurv == SCIP_EXPRCURV_LINEAR )
252  return rightcurv;
253  if( rightcurv == SCIP_EXPRCURV_LINEAR )
254  return leftcurv;
255  if( leftcurv == SCIP_EXPRCURV_UNKNOWN || rightcurv == SCIP_EXPRCURV_UNKNOWN )
256  return SCIP_EXPRCURV_UNKNOWN;
257  assert(leftcurv == SCIP_EXPRCURV_CONVEX || leftcurv == SCIP_EXPRCURV_CONCAVE);
258  assert(rightcurv == SCIP_EXPRCURV_CONVEX || rightcurv == SCIP_EXPRCURV_CONCAVE);
259  return SCIP_EXPRCURV_LINEAR;
260  }
261  assert(basebounds.inf >= 0.0 || basebounds.sup <= 0.0);
262 
263  /* inverting the logic from SCIPexprcurvPower here */
264  if( powercurv == SCIP_EXPRCURV_CONVEX )
265  {
266  SCIP_Real sign;
267 
268  if( basebounds.sup <= 0.0 && exponent < 0.0 && expisint && ((int)exponent)%2 == 0 )
269  return SCIP_EXPRCURV_CONVEX;
270  if( basebounds.inf >= 0.0 && exponent > 1.0 )
271  return SCIP_EXPRCURV_CONVEX;
272  if( basebounds.sup <= 0.0 && exponent > 1.0 && expisint && ((int)exponent)%2 == 0 )
273  return SCIP_EXPRCURV_CONCAVE;
274  if( basebounds.inf >= 0.0 && exponent < 0.0 )
275  return SCIP_EXPRCURV_CONCAVE;
276 
277  /* base^(exponent-2) is negative, if base < 0.0 and exponent is odd */
278  sign = exponent * (exponent - 1.0);
279  assert(basebounds.inf >= 0.0 || expisint);
280  if( basebounds.inf < 0.0 && ((int)exponent)%2 != 0 )
281  sign *= -1.0;
282  assert(sign != 0.0);
283 
284  if( sign > 0.0 )
285  return SCIP_EXPRCURV_LINEAR;
286  }
287  else
288  {
289  SCIP_Real sign;
290 
291  assert(powercurv == SCIP_EXPRCURV_CONCAVE); /* linear handled at top, unknown should not be the case */
292 
293  if( basebounds.sup <= 0.0 && exponent < 0.0 && expisint && ((int)exponent)%2 != 0 )
294  return SCIP_EXPRCURV_CONVEX;
295  if( basebounds.sup <= 0.0 && exponent > 1.0 && expisint && ((int)exponent)%2 != 0 )
296  return SCIP_EXPRCURV_CONCAVE;
297  if( basebounds.inf >= 0.0 && exponent < 1.0 && exponent >= 0.0 )
298  return SCIP_EXPRCURV_CONCAVE;
299 
300  /* base^(exponent-2) is negative, if base < 0.0 and exponent is odd */
301  sign = exponent * (exponent - 1.0);
302  assert(basebounds.inf >= 0.0 || expisint);
303  if( basebounds.inf < 0.0 && ((int)exponent)%2 != 0 )
304  sign *= -1.0;
305  assert(sign != 0.0);
306 
307  if( sign < 0.0 )
308  return SCIP_EXPRCURV_LINEAR;
309  }
310 
311  return SCIP_EXPRCURV_UNKNOWN;
312 }
313 
314 /** gives curvature for a monomial with given curvatures and bounds for each factor
315  *
316  * See Maranas and Floudas, Finding All Solutions of Nonlinearly Constrained Systems of Equations, JOGO 7, 1995
317  * for the categorization in the case that all factors are linear.
318  *
319  * Exponents can also be negative or rational.
320  */
322  int nfactors, /**< number of factors in monomial */
323  SCIP_Real* exponents, /**< exponents in monomial, or NULL if all 1.0 */
324  int* factoridxs, /**< indices of factors (but not exponents), or NULL if identity mapping */
325  SCIP_EXPRCURV* factorcurv, /**< curvature of each factor */
326  SCIP_INTERVAL* factorbounds /**< bounds of each factor */
327  )
328 {
329  SCIP_Real mult;
330  SCIP_Real e;
331  SCIP_INTERVAL bounds;
332  SCIP_EXPRCURV curv;
333  SCIP_EXPRCURV fcurv;
334  int nnegative;
335  int npositive;
336  SCIP_Real sum;
337  SCIP_Bool expcurvpos;
338  SCIP_Bool expcurvneg;
339  int j;
340  int f;
341 
342  assert(nfactors >= 0);
343  assert(factorcurv != NULL || nfactors == 0);
344  assert(factorbounds != NULL || nfactors == 0);
345 
346  if( nfactors == 0 )
347  return SCIP_EXPRCURV_LINEAR;
348 
349  if( nfactors == 1 )
350  {
351  f = factoridxs != NULL ? factoridxs[0] : 0;
352  e = exponents != NULL ? exponents[0] : 1.0;
353  /* SCIPdebugMessage("monomial [%g,%g]^%g is %s\n",
354  factorbounds[f].inf, factorbounds[f].sup, e,
355  SCIPexprcurvGetName(SCIPexprcurvPower(factorbounds[f], factorcurv[f], e))); */
356  return SCIPexprcurvPower(factorbounds[f], factorcurv[f], e); /*lint !e613*/
357  }
358 
359  mult = 1.0;
360 
361  nnegative = 0; /* number of negative exponents */
362  npositive = 0; /* number of positive exponents */
363  sum = 0.0; /* sum of exponents */
364  expcurvpos = TRUE; /* whether exp_j * f_j''(x) >= 0 for all factors (assuming f_j >= 0) */
365  expcurvneg = TRUE; /* whether exp_j * f_j''(x) <= 0 for all factors (assuming f_j >= 0) */
366 
367  for( j = 0; j < nfactors; ++j )
368  {
369  f = factoridxs != NULL ? factoridxs[j] : j;
370  if( factorcurv[f] == SCIP_EXPRCURV_UNKNOWN ) /*lint !e613*/
371  return SCIP_EXPRCURV_UNKNOWN;
372 
373  e = exponents != NULL ? exponents[j] : 1.0;
374  bounds = factorbounds[f]; /*lint !e613*/
375 
376  /* if argument is negative, then exponent should be integer; correct bounds if that doesn't hold */
377  if( !EPSISINT(e, 0.0) && bounds.inf < 0.0 ) /*lint !e835*/
378  {
379  bounds.inf = 0.0;
380  if( bounds.sup < 0.0 )
381  return SCIP_EXPRCURV_UNKNOWN;
382  }
383 
384  if( bounds.inf < 0.0 && bounds.sup > 0.0 )
385  return SCIP_EXPRCURV_UNKNOWN;
386 
387  if( e < 0.0 )
388  ++nnegative;
389  else
390  ++npositive;
391  sum += e;
392 
393  if( bounds.inf < 0.0 )
394  {
395  /* flip j'th argument: (f_j)^(exp_j) = (-1)^(exp_j) (-f_j)^(exp_j) */
396 
397  /* -f_j has negated curvature of f_j */
398  fcurv = SCIPexprcurvNegate(factorcurv[f]); /*lint !e613*/
399 
400  /* negate monomial, if exponent is odd, i.e., (-1)^(exp_j) = -1 */
401  if( (int)e % 2 != 0 )
402  mult *= -1.0;
403  }
404  else
405  {
406  fcurv = factorcurv[f]; /*lint !e613*/
407  }
408 
409  /* check if exp_j * fcurv is convex (>= 0) and/or concave */
410  fcurv = SCIPexprcurvMultiply(e, fcurv);
411  if( !(fcurv & SCIP_EXPRCURV_CONVEX) )
412  expcurvpos = FALSE;
413  if( !(fcurv & SCIP_EXPRCURV_CONCAVE) )
414  expcurvneg = FALSE;
415  }
416 
417  /* if all factors are linear, then a product f_j^exp_j with f_j >= 0 is convex if
418  * - all exponents are negative, or
419  * - all except one exponent j* are negative and exp_j* >= 1 - sum_{j!=j*}exp_j, but the latter is equivalent to sum_j exp_j >= 1
420  * further, the product is concave if
421  * - all exponents are positive and the sum of exponents is <= 1.0
422  *
423  * if factors are nonlinear, then we require additionally, that for convexity
424  * - each factor is convex if exp_j >= 0, or concave if exp_j <= 0, i.e., exp_j*f_j'' >= 0
425  * and for concavity, we require that
426  * - all factors are concave, i.e., exp_j*f_j'' <= 0
427  */
428 
429  if( nnegative == nfactors && expcurvpos )
430  curv = SCIP_EXPRCURV_CONVEX;
431  else if( nnegative == nfactors-1 && EPSGE(sum, 1.0, 1e-9) && expcurvpos )
432  curv = SCIP_EXPRCURV_CONVEX;
433  else if( npositive == nfactors && EPSLE(sum, 1.0, 1e-9) && expcurvneg )
434  curv = SCIP_EXPRCURV_CONCAVE;
435  else
436  curv = SCIP_EXPRCURV_UNKNOWN;
437  curv = SCIPexprcurvMultiply(mult, curv);
438 
439  return curv;
440 }
441 
442 /** for a monomial with given bounds for each factor, gives condition on the curvature of each factor,
443  * so that monomial has a requested curvature, if possible
444  *
445  * @return whether `monomialcurv` can be achieved
446  */
448  SCIP_EXPRCURV monomialcurv, /**< desired curvature */
449  int nfactors, /**< number of factors in monomial */
450  SCIP_Real* exponents, /**< exponents in monomial, or NULL if all 1.0 */
451  SCIP_INTERVAL* factorbounds, /**< bounds of each factor */
452  SCIP_EXPRCURV* factorcurv /**< buffer to store required curvature of each factor */
453  )
454 {
455  int nnegative;
456  int npositive;
457  SCIP_INTERVAL bounds;
458  SCIP_Real e;
459  SCIP_Real sum;
460  int j;
461 
462  assert(monomialcurv != SCIP_EXPRCURV_UNKNOWN);
463  assert(nfactors >= 1);
464  assert(factorbounds != NULL);
465  assert(factorcurv != NULL);
466 
467  if( nfactors == 1 )
468  {
469  factorcurv[0] = SCIPexprcurvPowerInv(factorbounds[0], exponents != NULL ? exponents[0] : 1.0, monomialcurv);
470  return factorcurv[0] != SCIP_EXPRCURV_UNKNOWN;
471  }
472 
473  /* any decent monomial with at least 2 factors is not linear */
474  if( monomialcurv == SCIP_EXPRCURV_LINEAR )
475  return FALSE;
476 
477  /* count positive and negative exponents, sum of exponents; flip negative factors */
478  nnegative = 0; /* number of negative exponents */
479  npositive = 0; /* number of positive exponents */
480  sum = 0.0; /* sum of exponents */
481  for( j = 0; j < nfactors; ++j )
482  {
483  e = exponents != NULL ? exponents[j] : 1.0;
484  assert(e != 0.0); /* should have been simplified away */
485 
486  bounds = factorbounds[j];
487 
488  /* if argument is negative, then exponent should be integer
489  * if that didn't happen, consider argument as if non-negative
490  */
491  if( !EPSISINT(e, 0.0) && bounds.inf < 0.0 ) /*lint !e835*/
492  {
493  bounds.inf = 0.0;
494  if( bounds.sup < 0.0 )
495  return FALSE;
496  }
497 
498  /* mixed signs are bad */
499  if( bounds.inf < 0.0 && bounds.sup > 0.0 )
500  return FALSE;
501 
502  if( e < 0.0 )
503  ++nnegative;
504  else
505  ++npositive;
506  sum += e;
507 
508  if( bounds.inf < 0.0 )
509  {
510  /* flip j'th argument: (f_j)^(exp_j) = (-1)^(exp_j) (-f_j)^(exp_j)
511  * thus, negate monomial, if exponent is odd, i.e., (-1)^(exp_j) = -1
512  */
513  if( (int)e % 2 != 0 )
514  monomialcurv = SCIPexprcurvNegate(monomialcurv);
515  }
516  }
517 
518  /* if all factors are linear, then a product f_j^exp_j with f_j >= 0 is convex if
519  * - all exponents are negative, or
520  * - all except one exponent j* are negative and exp_j* >= 1 - sum_{j!=j*}exp_j, but the latter is equivalent to sum_j exp_j >= 1
521  * further, the product is concave if
522  * - all exponents are positive and the sum of exponents is <= 1.0
523  *
524  * if factors are nonlinear, then we require additionally, that for convexity
525  * - each factor is convex if exp_j >= 0, or concave if exp_j <= 0, i.e., exp_j*f_j'' >= 0
526  * and for concavity, we require that
527  * - all factors are concave, i.e., exp_j*f_j'' <= 0
528  */
529 
530  if( monomialcurv == SCIP_EXPRCURV_CONVEX )
531  {
532  if( nnegative < nfactors-1 ) /* at least two positive exponents */
533  return FALSE;
534  if( nnegative < nfactors && !EPSGE(sum, 1.0, 1e-9) ) /* one negative exponent, but sum is not >= 1 */
535  return FALSE;
536 
537  /* monomial will be convex, if each factor is convex if exp_j >= 0, or concave if exp_j <= 0, i.e., exp_j*f_j'' >= 0 */
538  for( j = 0; j < nfactors; ++j )
539  {
540  e = exponents != NULL ? exponents[j] : 1.0;
541 
542  /* if factor is negative, then factorcurv[j] need to be flipped, which we can also get by flipping e */
543  if( factorbounds[j].inf < 0.0 && EPSISINT(e, 0.0) ) /*lint !e835*/
544  e = -e;
545  if( e >= 0.0 )
546  factorcurv[j] = SCIP_EXPRCURV_CONVEX;
547  else
548  factorcurv[j] = SCIP_EXPRCURV_CONCAVE;
549  }
550  }
551  else
552  {
553  assert(monomialcurv == SCIP_EXPRCURV_CONCAVE);
554  if( npositive < nfactors ) /* at least one negative exponent */
555  return FALSE;
556  if( !EPSLE(sum, 1.0, 1e-9) ) /* sum is not <= 1 */
557  return FALSE;
558 
559  /* monomial will be concave, if each factor is concave */
560  for( j = 0; j < nfactors; ++j )
561  {
562  e = exponents != NULL ? exponents[j] : 1.0;
563 
564  /* if factor is negative, then factorcurv[j] need to be flipped, i.e. convex */
565  if( factorbounds[j].inf < 0.0 && EPSISINT(e, 0.0) ) /*lint !e835*/
566  factorcurv[j] = SCIP_EXPRCURV_CONVEX;
567  else
568  factorcurv[j] = SCIP_EXPRCURV_CONCAVE;
569  }
570  }
571 
572  return TRUE;
573 }
574 
575 /** gives name as string for a curvature */
577  SCIP_EXPRCURV curv /**< curvature */
578  )
579 {
580  assert(0 <= curv && curv <= SCIP_EXPRCURV_LINEAR); /*lint !e685 !e2650 !e587 !e831 !e641 !e568*/
581 
582  return curvnames[curv];
583 }
const char * SCIPexprcurvGetName(SCIP_EXPRCURV curv)
Definition: exprcurv.c:576
SCIP_EXPRCURV SCIPexprcurvNegate(SCIP_EXPRCURV curvature)
Definition: exprcurv.c:52
#define FALSE
Definition: def.h:87
#define EPSISINT(x, eps)
Definition: def.h:214
SCIP_EXPRCURV SCIPexprcurvPower(SCIP_INTERVAL basebounds, SCIP_EXPRCURV basecurv, SCIP_Real exponent)
Definition: exprcurv.c:91
#define TRUE
Definition: def.h:86
#define EPSGE(x, y, eps)
Definition: def.h:206
public functions to work with algebraic expressions
SCIP_EXPRCURV SCIPexprcurvPowerInv(SCIP_INTERVAL basebounds, SCIP_Real exponent, SCIP_EXPRCURV powercurv)
Definition: exprcurv.c:199
SCIP_Real inf
Definition: intervalarith.h:46
#define SCIPerrorMessage
Definition: pub_message.h:55
#define NULL
Definition: lpi_spx1.cpp:155
SCIP_EXPRCURV SCIPexprcurvAdd(SCIP_EXPRCURV curv1, SCIP_EXPRCURV curv2)
Definition: exprcurv.c:43
SCIP_Real sup
Definition: intervalarith.h:47
#define SCIP_Bool
Definition: def.h:84
SCIP_EXPRCURV
Definition: type_expr.h:48
SCIP_Bool SCIPexprcurvMonomialInv(SCIP_EXPRCURV monomialcurv, int nfactors, SCIP_Real *exponents, SCIP_INTERVAL *factorbounds, SCIP_EXPRCURV *factorcurv)
Definition: exprcurv.c:447
SCIP_EXPRCURV SCIPexprcurvMonomial(int nfactors, SCIP_Real *exponents, int *factoridxs, SCIP_EXPRCURV *factorcurv, SCIP_INTERVAL *factorbounds)
Definition: exprcurv.c:321
#define EPSLE(x, y, eps)
Definition: def.h:204
void SCIPintervalSetBounds(SCIP_INTERVAL *resultant, SCIP_Real inf, SCIP_Real sup)
#define SCIP_Real
Definition: def.h:177
SCIP_EXPRCURV SCIPexprcurvMultiply(SCIP_Real factor, SCIP_EXPRCURV curvature)
Definition: exprcurv.c:78
static const char * curvnames[4]
Definition: exprcurv.c:28
#define SCIPABORT()
Definition: def.h:356