nlhdlr_signomial.c
Go to the documentation of this file.
56#define NLHDLR_MAXNUNDERVARS 14 /**< maximum number of variables when underestimating a concave power function (maximum: 14) */
62 * A signomial expression admits the form \f$ cx^a = y \f$, where \f$ y \f$ is an auxiliary variable representing this
65 * The natural formulation of the expression is defined as \f$ x^a = t = y/c \f$, where \f$ t \f$ is a
66 * non-existant slack variable denoting \f$ y/c \f$. The variables in \f$x\f$ with positive exponents form positive
67 * variables \f$ u \f$, and the associated exponents form positive exponents \f$ f \f$. The variables in \f$ x \f$ with
68 * negative exponents and \f$ t \f$ form negative variables \f$ v \f$, and the associated exponents form negative
69 * exponents \f$ g \f$. Let \f$ s = \max(|f|,|g|) \f$ be a normalization constant, where \f$ |\cdot| \f$ denotes the L1 norm. Apply a scaling step:
70 * Dividing the entries of \f$ f \f$ by \f$ s \f$, and dividing the entries of \f$ g \f$ by \f$ s \f$ as well. Then \f$ x^a = t \f$ has
82 SCIP_Bool* signs; /**< indicators for sign of variables after reformulation, TRUE for positive, FALSE for negative */
88 SCIP_INTERVAL* intervals; /**< intervals storing lower and upper bounds of variables \f$(x,y)\f$ */
89 SCIP_Real* box; /**< the upper/lower bounds of variables, used in SCIPcomputeFacetVertexPolyhedralNonlinear() */
90 SCIP_Real* xstar; /**< the values of variables, used in SCIPcomputeFacetVertexPolyhedralNonlinear() */
91 SCIP_Real* facetcoefs; /**< the coefficients of variables, returned by SCIPcomputeFacetVertexPolyhedralNonlinear() */
98 int maxnundervars; /**< maximum number of variables in underestimating a concave power function */
102/** data struct to be passed on to vertexpoly-evalfunction (see SCIPcomputeFacetVertexPolyhedralNonlinear) */
106 SCIP_Bool sign; /**< the sign of variables in the reformulated constraint for vertexpoly-evalfunction */
107 int nsignvars; /**< the number of variables in the reformulated constraint for vertexpoly-evalfunction */
129 SCIPdebugMsg(scip, " #all variables: %d, #positive exponent variables: %d, #negative exponent variables: %d, auxvar: %s \n expr: ",
130 nlhdlrexprdata->nvars, nlhdlrexprdata->nposvars, nlhdlrexprdata->nnegvars, SCIPvarGetName(SCIPgetExprAuxVarNonlinear(expr)) );
144 SCIPinfoMessage(scip, NULL, "%s^%.2f", SCIPvarGetName(nlhdlrexprdata->vars[i]), nlhdlrexprdata->exponents[i]);
146 SCIPinfoMessage(scip, NULL, " = %s", SCIPvarGetName(nlhdlrexprdata->vars[nlhdlrexprdata->nvars - 1]));
159 SCIPinfoMessage(scip, NULL, "%s^%.2f", SCIPvarGetName(nlhdlrexprdata->vars[i]), nlhdlrexprdata->refexponents[i]);
175 SCIPinfoMessage(scip, NULL, "(%s/%.2f)^%.2f", SCIPvarGetName(nlhdlrexprdata->vars[i]), nlhdlrexprdata->coef, nlhdlrexprdata->refexponents[i]);
179 SCIPinfoMessage(scip, NULL, "%s^%.2f", SCIPvarGetName(nlhdlrexprdata->vars[i]), nlhdlrexprdata->refexponents[i]);
219 * If in the overestimate mode, then we relax \f$ t \le x^a \f$, i.e., \f$ 0 \le u^f - v^g \f$. This implies that \f$ t \f$ is in \f$ v = (v',t) \f$.
220 * Therefore, the valid inequality is \f$ 0 \le a_u u + a_v v + b \f$. As overestimate mode requires that \f$ t \f$ is in the left hand side,
221 * the coefficients of \f$ t \f$ must be made negative while keeping the sign of the inequality, we can show that \f$ a_t \le 0 \f$, so it suffices
222 * to divide the both sides by \f$ -a_t \ge 0\f$, which yields \f$ t \le (a_u u + a_v' v' + b) / -a_t \f$.
224 * If in the underestimate mode, then we relax \f$ x^a \le t \f$, i.e., \f$ u^f - v^g \le 0 \f$. This implies that \f$ t \f$ is in \f$ v = (v',t) \f$.
225 * Therefore, the valid inequality is \f$ a_u u + a_v v + b \le 0 \f$. As overestimate mode requires that \f$ t \f$ is in the left hand side,
226 * the coefficients of \f$ t \f$ must be made negative while keeping the sign of the inequality, we can show that \f$ a_t \le 0 \f$, so it suffices
227 * to divide the both sides by \f$ -a_t \ge 0 \f$, which yields \f$ (a_u u + a_v' v' + b) / -a_t \le t \f$.
273 /* the reformation scales the cut so that coefficients and constant are divided by the absolute value of coefauxvar */
320/** get bounds of variables x,t and check whether they are box constrained signomial variables */
325 SCIP_Bool* isboxsignomial /**< buffer to store whether variables are box constrained signomial variables */
344 /* if the bounds of the variable are not positive and finite, or (bounds equal) then the expression is not a signomial */
345 if( !SCIPisPositive(scip, inf) || !SCIPisPositive(scip, sup) || SCIPisInfinity(scip, sup) || SCIPisEQ(scip, inf, sup) )
398/** determine whether a power function \f$ w^h \f$ is special and add an overunderestimator or underestimator to a given rowprep
400 * \f$ w^h \f$ is special, if all variables are fixed, or it is a constant to estimate, a univariate power to estimate,
401 * or a bivariate power to underestimate. The estimator is multiplied by the multiplier and stored in the rowprep.
501 SCIPestimateRoot(scip, refexponent, overestimate, nlhdlrexprdata->intervals[i].inf, nlhdlrexprdata->intervals[i].sup,
515 * supported by three upper right points. For a point xstar in the box, its corresponding affine function can be determined by
516 * which region (upper right or lower left half space) the point is in. Thus, we can determine the region, and use the
564 /* underestimator: fw0uw1u + (fw0uw1u - fw0lw1u) / (dw0) * (x0 - w0u) + (fw0uw1u - fw0uw1l) / (dw1) * (x1 - w1u) */
572 /* underestimator: fw0lw1l + (fw0uw1l - fw0lw1l) / (dw0) * (x0 - w0l) + (fw0lw1u- fw0lw1l) / (dw1) * (x1 - w1l) */
587/** adds an underestimator for a multivariate concave power function \f$ w^h \f$ to a given rowprep
602 SCIP_Real targetvalue, /**< a target value to achieve; if not reachable, then can give up early */
652 SCIP_CALL( SCIPcomputeFacetVertexPolyhedralNonlinear(scip, conshdlr, FALSE, nlhdlrExprEvalPower, (void*)&evaldata, xstar, box,
669 SCIP_CALL( SCIPaddRowprepTerm(scip, rowprep, nlhdlrexprdata->vars[i], multiplier * facetcoefs[j] / scale) );
777 /* check whether all variables have finite positive bounds, which is necessary for the expression to be a signomial term */
787 /* determine the sign of variables for over- and underestimators, and the multiplier for estimators in the rowprep */
807 /* compute the value of the overestimator, which is a target value for computing the underestimator efficiently */
814 targetunder *= pow(SCIPgetSolVal(scip, sol, nlhdlrexprdata->vars[i]) / scale, nlhdlrexprdata->refexponents[i]);
823 SCIPinfoMessage(scip, NULL, " Auxvalue: %f, targetvalue: %f, %sestimate.", auxvalue, targetvalue, overestimate ? "over" : "under");
831 targetover *= pow(SCIPgetSolVal(scip, sol, nlhdlrexprdata->vars[i]) / scale, nlhdlrexprdata->refexponents[i]);
836 SCIPinfoMessage(scip, NULL, " Undervalue (targetover): %f, overvalue (targetunder): %f.", targetover, targetunder);
840 SCIP_CALL( SCIPcreateRowprep(scip, &rowprep, overestimate ? SCIP_SIDETYPE_LEFT : SCIP_SIDETYPE_RIGHT, TRUE) );
843 /* only underestimate a concave function, if the number of variables is below a given threshold */
849 SCIP_CALL( estimateSpecialPower(scip, nlhdlrexprdata, undersign, undermultiplier, FALSE, sol, rowprep, &isspecial, success) );
852 SCIP_CALL( underEstimatePower(scip, conshdlr, nlhdlr, nlhdlrexprdata, undersign, undermultiplier, sol, targetunder, rowprep, success) );
861 SCIP_CALL( estimateSpecialPower(scip, nlhdlrexprdata, oversign, overmultiplier, TRUE, sol, rowprep, &isspecial, success) );
864 SCIP_CALL( overEstimatePower(scip, nlhdlrexprdata, oversign, overmultiplier, sol, rowprep, success) );
915 SCIP_CALL( SCIPgetExprMonomialData(scip, expr, &((*nlhdlrexprdata)->coef), (*nlhdlrexprdata)->exponents, (*nlhdlrexprdata)->factors) );
992 SCIP_CALL( SCIPregisterExprUsageNonlinear(scip, (*nlhdlrexprdata)->factors[c], TRUE, FALSE, TRUE, TRUE) );
1005 SCIPdebugMsg(scip, "scip depth: %d, step: %d, expr pointer: %p, expr data pointer: %p, detected expr: total vars (exps) %d ",
1006 SCIPgetSubscipDepth(scip), SCIPgetStage(scip), (void *)expr, (void *)nlhdlrexprdata, (*nlhdlrexprdata)->nfactors);
1119 SCIP_CALL( SCIPincludeNlhdlrNonlinear(scip, &nlhdlr, NLHDLR_NAME, NLHDLR_DESC, NLHDLR_DETECTPRIORITY,
constraint handler for nonlinear constraints specified by algebraic expressions
void SCIPestimateRoot(SCIP *scip, SCIP_Real exponent, SCIP_Bool overestimate, SCIP_Real xlb, SCIP_Real xub, SCIP_Real xref, SCIP_Real *constant, SCIP_Real *slope, SCIP_Bool *islocal, SCIP_Bool *success)
Definition: expr_pow.c:3395
power and signed power expression handlers
variable expression handler
SCIP_VAR * SCIPgetExprAuxVarNonlinear(SCIP_EXPR *expr)
Definition: cons_nonlinear.c:14336
SCIP_RETCODE SCIPregisterExprUsageNonlinear(SCIP *scip, SCIP_EXPR *expr, SCIP_Bool useauxvar, SCIP_Bool useactivityforprop, SCIP_Bool useactivityforsepabelow, SCIP_Bool useactivityforsepaabove)
Definition: cons_nonlinear.c:14478
SCIP_RETCODE SCIPcomputeFacetVertexPolyhedralNonlinear(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_Bool overestimate, SCIP_DECL_VERTEXPOLYFUN((*function)), void *fundata, SCIP_Real *xstar, SCIP_Real *box, int nallvars, SCIP_Real targetvalue, SCIP_Bool *success, SCIP_Real *facetcoefs, SCIP_Real *facetconstant)
Definition: cons_nonlinear.c:13590
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:208
SCIP_RETCODE SCIPincludeNlhdlrSignomial(SCIP *scip)
Definition: nlhdlr_signomial.c:1106
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:83
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
SCIP_RETCODE SCIPsetPtrarrayVal(SCIP *scip, SCIP_PTRARRAY *ptrarray, int idx, void *val)
Definition: scip_datastructures.c:574
SCIP_Bool SCIPisExprProduct(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1464
SCIP_RETCODE SCIPgetExprMonomialData(SCIP *scip, SCIP_EXPR *expr, SCIP_Real *coef, SCIP_Real *exponents, SCIP_EXPR **factors)
Definition: scip_expr.c:2623
SCIP_RETCODE SCIPreleaseExpr(SCIP *scip, SCIP_EXPR **expr)
Definition: scip_expr.c:1417
SCIP_RETCODE SCIPprintExpr(SCIP *scip, SCIP_EXPR *expr, FILE *file)
Definition: scip_expr.c:1486
#define SCIPallocClearBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:97
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip_mem.h:111
void SCIPnlhdlrSetCopyHdlr(SCIP_NLHDLR *nlhdlr, SCIP_DECL_NLHDLRCOPYHDLR((*copy)))
Definition: nlhdlr.c:76
void SCIPnlhdlrSetFreeExprData(SCIP_NLHDLR *nlhdlr, SCIP_DECL_NLHDLRFREEEXPRDATA((*freeexprdata)))
Definition: nlhdlr.c:98
void SCIPnlhdlrSetFreeHdlrData(SCIP_NLHDLR *nlhdlr, SCIP_DECL_NLHDLRFREEHDLRDATA((*freehdlrdata)))
Definition: nlhdlr.c:87
void SCIPnlhdlrSetSepa(SCIP_NLHDLR *nlhdlr, SCIP_DECL_NLHDLRINITSEPA((*initsepa)), SCIP_DECL_NLHDLRENFO((*enfo)), SCIP_DECL_NLHDLRESTIMATE((*estimate)), SCIP_DECL_NLHDLREXITSEPA((*exitsepa)))
Definition: nlhdlr.c:136
SCIP_RETCODE SCIPincludeNlhdlrNonlinear(SCIP *scip, SCIP_NLHDLR **nlhdlr, const char *name, const char *desc, int detectpriority, int enfopriority, SCIP_DECL_NLHDLRDETECT((*detect)), SCIP_DECL_NLHDLREVALAUX((*evalaux)), SCIP_NLHDLRDATA *nlhdlrdata)
Definition: cons_nonlinear.c:15245
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1217
SCIP_Bool SCIPisRelEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip_numerics.c:1156
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip_numerics.c:484
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip_numerics.c:445
SCIP_VAR ** SCIProwprepGetVars(SCIP_ROWPREP *rowprep)
Definition: misc_rowprep.c:639
SCIP_RETCODE SCIPensureRowprepSize(SCIP *scip, SCIP_ROWPREP *rowprep, int size)
Definition: misc_rowprep.c:887
SCIP_Real * SCIProwprepGetCoefs(SCIP_ROWPREP *rowprep)
Definition: misc_rowprep.c:649
void SCIProwprepAddConstant(SCIP_ROWPREP *rowprep, SCIP_Real constant)
Definition: misc_rowprep.c:760
SCIP_RETCODE SCIPaddRowprepTerm(SCIP *scip, SCIP_ROWPREP *rowprep, SCIP_VAR *var, SCIP_Real coef)
Definition: misc_rowprep.c:913
SCIP_RETCODE SCIPcreateRowprep(SCIP *scip, SCIP_ROWPREP **rowprep, SCIP_SIDETYPE sidetype, SCIP_Bool local)
Definition: misc_rowprep.c:563
void SCIProwprepAddSide(SCIP_ROWPREP *rowprep, SCIP_Real side)
Definition: misc_rowprep.c:746
void SCIPfreeRowprep(SCIP *scip, SCIP_ROWPREP **rowprep)
Definition: misc_rowprep.c:583
Definition: objbenders.h:44
static SCIP_DECL_NLHDLRESTIMATE(nlhdlrEstimateSignomial)
Definition: nlhdlr_signomial.c:748
static void reformRowprep(SCIP *scip, SCIP_NLHDLREXPRDATA *nlhdlrexprdata, SCIP_ROWPREP *rowprep, SCIP_Real mincutscale, SCIP_Bool *success)
Definition: nlhdlr_signomial.c:231
static SCIP_RETCODE estimateSpecialPower(SCIP *scip, SCIP_NLHDLREXPRDATA *nlhdlrexprdata, SCIP_Bool sign, SCIP_Real multiplier, SCIP_Bool overestimate, SCIP_SOL *sol, SCIP_ROWPREP *rowprep, SCIP_Bool *isspecial, SCIP_Bool *success)
Definition: nlhdlr_signomial.c:404
static SCIP_DECL_NLHDLREVALAUX(nlhdlrEvalauxSignomial)
Definition: nlhdlr_signomial.c:1016
static void checkSignomialBounds(SCIP *scip, SCIP_NLHDLREXPRDATA *nlhdlrexprdata, SCIP_Bool *isboxsignomial)
Definition: nlhdlr_signomial.c:322
static SCIP_DECL_NLHDLRCOPYHDLR(nlhdlrCopyhdlrSignomial)
Definition: nlhdlr_signomial.c:1047
static SCIP_DECL_NLHDLRDETECT(nlhdlrDetectSignomial)
Definition: nlhdlr_signomial.c:885
static SCIP_RETCODE overEstimatePower(SCIP *scip, SCIP_NLHDLREXPRDATA *nlhdlrexprdata, SCIP_Bool sign, SCIP_Real multiplier, SCIP_SOL *sol, SCIP_ROWPREP *rowprep, SCIP_Bool *success)
Definition: nlhdlr_signomial.c:681
static SCIP_RETCODE underEstimatePower(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_NLHDLR *nlhdlr, SCIP_NLHDLREXPRDATA *nlhdlrexprdata, SCIP_Bool sign, SCIP_Real multiplier, SCIP_SOL *sol, SCIP_Real targetvalue, SCIP_ROWPREP *rowprep, SCIP_Bool *success)
Definition: nlhdlr_signomial.c:594
static SCIP_RETCODE storeCaptureVars(SCIP *scip, SCIP_EXPR *expr, SCIP_NLHDLREXPRDATA *nlhdlrexprdata)
Definition: nlhdlr_signomial.c:291
static void freeExprDataMem(SCIP *scip, SCIP_NLHDLREXPRDATA **nlhdlrexprdata, SCIP_Bool ispartial)
Definition: nlhdlr_signomial.c:193
static SCIP_DECL_VERTEXPOLYFUN(nlhdlrExprEvalPower)
Definition: nlhdlr_signomial.c:365
static SCIP_DECL_NLHDLRFREEHDLRDATA(nlhdlrFreehdlrDataSignomial)
Definition: nlhdlr_signomial.c:1060
static SCIP_DECL_NLHDLRFREEEXPRDATA(nlhdlrFreeExprDataSignomial)
Definition: nlhdlr_signomial.c:1071
signomial nonlinear handler
preparation of a linear inequality to become a SCIP_ROW
public functions of nonlinear handlers of nonlinear constraints
static void printSignomial(SCIP *scip, FILE *file, char *linebuffer, int *linecnt, SCIP_EXPR *expr, SCIP_Real coef, SCIP_Bool needsign)
Definition: reader_pip.c:2177
public functions to work with algebraic expressions
Definition: struct_cons.h:127
Definition: struct_expr.h:106
Definition: intervalarith.h:54
Definition: struct_nlhdlr.h:44
Definition: struct_misc.h:287
Definition: struct_sol.h:74
Definition: struct_var.h:208
Definition: struct_scip.h:70
Definition: nlhdlr_convex.c:107
SCIP_NLHDLREXPRDATA * nlhdlrexprdata
Definition: nlhdlr_convex.c:108