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