Scippy

    SCIP

    Solving Constraint Integer Programs

    expr_log.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-2025 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_log.c
    26 * @ingroup DEFPLUGINS_EXPR
    27 * @brief logarithm expression handler
    28 * @author Stefan Vigerske
    29 * @author Benjamin Mueller
    30 * @author Ksenia Bestuzheva
    31 *
    32 */
    33
    34/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    35
    36#include <string.h>
    37
    38#include "scip/expr_value.h"
    39#include "scip/expr_log.h"
    40
    41#define EXPRHDLR_NAME "log"
    42#define EXPRHDLR_DESC "natural logarithm expression"
    43#define EXPRHDLR_PRECEDENCE 80000
    44#define EXPRHDLR_HASHKEY SCIPcalcFibHash(16273.0)
    45
    46/*
    47 * Data structures
    48 */
    49
    50/** expression handler data */
    51struct SCIP_ExprhdlrData
    52{
    53 SCIP_Real minzerodistance; /**< minimal distance from zero to enforce for child in bound tightening */
    54 SCIP_Bool warnedonpole; /**< whether we warned on enforcing a minimal non-zero bound for child */
    55};
    56
    57/*
    58 * Local methods
    59 */
    60
    61/** computes coefficients of secant of a logarithmic term */
    62static
    64 SCIP* scip, /**< SCIP data structure */
    65 SCIP_Real lb, /**< lower bound on variable */
    66 SCIP_Real ub, /**< upper bound on variable */
    67 SCIP_Real* lincoef, /**< buffer to add coefficient of secant */
    68 SCIP_Real* linconstant, /**< buffer to add constant of secant */
    69 SCIP_Bool* success /**< buffer to set to FALSE if secant has failed due to large numbers or unboundedness */
    70 )
    71{
    72 SCIP_Real coef;
    73 SCIP_Real constant;
    74
    75 assert(scip != NULL);
    76 assert(!SCIPisInfinity(scip, lb));
    77 assert(!SCIPisInfinity(scip, -ub));
    78 assert(SCIPisLE(scip, lb, ub));
    79 assert(lincoef != NULL);
    80 assert(linconstant != NULL);
    81 assert(success != NULL);
    82
    83 if( SCIPisLE(scip, lb, 0.0) || SCIPisInfinity(scip, ub) )
    84 {
    85 /* unboundedness */
    86 *success = FALSE;
    87 return;
    88 }
    89
    90 /* if lb and ub are too close use a safe secant */
    91 if( SCIPisEQ(scip, lb, ub) )
    92 {
    93 coef = 0.0;
    94 constant = log(ub);
    95 }
    96 else
    97 {
    98 coef = (log(ub) - log(lb)) / (ub - lb);
    99 constant = log(ub) - coef * ub;
    100 }
    101
    102 if( SCIPisInfinity(scip, REALABS(coef)) || SCIPisInfinity(scip, REALABS(constant)) )
    103 {
    104 *success = FALSE;
    105 return;
    106 }
    107
    108 *lincoef += coef;
    109 *linconstant += constant;
    110}
    111
    112/** computes coefficients of linearization of a logarithmic term in a reference point */
    113static
    115 SCIP* scip, /**< SCIP data structure */
    116 SCIP_Real refpoint, /**< point for which to compute value of linearization */
    117 SCIP_Bool isint, /**< whether corresponding variable is a discrete variable, and thus linearization could be moved */
    118 SCIP_Real* lincoef, /**< buffer to add coefficient of secant */
    119 SCIP_Real* linconstant, /**< buffer to add constant of secant */
    120 SCIP_Bool* success /**< buffer to set to FALSE if secant has failed due to large numbers or unboundedness */
    121 )
    122{
    123 SCIP_Real constant;
    124 SCIP_Real coef;
    125
    126 assert(scip != NULL);
    127 assert(lincoef != NULL);
    128 assert(linconstant != NULL);
    129 assert(success != NULL);
    130
    131 /* can not compute a valid cut if zero is contained in [lb,ub] */
    132 if( SCIPisInfinity(scip, REALABS(refpoint)) || SCIPisLE(scip, refpoint, 0.0) )
    133 {
    134 *success = FALSE;
    135 return;
    136 }
    137
    138 if( !isint || SCIPisIntegral(scip, refpoint) )
    139 {
    140 assert(refpoint != 0.0);
    141 coef = 1.0 / refpoint;
    142 constant = log(refpoint) - 1.0;
    143 }
    144 else
    145 {
    146 /* log(x) -> secant between f=floor(refpoint) and f+1 = log((f+1.0)/f) * x + log(f) - log((f+1.0)/f) * f */
    147 SCIP_Real f;
    148
    149 f = SCIPfloor(scip, refpoint);
    150 assert(f > 0.0);
    151
    152 coef = log((f+1.0) / f);
    153 constant = log(f) - coef * f;
    154 }
    155
    156 if( SCIPisInfinity(scip, REALABS(coef)) || SCIPisInfinity(scip, REALABS(constant)) )
    157 {
    158 *success = FALSE;
    159 return;
    160 }
    161
    162 *lincoef += coef;
    163 *linconstant += constant;
    164}
    165
    166/*
    167 * Callback methods of expression handler
    168 */
    169
    170/** simplifies a log expression
    171 *
    172 * Evaluates the logarithm function when its child is a value expression.
    173 *
    174 * TODO: split products ?
    175 * TODO: log(exp(*)) = *
    176 */
    177static
    179{ /*lint --e{715}*/
    180 SCIP_EXPR* child;
    181
    182 assert(scip != NULL);
    183 assert(expr != NULL);
    184 assert(simplifiedexpr != NULL);
    185 assert(SCIPexprGetNChildren(expr) == 1);
    186
    187 child = SCIPexprGetChildren(expr)[0];
    188 assert(child != NULL);
    189
    190 /* check for value expression */
    191 /* TODO better handling of non-positive value? */
    193 {
    194 assert(SCIPgetValueExprValue(child) > 0.0);
    195
    196 SCIP_CALL( SCIPcreateExprValue(scip, simplifiedexpr, log(SCIPgetValueExprValue(child)), ownercreate,
    197 ownercreatedata) );
    198 }
    199 else
    200 {
    201 *simplifiedexpr = expr;
    202
    203 /* we have to capture it, since it must simulate a "normal" simplified call in which a new expression is created */
    204 SCIPcaptureExpr(*simplifiedexpr);
    205 }
    206
    207 return SCIP_OKAY;
    208}
    209
    210/** expression handler copy callback */
    211static
    213{ /*lint --e{715}*/
    215
    216 return SCIP_OKAY;
    217}
    218
    219/** expression handler free callback */
    220static
    222{ /*lint --e{715}*/
    223 assert(exprhdlrdata != NULL);
    224 assert(*exprhdlrdata != NULL);
    225
    226 SCIPfreeBlockMemory(scip, exprhdlrdata);
    227
    228 return SCIP_OKAY;
    229}
    230
    231/** expression data copy callback */
    232static
    234{ /*lint --e{715}*/
    235 assert(targetexprdata != NULL);
    236 assert(sourceexpr != NULL);
    237 assert(SCIPexprGetData(sourceexpr) == NULL);
    238
    239 *targetexprdata = NULL;
    240
    241 return SCIP_OKAY;
    242}
    243
    244/** expression data free callback */
    245static
    247{ /*lint --e{715}*/
    248 assert(expr != NULL);
    249
    250 SCIPexprSetData(expr, NULL);
    251
    252 return SCIP_OKAY;
    253}
    254
    255/** expression parse callback */
    256static
    258{ /*lint --e{715}*/
    259 SCIP_EXPR* childexpr;
    260
    261 assert(expr != NULL);
    262
    263 /* parse child expression from remaining string */
    264 SCIP_CALL( SCIPparseExpr(scip, &childexpr, string, endstring, ownercreate, ownercreatedata) );
    265 assert(childexpr != NULL);
    266
    267 /* create logarithmic expression */
    268 SCIP_CALL( SCIPcreateExprLog(scip, expr, childexpr, ownercreate, ownercreatedata) );
    269 assert(*expr != NULL);
    270
    271 /* release child expression since it has been captured by the logarithmic expression */
    272 SCIP_CALL( SCIPreleaseExpr(scip, &childexpr) );
    273
    274 *success = TRUE;
    275
    276 return SCIP_OKAY;
    277}
    278
    279/** expression point evaluation callback */
    280static
    282{ /*lint --e{715}*/
    283 assert(expr != NULL);
    284 assert(SCIPexprGetData(expr) == NULL);
    285 assert(SCIPexprGetNChildren(expr) == 1);
    286 assert(SCIPexprGetEvalValue(SCIPexprGetChildren(expr)[0]) != SCIP_INVALID); /*lint !e777*/
    287
    288 /**! [SnippetExprEvalLog] */
    289 if( SCIPexprGetEvalValue(SCIPexprGetChildren(expr)[0]) <= 0.0 )
    290 {
    291 SCIPdebugMsg(scip, "invalid evaluation of logarithmic expression\n");
    292 *val = SCIP_INVALID;
    293 }
    294 else
    295 {
    296 *val = log(SCIPexprGetEvalValue(SCIPexprGetChildren(expr)[0]));
    297 }
    298 /**! [SnippetExprEvalLog] */
    299
    300 return SCIP_OKAY;
    301}
    302
    303/** expression derivative evaluation callback */
    304static
    306{ /*lint --e{715}*/
    307 SCIP_EXPR* child;
    308
    309 assert(expr != NULL);
    310 assert(childidx == 0);
    311 assert(SCIPexprGetEvalValue(expr) != SCIP_INVALID); /*lint !e777*/
    312
    313 child = SCIPexprGetChildren(expr)[0];
    314 assert(child != NULL);
    315 assert(strcmp(SCIPexprhdlrGetName(SCIPexprGetHdlr(child)), "val") != 0);
    316 assert(SCIPexprGetEvalValue(child) > 0.0);
    317
    318 *val = 1.0 / SCIPexprGetEvalValue(child);
    319
    320 return SCIP_OKAY;
    321}
    322
    323/** expression interval evaluation callback */
    324static
    326{ /*lint --e{715}*/
    327 SCIP_EXPRHDLRDATA* exprhdlrdata;
    328 SCIP_INTERVAL childinterval;
    329
    330 assert(expr != NULL);
    331 assert(SCIPexprGetData(expr) == NULL);
    332 assert(SCIPexprGetNChildren(expr) == 1);
    333
    334 exprhdlrdata = SCIPexprhdlrGetData(SCIPexprGetHdlr(expr));
    335 assert(exprhdlrdata != NULL);
    336
    337 childinterval = SCIPexprGetActivity(SCIPexprGetChildren(expr)[0]);
    338
    339 /* pretend childinterval to be >= epsilon, see also reversepropLog */
    340 if( childinterval.inf < exprhdlrdata->minzerodistance && exprhdlrdata->minzerodistance > 0.0 )
    341 {
    342 if( !exprhdlrdata->warnedonpole && SCIPgetVerbLevel(scip) > SCIP_VERBLEVEL_NONE )
    343 {
    344 SCIPinfoMessage(scip, NULL, "Changing lower bound for child of log() from %g to %g.\n"
    345 "Check your model formulation or use option expr/" EXPRHDLR_NAME "/minzerodistance to avoid this warning.\n",
    346 childinterval.inf, exprhdlrdata->minzerodistance);
    347 SCIPinfoMessage(scip, NULL, "Expression: ");
    348 SCIP_CALL( SCIPprintExpr(scip, expr, NULL) );
    349 SCIPinfoMessage(scip, NULL, "\n");
    350 exprhdlrdata->warnedonpole = TRUE;
    351 }
    352 childinterval.inf = exprhdlrdata->minzerodistance;
    353 }
    354
    355 if( SCIPintervalIsEmpty(SCIP_INTERVAL_INFINITY, childinterval) )
    356 {
    357 SCIPintervalSetEmpty(interval);
    358 return SCIP_OKAY;
    359 }
    360
    361 SCIPintervalLog(SCIP_INTERVAL_INFINITY, interval, childinterval);
    362
    363 return SCIP_OKAY;
    364}
    365
    366/** expression estimation callback */
    367static
    369{ /*lint --e{715}*/
    370 SCIP_Real lb;
    371 SCIP_Real ub;
    372
    373 assert(scip != NULL);
    374 assert(expr != NULL);
    375 assert(SCIPexprGetNChildren(expr) == 1);
    376 assert(strcmp(SCIPexprhdlrGetName(SCIPexprGetHdlr(expr)), EXPRHDLR_NAME) == 0);
    377 assert(coefs != NULL);
    378 assert(constant != NULL);
    379 assert(islocal != NULL);
    380 assert(branchcand != NULL);
    381 assert(*branchcand == TRUE);
    382 assert(success != NULL);
    383 assert(refpoint != NULL);
    384
    385 lb = localbounds[0].inf;
    386 ub = localbounds[0].sup;
    387
    388 *coefs = 0.0;
    389 *constant = 0.0;
    390 *success = TRUE;
    391
    392 if( overestimate )
    393 {
    394 if( !SCIPisPositive(scip, refpoint[0]) )
    395 {
    396 /* if refpoint is 0 (then lb=0 probably) or below, then slope is infinite, then try to move away from 0 */
    397 if( SCIPisZero(scip, ub) )
    398 {
    399 *success = FALSE;
    400 return SCIP_OKAY;
    401 }
    402
    403 if( localbounds[0].sup < 0.2 )
    404 refpoint[0] = 0.5 * lb + 0.5 * ub;
    405 else
    406 refpoint[0] = 0.1;
    407 }
    408
    409 addLogLinearization(scip, refpoint[0], SCIPexprIsIntegral(SCIPexprGetChildren(expr)[0]), coefs, constant, success);
    410 *islocal = FALSE; /* linearization is globally valid */
    411 *branchcand = FALSE;
    412 }
    413 else
    414 {
    415 addLogSecant(scip, lb, ub, coefs, constant, success);
    416 *islocal = TRUE; /* secants are only valid locally */
    417 }
    418
    419 return SCIP_OKAY;
    420}
    421
    422/** initial estimates callback that provides initial linear estimators for a logarithm expression */
    423static
    425{
    426 SCIP_Real refpointsover[3] = {SCIP_INVALID, SCIP_INVALID, SCIP_INVALID};
    427 SCIP_Bool overest[4] = {TRUE, TRUE, TRUE, FALSE};
    428 SCIP_EXPR* child;
    429 SCIP_Real lb;
    430 SCIP_Real ub;
    431 SCIP_Bool success;
    432 int i;
    433
    434 assert(scip != NULL);
    435 assert(expr != NULL);
    436 assert(SCIPexprGetNChildren(expr) == 1);
    437 assert(strcmp(SCIPexprhdlrGetName(SCIPexprGetHdlr(expr)), EXPRHDLR_NAME) == 0);
    438
    439 /* get expression data */
    440 child = SCIPexprGetChildren(expr)[0];
    441 assert(child != NULL);
    442
    443 lb = SCIPintervalGetInf(bounds[0]);
    444 ub = SCIPintervalGetSup(bounds[0]);
    445
    446 if( SCIPisEQ(scip, lb, ub) )
    447 return SCIP_OKAY;
    448
    449 if( overestimate )
    450 {
    451 /* adjust lb */
    452 lb = MAX(lb, MIN(0.5 * lb + 0.5 * ub, 0.1));
    453
    454 refpointsover[0] = lb;
    455 refpointsover[1] = SCIPisInfinity(scip, ub) ? lb + 2.0 : (lb + ub) / 2;
    456 refpointsover[2] = SCIPisInfinity(scip, ub) ? lb + 20.0 : ub;
    457 }
    458
    459 *nreturned = 0;
    460
    461 for( i = 0; i < 4; ++i )
    462 {
    463 if( (overest[i] && !overestimate) || (!overest[i] && (overestimate || SCIPisInfinity(scip, ub))) )
    464 continue;
    465
    466 assert(!overest[i] || (SCIPisLE(scip, refpointsover[i], ub) && SCIPisGE(scip, refpointsover[i], lb))); /*lint !e661*/
    467
    468 success = TRUE;
    469 coefs[*nreturned][0] = 0.0;
    470 constant[*nreturned] = 0.0;
    471
    472 if( overest[i] )
    473 {
    474 assert(i < 3);
    475 /* coverity[overrun] */
    476 addLogLinearization(scip, refpointsover[i], SCIPexprIsIntegral(child), coefs[*nreturned], &constant[*nreturned], &success); /*lint !e661*/
    477 if( success )
    478 {
    479 SCIPdebugMsg(scip, "init overestimate log(x) at x=%g -> %g*x+%g\n", refpointsover[i], coefs[*nreturned][0], constant[*nreturned]);
    480 }
    481 }
    482 else
    483 {
    484 addLogSecant(scip, lb, ub, coefs[*nreturned], &constant[*nreturned], &success);
    485 if( success )
    486 {
    487 SCIPdebugMsg(scip, "init underestimate log(x) on x=[%g,%g] -> %g*x+%g\n", lb, ub, coefs[*nreturned][0], constant[*nreturned]);
    488 }
    489 }
    490
    491 if( success )
    492 {
    493 ++(*nreturned);
    494 }
    495 }
    496
    497 return SCIP_OKAY;
    498}
    499
    500/** expression reverse propagation callback */
    501static
    503{ /*lint --e{715}*/
    504 SCIP_EXPRHDLRDATA* exprhdlrdata;
    505
    506 assert(scip != NULL);
    507 assert(expr != NULL);
    508 assert(SCIPexprGetNChildren(expr) == 1);
    509
    510 exprhdlrdata = SCIPexprhdlrGetData(SCIPexprGetHdlr(expr));
    511 assert(exprhdlrdata != NULL);
    512
    513 /* f = log(c0) -> c0 = exp(f) */
    514 SCIPintervalExp(SCIP_INTERVAL_INFINITY, &childrenbounds[0], bounds);
    515
    516 /* force child lower bound to be at least epsilon away from 0
    517 * this can help a lot in enforcement (try ex8_5_3)
    518 * child being equal 0 is already forbidden, so making it strictly greater-equal epsilon enforces
    519 * and hopefully doesn't introduce much problems
    520 * if childrenbounds[0].sup < epsilon, too, then this will result in a cutoff
    521 */
    522 if( childrenbounds[0].inf < exprhdlrdata->minzerodistance )
    523 {
    524 SCIPdebugMsg(scip, "Pushing child lower bound from %g to %g; upper bound remains at %g\n", childrenbounds[0].inf, SCIPepsilon(scip), childrenbounds[0].sup);
    525
    526 if( !exprhdlrdata->warnedonpole && SCIPgetVerbLevel(scip) > SCIP_VERBLEVEL_NONE )
    527 {
    528 SCIPinfoMessage(scip, NULL, "Changing lower bound for child of log() from %g to %g.\n"
    529 "Check your model formulation or use option expr/" EXPRHDLR_NAME "/minzerodistance to avoid this warning.\n",
    530 childrenbounds[0].inf, exprhdlrdata->minzerodistance);
    531 SCIPinfoMessage(scip, NULL, "Expression: ");
    532 SCIP_CALL( SCIPprintExpr(scip, expr, NULL) );
    533 SCIPinfoMessage(scip, NULL, "\n");
    534 exprhdlrdata->warnedonpole = TRUE;
    535 }
    536
    537 childrenbounds[0].inf = exprhdlrdata->minzerodistance;
    538 }
    539
    540 return SCIP_OKAY;
    541}
    542
    543/** expression hash callback */
    544static
    546{ /*lint --e{715}*/
    547 assert(scip != NULL);
    548 assert(expr != NULL);
    549 assert(SCIPexprGetNChildren(expr) == 1);
    550 assert(hashkey != NULL);
    551 assert(childrenhashes != NULL);
    552
    553 *hashkey = EXPRHDLR_HASHKEY;
    554 *hashkey ^= childrenhashes[0];
    555
    556 return SCIP_OKAY;
    557}
    558
    559/** expression curvature detection callback */
    560static
    562{ /*lint --e{715}*/
    563 assert(scip != NULL);
    564 assert(expr != NULL);
    565 assert(childcurv != NULL);
    566 assert(SCIPexprGetNChildren(expr) == 1);
    567
    568 /* expression is concave if child is concave, expression cannot be linear or convex */
    569 if( exprcurvature == SCIP_EXPRCURV_CONCAVE )
    570 {
    571 *childcurv = SCIP_EXPRCURV_CONCAVE;
    572 *success = TRUE;
    573 }
    574 else
    575 *success = FALSE;
    576
    577 return SCIP_OKAY;
    578}
    579
    580/** expression monotonicity detection callback */
    581static
    583{ /*lint --e{715}*/
    584 assert(scip != NULL);
    585 assert(expr != NULL);
    586 assert(result != NULL);
    587 assert(childidx == 0);
    588
    589 *result = SCIP_MONOTONE_INC;
    590
    591 return SCIP_OKAY;
    592}
    593
    594/** creates the handler for logarithmic expression and includes it into SCIP */
    596 SCIP* scip /**< SCIP data structure */
    597 )
    598{
    599 SCIP_EXPRHDLR* exprhdlr;
    600 SCIP_EXPRHDLRDATA* exprhdlrdata;
    601
    602 /**! [SnippetIncludeExprhdlrLog] */
    603 SCIP_CALL( SCIPallocClearBlockMemory(scip, &exprhdlrdata) );
    604
    606 exprhdlrdata) );
    607 assert(exprhdlr != NULL);
    608
    609 SCIPexprhdlrSetCopyFreeHdlr(exprhdlr, copyhdlrLog, freehdlrLog);
    610 SCIPexprhdlrSetCopyFreeData(exprhdlr, copydataLog, freedataLog);
    611 SCIPexprhdlrSetSimplify(exprhdlr, simplifyLog);
    612 SCIPexprhdlrSetParse(exprhdlr, parseLog);
    613 SCIPexprhdlrSetIntEval(exprhdlr, intevalLog);
    614 SCIPexprhdlrSetEstimate(exprhdlr, initestimatesLog, estimateLog);
    615 SCIPexprhdlrSetReverseProp(exprhdlr, reversepropLog);
    616 SCIPexprhdlrSetHash(exprhdlr, hashLog);
    617 SCIPexprhdlrSetDiff(exprhdlr, bwdiffLog, NULL, NULL);
    618 SCIPexprhdlrSetCurvature(exprhdlr, curvatureLog);
    619 SCIPexprhdlrSetMonotonicity(exprhdlr, monotonicityLog);
    620
    621 SCIP_CALL( SCIPaddRealParam(scip, "expr/" EXPRHDLR_NAME "/minzerodistance",
    622 "minimal distance from zero to enforce for child in bound tightening",
    623 &exprhdlrdata->minzerodistance, FALSE, SCIPepsilon(scip), 0.0, 1.0, NULL, NULL) );
    624 /**! [SnippetIncludeExprhdlrLog] */
    625
    626 return SCIP_OKAY;
    627}
    628
    629/** creates a logarithmic expression */
    631 SCIP* scip, /**< SCIP data structure */
    632 SCIP_EXPR** expr, /**< pointer where to store expression */
    633 SCIP_EXPR* child, /**< single child */
    634 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
    635 void* ownercreatedata /**< data to pass to ownercreate */
    636 )
    637{
    638 assert(expr != NULL);
    639 assert(child != NULL);
    640
    641 SCIP_CALL( SCIPcreateExpr(scip, expr, SCIPfindExprhdlr(scip, EXPRHDLR_NAME), NULL, 1, &child, ownercreate,
    642 ownercreatedata) );
    643
    644 return SCIP_OKAY;
    645}
    646
    647/** indicates whether expression is of log-type */ /*lint -e{715}*/
    649 SCIP* scip, /**< SCIP data structure */
    650 SCIP_EXPR* expr /**< expression */
    651 )
    652{ /*lint --e{715}*/
    653 assert(expr != NULL);
    654
    655 return strcmp(SCIPexprhdlrGetName(SCIPexprGetHdlr(expr)), EXPRHDLR_NAME) == 0;
    656}
    #define NULL
    Definition: def.h:248
    #define SCIP_INVALID
    Definition: def.h:178
    #define SCIP_INTERVAL_INFINITY
    Definition: def.h:180
    #define SCIP_Bool
    Definition: def.h:91
    #define MIN(x, y)
    Definition: def.h:224
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define MAX(x, y)
    Definition: def.h:220
    #define REALABS(x)
    Definition: def.h:182
    #define SCIP_CALL(x)
    Definition: def.h:355
    static SCIP_DECL_EXPRHASH(hashLog)
    Definition: expr_log.c:545
    static void addLogLinearization(SCIP *scip, SCIP_Real refpoint, SCIP_Bool isint, SCIP_Real *lincoef, SCIP_Real *linconstant, SCIP_Bool *success)
    Definition: expr_log.c:114
    static SCIP_DECL_EXPRFREEHDLR(freehdlrLog)
    Definition: expr_log.c:221
    static SCIP_DECL_EXPRBWDIFF(bwdiffLog)
    Definition: expr_log.c:305
    #define EXPRHDLR_HASHKEY
    Definition: expr_log.c:44
    static SCIP_DECL_EXPRINITESTIMATES(initestimatesLog)
    Definition: expr_log.c:424
    static SCIP_DECL_EXPRFREEDATA(freedataLog)
    Definition: expr_log.c:246
    static SCIP_DECL_EXPRCOPYDATA(copydataLog)
    Definition: expr_log.c:233
    #define EXPRHDLR_NAME
    Definition: expr_log.c:41
    static SCIP_DECL_EXPRMONOTONICITY(monotonicityLog)
    Definition: expr_log.c:582
    static SCIP_DECL_EXPRPARSE(parseLog)
    Definition: expr_log.c:257
    static SCIP_DECL_EXPRESTIMATE(estimateLog)
    Definition: expr_log.c:368
    static SCIP_DECL_EXPRREVERSEPROP(reversepropLog)
    Definition: expr_log.c:502
    static SCIP_DECL_EXPRCOPYHDLR(copyhdlrLog)
    Definition: expr_log.c:212
    static SCIP_DECL_EXPRSIMPLIFY(simplifyLog)
    Definition: expr_log.c:178
    static SCIP_DECL_EXPREVAL(evalLog)
    Definition: expr_log.c:281
    #define EXPRHDLR_DESC
    Definition: expr_log.c:42
    static void addLogSecant(SCIP *scip, SCIP_Real lb, SCIP_Real ub, SCIP_Real *lincoef, SCIP_Real *linconstant, SCIP_Bool *success)
    Definition: expr_log.c:63
    #define EXPRHDLR_PRECEDENCE
    Definition: expr_log.c:43
    static SCIP_DECL_EXPRCURVATURE(curvatureLog)
    Definition: expr_log.c:561
    static SCIP_DECL_EXPRINTEVAL(intevalLog)
    Definition: expr_log.c:325
    logarithm expression handler
    constant value expression handler
    SCIP_Bool SCIPisExprLog(SCIP *scip, SCIP_EXPR *expr)
    Definition: expr_log.c:648
    SCIP_RETCODE SCIPcreateExprLog(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPR *child, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
    Definition: expr_log.c:630
    SCIP_RETCODE SCIPcreateExprValue(SCIP *scip, SCIP_EXPR **expr, SCIP_Real value, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
    Definition: expr_value.c:274
    SCIP_RETCODE SCIPincludeExprhdlrLog(SCIP *scip)
    Definition: expr_log.c:595
    void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:208
    SCIP_VERBLEVEL SCIPgetVerbLevel(SCIP *scip)
    Definition: scip_message.c:249
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:139
    const char * SCIPexprhdlrGetName(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:545
    void SCIPexprhdlrSetCopyFreeData(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRCOPYDATA((*copydata)), SCIP_DECL_EXPRFREEDATA((*freedata)))
    Definition: expr.c:383
    void SCIPexprhdlrSetHash(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRHASH((*hash)))
    Definition: expr.c:451
    SCIP_EXPRHDLRDATA * SCIPexprhdlrGetData(SCIP_EXPRHDLR *exprhdlr)
    Definition: expr.c:575
    void SCIPexprhdlrSetCopyFreeHdlr(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRCOPYHDLR((*copyhdlr)), SCIP_DECL_EXPRFREEHDLR((*freehdlr)))
    Definition: expr.c:370
    void SCIPexprhdlrSetDiff(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRBWDIFF((*bwdiff)), SCIP_DECL_EXPRFWDIFF((*fwdiff)), SCIP_DECL_EXPRBWFWDIFF((*bwfwdiff)))
    Definition: expr.c:473
    void SCIPexprhdlrSetReverseProp(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRREVERSEPROP((*reverseprop)))
    Definition: expr.c:510
    void SCIPexprhdlrSetParse(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRPARSE((*parse)))
    Definition: expr.c:407
    void SCIPexprhdlrSetEstimate(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRINITESTIMATES((*initestimates)), SCIP_DECL_EXPRESTIMATE((*estimate)))
    Definition: expr.c:532
    void SCIPexprhdlrSetMonotonicity(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRMONOTONICITY((*monotonicity)))
    Definition: expr.c:429
    void SCIPexprhdlrSetIntEval(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRINTEVAL((*inteval)))
    Definition: expr.c:488
    void SCIPexprhdlrSetCurvature(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRCURVATURE((*curvature)))
    Definition: expr.c:418
    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:847
    SCIP_EXPRHDLR * SCIPfindExprhdlr(SCIP *scip, const char *name)
    Definition: scip_expr.c:894
    void SCIPexprhdlrSetSimplify(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRSIMPLIFY((*simplify)))
    Definition: expr.c:499
    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:1000
    void SCIPexprSetData(SCIP_EXPR *expr, SCIP_EXPRDATA *exprdata)
    Definition: expr.c:3920
    int SCIPexprGetNChildren(SCIP_EXPR *expr)
    Definition: expr.c:3872
    SCIP_Bool SCIPexprIsIntegral(SCIP_EXPR *expr)
    Definition: expr.c:4101
    SCIP_Bool SCIPisExprValue(SCIP *scip, SCIP_EXPR *expr)
    Definition: scip_expr.c:1468
    SCIP_RETCODE SCIPreleaseExpr(SCIP *scip, SCIP_EXPR **expr)
    Definition: scip_expr.c:1443
    SCIP_EXPRDATA * SCIPexprGetData(SCIP_EXPR *expr)
    Definition: expr.c:3905
    SCIP_RETCODE SCIPparseExpr(SCIP *scip, SCIP_EXPR **expr, const char *exprstr, const char **finalpos, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
    Definition: scip_expr.c:1406
    SCIP_RETCODE SCIPprintExpr(SCIP *scip, SCIP_EXPR *expr, FILE *file)
    Definition: scip_expr.c:1512
    SCIP_Real SCIPgetValueExprValue(SCIP_EXPR *expr)
    Definition: expr_value.c:298
    SCIP_Real SCIPexprGetEvalValue(SCIP_EXPR *expr)
    Definition: expr.c:3946
    SCIP_EXPR ** SCIPexprGetChildren(SCIP_EXPR *expr)
    Definition: expr.c:3882
    SCIP_INTERVAL SCIPexprGetActivity(SCIP_EXPR *expr)
    Definition: expr.c:4028
    void SCIPcaptureExpr(SCIP_EXPR *expr)
    Definition: scip_expr.c:1435
    SCIP_EXPRHDLR * SCIPexprGetHdlr(SCIP_EXPR *expr)
    Definition: expr.c:3895
    SCIP_Real SCIPintervalGetInf(SCIP_INTERVAL interval)
    SCIP_Bool SCIPintervalIsEmpty(SCIP_Real infinity, SCIP_INTERVAL operand)
    void SCIPintervalLog(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand)
    SCIP_Real SCIPintervalGetSup(SCIP_INTERVAL interval)
    void SCIPintervalExp(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand)
    void SCIPintervalSetEmpty(SCIP_INTERVAL *resultant)
    #define SCIPallocClearBlockMemory(scip, ptr)
    Definition: scip_mem.h:91
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPepsilon(SCIP *scip)
    SCIP_Real inf
    Definition: intervalarith.h:56
    #define SCIP_DECL_EXPR_OWNERCREATE(x)
    Definition: type_expr.h:143
    struct SCIP_ExprhdlrData SCIP_EXPRHDLRDATA
    Definition: type_expr.h:195
    @ SCIP_EXPRCURV_CONCAVE
    Definition: type_expr.h:64
    @ SCIP_MONOTONE_INC
    Definition: type_expr.h:72
    @ SCIP_VERBLEVEL_NONE
    Definition: type_message.h:57
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63