1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 2 /* */ 3 /* This file is part of the program and library */ 4 /* SCIP --- Solving Constraint Integer Programs */ 5 /* */ 6 /* Copyright (c) 2002-2023 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_value.c 26 * @ingroup DEFPLUGINS_EXPR 27 * @brief constant value expression handler 28 * @author Stefan Vigerske 29 * @author Benjamin Mueller 30 */ 31 32 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/ 33 34 #include <string.h> 35 36 #include "scip/expr_value.h" 37 38 #define EXPRHDLR_NAME "val" 39 #define EXPRHDLR_DESC "constant value" 40 #define EXPRHDLR_PRECEDENCE 10000 41 #define EXPRHDLR_HASHKEY SCIPcalcFibHash(36787.0) 42 43 /* 44 * Data structures 45 */ 46 47 /** expression data */ 48 struct SCIP_ExprData 49 { 50 SCIP_Real value; /**< value that expression represents */ 51 }; 52 53 /* 54 * Callback methods of expression handler 55 */ 56 57 /** the order of two values is the real order */ 58 static 59 SCIP_DECL_EXPRCOMPARE(compareValue) 60 { /*lint --e{715}*/ 61 SCIP_Real val1; 62 SCIP_Real val2; 63 64 assert(SCIPexprGetData(expr1) != NULL); 65 assert(SCIPexprGetData(expr2) != NULL); 66 67 val1 = SCIPexprGetData(expr1)->value; 68 val2 = SCIPexprGetData(expr2)->value; 69 70 return val1 < val2 ? -1 : val1 == val2 ? 0 : 1; /*lint !e777*/ 71 } 72 73 /** expression handler copy callback */ 74 static 75 SCIP_DECL_EXPRCOPYHDLR(copyhdlrValue) 76 { /*lint --e{715}*/ 77 SCIP_CALL( SCIPincludeExprhdlrValue(scip) ); 78 79 return SCIP_OKAY; 80 } 81 82 /** expression data copy callback */ 83 static 84 SCIP_DECL_EXPRCOPYDATA(copydataValue) 85 { /*lint --e{715}*/ 86 assert(targetexprdata != NULL); 87 assert(sourceexpr != NULL); 88 89 SCIP_CALL( SCIPallocBlockMemory(targetscip, targetexprdata) ); 90 (*targetexprdata)->value = SCIPexprGetData(sourceexpr)->value; 91 92 return SCIP_OKAY; 93 } 94 95 /** expression data free callback */ 96 static 97 SCIP_DECL_EXPRFREEDATA(freedataValue) 98 { /*lint --e{715}*/ 99 SCIP_EXPRDATA* exprdata; 100 101 assert(expr != NULL); 102 103 exprdata = SCIPexprGetData(expr); 104 assert(exprdata != NULL); 105 106 SCIPfreeBlockMemory(scip, &exprdata); 107 SCIPexprSetData(expr, NULL); 108 109 return SCIP_OKAY; 110 } 111 112 /** expression print callback */ 113 static 114 SCIP_DECL_EXPRPRINT(printValue) 115 { /*lint --e{715}*/ 116 assert(expr != NULL); 117 assert(SCIPexprGetData(expr) != NULL); 118 119 if( stage == SCIP_EXPRITER_ENTEREXPR ) 120 { 121 SCIP_Real v = SCIPexprGetData(expr)->value; 122 if( v < 0.0 && EXPRHDLR_PRECEDENCE <= parentprecedence ) 123 { 124 SCIPinfoMessage(scip, file, "(%g)", v); 125 } 126 else 127 { 128 SCIPinfoMessage(scip, file, "%g", v); 129 } 130 } 131 132 return SCIP_OKAY; 133 } 134 135 /** expression point evaluation callback */ 136 static 137 SCIP_DECL_EXPREVAL(evalValue) 138 { /*lint --e{715}*/ 139 assert(expr != NULL); 140 assert(SCIPexprGetData(expr) != NULL); 141 142 *val = SCIPexprGetData(expr)->value; 143 144 return SCIP_OKAY; 145 } 146 147 /** expression backward derivative evaluation callback */ 148 static 149 SCIP_DECL_EXPRBWDIFF(bwdiffValue) 150 { /*lint --e{715}*/ 151 /* should never be called since value expressions do not have children */ 152 return SCIP_INVALIDCALL; 153 } 154 155 /** expression forward derivative evaluation callback */ 156 static 157 SCIP_DECL_EXPRFWDIFF(fwdiffValue) 158 { /*lint --e{715}*/ 159 assert(expr != NULL); 160 161 *dot = 0.0; 162 163 return SCIP_OKAY; 164 } 165 166 /** derivative evaluation callback for Hessian directions (backward over forward) */ 167 static 168 SCIP_DECL_EXPRBWFWDIFF(bwfwdiffValue) 169 { /*lint --e{715}*/ 170 /* should never be called since value expressions do not have children */ 171 return SCIP_INVALIDCALL; 172 } 173 174 /** expression interval evaluation callback */ 175 static 176 SCIP_DECL_EXPRINTEVAL(intevalValue) 177 { /*lint --e{715}*/ 178 assert(expr != NULL); 179 assert(SCIPexprGetData(expr) != NULL); 180 181 SCIPintervalSet(interval, SCIPexprGetData(expr)->value); 182 183 return SCIP_OKAY; 184 } 185 186 /** expression hash callback */ 187 static 188 SCIP_DECL_EXPRHASH(hashValue) 189 { /*lint --e{715}*/ 190 assert(scip != NULL); 191 assert(expr != NULL); 192 assert(SCIPexprGetData(expr) != NULL); 193 assert(SCIPexprGetNChildren(expr) == 0); 194 assert(hashkey != NULL); 195 196 *hashkey = EXPRHDLR_HASHKEY; 197 *hashkey ^= SCIPcalcFibHash(SCIPexprGetData(expr)->value); 198 199 return SCIP_OKAY; 200 } 201 202 /** expression curvature detection callback */ 203 static 204 SCIP_DECL_EXPRCURVATURE(curvatureValue) 205 { /*lint --e{715}*/ 206 assert(scip != NULL); 207 assert(expr != NULL); 208 assert(success != NULL); 209 assert(SCIPexprGetNChildren(expr) == 0); 210 211 *success = TRUE; 212 213 return SCIP_OKAY; 214 } 215 216 /** expression monotonicity detection callback */ 217 static 218 SCIP_DECL_EXPRMONOTONICITY(monotonicityValue) 219 { /*lint --e{715}*/ 220 assert(scip != NULL); 221 assert(expr != NULL); 222 assert(result != NULL); 223 assert(SCIPexprGetNChildren(expr) == 0); 224 225 *result = SCIP_MONOTONE_CONST; 226 227 return SCIP_OKAY; 228 } 229 230 /** expression integrality detection callback */ 231 static 232 SCIP_DECL_EXPRINTEGRALITY(integralityValue) 233 { /*lint --e{715}*/ 234 assert(scip != NULL); 235 assert(expr != NULL); 236 assert(isintegral != NULL); 237 assert(SCIPexprGetData(expr) != NULL); 238 239 *isintegral = EPSISINT(SCIPexprGetData(expr)->value, 0.0); /*lint !e835 !e666*/ 240 241 return SCIP_OKAY; 242 } 243 244 /** creates the handler for constant value expression and includes it into SCIP */ 245 SCIP_RETCODE SCIPincludeExprhdlrValue( 246 SCIP* scip /**< SCIP data structure */ 247 ) 248 { 249 SCIP_EXPRHDLR* exprhdlr; 250 251 SCIP_CALL( SCIPincludeExprhdlr(scip, &exprhdlr, EXPRHDLR_NAME, EXPRHDLR_DESC, EXPRHDLR_PRECEDENCE, 252 evalValue, NULL) ); 253 assert(exprhdlr != NULL); 254 255 SCIPexprhdlrSetCopyFreeHdlr(exprhdlr, copyhdlrValue, NULL); 256 SCIPexprhdlrSetCopyFreeData(exprhdlr, copydataValue, freedataValue); 257 SCIPexprhdlrSetCompare(exprhdlr, compareValue); 258 SCIPexprhdlrSetPrint(exprhdlr, printValue); 259 SCIPexprhdlrSetIntEval(exprhdlr, intevalValue); 260 SCIPexprhdlrSetHash(exprhdlr, hashValue); 261 SCIPexprhdlrSetDiff(exprhdlr, bwdiffValue, fwdiffValue, bwfwdiffValue); 262 SCIPexprhdlrSetCurvature(exprhdlr, curvatureValue); 263 SCIPexprhdlrSetMonotonicity(exprhdlr, monotonicityValue); 264 SCIPexprhdlrSetIntegrality(exprhdlr, integralityValue); 265 266 return SCIP_OKAY; 267 } 268 269 /** creates constant value expression */ 270 SCIP_RETCODE SCIPcreateExprValue( 271 SCIP* scip, /**< SCIP data structure */ 272 SCIP_EXPR** expr, /**< pointer where to store expression */ 273 SCIP_Real value, /**< value to be stored */ 274 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */ 275 void* ownercreatedata /**< data to pass to ownercreate */ 276 ) 277 { 278 SCIP_EXPRDATA* exprdata; 279 280 assert(expr != NULL); 281 assert(SCIPisFinite(value)); 282 283 SCIP_CALL( SCIPallocBlockMemory(scip, &exprdata) ); 284 exprdata->value = value; 285 286 SCIP_CALL( SCIPcreateExpr(scip, expr, SCIPgetExprhdlrValue(scip), exprdata, 0, NULL, ownercreate, ownercreatedata) ); 287 288 return SCIP_OKAY; 289 } 290 291 /* from pub_expr.h */ 292 293 /** gets the value of a constant value expression */ 294 SCIP_Real SCIPgetValueExprValue( 295 SCIP_EXPR* expr /**< sum expression */ 296 ) 297 { 298 assert(expr != NULL); 299 assert(SCIPexprGetData(expr) != NULL); 300 301 return SCIPexprGetData(expr)->value; 302 } 303