Scippy

SCIP

Solving Constraint Integer Programs

scip_expr.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 scip_expr.c
26 * @ingroup OTHER_CFILES
27 * @brief public functions to work with algebraic expressions
28 * @author Ksenia Bestuzheva
29 * @author Benjamin Mueller
30 * @author Felipe Serrano
31 * @author Stefan Vigerske
32 */
33
34#include <string.h>
35#include <ctype.h>
36
37#include "scip/scip_expr.h"
38#include "scip/expr.h"
39#include "scip/set.h"
40#include "scip/misc.h"
41#include "scip/scip_copy.h"
42#include "scip/scip_mem.h"
43#include "scip/scip_message.h"
44#include "scip/scip_prob.h"
45#include "scip/scip_var.h"
46#include "scip/scip_sol.h"
47#include "scip/pub_var.h"
48#include "scip/struct_scip.h"
49#include "scip/struct_mem.h"
50#include "scip/struct_stat.h"
51
52/* core expression handler plugins */
53#include "scip/expr_value.h"
54#include "scip/expr_var.h"
55#include "scip/expr_sum.h"
56#include "scip/expr_product.h"
57#include "scip/expr_pow.h"
58
59/* #define PARSE_DEBUG */
60
61/*lint -e440*/
62/*lint -e441*/
63
64/*
65 * local functions
66 */
67
68/** variable mapping data passed on during copying expressions when copying SCIP instances */
69typedef struct
70{
71 SCIP_HASHMAP* varmap; /**< SCIP_HASHMAP mapping variables of the source SCIP to corresponding
72 variables of the target SCIP */
73 SCIP_HASHMAP* consmap; /**< SCIP_HASHMAP mapping constraints of the source SCIP to corresponding
74 constraints of the target SCIP */
75 SCIP_Bool global; /**< should a global or a local copy be created */
76 SCIP_Bool valid; /**< indicates whether every variable copy was valid */
78
79/** variable expression mapping callback to call when copying expressions (within same or different SCIPs) */
80static
82{
84 SCIP_Bool valid;
85 SCIP_VAR* targetvar;
86
87 assert(sourcescip != NULL);
88 assert(sourceexpr != NULL);
89 assert(targetscip != NULL);
90 assert(targetexpr != NULL);
91 assert(mapexprdata != NULL);
92
93 *targetexpr = NULL;
94
95 if( !SCIPisExprVar(sourcescip, sourceexpr) )
96 return SCIP_OKAY;
97
98 data = (COPY_MAPEXPR_DATA*)mapexprdata;
99
100 SCIP_CALL( SCIPgetVarCopy(sourcescip, targetscip, SCIPgetVarExprVar(sourceexpr), &targetvar, data->varmap,
101 data->consmap, data->global, &valid) );
102 assert(targetvar != NULL);
103
104 /* if copy was not valid, store so in mapvar data */
105 if( !valid )
106 data->valid = FALSE;
107
108 SCIP_CALL( SCIPcreateExprVar(targetscip, targetexpr, targetvar, ownercreate, ownercreatedata) );
109
110 return SCIP_OKAY;
111}
112
113
114/** @name Parsing methods (internal)
115 * @{
116 * Here is an attempt at defining the grammar of an expression.
117 * We use upper case names for variables (in the grammar sense) and terminals are between "".
118 * Loosely speaking, a Base will be any "block", a Factor is a Base to a power, a Term is a product of Factors
119 * and an Expression is a sum of terms.
120 * The actual definition:
121 * <pre>
122 * Expression -> ["+" | "-"] Term { ("+" | "-" | "number *") ] Term }
123 * Term -> Factor { ("*" | "/" ) Factor }
124 * Factor -> Base [ "^" "number" | "^(" "number" ")" ]
125 * Base -> "number" | "<varname>" | "(" Expression ")" | Op "(" OpExpression ")
126 * </pre>
127 * where [a|b] means a or b or none, (a|b) means a or b, {a} means 0 or more a.
128 *
129 * Note that Op and OpExpression are undefined. Op corresponds to the name of an expression handler and
130 * OpExpression to whatever string the expression handler accepts (through its parse method).
131 *
132 * parse(Expr|Term|Base) returns an SCIP_EXPR
133 *
134 * @todo We can change the grammar so that Factor becomes base and we allow a Term to be
135 * <pre> Term -> Factor { ("*" | "/" | "^") Factor } </pre>
136 */
137
138/*lint -emacro(681,debugParse) */
139/*lint -emacro(506,debugParse) */
140/*lint -emacro(774,debugParse) */
141#ifdef PARSE_DEBUG
142#define debugParse printf
143#else
144#define debugParse while( FALSE ) printf
145#endif
146
147/* forward declaration */
148static
150 SCIP* scip, /**< SCIP data structure */
151 SCIP_HASHMAP* vartoexprvarmap, /**< hashmap to map between scip vars and var expressions */
152 const char* expr, /**< expr that we are parsing */
153 const char** newpos, /**< buffer to store the position of expr where we finished reading */
154 SCIP_EXPR** exprtree, /**< buffer to store the expr parsed by Expr */
155 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
156 void* ownercreatedata /**< data to pass to ownercreate */
157 );
158
159/** Parses base to build a value, variable, sum, or function-like ("func(...)") expression.
160 * <pre>
161 * Base -> "number" | "<varname>" | "(" Expression ")" | Op "(" OpExpression ")
162 * </pre>
163 */
164static
166 SCIP* scip, /**< SCIP data structure */
167 SCIP_HASHMAP* vartoexprvarmap, /**< hashmap to map between SCIP vars and var expressions */
168 const char* expr, /**< expr that we are parsing */
169 const char** newpos, /**< buffer to store the position of expr where we finished reading */
170 SCIP_EXPR** basetree, /**< buffer to store the expr parsed by Base */
171 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
172 void* ownercreatedata /**< data to pass to ownercreate */
173 )
174{
175 debugParse("parsing base from %s\n", expr);
176
177 /* ignore whitespace */
178 SCIP_CALL( SCIPskipSpace((char**)&expr) );
179
180 if( *expr == '\0' )
181 {
182 SCIPerrorMessage("Unexpected end of expression string\n");
183 return SCIP_READERROR;
184 }
185
186 if( *expr == '<' )
187 {
188 /* parse a variable */
189 SCIP_VAR* var;
190
191 SCIP_CALL( SCIPparseVarName(scip, expr, &var, (char**)newpos) );
192
193 if( var == NULL )
194 {
195 SCIPerrorMessage("Could not find variable with name '%s'\n", expr);
196 return SCIP_READERROR;
197 }
198
199 expr = *newpos;
200
201 /* check if we have already created an expression out of this var */
202 if( SCIPhashmapExists(vartoexprvarmap, (void*)var) )
203 {
204 debugParse("Variable <%s> has already been parsed, capturing its expression\n", SCIPvarGetName(var));
205 *basetree = (SCIP_EXPR*)SCIPhashmapGetImage(vartoexprvarmap, (void*)var);
206 SCIPexprCapture(*basetree);
207 }
208 else
209 {
210 debugParse("First time parsing variable <%s>, creating varexpr and adding it to hashmap\n", SCIPvarGetName(var));
211 /* intentionally not using createExprVar here, since parsed expressions are not part of a constraint
212 * (they will be copied when a constraint is created)
213 */
214 SCIP_CALL( SCIPcreateExprVar(scip, basetree, var, ownercreate, ownercreatedata) );
215 SCIP_CALL( SCIPhashmapInsert(vartoexprvarmap, (void*)var, (void*)(*basetree)) );
216 }
217 }
218 else if( *expr == '(' )
219 {
220 /* parse expression */
221 SCIP_CALL( parseExpr(scip, vartoexprvarmap, ++expr, newpos, basetree, ownercreate, ownercreatedata) );
222 expr = *newpos;
223
224 /* expect ')' */
225 if( *expr != ')' )
226 {
227 SCIPerrorMessage("Read a '(', parsed expression inside --> expecting closing ')'. Got <%c>: rest of string <%s>\n", *expr, expr);
228 SCIP_CALL( SCIPreleaseExpr(scip, basetree) );
229 return SCIP_READERROR;
230 }
231 ++expr;
232 debugParse("Done parsing expression, continue with <%s>\n", expr);
233 }
234 else if( isdigit((unsigned char)*expr) )
235 {
236 /* parse number */
237 SCIP_Real value;
238 if( !SCIPstrToRealValue(expr, &value, (char**)&expr) )
239 {
240 SCIPerrorMessage("error parsing number from <%s>\n", expr);
241 return SCIP_READERROR;
242 }
243 debugParse("Parsed value %g, creating a value-expression.\n", value);
244 if( !SCIPisFinite(value) || SCIPisInfinity(scip, value) )
245 {
246 SCIPerrorMessage("Infinite or nan term value expression within nonlinear expression %s\n", expr);
247 return SCIP_INVALIDDATA;
248 }
249 SCIP_CALL( SCIPcreateExprValue(scip, basetree, value, ownercreate, ownercreatedata) );
250 }
251 else if( isalpha((unsigned char)*expr) )
252 {
253 /* a (function) name is coming, should find exprhandler with such name */
254 int i;
255 char operatorname[SCIP_MAXSTRLEN];
256 SCIP_EXPRHDLR* exprhdlr;
257 SCIP_Bool success;
258
259 /* get name */
260 i = 0;
261 while( *expr != '(' && *expr != '\0' && !isspace((unsigned char)*expr)
262 && !( *expr == '\\' && *(expr+1) != '\0' && strchr(SCIP_SPACECONTROL, *(expr+1)) ) )
263 {
264 operatorname[i] = *expr;
265 ++expr;
266 ++i;
267 }
268 operatorname[i] = '\0';
269
270 /* after name we must see a '(' */
271 if( *expr != '(' )
272 {
273 SCIPerrorMessage("Expected '(' after operator name <%s>, but got %s.\n", operatorname, expr);
274 return SCIP_READERROR;
275 }
276
277 /* search for expression handler */
278 exprhdlr = SCIPfindExprhdlr(scip, operatorname);
279
280 /* check expression handler exists and has a parsing method */
281 if( exprhdlr == NULL )
282 {
283 SCIPerrorMessage("No expression handler with name <%s> found.\n", operatorname);
284 return SCIP_READERROR;
285 }
286
287 ++expr;
288 SCIP_CALL( SCIPexprhdlrParseExpr(exprhdlr, scip->set, expr, newpos, basetree, &success, ownercreate, ownercreatedata) );
289
290 if( !success )
291 {
292 SCIPerrorMessage("Error while expression handler <%s> was parsing %s\n", operatorname, expr);
293 assert(*basetree == NULL);
294 return SCIP_READERROR;
295 }
296 expr = *newpos;
297
298 /* we should see the ')' of Op "(" OpExpression ") */
299 assert(*expr == ')');
300
301 /* move one character forward */
302 ++expr;
303 }
304 else
305 {
306 /* Base -> "number" | "<varname>" | "(" Expression ")" | Op "(" OpExpression ") */
307 SCIPerrorMessage("Expected a number, (expression), <varname>, Opname(Opexpr), instead got <%c> from %s\n", *expr, expr);
308 return SCIP_READERROR;
309 }
310
311 *newpos = expr;
312
313 return SCIP_OKAY;
314}
315
316/** Parses a factor and builds a product-expression if there is an exponent, otherwise returns the base expression.
317 * <pre>
318 * Factor -> Base [ "^" "number" | "^(" "number" ")" ]
319 * </pre>
320 */
321static
323 SCIP* scip, /**< SCIP data structure */
324 SCIP_Bool isdenominator, /**< whether factor is in the denominator */
325 SCIP_HASHMAP* vartoexprvarmap, /**< hashmap to map between scip vars and var expressions */
326 const char* expr, /**< expr that we are parsing */
327 const char** newpos, /**< buffer to store the position of expr where we finished reading */
328 SCIP_EXPR** factortree, /**< buffer to store the expr parsed by Factor */
329 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
330 void* ownercreatedata /**< data to pass to ownercreate */
331 )
332{
333 SCIP_EXPR* basetree;
334 SCIP_Real exponent;
335
336 debugParse("parsing factor from %s\n", expr);
337
338 if( *expr == '\0' )
339 {
340 SCIPerrorMessage("Unexpected end of expression string.\n");
341 return SCIP_READERROR;
342 }
343
344 /* parse Base */
345 /* ignore whitespace */
346 SCIP_CALL( SCIPskipSpace((char**)&expr) );
347
348 SCIP_CALL( parseBase(scip, vartoexprvarmap, expr, newpos, &basetree, ownercreate, ownercreatedata) );
349 expr = *newpos;
350
351 /* check if there is an exponent */
352 /* ignore whitespace */
353 SCIP_CALL( SCIPskipSpace((char**)&expr) );
354
355 if( *expr == '^' )
356 {
357 ++expr;
358 SCIP_CALL( SCIPskipSpace((char**)&expr) );
359
360 if( *expr == '\0' )
361 {
362 SCIPerrorMessage("Unexpected end of expression string after '^'.\n");
363 SCIP_CALL( SCIPreleaseExpr(scip, &basetree) );
364 return SCIP_READERROR;
365 }
366
367 if( *expr == '(' )
368 {
369 ++expr;
370
371 /* it is exponent with parenthesis; expect number possibly starting with + or - */
372 if( !SCIPstrToRealValue(expr, &exponent, (char**)&expr) )
373 {
374 SCIPerrorMessage("error parsing number from <%s>\n", expr);
375 SCIP_CALL( SCIPreleaseExpr(scip, &basetree) );
376 return SCIP_READERROR;
377 }
378
379 /* expect the ')' */
380 SCIP_CALL( SCIPskipSpace((char**)&expr) );
381 if( *expr != ')' )
382 {
383 SCIPerrorMessage("error in parsing exponent: expected ')', received <%c> from <%s>\n", *expr, expr);
384 SCIP_CALL( SCIPreleaseExpr(scip, &basetree) );
385 return SCIP_READERROR;
386 }
387 ++expr;
388 }
389 else
390 {
391 /* no parenthesis, we should see just a positive number */
392
393 /* expect a digit */
394 if( isdigit((unsigned char)*expr) )
395 {
396 if( !SCIPstrToRealValue(expr, &exponent, (char**)&expr) )
397 {
398 SCIPerrorMessage("error parsing number from <%s>\n", expr);
399 SCIP_CALL( SCIPreleaseExpr(scip, &basetree) );
400 return SCIP_READERROR;
401 }
402 }
403 else
404 {
405 SCIPerrorMessage("error in parsing exponent, expected a digit, received <%c> from <%s>\n", *expr, expr);
406 SCIP_CALL( SCIPreleaseExpr(scip, &basetree) );
407 return SCIP_READERROR;
408 }
409 }
410
411 if( !SCIPisFinite(exponent) || SCIPisInfinity(scip, exponent) )
412 {
413 SCIPerrorMessage("Infinite or nan term exponent in nonlinear expression %s\n", expr);
414 SCIP_CALL( SCIPreleaseExpr(scip, &basetree) );
415 return SCIP_INVALIDDATA;
416 }
417
418 debugParse("parsed the exponent %g\n", exponent); /*lint !e506 !e681*/
419 }
420 else
421 {
422 /* there is no explicit exponent */
423 exponent = 1.0;
424 }
425 *newpos = expr;
426
427 /* multiply with -1 when we are in the denominator */
428 if( isdenominator )
429 exponent *= -1.0;
430
431 /* create power */
432 if( exponent != 1.0 )
433 {
434 SCIP_CALL( SCIPcreateExprPow(scip, factortree, basetree, exponent, ownercreate, ownercreatedata) );
435 SCIP_CALL( SCIPreleaseExpr(scip, &basetree) );
436 }
437 else
438 /* Factor consists of this unique Base */
439 *factortree = basetree;
440
441 return SCIP_OKAY;
442}
443
444/** Parses a term and builds a product-expression, where each factor is a child.
445 * <pre>
446 * Term -> Factor { ("*" | "/" ) Factor }
447 * </pre>
448 */
449static
451 SCIP* scip, /**< SCIP data structure */
452 SCIP_HASHMAP* vartoexprvarmap, /**< hashmap to map between scip vars and var expressions */
453 const char* expr, /**< expr that we are parsing */
454 const char** newpos, /**< buffer to store the position of expr where we finished reading */
455 SCIP_EXPR** termtree, /**< buffer to store the expr parsed by Term */
456 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
457 void* ownercreatedata /**< data to pass to ownercreate */
458 )
459{
460 SCIP_EXPR* factortree;
461
462 debugParse("parsing term from %s\n", expr);
463
464 /* parse Factor */
465 /* ignore whitespace */
466 SCIP_CALL( SCIPskipSpace((char**)&expr) );
467
468 SCIP_CALL( parseFactor(scip, FALSE, vartoexprvarmap, expr, newpos, &factortree, ownercreate, ownercreatedata) );
469 expr = *newpos;
470
471 debugParse("back to parsing Term, continue parsing from %s\n", expr);
472
473 /* check if Terms has another Factor incoming */
474 SCIP_CALL( SCIPskipSpace((char**)&expr) );
475 if( *expr == '*' || *expr == '/' )
476 {
477 /* initialize termtree as a product expression with a single term, so we can append the extra Factors */
478 SCIP_CALL( SCIPcreateExprProduct(scip, termtree, 1, &factortree, 1.0, ownercreate, ownercreatedata) );
479 SCIP_CALL( SCIPreleaseExpr(scip, &factortree) );
480
481 /* loop: parse Factor, find next symbol */
482 do
483 {
484 SCIP_RETCODE retcode;
485 SCIP_Bool isdivision;
486
487 isdivision = (*expr == '/') ? TRUE : FALSE;
488
489 debugParse("while parsing term, read char %c\n", *expr); /*lint !e506 !e681*/
490
491 ++expr;
492 retcode = parseFactor(scip, isdivision, vartoexprvarmap, expr, newpos, &factortree, ownercreate, ownercreatedata);
493
494 /* release termtree, if parseFactor fails with a read-error */
495 if( retcode == SCIP_READERROR )
496 {
497 SCIP_CALL( SCIPreleaseExpr(scip, termtree) );
498 }
499 SCIP_CALL( retcode );
500
501 /* append newly created factor */
502 SCIP_CALL( SCIPappendExprChild(scip, *termtree, factortree) );
503 SCIP_CALL( SCIPreleaseExpr(scip, &factortree) );
504
505 /* find next symbol */
506 expr = *newpos;
507 SCIP_CALL( SCIPskipSpace((char**)&expr) );
508 }
509 while( *expr == '*' || *expr == '/' );
510 }
511 else
512 {
513 /* Term consists of this unique factor */
514 *termtree = factortree;
515 }
516
517 *newpos = expr;
518
519 return SCIP_OKAY;
520}
521
522/** parses an expression and builds a sum-expression with children
523 *
524 * <pre>
525 * Expression -> ["+" | "-"] Term { ("+" | "-" | "number *") ] Term }
526 * </pre>
527 */
528static
530 SCIP* scip, /**< SCIP data structure */
531 SCIP_HASHMAP* vartoexprvarmap, /**< hashmap to map between scip vars and var expressions */
532 const char* expr, /**< expr that we are parsing */
533 const char** newpos, /**< buffer to store the position of expr where we finished reading */
534 SCIP_EXPR** exprtree, /**< buffer to store the expr parsed by Expr */
535 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
536 void* ownercreatedata /**< data to pass to ownercreate */
537 )
538{
539 SCIP_Real sign;
540 SCIP_EXPR* termtree;
541
542 debugParse("parsing expression %s\n", expr); /*lint !e506 !e681*/
543
544 /* ignore whitespace */
545 SCIP_CALL( SCIPskipSpace((char**)&expr) );
546
547 /* if '+' or '-', store it */
548 sign = 1.0;
549 if( *expr == '+' || *expr == '-' )
550 {
551 debugParse("while parsing expression, read char %c\n", *expr); /*lint !e506 !e681*/
552 sign = *expr == '+' ? 1.0 : -1.0;
553 ++expr;
554 }
555
556 SCIP_CALL( parseTerm(scip, vartoexprvarmap, expr, newpos, &termtree, ownercreate, ownercreatedata) );
557 expr = *newpos;
558
559 debugParse("back to parsing expression (we have the following term), continue parsing from %s\n", expr); /*lint !e506 !e681*/
560
561 /* check if Expr has another Term incoming */
562 SCIP_CALL( SCIPskipSpace((char**)&expr) );
563 if( *expr == '+' || *expr == '-' )
564 {
565 if( SCIPexprIsValue(scip->set, termtree) )
566 {
567 /* initialize exprtree as a sum expression with a constant only, so we can append the following terms */
568 SCIP_CALL( SCIPcreateExprSum(scip, exprtree, 0, NULL, NULL, sign * SCIPgetValueExprValue(termtree), ownercreate, ownercreatedata) );
569 SCIP_CALL( SCIPreleaseExpr(scip, &termtree) );
570 }
571 else
572 {
573 /* initialize exprtree as a sum expression with a single term, so we can append the following terms */
574 SCIP_CALL( SCIPcreateExprSum(scip, exprtree, 1, &termtree, &sign, 0.0, ownercreate, ownercreatedata) );
575 SCIP_CALL( SCIPreleaseExpr(scip, &termtree) );
576 }
577
578 /* loop: parse Term, find next symbol */
579 do
580 {
581 SCIP_RETCODE retcode;
582 SCIP_Real coef;
583
584 /* check if we have a "coef * <term>" */
585 if( SCIPstrToRealValue(expr, &coef, (char**)newpos) )
586 {
587 if( !SCIPisFinite(coef) || SCIPisInfinity(scip, coef) )
588 {
589 SCIPerrorMessage("Infinite or nan term coefficient in nonlinear expression %s\n", expr);
590 SCIP_CALL( SCIPreleaseExpr(scip, exprtree) );
591 return SCIP_INVALIDDATA;
592 }
593
594 SCIP_CALL( SCIPskipSpace((char**)newpos) );
595
596 if( **newpos == '<' )
597 {
598 /* found variable name ('*' is considered optional);
599 * keep coefficient in coef and continue parsing term after coefficient
600 */
601 expr = *newpos;
602
603 SCIP_CALL( SCIPskipSpace((char**)&expr) );
604 }
605 else if( **newpos == '*' )
606 {
607 /* keep coefficient in coef and continue parsing term after coefficient */
608 expr = (*newpos)+1;
609
610 SCIP_CALL( SCIPskipSpace((char**)&expr) );
611 }
612 else
613 {
614 /* term consists of single value; let parseTerm() below parse it */
615 coef = (*expr == '+') ? 1.0 : -1.0;
616 ++expr;
617 }
618 }
619 else
620 {
621 coef = (*expr == '+') ? 1.0 : -1.0;
622 ++expr;
623 }
624
625 debugParse("while parsing expression, read coefficient %g\n", coef); /*lint !e506 !e681*/
626
627 retcode = parseTerm(scip, vartoexprvarmap, expr, newpos, &termtree, ownercreate, ownercreatedata);
628
629 /* release exprtree if parseTerm fails with an read-error */
630 if( retcode == SCIP_READERROR )
631 {
632 SCIP_CALL( SCIPreleaseExpr(scip, exprtree) );
633 }
634 SCIP_CALL( retcode );
635
636 /* append newly created term */
637 SCIP_CALL( SCIPappendExprSumExpr(scip, *exprtree, termtree, coef) );
638 SCIP_CALL( SCIPreleaseExpr(scip, &termtree) );
639
640 /* find next symbol */
641 expr = *newpos;
642 SCIP_CALL( SCIPskipSpace((char**)&expr) );
643 } while( *expr == '+' || *expr == '-' );
644 }
645 else
646 {
647 /* Expr consists of this unique ['+' | '-'] Term */
648 if( sign < 0.0 )
649 {
650 assert(sign == -1.0);
651 SCIP_CALL( SCIPcreateExprSum(scip, exprtree, 1, &termtree, &sign, 0.0, ownercreate, ownercreatedata) );
652 SCIP_CALL( SCIPreleaseExpr(scip, &termtree) );
653 }
654 else
655 *exprtree = termtree;
656 }
657
658 *newpos = expr;
659
660 return SCIP_OKAY;
661}
662
663/** @} */ /* end of parsing methods */
664
665/** @name Simplify methods (internal)
666 * @{
667 */
668
669/** returns an equivalent expression for a given expression if possible
670 *
671 * it adds the expression to key2expr if the map does not contain the key
672 */
673static
675 SCIP_SET* set, /**< global SCIP settings */
676 SCIP_EXPR* expr, /**< expression to replace */
677 SCIP_MULTIHASH* key2expr, /**< mapping of hashes to expressions */
678 SCIP_EXPR** newexpr /**< pointer to store an equivalent expression (NULL if there is none) */
679 )
680{ /*lint --e{438}*/
681 SCIP_MULTIHASHLIST* multihashlist;
682
683 assert(set != NULL);
684 assert(expr != NULL);
685 assert(key2expr != NULL);
686 assert(newexpr != NULL);
687
688 *newexpr = NULL;
689 multihashlist = NULL;
690 do
691 {
692 /* search for an equivalent expression */
693 *newexpr = (SCIP_EXPR*)(SCIPmultihashRetrieveNext(key2expr, &multihashlist, (void*)expr));
694
695 if( *newexpr == NULL )
696 {
697 /* processed all expressions like expr from hash table, so insert expr */
698 SCIP_CALL( SCIPmultihashInsert(key2expr, (void*) expr) );
699 break;
700 }
701 else if( expr != *newexpr )
702 {
703 assert(SCIPexprCompare(set, expr, *newexpr) == 0);
704 break;
705 }
706 else
707 {
708 /* can not replace expr since it is already contained in the hashtablelist */
709 assert(expr == *newexpr);
710 *newexpr = NULL;
711 break;
712 }
713 }
714 while( TRUE ); /*lint !e506*/
715
716 return SCIP_OKAY;
717}
718
719/** userdata for multihash for common subexpression */
720typedef struct
721{
725
726/** get key of hash element */
727static
728SCIP_DECL_HASHGETKEY(hashCommonSubexprGetKey)
729{
730 return elem;
731} /*lint !e715*/
732
733/** checks if two expressions are structurally the same */
734static
735SCIP_DECL_HASHKEYEQ(hashCommonSubexprEq)
736{
738 SCIP_EXPR* expr1;
739 SCIP_EXPR* expr2;
740
741 data = (COMMONSUBEXPR_HASH_DATA*)userptr;
742 assert(data != NULL);
743
744 expr1 = (SCIP_EXPR*)key1;
745 expr2 = (SCIP_EXPR*)key2;
746 assert(expr1 != NULL);
747 assert(expr2 != NULL);
748
749 return expr1 == expr2 || SCIPexprCompare(data->set, expr1, expr2) == 0;
750} /*lint !e715*/
751
752/** get value of hash element when comparing with another expression */
753static
754SCIP_DECL_HASHKEYVAL(hashCommonSubexprKeyval)
755{
757 SCIP_EXPR* expr;
758
759 expr = (SCIP_EXPR*) key;
760 assert(expr != NULL);
761
762 data = (COMMONSUBEXPR_HASH_DATA*) userptr;
763 assert(data != NULL);
764
766} /*lint !e715*/
767
768/** hashes an expression using an already existing iterator
769 *
770 * The iterator must by of type DFS with allowrevisit=FALSE and only the leaveexpr stage enabled.
771 * The hashes of all visited expressions will be stored in the iterators expression data.
772 */
773static
775 SCIP_SET* set, /**< global SCIP settings */
776 BMS_BUFMEM* bufmem, /**< buffer memory */
777 SCIP_EXPR* expr, /**< expression to hash */
778 SCIP_EXPRITER* hashiterator, /**< iterator to use for hashing */
779 int* nvisitedexprs /**< counter to increment by the number of expressions visited, or NULL */
780 )
781{
782 SCIP_EXPRITER_USERDATA iterdata;
783 unsigned int* childrenhashes;
784 int childrenhashessize;
785 int i;
786
787 assert(set != NULL);
788 assert(expr != NULL);
789 assert(hashiterator != NULL);
790
791 childrenhashessize = 5;
792 SCIP_ALLOC( BMSallocBufferMemoryArray(bufmem, &childrenhashes, childrenhashessize) );
793
794 for( expr = SCIPexpriterRestartDFS(hashiterator, expr); !SCIPexpriterIsEnd(hashiterator); expr = SCIPexpriterGetNext(hashiterator) ) /*lint !e441*/
795 {
796 assert(SCIPexpriterGetStageDFS(hashiterator) == SCIP_EXPRITER_LEAVEEXPR);
797
798 if( nvisitedexprs != NULL )
799 ++*nvisitedexprs;
800
801 /* collect hashes of children */
802 if( childrenhashessize < SCIPexprGetNChildren(expr) )
803 {
804 childrenhashessize = SCIPsetCalcMemGrowSize(set, SCIPexprGetNChildren(expr));
805 SCIP_ALLOC( BMSreallocBufferMemoryArray(bufmem, &childrenhashes, childrenhashessize) );
806 }
807 for( i = 0; i < SCIPexprGetNChildren(expr); ++i )
808 childrenhashes[i] = SCIPexpriterGetExprUserData(hashiterator, SCIPexprGetChildren(expr)[i]).uintval;
809
810 SCIP_CALL( SCIPexprhdlrHashExpr(SCIPexprGetHdlr(expr), set, expr, &iterdata.uintval, childrenhashes) );
811
812 SCIPexpriterSetCurrentUserData(hashiterator, iterdata);
813 }
814
815 BMSfreeBufferMemoryArray(bufmem, &childrenhashes);
816
817 return SCIP_OKAY;
818}
819
820/** @} */ /* end of simplify methods */
821
822/*
823 * public functions
824 */
825
826/**@addtogroup PublicExprHandlerMethods
827 * @{
828 */
829
830#ifdef NDEBUG
831#undef SCIPgetExprhdlrs
832#undef SCIPgetNExprhdlrs
833#undef SCIPfindExprhdlr
834#undef SCIPgetExprhdlrVar
835#undef SCIPgetExprhdlrValue
836#undef SCIPgetExprhdlrSum
837#undef SCIPgetExprhdlrProduct
838#undef SCIPgetExprhdlrPower
839#endif
840
841/** creates the handler for an expression handler and includes it into SCIP
842 *
843 * @pre This method can be called if SCIP is in one of the following stages:
844 * - \ref SCIP_STAGE_INIT
845 * - \ref SCIP_STAGE_PROBLEM
846 */
848 SCIP* scip, /**< SCIP data structure */
849 SCIP_EXPRHDLR** exprhdlr, /**< buffer where to store created expression handler */
850 const char* name, /**< name of expression handler (must not be NULL) */
851 const char* desc, /**< description of expression handler (can be NULL) */
852 unsigned int precedence, /**< precedence of expression operation (used for printing) */
853 SCIP_DECL_EXPREVAL((*eval)), /**< point evaluation callback (must not be NULL) */
854 SCIP_EXPRHDLRDATA* data /**< data of expression handler (can be NULL) */
855 )
856{
857 assert(scip != NULL);
858 assert(scip->mem != NULL);
859 assert(exprhdlr != NULL);
860
862
863 SCIP_CALL( SCIPexprhdlrCreate(scip->mem->setmem, exprhdlr, name, desc, precedence, eval, data) );
864 assert(*exprhdlr != NULL);
865
866 SCIP_CALL( SCIPsetIncludeExprhdlr(scip->set, *exprhdlr) );
867
868 return SCIP_OKAY;
869}
870
871/** gives expression handlers */
873 SCIP* scip /**< SCIP data structure */
874 )
875{
876 assert(scip != NULL);
877 assert(scip->set != NULL);
878
879 return scip->set->exprhdlrs;
880}
881
882/** gives number of expression handlers */
884 SCIP* scip /**< SCIP data structure */
885 )
886{
887 assert(scip != NULL);
888 assert(scip->set != NULL);
889
890 return scip->set->nexprhdlrs;
891}
892
893/** returns an expression handler of a given name (or NULL if not found) */
895 SCIP* scip, /**< SCIP data structure */
896 const char* name /**< name of expression handler */
897 )
898{
899 assert(scip != NULL);
900 assert(scip->set != NULL);
901
902 return SCIPsetFindExprhdlr(scip->set, name);
903}
904
905/** returns expression handler for variable expressions (or NULL if not included) */
907 SCIP* scip /**< SCIP data structure */
908 )
909{
910 assert(scip != NULL);
911 assert(scip->set != NULL);
912
913 return scip->set->exprhdlrvar;
914}
915
916/** returns expression handler for constant value expressions (or NULL if not included) */
918 SCIP* scip /**< SCIP data structure */
919 )
920{
921 assert(scip != NULL);
922 assert(scip->set != NULL);
923
924 return scip->set->exprhdlrval;
925}
926
927/** returns expression handler for sum expressions (or NULL if not included) */
929 SCIP* scip /**< SCIP data structure */
930 )
931{
932 assert(scip != NULL);
933 assert(scip->set != NULL);
934
935 return scip->set->exprhdlrsum;
936}
937
938/** returns expression handler for product expressions (or NULL if not included) */
940 SCIP* scip /**< SCIP data structure */
941 )
942{
943 assert(scip != NULL);
944 assert(scip->set != NULL);
945
946 return scip->set->exprhdlrproduct;
947}
948
949/** returns expression handler for power expressions (or NULL if not included) */
951 SCIP* scip /**< SCIP data structure */
952 )
953{
954 assert(scip != NULL);
955 assert(scip->set != NULL);
956
957 return scip->set->exprhdlrpow;
958}
959
960/**@} */
961
962
963/**@name Expression Methods */
964/**@{ */
965
966#ifdef NDEBUG
967#undef SCIPappendExprChild
968#undef SCIPreplaceExprChild
969#undef SCIPremoveExprChildren
970#undef SCIPduplicateExpr
971#undef SCIPduplicateExprShallow
972#undef SCIPcaptureExpr
973#undef SCIPreleaseExpr
974#undef SCIPisExprVar
975#undef SCIPisExprValue
976#undef SCIPisExprSum
977#undef SCIPisExprProduct
978#undef SCIPisExprPower
979#undef SCIPprintExpr
980#undef SCIPevalExpr
981#undef SCIPgetExprNewSoltag
982#undef SCIPevalExprGradient
983#undef SCIPevalExprHessianDir
984#undef SCIPevalExprActivity
985#undef SCIPcompareExpr
986#undef SCIPsimplifyExpr
987#undef SCIPcallExprCurvature
988#undef SCIPcallExprMonotonicity
989#undef SCIPcallExprEval
990#undef SCIPcallExprEvalFwdiff
991#undef SCIPcallExprInteval
992#undef SCIPcallExprEstimate
993#undef SCIPcallExprInitestimates
994#undef SCIPcallExprSimplify
995#undef SCIPcallExprReverseprop
996#undef SCIPcallExprGetSymData
997#endif
998
999/** creates and captures an expression with given expression data and children */
1001 SCIP* scip, /**< SCIP data structure */
1002 SCIP_EXPR** expr, /**< pointer where to store expression */
1003 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1004 SCIP_EXPRDATA* exprdata, /**< expression data (expression assumes ownership) */
1005 int nchildren, /**< number of children */
1006 SCIP_EXPR** children, /**< children (can be NULL if nchildren is 0) */
1007 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
1008 void* ownercreatedata /**< data to pass to ownercreate */
1009 )
1010{
1011 assert(scip != NULL);
1012 assert(scip->set != NULL);
1013
1014 SCIP_CALL( SCIPexprCreate(scip->set, scip->mem->probmem, expr, exprhdlr, exprdata, nchildren, children, ownercreate,
1015 ownercreatedata) );
1016
1017 return SCIP_OKAY;
1018}
1019
1020/** creates and captures an expression with given expression data and up to two children */
1022 SCIP* scip, /**< SCIP data structure */
1023 SCIP_EXPR** expr, /**< pointer where to store expression */
1024 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1025 SCIP_EXPRDATA* exprdata, /**< expression data */
1026 SCIP_EXPR* child1, /**< first child (can be NULL) */
1027 SCIP_EXPR* child2, /**< second child (can be NULL) */
1028 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
1029 void* ownercreatedata /**< data to pass to ownercreate */
1030 )
1031{
1032 assert(scip != NULL);
1033 assert(expr != NULL);
1034 assert(exprhdlr != NULL);
1035
1036 if( child1 != NULL && child2 != NULL )
1037 {
1038 SCIP_EXPR* pair[2];
1039 pair[0] = child1;
1040 pair[1] = child2;
1041
1042 SCIP_CALL( SCIPcreateExpr(scip, expr, exprhdlr, exprdata, 2, pair, ownercreate, ownercreatedata) );
1043 }
1044 else if( child2 == NULL )
1045 {
1046 SCIP_CALL( SCIPcreateExpr(scip, expr, exprhdlr, exprdata, child1 == NULL ? 0 : 1, &child1, ownercreate,
1047 ownercreatedata) );
1048 }
1049 else
1050 {
1051 /* child2 != NULL, child1 == NULL */
1052 SCIP_CALL( SCIPcreateExpr(scip, expr, exprhdlr, exprdata, 1, &child2, ownercreate, ownercreatedata) );
1053 }
1054
1055 return SCIP_OKAY;
1056}
1057
1058/** creates and captures an expression representing a quadratic function */
1060 SCIP* scip, /**< SCIP data structure */
1061 SCIP_EXPR** expr, /**< pointer where to store expression */
1062 int nlinvars, /**< number of linear terms */
1063 SCIP_VAR** linvars, /**< array with variables in linear part */
1064 SCIP_Real* lincoefs, /**< array with coefficients of variables in linear part */
1065 int nquadterms, /**< number of quadratic terms */
1066 SCIP_VAR** quadvars1, /**< array with first variables in quadratic terms */
1067 SCIP_VAR** quadvars2, /**< array with second variables in quadratic terms */
1068 SCIP_Real* quadcoefs, /**< array with coefficients of quadratic terms */
1069 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
1070 void* ownercreatedata /**< data to pass to ownercreate */
1071 )
1072{
1073 SCIP_EXPR** children;
1074 SCIP_Real* coefs;
1075 int i;
1076
1077 assert(scip != NULL);
1078 assert(expr != NULL);
1079 assert(nlinvars == 0 || (linvars != NULL && lincoefs != NULL));
1080 assert(nquadterms == 0 || (quadvars1 != NULL && quadvars2 != NULL && quadcoefs != NULL));
1081
1082 /* allocate memory */
1083 SCIP_CALL( SCIPallocBufferArray(scip, &children, nquadterms + nlinvars) );
1084 SCIP_CALL( SCIPallocBufferArray(scip, &coefs, nquadterms + nlinvars) );
1085
1086 /* create children for quadratic terms */
1087 for( i = 0; i < nquadterms; ++i )
1088 {
1089 assert(quadvars1 != NULL && quadvars1[i] != NULL);
1090 assert(quadvars2 != NULL && quadvars2[i] != NULL);
1091
1092 /* quadratic term */
1093 if( quadvars1[i] == quadvars2[i] )
1094 {
1095 SCIP_EXPR* xexpr;
1096
1097 /* create variable expression; intentionally not using createExprVar here,
1098 * since expression created here is not part of a constraint (they will be copied when a constraint is created)
1099 */
1100 SCIP_CALL( SCIPcreateExprVar(scip, &xexpr, quadvars1[i], ownercreate, ownercreatedata) );
1101
1102 /* create pow expression */
1103 SCIP_CALL( SCIPcreateExprPow(scip, &children[i], xexpr, 2.0, ownercreate, ownercreatedata) );
1104
1105 /* release variable expression; note that the variable expression is still captured by children[i] */
1106 SCIP_CALL( SCIPreleaseExpr(scip, &xexpr) );
1107 }
1108 else /* bilinear term */
1109 {
1110 SCIP_EXPR* exprs[2];
1111
1112 /* create variable expressions; intentionally not using createExprVar here,
1113 * since expression created here is not part of a constraint (they will be copied when a constraint is created)
1114 */
1115 SCIP_CALL( SCIPcreateExprVar(scip, &exprs[0], quadvars1[i], ownercreate, ownercreatedata) );
1116 SCIP_CALL( SCIPcreateExprVar(scip, &exprs[1], quadvars2[i], ownercreate, ownercreatedata) );
1117
1118 /* create product expression */
1119 SCIP_CALL( SCIPcreateExprProduct(scip, &children[i], 2, exprs, 1.0, ownercreate, ownercreatedata) );
1120
1121 /* release variable expressions; note that the variable expressions are still captured by children[i] */
1122 SCIP_CALL( SCIPreleaseExpr(scip, &exprs[1]) );
1123 SCIP_CALL( SCIPreleaseExpr(scip, &exprs[0]) );
1124 }
1125
1126 /* store coefficient */
1127 coefs[i] = quadcoefs[i];
1128 }
1129
1130 /* create children for linear terms */
1131 for( i = 0; i < nlinvars; ++i )
1132 {
1133 assert(linvars != NULL && linvars[i] != NULL);
1134
1135 /* create variable expression; intentionally not using createExprVar here,
1136 * since expression created here is not part of a constraint (they will be copied when a constraint is created);
1137 * release variable expression after the sum expression has been created
1138 */
1139 SCIP_CALL( SCIPcreateExprVar(scip, &children[nquadterms + i], linvars[i], ownercreate, ownercreatedata) );
1140
1141 /* store coefficient */
1142 coefs[nquadterms + i] = lincoefs[i];
1143 }
1144
1145 /* create sum expression */
1146 SCIP_CALL( SCIPcreateExprSum(scip, expr, nquadterms + nlinvars, children, coefs, 0.0, ownercreate, ownercreatedata) );
1147
1148 /* release children */
1149 for( i = 0; i < nquadterms + nlinvars; ++i )
1150 {
1151 assert(children[i] != NULL);
1152 SCIP_CALL( SCIPreleaseExpr(scip, &children[i]) );
1153 }
1154
1155 /* free memory */
1156 SCIPfreeBufferArray(scip, &coefs);
1157 SCIPfreeBufferArray(scip, &children);
1158
1159 return SCIP_OKAY;
1160}
1161
1162/** creates and captures an expression representing a monomial
1163 *
1164 * @note In deviation from the actual definition of monomials, we also allow for negative and rational exponents.
1165 * So this function actually creates an expression for a signomial that has exactly one term.
1166 */
1168 SCIP* scip, /**< SCIP data structure */
1169 SCIP_EXPR** expr, /**< pointer where to store expression */
1170 int nfactors, /**< number of factors in monomial */
1171 SCIP_VAR** vars, /**< variables in the monomial */
1172 SCIP_Real* exponents, /**< exponent in each factor, or NULL if all 1.0 */
1173 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
1174 void* ownercreatedata /**< data to pass to ownercreate */
1175 )
1176{
1177 assert(scip != NULL);
1178 assert(expr != NULL);
1179 assert(nfactors >= 0);
1180
1181 /* return 1 as constant expression if there are no factors */
1182 if( nfactors == 0 )
1183 {
1184 SCIP_CALL( SCIPcreateExprValue(scip, expr, 1.0, ownercreate, ownercreatedata) );
1185 }
1186 else if( nfactors == 1 )
1187 {
1188 /* only one factor and exponent is 1 => return factors[0] */
1189 if( exponents == NULL || exponents[0] == 1.0 )
1190 {
1191 /* intentionally not using createExprVar here, since expression created here is not part of
1192 * a constraint (they will be copied when a constraint is created)
1193 */
1194 SCIP_CALL( SCIPcreateExprVar(scip, expr, vars[0], ownercreate, ownercreatedata) );
1195 }
1196 else
1197 {
1198 SCIP_EXPR* varexpr;
1199
1200 /* create variable and power expression; intentionally not using createExprVar here,
1201 * since expression created here is not part of a constraint (they will be copied when a constraint is created)
1202 */
1203 SCIP_CALL( SCIPcreateExprVar(scip, &varexpr, vars[0], ownercreate, ownercreatedata) );
1204 SCIP_CALL( SCIPcreateExprPow(scip, expr, varexpr, exponents[0], ownercreate, ownercreatedata) );
1205 SCIP_CALL( SCIPreleaseExpr(scip, &varexpr) );
1206 }
1207 }
1208 else
1209 {
1210 SCIP_EXPR** children;
1211 int i;
1212
1213 /* allocate memory to store the children */
1214 SCIP_CALL( SCIPallocBufferArray(scip, &children, nfactors) );
1215
1216 /* create children */
1217 for( i = 0; i < nfactors; ++i )
1218 {
1219 /* check whether to create a power expression or not, i.e., exponent == 1 */
1220 if( exponents == NULL || exponents[i] == 1.0 )
1221 {
1222 SCIP_CALL( SCIPcreateExprVar(scip, &children[i], vars[i], ownercreate, ownercreatedata) );
1223 }
1224 else
1225 {
1226 SCIP_EXPR* varexpr;
1227
1228 /* create variable and pow expression */
1229 SCIP_CALL( SCIPcreateExprVar(scip, &varexpr, vars[i], ownercreate, ownercreatedata) );
1230 SCIP_CALL( SCIPcreateExprPow(scip, &children[i], varexpr, exponents[i], ownercreate, ownercreatedata) );
1231 SCIP_CALL( SCIPreleaseExpr(scip, &varexpr) );
1232 }
1233 }
1234
1235 /* create product expression */
1236 SCIP_CALL( SCIPcreateExprProduct(scip, expr, nfactors, children, 1.0, ownercreate, ownercreatedata) );
1237
1238 /* release children */
1239 for( i = 0; i < nfactors; ++i )
1240 {
1241 assert(children[i] != NULL);
1242 SCIP_CALL( SCIPreleaseExpr(scip, &children[i]) );
1243 }
1244
1245 /* free memory */
1246 SCIPfreeBufferArray(scip, &children);
1247 }
1248
1249 return SCIP_OKAY;
1250}
1251
1252/** appends child to the children list of expr
1253 *
1254 * @attention Only use if you really know what you are doing. The expression handler of the expression needs to be able to handle an increase in the number of children.
1255 */
1257 SCIP* scip, /**< SCIP data structure */
1258 SCIP_EXPR* expr, /**< expression */
1259 SCIP_EXPR* child /**< expression to be appended */
1260 )
1261{
1262 assert(scip != NULL);
1263 assert(scip->mem != NULL);
1264
1265 SCIP_CALL( SCIPexprAppendChild(scip->set, scip->mem->probmem, expr, child) );
1266
1267 return SCIP_OKAY;
1268}
1269
1270/** overwrites/replaces a child of an expressions
1271 *
1272 * The old child is released and the newchild is captured, unless they are the same (=same pointer).
1273 */
1275 SCIP* scip, /**< SCIP data structure */
1276 SCIP_EXPR* expr, /**< expression which is going to replace a child */
1277 int childidx, /**< index of child being replaced */
1278 SCIP_EXPR* newchild /**< the new child */
1279 )
1280{
1281 assert(scip != NULL);
1282 assert(scip->mem != NULL);
1283
1284 SCIP_CALL( SCIPexprReplaceChild(scip->set, scip->stat, scip->mem->probmem, expr, childidx, newchild) );
1285
1286 return SCIP_OKAY;
1287}
1288
1289/** remove all children of expr
1290 *
1291 * @attention Only use if you really know what you are doing. The expression handler of the expression needs to be able to handle the removal of all children.
1292 */
1294 SCIP* scip, /**< SCIP data structure */
1295 SCIP_EXPR* expr /**< expression */
1296 )
1297{
1298 assert(scip != NULL);
1299 assert(scip->mem != NULL);
1300
1301 SCIP_CALL( SCIPexprRemoveChildren(scip->set, scip->stat, scip->mem->probmem, expr) );
1302
1303 return SCIP_OKAY;
1304}
1305
1306/** duplicates the given expression and its children */
1308 SCIP* scip, /**< SCIP data structure */
1309 SCIP_EXPR* expr, /**< original expression */
1310 SCIP_EXPR** copyexpr, /**< buffer to store duplicate of expr */
1311 SCIP_DECL_EXPR_MAPEXPR((*mapexpr)), /**< expression mapping function, or NULL for creating new expressions */
1312 void* mapexprdata, /**< data of expression mapping function */
1313 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call on expression copy to create ownerdata */
1314 void* ownercreatedata /**< data to pass to ownercreate */
1315 )
1316{
1317 assert(scip != NULL);
1318 assert(scip->mem != NULL);
1319
1320 SCIP_CALL( SCIPexprCopy(scip->set, scip->stat, scip->mem->probmem, scip->set, scip->stat, scip->mem->probmem,
1321 expr, copyexpr, mapexpr, mapexprdata, ownercreate, ownercreatedata) );
1322
1323 return SCIP_OKAY;
1324}
1325
1326/** duplicates the given expression, but reuses its children */
1328 SCIP* scip, /**< SCIP data structure */
1329 SCIP_EXPR* expr, /**< original expression */
1330 SCIP_EXPR** copyexpr, /**< buffer to store (shallow) duplicate of expr */
1331 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
1332 void* ownercreatedata /**< data to pass to ownercreate */
1333 )
1334{
1335 assert(scip != NULL);
1336 assert(scip->mem != NULL);
1337
1338 SCIP_CALL( SCIPexprDuplicateShallow(scip->set, scip->mem->probmem, expr, copyexpr, ownercreate, ownercreatedata) );
1339
1340 return SCIP_OKAY;
1341}
1342
1343/** copies an expression including children to use in a (possibly different) SCIP instance */
1345 SCIP* sourcescip, /**< source SCIP data structure */
1346 SCIP* targetscip, /**< target SCIP data structure */
1347 SCIP_EXPR* expr, /**< original expression */
1348 SCIP_EXPR** copyexpr, /**< buffer to store duplicate of expr */
1349 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call on expression copy to create ownerdata */
1350 void* ownercreatedata, /**< data to pass to ownercreate */
1351 SCIP_HASHMAP* varmap, /**< a SCIP_HASHMAP mapping variables of the source SCIP to the corresponding
1352 * variables of the target SCIP, or NULL */
1353 SCIP_HASHMAP* consmap, /**< a hashmap to store the mapping of source constraints to the corresponding
1354 * target constraints, or NULL */
1355 SCIP_Bool global, /**< create a global or a local copy? */
1356 SCIP_Bool* valid /**< pointer to store whether all checked or enforced constraints were validly copied */
1357 )
1358{
1359#ifndef _MSC_VER
1360 COPY_MAPEXPR_DATA copydata = {
1361 .varmap = varmap,
1362 .consmap = consmap,
1363 .global = global,
1364 .valid = TRUE
1365 };
1366#else /* MS compiler doesn't have proper C99 support... */
1367 COPY_MAPEXPR_DATA copydata;
1368 copydata.varmap = varmap;
1369 copydata.consmap = consmap;
1370 copydata.global = global;
1371 copydata.valid = TRUE;
1372#endif
1373
1374 assert(sourcescip != NULL);
1375 assert(sourcescip->mem != NULL);
1376 assert(targetscip != NULL);
1377 assert(targetscip->mem != NULL);
1378
1379 SCIP_CALL( SCIPexprCopy(sourcescip->set, sourcescip->stat, sourcescip->mem->probmem,
1380 targetscip->set, targetscip->stat, targetscip->mem->probmem,
1381 expr, copyexpr, copyVarExpr, &copydata, ownercreate, ownercreatedata) );
1382
1383 *valid = copydata.valid;
1384
1385 return SCIP_OKAY;
1386}
1387
1388/** creates an expression from a string
1389 *
1390 * We specify the grammar that defines the syntax of an expression.
1391 * Loosely speaking, a `Base` will be any "block", a `Factor` is a `Base` to a power,
1392 * a `Term` is a product of `Factors` and an `Expression` is a sum of `Terms`.
1393 *
1394 * The actual definition:
1395 * ```
1396 * Expression -> ["+" | "-"] Term { [ ("+" | "-" | "number *") Term | ("number" <varname>) ] }
1397 * Term -> Factor { ("*" | "/" ) Factor }
1398 * Factor -> Base [ "^" "number" | "^(" "number" ")" ]
1399 * Base -> "number" | "<varname>" | "(" Expression ")" | Op "(" OpExpression ")
1400 * ```
1401 * where `[a|b]` means `a` or `b` or none, `(a|b)` means `a` or `b`, `{a}` means 0 or more `a`.
1402 *
1403 * Note that `Op` and `OpExpression` are undefined.
1404 * `Op` corresponds to the name of an expression handler and `OpExpression` to whatever string the expression handler accepts (through its parse method).
1405 */
1407 SCIP* scip, /**< SCIP data structure */
1408 SCIP_EXPR** expr, /**< pointer to store the expr parsed */
1409 const char* exprstr, /**< string with the expr to parse */
1410 const char** finalpos, /**< buffer to store the position of exprstr where we finished reading, or NULL if not of interest */
1411 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
1412 void* ownercreatedata /**< data to pass to ownercreate */
1413 )
1414{
1415 const char* finalpos_;
1416 SCIP_RETCODE retcode;
1417 SCIP_HASHMAP* vartoexprvarmap;
1418
1419 assert(scip != NULL);
1420
1421 SCIP_CALL( SCIPhashmapCreate(&vartoexprvarmap, SCIPblkmem(scip), 5 * SCIPgetNVars(scip)) );
1422
1423 /* if parseExpr fails, we still want to free hashmap */
1424 retcode = parseExpr(scip, vartoexprvarmap, exprstr, &finalpos_, expr, ownercreate, ownercreatedata);
1425
1426 SCIPhashmapFree(&vartoexprvarmap);
1427
1428 if( finalpos != NULL )
1429 *finalpos = finalpos_;
1430
1431 return retcode;
1432}
1433
1434/** captures an expression (increments usage count) */
1436 SCIP_EXPR* expr /**< expression to be captured */
1437 )
1438{
1439 SCIPexprCapture(expr);
1440}
1441
1442/** releases an expression (decrements usage count and possibly frees expression) */
1444 SCIP* scip, /**< SCIP data structure */
1445 SCIP_EXPR** expr /**< pointer to expression to be released */
1446 )
1447{
1448 assert(scip != NULL);
1449 assert(scip->mem != NULL);
1450
1451 SCIP_CALL( SCIPexprRelease(scip->set, scip->stat, scip->mem->probmem, expr) );
1452
1453 return SCIP_OKAY;
1454}
1455
1456/** returns whether an expression is a variable expression */
1458 SCIP* scip, /**< SCIP data structure */
1459 SCIP_EXPR* expr /**< expression */
1460 )
1461{
1462 assert(scip != NULL);
1463
1464 return SCIPexprIsVar(scip->set, expr);
1465}
1466
1467/** returns whether an expression is a value expression */
1469 SCIP* scip, /**< SCIP data structure */
1470 SCIP_EXPR* expr /**< expression */
1471 )
1472{
1473 assert(scip != NULL);
1474
1475 return SCIPexprIsValue(scip->set, expr);
1476}
1477
1478/** returns whether an expression is a sum expression */
1480 SCIP* scip, /**< SCIP data structure */
1481 SCIP_EXPR* expr /**< expression */
1482 )
1483{
1484 assert(scip != NULL);
1485
1486 return SCIPexprIsSum(scip->set, expr);
1487}
1488
1489/** returns whether an expression is a product expression */
1491 SCIP* scip, /**< SCIP data structure */
1492 SCIP_EXPR* expr /**< expression */
1493 )
1494{
1495 assert(scip != NULL);
1496
1497 return SCIPexprIsProduct(scip->set, expr);
1498}
1499
1500/** returns whether an expression is a power expression */
1502 SCIP* scip, /**< SCIP data structure */
1503 SCIP_EXPR* expr /**< expression */
1504 )
1505{
1506 assert(scip != NULL);
1507
1508 return SCIPexprIsPower(scip->set, expr);
1509}
1510
1511/** print an expression as info-message */
1513 SCIP* scip, /**< SCIP data structure */
1514 SCIP_EXPR* expr, /**< expression to be printed */
1515 FILE* file /**< file to print to, or NULL for stdout */
1516 )
1517{
1518 assert(scip != NULL);
1519 assert(scip->mem != NULL);
1520
1521 SCIP_CALL( SCIPexprPrint(scip->set, scip->stat, scip->mem->probmem, scip->messagehdlr, file, expr) );
1522
1523 return SCIP_OKAY;
1524}
1525
1526/** initializes printing of expressions in dot format to a give FILE* pointer */
1528 SCIP* scip, /**< SCIP data structure */
1529 SCIP_EXPRPRINTDATA** printdata, /**< buffer to store dot printing data */
1530 FILE* file, /**< file to print to, or NULL for stdout */
1531 SCIP_EXPRPRINT_WHAT whattoprint /**< info on what to print for each expression */
1532 )
1533{
1534 assert(scip != NULL);
1535 assert(scip->mem != NULL);
1536
1537 SCIP_CALL( SCIPexprPrintDotInit(scip->set, scip->stat, scip->mem->probmem, printdata, file, whattoprint) );
1538
1539 return SCIP_OKAY;
1540}
1541
1542/** initializes printing of expressions in dot format to a file with given filename */
1544 SCIP* scip, /**< SCIP data structure */
1545 SCIP_EXPRPRINTDATA** printdata, /**< buffer to store dot printing data */
1546 const char* filename, /**< name of file to print to */
1547 SCIP_EXPRPRINT_WHAT whattoprint /**< info on what to print for each expression */
1548 )
1549{
1550 assert(scip != NULL);
1551 assert(scip->mem != NULL);
1552
1553 SCIP_CALL( SCIPexprPrintDotInit2(scip->set, scip->stat, scip->mem->probmem, printdata, filename, whattoprint) );
1554
1555 return SCIP_OKAY;
1556}
1557
1558/** main part of printing an expression in dot format */
1560 SCIP* scip, /**< SCIP data structure */
1561 SCIP_EXPRPRINTDATA* printdata, /**< data as initialized by \ref SCIPprintExprDotInit() */
1562 SCIP_EXPR* expr /**< expression to be printed */
1563 )
1564{
1565 assert(scip != NULL);
1566
1567 SCIP_CALL( SCIPexprPrintDot(scip->set, scip->messagehdlr, printdata, expr) );
1568
1569 return SCIP_OKAY;
1570}
1571
1572/** finishes printing of expressions in dot format */
1574 SCIP* scip, /**< SCIP data structure */
1575 SCIP_EXPRPRINTDATA** printdata /**< buffer where dot printing data has been stored */
1576 )
1577{
1578 assert(scip != NULL);
1579 assert(scip->mem != NULL);
1580
1581 SCIP_CALL( SCIPexprPrintDotFinal(scip->set, scip->stat, scip->mem->probmem, printdata) );
1582
1583 return SCIP_OKAY;
1584}
1585
1586/** shows a single expression by use of dot and gv
1587 *
1588 * This function is meant for debugging purposes.
1589 * It's signature is kept as simple as possible to make it
1590 * easily callable from gdb, for example.
1591 *
1592 * It prints the expression into a temporary file in dot format, then calls dot to create a postscript file,
1593 * then calls ghostview (gv) to show the file. SCIP will hold until ghostscript is closed.
1594 */
1596 SCIP* scip, /**< SCIP data structure */
1597 SCIP_EXPR* expr /**< expression to be printed */
1598 )
1599{
1600 /* this function is for developers, so don't bother with C variants that don't have popen() */
1601#if _POSIX_C_SOURCE < 2
1602 SCIPerrorMessage("No POSIX version 2. Try http://distrowatch.com/.");
1603 return SCIP_ERROR;
1604#else
1605 SCIP_EXPRPRINTDATA* dotdata;
1606 FILE* f;
1607 SCIP_RETCODE retcode = SCIP_OKAY;
1608
1609 assert(scip != NULL);
1610 assert(expr != NULL);
1611
1612 /* call dot to generate postscript output and show it via ghostview */
1613 f = popen("dot -Tps | gv --media=a3 -", "w");
1614 if( f == NULL )
1615 {
1616 SCIPerrorMessage("Calling popen() failed");
1617 return SCIP_FILECREATEERROR;
1618 }
1619
1620 /* print all of the expression into the pipe */
1621 SCIP_CALL_TERMINATE( retcode, SCIPprintExprDotInit(scip, &dotdata, f, SCIP_EXPRPRINT_ALL), TERMINATE );
1622 SCIP_CALL_TERMINATE( retcode, SCIPprintExprDot(scip, dotdata, expr), TERMINATE );
1623 SCIP_CALL_TERMINATE( retcode, SCIPprintExprDotFinal(scip, &dotdata), TERMINATE );
1624
1625 TERMINATE:
1626 /* close the pipe */
1627 (void) pclose(f);
1628
1629 return retcode;
1630#endif
1631}
1632
1633/** prints structure of an expression a la Maple's dismantle */
1635 SCIP* scip, /**< SCIP data structure */
1636 FILE* file, /**< file to print to, or NULL for stdout */
1637 SCIP_EXPR* expr /**< expression to dismantle */
1638 )
1639{
1640 assert(scip != NULL);
1641 assert(scip->mem != NULL);
1642
1643 SCIP_CALL( SCIPexprDismantle(scip->set, scip->stat, scip->mem->probmem, scip->messagehdlr, file, expr) );
1644
1645 return SCIP_OKAY;
1646}
1647
1648/** evaluate an expression in a point
1649 *
1650 * Iterates over expressions to also evaluate children, if necessary.
1651 * Value can be received via SCIPexprGetEvalValue().
1652 * If an evaluation error (division by zero, ...) occurs, this value will
1653 * be set to SCIP_INVALID.
1654 *
1655 * If a nonzero \p soltag is passed, then only (sub)expressions are
1656 * reevaluated that have a different solution tag. If a soltag of 0
1657 * is passed, then subexpressions are always reevaluated.
1658 * The tag is stored together with the value and can be received via
1659 * SCIPexprGetEvalTag().
1660 */
1662 SCIP* scip, /**< SCIP data structure */
1663 SCIP_EXPR* expr, /**< expression to be evaluated */
1664 SCIP_SOL* sol, /**< solution to be evaluated */
1665 SCIP_Longint soltag /**< tag that uniquely identifies the solution (with its values), or 0. */
1666 )
1667{
1668 assert(scip != NULL);
1669 assert(scip->mem != NULL);
1670
1671 SCIP_CALL( SCIPexprEval(scip->set, scip->stat, scip->mem->probmem, expr, sol, soltag) );
1672
1673 return SCIP_OKAY;
1674}
1675
1676/** returns a previously unused solution tag for expression evaluation */
1678 SCIP* scip /**< SCIP data structure */
1679 )
1680{
1681 assert(scip != NULL);
1682
1683 return ++(scip->stat->exprlastsoltag);
1684}
1685
1686/** evaluates gradient of an expression for a given point
1687 *
1688 * Initiates an expression walk to also evaluate children, if necessary.
1689 * Value can be received from variable expressions via SCIPexprGetDerivative() or via SCIPgetExprPartialDiffNonlinear().
1690 * If an error (division by zero, ...) occurs, these functions return SCIP_INVALID.
1691 */
1693 SCIP* scip, /**< SCIP data structure */
1694 SCIP_EXPR* expr, /**< expression to be differentiated */
1695 SCIP_SOL* sol, /**< solution to be evaluated (NULL for the current LP solution) */
1696 SCIP_Longint soltag /**< tag that uniquely identifies the solution (with its values), or 0. */
1697 )
1698{
1699 assert(scip != NULL);
1700 assert(scip->mem != NULL);
1701
1702 SCIP_CALL( SCIPexprEvalGradient(scip->set, scip->stat, scip->mem->probmem, expr, sol, soltag) );
1703
1704 return SCIP_OKAY;
1705}
1706
1707/** evaluates Hessian-vector product of an expression for a given point and direction
1708 *
1709 * Evaluates children, if necessary.
1710 * Value can be received via SCIPgetExprPartialDiffGradientDirNonlinear().
1711 * If an error (division by zero, ...) occurs, this value will
1712 * be set to SCIP_INVALID.
1713 */
1715 SCIP* scip, /**< SCIP data structure */
1716 SCIP_EXPR* expr, /**< expression to be differentiated */
1717 SCIP_SOL* sol, /**< solution to be evaluated (NULL for the current LP solution) */
1718 SCIP_Longint soltag, /**< tag that uniquely identifies the solution (with its values), or 0. */
1719 SCIP_SOL* direction /**< direction */
1720 )
1721{
1722 assert(scip != NULL);
1723 assert(scip->mem != NULL);
1724
1725 SCIP_CALL( SCIPexprEvalHessianDir(scip->set, scip->stat, scip->mem->probmem, expr, sol, soltag, direction) );
1726
1727 return SCIP_OKAY;
1728}
1729
1730/** possibly reevaluates the activity of the expression
1731 *
1732 * Reevaluate activity if currently stored is no longer uptodate (some bound was changed since last evaluation).
1733 *
1734 * The owner of the expression may overwrite the methods used to evaluate the activity,
1735 * including whether the local or global domain of variables is used.
1736 * By default (no owner, or owner doesn't overwrite activity evaluation),
1737 * the local domain of variables is used.
1738 *
1739 * @note If expression is set to be integral, then activities are tightened to integral values.
1740 * Thus, ensure that the integrality information is valid (if set to TRUE; the default (FALSE) is always ok).
1741 */
1743 SCIP* scip, /**< SCIP data structure */
1744 SCIP_EXPR* expr /**< expression */
1745 )
1746{
1747 assert(scip != NULL);
1748 assert(scip->mem != NULL);
1749
1750 SCIP_CALL( SCIPexprEvalActivity(scip->set, scip->stat, scip->mem->probmem, expr) );
1751
1752 return SCIP_OKAY;
1753}
1754
1755/** compare expressions
1756 * @return -1, 0 or 1 if expr1 <, =, > expr2, respectively
1757 * @note The given expressions are assumed to be simplified.
1758 */
1760 SCIP* scip, /**< SCIP data structure */
1761 SCIP_EXPR* expr1, /**< first expression */
1762 SCIP_EXPR* expr2 /**< second expression */
1763 )
1764{
1765 assert(scip != NULL);
1766
1767 return SCIPexprCompare(scip->set, expr1, expr2);
1768}
1769
1770/** compute the hash value of an expression */
1772 SCIP* scip, /**< SCIP data structure */
1773 SCIP_EXPR* expr, /**< expression */
1774 unsigned int* hashval /**< pointer to store the hash value */
1775 )
1776{
1777 SCIP_EXPRITER* it;
1778
1779 assert(scip != NULL);
1780 assert(scip->mem != NULL);
1781 assert(expr != NULL);
1782 assert(hashval != NULL);
1783
1784 SCIP_CALL( SCIPexpriterCreate(scip->stat, scip->mem->probmem, &it) );
1787
1788 SCIP_CALL( hashExpr(scip->set, scip->mem->buffer, expr, it, NULL) );
1789
1790 *hashval = SCIPexpriterGetExprUserData(it, expr).uintval;
1791
1792 SCIPexpriterFree(&it);
1793
1794 return SCIP_OKAY;
1795}
1796
1797/** simplifies an expression (duplication of long doxygen comment omitted here) */
1799 SCIP* scip, /**< SCIP data structure */
1800 SCIP_EXPR* rootexpr, /**< expression to be simplified */
1801 SCIP_EXPR** simplified, /**< buffer to store simplified expression */
1802 SCIP_Bool* changed, /**< buffer to store if rootexpr actually changed */
1803 SCIP_Bool* infeasible, /**< buffer to store whether infeasibility has been detected */
1804 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
1805 void* ownercreatedata /**< data to pass to ownercreate */
1806 )
1807{
1808 assert(scip != NULL);
1809 assert(scip->mem != NULL);
1810
1811 SCIP_CALL( SCIPexprSimplify(scip->set, scip->stat, scip->mem->probmem, rootexpr, simplified, changed, infeasible, ownercreate, ownercreatedata) );
1812
1813 return SCIP_OKAY;
1814}
1815
1816/** retrieves symmetry information from an expression */
1818 SCIP* scip, /**< SCIP data structure */
1819 SCIP_EXPR* expr, /**< expression from which information needs to be retrieved */
1820 SYM_EXPRDATA** symdata /**< buffer to store symmetry data */
1821 )
1822{
1823 assert(scip != NULL);
1824 assert(expr != NULL);
1825 assert(symdata != NULL);
1826
1827 SCIP_CALL( SCIPexprGetSymData(scip->set, expr, symdata) );
1828
1829 return SCIP_OKAY;
1830}
1831
1832/** replaces common sub-expressions in a given expression graph by using a hash key for each expression
1833 *
1834 * The algorithm consists of two steps:
1835 *
1836 * 1. traverse through all given expressions and compute for each of them a (not necessarily unique) hash
1837 *
1838 * 2. initialize an empty hash table and traverse through all expression; check for each of them if we can find a
1839 * structural equivalent expression in the hash table; if yes we replace the expression by the expression inside the
1840 * hash table, otherwise we add it to the hash table
1841 *
1842 * @note the hash keys of the expressions are used for the hashing inside the hash table; to compute if two expressions
1843 * (with the same hash) are structurally the same we use the function SCIPexprCompare().
1844 */
1846 SCIP* scip, /**< SCIP data structure */
1847 SCIP_EXPR** exprs, /**< expressions (possibly replaced by equivalent on output) */
1848 int nexprs, /**< total number of expressions */
1849 SCIP_Bool* replacedroot /**< buffer to store whether any root expression (expression in exprs) was replaced */
1850 )
1851{
1852 COMMONSUBEXPR_HASH_DATA hashdata;
1853 SCIP_EXPRITER* hashiterator;
1854 SCIP_EXPRITER* repliterator;
1855 SCIP_MULTIHASH* key2expr;
1856 int i;
1857 int nvisitedexprs = 0;
1858
1859 assert(scip != NULL);
1860 assert(scip->mem != NULL);
1861 assert(exprs != NULL);
1862 assert(nexprs >= 0);
1863 assert(replacedroot != NULL);
1864
1865 *replacedroot = FALSE;
1866
1867 if( nexprs == 0 )
1868 return SCIP_OKAY;
1869
1870 SCIP_CALL( SCIPcreateExpriter(scip, &hashiterator) );
1873
1874 /* compute all hashes for each sub-expression */
1875 for( i = 0; i < nexprs; ++i )
1876 {
1877 assert(exprs[i] != NULL);
1878 SCIP_CALL( hashExpr(scip->set, scip->mem->buffer, exprs[i], hashiterator, &nvisitedexprs) );
1879 }
1880
1881 /* replace equivalent sub-expressions */
1882 hashdata.hashiterator = hashiterator;
1883 hashdata.set = scip->set;
1884 SCIP_CALL( SCIPmultihashCreate(&key2expr, scip->mem->probmem, nvisitedexprs,
1885 hashCommonSubexprGetKey, hashCommonSubexprEq, hashCommonSubexprKeyval, (void*)&hashdata) );
1886
1887 SCIP_CALL( SCIPcreateExpriter(scip, &repliterator) );
1888
1889 for( i = 0; i < nexprs; ++i )
1890 {
1891 SCIP_EXPR* newroot;
1892 SCIP_EXPR* newchild;
1893 SCIP_EXPR* child;
1894
1895 /* check the root for equivalence separately first */
1896 SCIP_CALL( findEqualExpr(scip->set, exprs[i], key2expr, &newroot) );
1897
1898 if( newroot != NULL )
1899 {
1900 assert(newroot != exprs[i]);
1901 assert(SCIPexprCompare(scip->set, exprs[i], newroot) == 0);
1902
1903 SCIPdebugMsg(scip, "replacing common root expression of %dth expr: %p -> %p\n", i, (void*)exprs[i], (void*)newroot);
1904
1905 SCIP_CALL( SCIPreleaseExpr(scip, &exprs[i]) );
1906
1907 exprs[i] = newroot;
1908 SCIPexprCapture(newroot);
1909
1910 *replacedroot = TRUE;
1911
1912 continue;
1913 }
1914
1915 /* replace equivalent sub-expressions in the tree */
1916 SCIP_CALL( SCIPexpriterInit(repliterator, exprs[i], SCIP_EXPRITER_DFS, FALSE) );
1918
1919 while( !SCIPexpriterIsEnd(repliterator) )
1920 {
1921 child = SCIPexpriterGetChildExprDFS(repliterator);
1922 assert(child != NULL);
1923
1924 /* try to find an equivalent expression */
1925 SCIP_CALL( findEqualExpr(scip->set, child, key2expr, &newchild) );
1926
1927 /* replace child with newchild */
1928 if( newchild != NULL )
1929 {
1930 assert(child != newchild);
1931 assert(SCIPexprCompare(scip->set, child, newchild) == 0);
1932
1933 SCIPdebugMsg(scip, "replacing common child expression %p -> %p\n", (void*)child, (void*)newchild);
1934
1935 SCIP_CALL( SCIPreplaceExprChild(scip, SCIPexpriterGetCurrent(repliterator), SCIPexpriterGetChildIdxDFS(repliterator), newchild) );
1936
1937 (void) SCIPexpriterSkipDFS(repliterator);
1938 }
1939 else
1940 {
1941 (void) SCIPexpriterGetNext(repliterator);
1942 }
1943 }
1944 }
1945
1946 /* free memory */
1947 SCIPexpriterFree(&repliterator);
1948 SCIPmultihashFree(&key2expr);
1949 SCIPexpriterFree(&hashiterator);
1950
1951 return SCIP_OKAY;
1952}
1953
1954/** computes the curvature of a given expression and all its subexpressions
1955 *
1956 * @note this function also evaluates all subexpressions w.r.t. current variable bounds
1957 * @note this function relies on information from the curvature callback of expression handlers only,
1958 * consider using function @ref SCIPhasExprCurvature() of the convex-nlhdlr instead, as that uses more information to deduce convexity
1959 */
1961 SCIP* scip, /**< SCIP data structure */
1962 SCIP_EXPR* expr /**< expression */
1963 )
1964{
1965 SCIP_EXPRITER* it;
1966 SCIP_EXPRCURV curv;
1967 SCIP_EXPRCURV* childcurv;
1968 int childcurvsize;
1969 SCIP_Bool success;
1971 int i, c;
1972
1973 assert(scip != NULL);
1974 assert(scip->mem != NULL);
1975 assert(expr != NULL);
1976
1977 childcurvsize = 5;
1978 SCIP_CALL( SCIPallocBufferArray(scip, &childcurv, childcurvsize) );
1979
1980 SCIP_CALL( SCIPexpriterCreate(scip->stat, scip->mem->probmem, &it) );
1983
1984 for( expr = SCIPexpriterGetCurrent(it); !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
1985 {
1986 curv = SCIP_EXPRCURV_UNKNOWN;
1987
1989 {
1990 /* set curvature in expression */
1991 SCIPexprSetCurvature(expr, curv);
1992 continue;
1993 }
1994
1995 if( SCIPexprGetNChildren(expr) > childcurvsize )
1996 {
1997 childcurvsize = SCIPcalcMemGrowSize(scip, SCIPexprGetNChildren(expr));
1998 SCIP_CALL( SCIPreallocBufferArray(scip, &childcurv, childcurvsize) );
1999 }
2000
2001 for( i = 0; i < 3; ++i )
2002 {
2003 /* check if expression can have a curvature trialcurv[i] */
2004 SCIP_CALL( SCIPexprhdlrCurvatureExpr(SCIPexprGetHdlr(expr), scip->set, expr, trialcurv[i], &success, childcurv) );
2005 if( !success )
2006 continue;
2007
2008 /* check if conditions on children are satisfied */
2009 for( c = 0; c < SCIPexprGetNChildren(expr); ++c )
2010 {
2011 if( (childcurv[c] & SCIPexprGetCurvature(SCIPexprGetChildren(expr)[c])) != childcurv[c] )
2012 {
2013 success = FALSE;
2014 break;
2015 }
2016 }
2017
2018 if( success )
2019 {
2020 curv = trialcurv[i];
2021 break;
2022 }
2023 }
2024
2025 /* set curvature in expression */
2026 SCIPexprSetCurvature(expr, curv);
2027 }
2028
2029 SCIPexpriterFree(&it);
2030
2031 SCIPfreeBufferArray(scip, &childcurv);
2032
2033 return SCIP_OKAY;
2034}
2035
2036/** computes integrality information of a given expression and all its subexpressions
2037 *
2038 * The integrality information can be accessed via SCIPexprGetIntegrality() and SCIPexprIsIntegral()
2039 */
2041 SCIP* scip, /**< SCIP data structure */
2042 SCIP_EXPR* expr /**< expression */
2043 )
2044{
2045 SCIP_EXPRITER* it;
2046 SCIP_IMPLINTTYPE integrality;
2047
2048 assert(scip != NULL);
2049 assert(scip->mem != NULL);
2050 assert(expr != NULL);
2051
2052 /* shortcut for expr without children */
2053 if( SCIPexprGetNChildren(expr) == 0 )
2054 {
2055 /* compute integrality information */
2056 SCIP_CALL( SCIPexprhdlrIntegralityExpr(SCIPexprGetHdlr(expr), scip->set, expr, &integrality) );
2057 SCIPexprSetIntegrality(expr, integrality);
2058
2059 return SCIP_OKAY;
2060 }
2061
2062 SCIP_CALL( SCIPexpriterCreate(scip->stat, scip->mem->probmem, &it) );
2065
2066 for( expr = SCIPexpriterGetCurrent(it); !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
2067 {
2068 /* compute integrality information */
2069 SCIP_CALL( SCIPexprhdlrIntegralityExpr(SCIPexprGetHdlr(expr), scip->set, expr, &integrality) );
2070 SCIPexprSetIntegrality(expr, integrality);
2071 }
2072
2073 SCIPexpriterFree(&it);
2074
2075 return SCIP_OKAY;
2076}
2077
2078/** returns the total number of variable expressions in an expression
2079 *
2080 * The function counts variable expressions in common sub-expressions only once, but
2081 * counts variables appearing in several variable expressions multiple times.
2082 */
2084 SCIP* scip, /**< SCIP data structure */
2085 SCIP_EXPR* expr, /**< expression */
2086 int* nvars /**< buffer to store the total number of variables */
2087 )
2088{
2089 SCIP_EXPRITER* it;
2090
2091 assert(scip != NULL);
2092 assert(scip->mem != NULL);
2093 assert(expr != NULL);
2094 assert(nvars != NULL);
2095
2096 SCIP_CALL( SCIPexpriterCreate(scip->stat, scip->mem->probmem, &it) );
2098
2099 *nvars = 0;
2100 for( ; !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
2101 if( SCIPexprIsVar(scip->set, expr) )
2102 ++(*nvars);
2103
2104 SCIPexpriterFree(&it);
2105
2106 return SCIP_OKAY;
2107}
2108
2109/** returns all variable expressions contained in a given expression
2110 *
2111 * The array to store all variable expressions needs to be at least of size
2112 * the number of unique variable expressions in the expression which is given by SCIPgetExprNVars().
2113 *
2114 * If every variable is represented by only one variable expression (common subexpression have been removed)
2115 * then SCIPgetExprNVars() can be bounded by SCIPgetNTotalVars().
2116 * If, in addition, non-active variables have been removed from the expression, e.g., by simplifying,
2117 * then SCIPgetExprNVars() can be bounded by SCIPgetNVars().
2118 *
2119 * @note function captures variable expressions
2120 */
2122 SCIP* scip, /**< SCIP data structure */
2123 SCIP_EXPR* expr, /**< expression */
2124 SCIP_EXPR** varexprs, /**< array to store all variable expressions */
2125 int* nvarexprs /**< buffer to store the total number of variable expressions */
2126 )
2127{
2128 SCIP_EXPRITER* it;
2129
2130 assert(scip != NULL);
2131 assert(scip->mem != NULL);
2132 assert(expr != NULL);
2133 assert(varexprs != NULL);
2134 assert(nvarexprs != NULL);
2135
2136 SCIP_CALL( SCIPexpriterCreate(scip->stat, scip->mem->probmem, &it) );
2138
2139 *nvarexprs = 0;
2140 for( ; !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
2141 {
2142 assert(expr != NULL);
2143
2144 if( SCIPexprIsVar(scip->set, expr) )
2145 {
2146 varexprs[(*nvarexprs)++] = expr;
2147
2148 /* capture expression */
2149 SCIPcaptureExpr(expr);
2150 }
2151 }
2152
2153 /* @todo sort variable expressions here? */
2154
2155 SCIPexpriterFree(&it);
2156
2157 return SCIP_OKAY;
2158}
2159
2160/** calls the print callback for an expression
2161 *
2162 * @see SCIP_DECL_EXPRPRINT
2163 */
2164SCIP_DECL_EXPRPRINT(SCIPcallExprPrint)
2165{
2166 assert(scip != NULL);
2167
2168 SCIP_CALL( SCIPexprhdlrPrintExpr(SCIPexprGetHdlr(expr), scip->set, scip->messagehdlr, expr, stage, currentchild, parentprecedence, file) );
2169
2170 return SCIP_OKAY;
2171}
2172
2173/** calls the curvature callback for an expression
2174 *
2175 * @see SCIP_DECL_EXPRCURVATURE
2176 *
2177 * Returns unknown curvature if callback not implemented.
2178 */
2179SCIP_DECL_EXPRCURVATURE(SCIPcallExprCurvature)
2180{
2181 assert(scip != NULL);
2182
2183 SCIP_CALL( SCIPexprhdlrCurvatureExpr(SCIPexprGetHdlr(expr), scip->set, expr, exprcurvature, success, childcurv) );
2184
2185 return SCIP_OKAY;
2186}
2187
2188/** calls the monotonicity callback for an expression
2189 *
2190 * @see SCIP_DECL_EXPRMONOTONICITY
2191 *
2192 * Returns unknown monotonicity if callback not implemented.
2193 */
2194SCIP_DECL_EXPRMONOTONICITY(SCIPcallExprMonotonicity)
2195{
2196 assert(scip != NULL);
2197
2198 SCIP_CALL( SCIPexprhdlrMonotonicityExpr(SCIPexprGetHdlr(expr), scip->set, expr, childidx, result) );
2199
2200 return SCIP_OKAY;
2201}
2202
2203/** calls the eval callback for an expression with given values for children
2204 *
2205 * Does not iterates over expressions, but requires values for children to be given.
2206 * Value is not stored in expression, but returned in `val`.
2207 * If an evaluation error (division by zero, ...) occurs, this value will
2208 * be set to `SCIP_INVALID`.
2209 */
2211 SCIP* scip, /**< SCIP data structure */
2212 SCIP_EXPR* expr, /**< expression to be evaluated */
2213 SCIP_Real* childrenvalues, /**< values for children */
2214 SCIP_Real* val /**< buffer to store evaluated value */
2215 )
2216{
2217 assert(scip != NULL);
2218 assert(scip->mem != NULL);
2219 assert(childrenvalues != NULL);
2220 assert(val != NULL);
2221
2222 SCIP_CALL( SCIPexprhdlrEvalExpr(SCIPexprGetHdlr(expr), scip->set, scip->mem->buffer, expr, val, childrenvalues, NULL) );
2223
2224 return SCIP_OKAY;
2225}
2226
2227/** calls the eval and fwdiff callback of an expression with given values for children
2228 *
2229 * Does not iterates over expressions, but requires values for children and direction to be given.
2230 *
2231 * Value is not stored in expression, but returned in `val`.
2232 * If an evaluation error (division by zero, ...) occurs, this value will be set to `SCIP_INVALID`.
2233 *
2234 * Direction is not stored in expression, but returned in `dot`.
2235 * If an differentiation error (division by zero, ...) occurs, this value will be set to `SCIP_INVALID`.
2236 */
2238 SCIP* scip, /**< SCIP data structure */
2239 SCIP_EXPR* expr, /**< expression to be evaluated */
2240 SCIP_Real* childrenvalues, /**< values for children */
2241 SCIP_Real* direction, /**< direction in which to differentiate */
2242 SCIP_Real* val, /**< buffer to store evaluated value */
2243 SCIP_Real* dot /**< buffer to store derivative value */
2244 )
2245{
2246 assert(scip != NULL);
2247 assert(scip->mem != NULL);
2248
2249 SCIP_CALL( SCIPexprhdlrEvalFwDiffExpr(SCIPexprGetHdlr(expr), scip->set, scip->mem->buffer, expr, val, dot,
2250 childrenvalues, NULL, direction, NULL) );
2251
2252 return SCIP_OKAY;
2253}
2254
2255/** calls the interval evaluation callback for an expression
2256 *
2257 * @see SCIP_DECL_EXPRINTEVAL
2258 *
2259 * Returns entire interval if callback not implemented.
2260 */
2261SCIP_DECL_EXPRINTEVAL(SCIPcallExprInteval)
2262{
2263 assert(scip != NULL);
2264
2265 SCIP_CALL( SCIPexprhdlrIntEvalExpr(SCIPexprGetHdlr(expr), scip->set, expr, interval, intevalvar, intevalvardata) );
2266
2267 return SCIP_OKAY;
2268}
2269
2270/** calls the estimate callback for an expression
2271 *
2272 * @see SCIP_DECL_EXPRESTIMATE
2273 *
2274 * Returns without success if callback not implemented.
2275 */
2276SCIP_DECL_EXPRESTIMATE(SCIPcallExprEstimate)
2277{
2278 assert(scip != NULL);
2279
2280 SCIP_CALL( SCIPexprhdlrEstimateExpr(SCIPexprGetHdlr(expr), scip->set, expr, localbounds, globalbounds, refpoint,
2281 overestimate, targetvalue, coefs, constant, islocal, success, branchcand) );
2282
2283 return SCIP_OKAY;
2284}
2285
2286/** calls the initial estimators callback for an expression
2287 *
2288 * @see SCIP_DECL_EXPRINITESTIMATES
2289 *
2290 * Returns no estimators if callback not implemented.
2291 */
2292SCIP_DECL_EXPRINITESTIMATES(SCIPcallExprInitestimates)
2293{
2294 assert(scip != NULL);
2295
2296 SCIP_CALL( SCIPexprhdlrInitEstimatesExpr(SCIPexprGetHdlr(expr), scip->set, expr, bounds, overestimate, coefs,
2297 constant, nreturned) );
2298
2299 return SCIP_OKAY;
2300}
2301
2302/** calls the simplify callback for an expression
2303 *
2304 * @see SCIP_DECL_EXPRSIMPLIFY
2305 *
2306 * Returns unmodified expression if simplify callback not implemented.
2307 *
2308 * Does not simplify descendants (children, etc). Use SCIPsimplifyExpr() for that.
2309 */
2310SCIP_DECL_EXPRSIMPLIFY(SCIPcallExprSimplify)
2311{
2312 assert(scip != NULL);
2313
2314 /* use simplification of expression handlers */
2315 SCIP_CALL( SCIPexprhdlrSimplifyExpr(SCIPexprGetHdlr(expr), scip->set, expr, simplifiedexpr, ownercreate,
2316 ownercreatedata) );
2317
2318 return SCIP_OKAY;
2319}
2320
2321/** calls the reverse propagation callback for an expression
2322 *
2323 * @see SCIP_DECL_EXPRREVERSEPROP
2324 *
2325 * Returns unmodified childrenbounds if reverseprop callback not implemented.
2326 */
2327SCIP_DECL_EXPRREVERSEPROP(SCIPcallExprReverseprop)
2328{
2329 assert(scip != NULL);
2330
2331 SCIP_CALL( SCIPexprhdlrReversePropExpr(SCIPexprGetHdlr(expr), scip->set, expr, bounds, childrenbounds, infeasible) );
2332
2333 return SCIP_OKAY;
2334}
2335
2336/** calls the symmetry data callback for an expression
2337 *
2338 * Returns no information if not implemented.
2339 */
2340SCIP_DECL_EXPRGETSYMDATA(SCIPcallExprGetSymData)
2341{
2342 assert(scip != NULL);
2343 assert(expr != NULL);
2344 assert(symdata != NULL);
2345
2346 SCIP_CALL( SCIPexprGetSymData(scip->set, expr, symdata) );
2347
2348 return SCIP_OKAY;
2349}
2350
2351/**@} */
2352
2353/**@name Expression Iterator Methods */
2354/**@{ */
2355
2356#ifdef NDEBUG
2357#undef SCIPcreateExpriter
2358#undef SCIPfreeExpriter
2359#endif
2360
2361/** creates an expression iterator */
2363 SCIP* scip, /**< SCIP data structure */
2364 SCIP_EXPRITER** iterator /**< buffer to store expression iterator */
2365 )
2366{
2367 assert(scip != NULL);
2368 assert(scip->mem != NULL);
2369
2370 SCIP_CALL( SCIPexpriterCreate(scip->stat, scip->mem->probmem, iterator) );
2371
2372 return SCIP_OKAY;
2373}
2374
2375/** frees an expression iterator */
2377 SCIP_EXPRITER** iterator /**< pointer to the expression iterator */
2378 )
2379{
2380 SCIPexpriterFree(iterator);
2381}
2382
2383/**@} */
2384
2385
2386/**@name Quadratic expression functions */
2387/**@{ */
2388
2389#ifdef NDEBUG
2390#undef SCIPcheckExprQuadratic
2391#undef SCIPfreeExprQuadratic
2392#undef SCIPcomputeExprQuadraticCurvature
2393#endif
2394
2395/** checks whether an expression is quadratic
2396 *
2397 * An expression is quadratic if it is either a square (of some expression), a product (of two expressions),
2398 * or a sum of terms where at least one is a square or a product.
2399 *
2400 * Use SCIPexprGetQuadraticData() to get data about the representation as quadratic.
2401 */
2403 SCIP* scip, /**< SCIP data structure */
2404 SCIP_EXPR* expr, /**< expression */
2405 SCIP_Bool* isquadratic /**< buffer to store result */
2406 )
2407{
2408 assert(scip != NULL);
2409 assert(scip->mem != NULL);
2410
2411 SCIP_CALL( SCIPexprCheckQuadratic(scip->set, scip->mem->probmem, expr, isquadratic) );
2412
2413 return SCIP_OKAY;
2414}
2415
2416/** frees information on quadratic representation of an expression
2417 *
2418 * Before doing changes to an expression, it can be useful to call this function.
2419 */
2421 SCIP* scip, /**< SCIP data structure */
2422 SCIP_EXPR* expr /**< expression */
2423 )
2424{
2425 assert(scip != NULL);
2426 assert(scip->mem != NULL);
2427
2428 SCIPexprFreeQuadratic(scip->mem->probmem, expr);
2429}
2430
2431/** evaluates quadratic term in a solution
2432 *
2433 * \note This requires that every expression used in the quadratic data is a variable expression.
2434 */
2436 SCIP* scip, /**< SCIP data structure */
2437 SCIP_EXPR* expr, /**< quadratic expression */
2438 SCIP_SOL* sol /**< solution to evaluate, or NULL for LP solution */
2439 )
2440{
2441 SCIP_Real auxvalue;
2442 int nlinexprs;
2443 SCIP_Real* lincoefs;
2444 SCIP_EXPR** linexprs;
2445 int nquadexprs;
2446 int nbilinexprs;
2447 int i;
2448
2449 assert(scip != NULL);
2450 assert(expr != NULL);
2451
2452 SCIPexprGetQuadraticData(expr, &auxvalue, &nlinexprs, &linexprs, &lincoefs, &nquadexprs, &nbilinexprs, NULL, NULL);
2453
2454 /* linear terms */
2455 for( i = 0; i < nlinexprs; ++i )
2456 {
2457 assert(SCIPexprIsVar(scip->set, linexprs[i]));
2458 auxvalue += lincoefs[i] * SCIPgetSolVal(scip, sol, SCIPgetVarExprVar(linexprs[i]));
2459 }
2460
2461 /* quadratic terms */
2462 for( i = 0; i < nquadexprs; ++i )
2463 {
2464 SCIP_EXPR* quadexprterm;
2465 SCIP_Real lincoef;
2466 SCIP_Real sqrcoef;
2467 SCIP_Real solval;
2468
2469 SCIPexprGetQuadraticQuadTerm(expr, i, &quadexprterm, &lincoef, &sqrcoef, NULL, NULL, NULL);
2470
2471 assert(SCIPexprIsVar(scip->set, quadexprterm));
2472
2473 solval = SCIPgetSolVal(scip, sol, SCIPgetVarExprVar(quadexprterm));
2474 auxvalue += (lincoef + sqrcoef * solval) * solval;
2475 }
2476
2477 /* bilinear terms */
2478 for( i = 0; i < nbilinexprs; ++i )
2479 {
2480 SCIP_EXPR* expr1;
2481 SCIP_EXPR* expr2;
2482 SCIP_Real coef;
2483
2484 SCIPexprGetQuadraticBilinTerm(expr, i, &expr1, &expr2, &coef, NULL, NULL);
2485
2486 assert(SCIPexprIsVar(scip->set, expr1));
2487 assert(SCIPexprIsVar(scip->set, expr2));
2488 auxvalue += coef * SCIPgetSolVal(scip, sol, SCIPgetVarExprVar(expr1)) * SCIPgetSolVal(scip, sol, SCIPgetVarExprVar(expr2));
2489 }
2490
2491 return auxvalue;
2492}
2493
2494/** prints quadratic expression */
2496 SCIP* scip, /**< SCIP data structure */
2497 SCIP_EXPR* expr /**< quadratic expression */
2498 )
2499{
2500 SCIP_Real constant;
2501 int nlinexprs;
2502 SCIP_Real* lincoefs;
2503 SCIP_EXPR** linexprs;
2504 int nquadexprs;
2505 int nbilinexprs;
2506 int c;
2507
2508 assert(scip != NULL);
2509 assert(expr != NULL);
2510
2511 SCIPexprGetQuadraticData(expr, &constant, &nlinexprs, &linexprs, &lincoefs, &nquadexprs, &nbilinexprs, NULL, NULL);
2512
2513 SCIPinfoMessage(scip, NULL, "Constant: %g\n", constant);
2514
2515 SCIPinfoMessage(scip, NULL, "Linear: ");
2516 for( c = 0; c < nlinexprs; ++c )
2517 {
2518 SCIPinfoMessage(scip, NULL, "%g * ", lincoefs[c]);
2519 SCIP_CALL( SCIPprintExpr(scip, linexprs[c], NULL) );
2520 if( c < nlinexprs - 1 )
2521 SCIPinfoMessage(scip, NULL, " + ");
2522 }
2523 SCIPinfoMessage(scip, NULL, "\n");
2524
2525 SCIPinfoMessage(scip, NULL, "Quadratic: ");
2526 for( c = 0; c < nquadexprs; ++c )
2527 {
2528 SCIP_EXPR* quadexprterm;
2529 SCIP_Real lincoef;
2530 SCIP_Real sqrcoef;
2531
2532 SCIPexprGetQuadraticQuadTerm(expr, c, &quadexprterm, &lincoef, &sqrcoef, NULL, NULL, NULL);
2533 SCIPinfoMessage(scip, NULL, "(%g * sqr(", sqrcoef);
2534 SCIP_CALL( SCIPprintExpr(scip, quadexprterm, NULL) );
2535 SCIPinfoMessage(scip, NULL, ") + %g) * ", lincoef);
2536 SCIP_CALL( SCIPprintExpr(scip, quadexprterm, NULL) );
2537 if( c < nquadexprs - 1 )
2538 SCIPinfoMessage(scip, NULL, " + ");
2539 }
2540 SCIPinfoMessage(scip, NULL, "\n");
2541
2542 if( nbilinexprs == 0 )
2543 {
2544 SCIPinfoMessage(scip, NULL, "Bilinear: none\n");
2545 return SCIP_OKAY;
2546 }
2547
2548 SCIPinfoMessage(scip, NULL, "Bilinear: ");
2549 for( c = 0; c < nbilinexprs; ++c )
2550 {
2551 SCIP_EXPR* expr1;
2552 SCIP_EXPR* expr2;
2553 SCIP_Real coef;
2554
2555 SCIPexprGetQuadraticBilinTerm(expr, c, &expr1, &expr2, &coef, NULL, NULL);
2556
2557 SCIPinfoMessage(scip, NULL, "%g * ", coef);
2558 SCIP_CALL( SCIPprintExpr(scip, expr1, NULL) );
2559 SCIPinfoMessage(scip, NULL, " * ");
2560 SCIP_CALL( SCIPprintExpr(scip, expr2, NULL) );
2561 if( c < nbilinexprs - 1 )
2562 SCIPinfoMessage(scip, NULL, " + ");
2563 }
2564 SCIPinfoMessage(scip, NULL, "\n");
2565
2566 SCIPinfoMessage(scip, NULL, "Bilinear of quadratics: \n");
2567 for( c = 0; c < nquadexprs; ++c )
2568 {
2569 SCIP_EXPR* quadexprterm;
2570 int nadjbilin;
2571 int* adjbilin;
2572 int i;
2573
2574 SCIPexprGetQuadraticQuadTerm(expr, c, &quadexprterm, NULL, NULL, &nadjbilin, &adjbilin, NULL);
2575
2576 SCIPinfoMessage(scip, NULL, " For ");
2577 SCIP_CALL( SCIPprintExpr(scip, quadexprterm, NULL) );
2578 SCIPinfoMessage(scip, NULL, " we see: ");
2579 for( i = 0; i < nadjbilin; ++i )
2580 {
2581 SCIP_EXPR* expr1;
2582 SCIP_EXPR* expr2;
2583 SCIP_Real coef;
2584
2585 SCIPexprGetQuadraticBilinTerm(expr, adjbilin[i], &expr1, &expr2, &coef, NULL, NULL);
2586
2587 SCIPinfoMessage(scip, NULL, "%g * ", coef);
2588 SCIP_CALL( SCIPprintExpr(scip, expr1, NULL) );
2589 SCIPinfoMessage(scip, NULL, " * ");
2590 SCIP_CALL( SCIPprintExpr(scip, expr2, NULL) );
2591 if( i < nadjbilin - 1 )
2592 SCIPinfoMessage(scip, NULL, " + ");
2593 }
2594 SCIPinfoMessage(scip, NULL, "\n");
2595 }
2596
2597 return SCIP_OKAY;
2598}
2599
2600/** checks the curvature of the quadratic expression
2601 *
2602 * For this, it builds the matrix Q of quadratic coefficients and computes its eigenvalues using LAPACK.
2603 * If Q is
2604 * - semidefinite positive -> curv is set to convex,
2605 * - semidefinite negative -> curv is set to concave,
2606 * - otherwise -> curv is set to unknown.
2607 *
2608 * If `assumevarfixed` is given and some expressions in quadratic terms correspond to variables present in
2609 * this hashmap, then the corresponding rows and columns are ignored in the matrix Q.
2610 */
2612 SCIP* scip, /**< SCIP data structure */
2613 SCIP_EXPR* expr, /**< quadratic expression */
2614 SCIP_EXPRCURV* curv, /**< pointer to store the curvature of quadratics */
2615 SCIP_HASHMAP* assumevarfixed, /**< hashmap containing variables that should be assumed to be fixed, or NULL */
2616 SCIP_Bool storeeigeninfo /**< whether the eigenvalues and eigenvectors should be stored */
2617 )
2618{
2619 assert(scip != NULL);
2620 assert(scip->mem != NULL);
2621
2622 SCIP_CALL( SCIPexprComputeQuadraticCurvature(scip->set, scip->mem->probmem, scip->mem->buffer, scip->messagehdlr,
2623 expr, curv, assumevarfixed, storeeigeninfo) );
2624
2625 return SCIP_OKAY;
2626}
2627
2628/**@} */
2629
2630/**@name Monomial expression functions */
2631/**@{ */
2632
2633#ifdef NDEBUG
2634#undef SCIPgetExprMonomialData
2635#endif
2636
2637/** returns a monomial representation of a product expression
2638 *
2639 * The array to store all factor expressions needs to be of size the number of
2640 * children in the expression which is given by SCIPexprGetNChildren().
2641 *
2642 * Given a non-trivial monomial expression, the function finds its representation as \f$cx^\alpha\f$, where
2643 * \f$c\f$ is a real coefficient, \f$x\f$ is a vector of auxiliary or original variables (where some entries can
2644 * be NULL is the auxiliary variable has not been created yet), and \f$\alpha\f$ is a real vector of exponents.
2645 *
2646 * A non-trivial monomial is a product of a least two expressions.
2647 */
2649 SCIP* scip, /**< SCIP data structure */
2650 SCIP_EXPR* expr, /**< expression */
2651 SCIP_Real* coef, /**< coefficient \f$c\f$ */
2652 SCIP_Real* exponents, /**< exponents \f$\alpha\f$ */
2653 SCIP_EXPR** factors /**< factor expressions \f$x\f$ */
2654 )
2655{
2656 assert(scip != NULL);
2657 assert(scip->mem != NULL);
2658
2659 SCIP_CALL( SCIPexprGetMonomialData(scip->set, scip->mem->probmem, expr, coef, exponents, factors) );
2660
2661 return SCIP_OKAY;
2662}
2663
2664/**@} */
#define SCIPcheckStage(scip, method, init, problem, transforming, transformed, initpresolve, presolving, exitpresolve, presolved, initsolve, solving, solved, exitsolve, freetrans, freescip)
Definition: debug.h:364
#define NULL
Definition: def.h:248
#define SCIP_MAXSTRLEN
Definition: def.h:269
#define SCIP_Longint
Definition: def.h:141
#define SCIP_SPACECONTROL
Definition: def.h:270
#define SCIP_Bool
Definition: def.h:91
#define SCIP_ALLOC(x)
Definition: def.h:366
#define SCIP_Real
Definition: def.h:156
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define SCIP_CALL_TERMINATE(retcode, x, TERM)
Definition: def.h:376
#define SCIP_CALL(x)
Definition: def.h:355
SCIP_RETCODE SCIPexprPrint(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_MESSAGEHDLR *messagehdlr, FILE *file, SCIP_EXPR *expr)
Definition: expr.c:2266
SCIP_Bool SCIPexprIsPower(SCIP_SET *set, SCIP_EXPR *expr)
Definition: expr.c:2254
SCIP_RETCODE SCIPexprEvalActivity(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *rootexpr)
Definition: expr.c:2961
SCIP_RETCODE SCIPexprPrintDotInit(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPRPRINTDATA **printdata, FILE *file, SCIP_EXPRPRINT_WHAT whattoprint)
Definition: expr.c:2315
SCIP_RETCODE SCIPexprCopy(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_SET *targetset, SCIP_STAT *targetstat, BMS_BLKMEM *targetblkmem, SCIP_EXPR *sourceexpr, SCIP_EXPR **targetexpr, SCIP_DECL_EXPR_MAPEXPR((*mapexpr)), void *mapexprdata, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr.c:1878
SCIP_RETCODE SCIPexprPrintDotInit2(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPRPRINTDATA **printdata, const char *filename, SCIP_EXPRPRINT_WHAT whattoprint)
Definition: expr.c:2347
SCIP_RETCODE SCIPexprSimplify(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *rootexpr, SCIP_EXPR **simplified, SCIP_Bool *changed, SCIP_Bool *infeasible, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr.c:3200
SCIP_RETCODE SCIPexprhdlrInitEstimatesExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_INTERVAL *bounds, SCIP_Bool overestimate, SCIP_Real *coefs[SCIP_EXPR_MAXINITESTIMATES], SCIP_Real constant[SCIP_EXPR_MAXINITESTIMATES], int *nreturned)
Definition: expr.c:1600
SCIP_RETCODE SCIPexprComputeQuadraticCurvature(SCIP_SET *set, BMS_BLKMEM *blkmem, BMS_BUFMEM *bufmem, SCIP_MESSAGEHDLR *messagehdlr, SCIP_EXPR *expr, SCIP_EXPRCURV *curv, SCIP_HASHMAP *assumevarfixed, SCIP_Bool storeeigeninfo)
Definition: expr.c:3646
SCIP_RETCODE SCIPexprGetSymData(SCIP_SET *set, SCIP_EXPR *expr, SYM_EXPRDATA **symdata)
Definition: expr.c:3294
SCIP_RETCODE SCIPexprhdlrSimplifyExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_EXPR **simplifiedexpr, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr.c:1635
SCIP_RETCODE SCIPexprEvalGradient(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *rootexpr, SCIP_SOL *sol, SCIP_Longint soltag)
Definition: expr.c:2745
SCIP_RETCODE SCIPexprReplaceChild(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, int childidx, SCIP_EXPR *newchild)
Definition: expr.c:1816
SCIP_RETCODE SCIPexprhdlrReversePropExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_INTERVAL bounds, SCIP_INTERVAL *childrenbounds, SCIP_Bool *infeasible)
Definition: expr.c:1680
SCIP_Bool SCIPexprIsVar(SCIP_SET *set, SCIP_EXPR *expr)
Definition: expr.c:2206
SCIP_RETCODE SCIPexprCheckQuadratic(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, SCIP_Bool *isquadratic)
Definition: expr.c:3326
SCIP_RETCODE SCIPexprhdlrPrintExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_EXPR *expr, SCIP_EXPRITER_STAGE stage, int currentchild, unsigned int parentprecedence, FILE *file)
Definition: expr.c:917
SCIP_RETCODE SCIPexprEvalHessianDir(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *rootexpr, SCIP_SOL *sol, SCIP_Longint soltag, SCIP_SOL *direction)
Definition: expr.c:2855
int SCIPexprCompare(SCIP_SET *set, SCIP_EXPR *expr1, SCIP_EXPR *expr2)
Definition: expr.c:3093
SCIP_RETCODE SCIPexprhdlrMonotonicityExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, int childidx, SCIP_MONOTONE *result)
Definition: expr.c:1054
SCIP_RETCODE SCIPexprhdlrEvalExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, BMS_BUFMEM *bufmem, SCIP_EXPR *expr, SCIP_Real *val, SCIP_Real *childrenvals, SCIP_SOL *sol)
Definition: expr.c:1205
SCIP_RETCODE SCIPexprRemoveChildren(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *expr)
Definition: expr.c:1846
SCIP_RETCODE SCIPexprhdlrIntegralityExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_IMPLINTTYPE *integrality)
Definition: expr.c:1083
SCIP_RETCODE SCIPexprhdlrHashExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, unsigned int *hashkey, unsigned int *childrenhashes)
Definition: expr.c:1113
SCIP_Bool SCIPexprIsValue(SCIP_SET *set, SCIP_EXPR *expr)
Definition: expr.c:2218
void SCIPexprCapture(SCIP_EXPR *expr)
Definition: expr.c:2064
SCIP_RETCODE SCIPexprhdlrIntEvalExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_INTERVAL *interval, SCIP_DECL_EXPR_INTEVALVAR((*intevalvar)), void *intevalvardata)
Definition: expr.c:1525
SCIP_RETCODE SCIPexprPrintDotFinal(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPRPRINTDATA **printdata)
Definition: expr.c:2493
SCIP_RETCODE SCIPexprAppendChild(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, SCIP_EXPR *child)
Definition: expr.c:1785
SCIP_RETCODE SCIPexprDuplicateShallow(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, SCIP_EXPR **copyexpr, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr.c:2033
SCIP_RETCODE SCIPexprhdlrParseExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, const char *string, const char **endstring, SCIP_EXPR **expr, SCIP_Bool *success, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr.c:986
SCIP_RETCODE SCIPexprRelease(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR **expr)
Definition: expr.c:2074
SCIP_RETCODE SCIPexprGetMonomialData(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, SCIP_Real *coef, SCIP_Real *exponents, SCIP_EXPR **factors)
Definition: expr.c:4283
SCIP_RETCODE SCIPexprhdlrCurvatureExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_EXPRCURV exprcurvature, SCIP_Bool *success, SCIP_EXPRCURV *childcurv)
Definition: expr.c:1025
SCIP_RETCODE SCIPexprDismantle(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_MESSAGEHDLR *messagehdlr, FILE *file, SCIP_EXPR *expr)
Definition: expr.c:2546
SCIP_RETCODE SCIPexprCreate(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_EXPR **expr, SCIP_EXPRHDLR *exprhdlr, SCIP_EXPRDATA *exprdata, int nchildren, SCIP_EXPR **children, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr.c:1728
SCIP_Bool SCIPexprIsProduct(SCIP_SET *set, SCIP_EXPR *expr)
Definition: expr.c:2242
SCIP_RETCODE SCIPexprPrintDot(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_EXPRPRINTDATA *printdata, SCIP_EXPR *expr)
Definition: expr.c:2379
SCIP_Bool SCIPexprIsSum(SCIP_SET *set, SCIP_EXPR *expr)
Definition: expr.c:2230
SCIP_RETCODE SCIPexprhdlrEstimateExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_INTERVAL *localbounds, SCIP_INTERVAL *globalbounds, SCIP_Real *refpoint, SCIP_Bool overestimate, SCIP_Real targetvalue, SCIP_Real *coefs, SCIP_Real *constant, SCIP_Bool *islocal, SCIP_Bool *success, SCIP_Bool *branchcand)
Definition: expr.c:1556
SCIP_RETCODE SCIPexprhdlrEvalFwDiffExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, BMS_BUFMEM *bufmem, SCIP_EXPR *expr, SCIP_Real *val, SCIP_Real *dot, SCIP_Real *childrenvals, SCIP_SOL *sol, SCIP_Real *childrendirs, SCIP_SOL *direction)
Definition: expr.c:1386
SCIP_RETCODE SCIPexprhdlrCreate(BMS_BLKMEM *blkmem, SCIP_EXPRHDLR **exprhdlr, const char *name, const char *desc, unsigned int precedence, SCIP_DECL_EXPREVAL((*eval)), SCIP_EXPRHDLRDATA *data)
Definition: expr.c:305
void SCIPexprFreeQuadratic(BMS_BLKMEM *blkmem, SCIP_EXPR *expr)
Definition: expr.c:3600
SCIP_RETCODE SCIPexprEval(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, SCIP_SOL *sol, SCIP_Longint soltag)
Definition: expr.c:2654
private functions to work with algebraic expressions
void SCIPexpriterFree(SCIP_EXPRITER **iterator)
Definition: expriter.c:446
SCIP_RETCODE SCIPexpriterCreate(SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPRITER **iterator)
Definition: expriter.c:427
power and signed power expression handlers
product expression handler
sum expression handler
constant value expression handler
variable expression handler
static SCIP_RETCODE eval(SCIP *scip, SCIP_EXPR *expr, SCIP_EXPRINTDATA *exprintdata, const vector< Type > &x, Type &val)
SCIP_RETCODE SCIPgetVarCopy(SCIP *sourcescip, SCIP *targetscip, SCIP_VAR *sourcevar, SCIP_VAR **targetvar, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, SCIP_Bool *success)
Definition: scip_copy.c:713
SCIP_RETCODE SCIPcreateExprVar(SCIP *scip, SCIP_EXPR **expr, SCIP_VAR *var, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_var.c:398
SCIP_RETCODE SCIPcreateExprProduct(SCIP *scip, SCIP_EXPR **expr, int nchildren, SCIP_EXPR **children, SCIP_Real coefficient, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
SCIP_RETCODE SCIPappendExprSumExpr(SCIP *scip, SCIP_EXPR *expr, SCIP_EXPR *child, SCIP_Real childcoef)
Definition: expr_sum.c:1154
SCIP_RETCODE SCIPcreateExprSum(SCIP *scip, SCIP_EXPR **expr, int nchildren, SCIP_EXPR **children, SCIP_Real *coefficients, SCIP_Real constant, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_sum.c:1117
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 SCIPcreateExprPow(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPR *child, SCIP_Real exponent, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_pow.c:3185
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:2246
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:3095
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3284
SCIP_RETCODE SCIPhashmapInsert(SCIP_HASHMAP *hashmap, void *origin, void *image)
Definition: misc.c:3143
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:3061
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3466
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:208
#define SCIPdebugMsg
Definition: scip_message.h:78
void SCIPmultihashFree(SCIP_MULTIHASH **multihash)
Definition: misc.c:1995
SCIP_RETCODE SCIPmultihashInsert(SCIP_MULTIHASH *multihash, void *element)
Definition: misc.c:2026
SCIP_RETCODE SCIPmultihashCreate(SCIP_MULTIHASH **multihash, BMS_BLKMEM *blkmem, int tablesize, SCIP_DECL_HASHGETKEY((*hashgetkey)), SCIP_DECL_HASHKEYEQ((*hashkeyeq)), SCIP_DECL_HASHKEYVAL((*hashkeyval)), void *userptr)
Definition: misc.c:1962
void * SCIPmultihashRetrieveNext(SCIP_MULTIHASH *multihash, SCIP_MULTIHASHLIST **multihashlist, void *key)
Definition: misc.c:2115
int SCIPgetNExprhdlrs(SCIP *scip)
Definition: scip_expr.c:883
SCIP_Bool SCIPexprhdlrHasCurvature(SCIP_EXPRHDLR *exprhdlr)
Definition: expr.c:655
SCIP_EXPRHDLR * SCIPgetExprhdlrProduct(SCIP *scip)
Definition: scip_expr.c:939
SCIP_EXPRHDLR * SCIPgetExprhdlrVar(SCIP *scip)
Definition: scip_expr.c:906
SCIP_EXPRHDLR ** SCIPgetExprhdlrs(SCIP *scip)
Definition: scip_expr.c:872
SCIP_EXPRHDLR * SCIPgetExprhdlrValue(SCIP *scip)
Definition: scip_expr.c:917
SCIP_EXPRHDLR * SCIPgetExprhdlrSum(SCIP *scip)
Definition: scip_expr.c:928
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 * SCIPgetExprhdlrPower(SCIP *scip)
Definition: scip_expr.c:950
SCIP_EXPRHDLR * SCIPfindExprhdlr(SCIP *scip, const char *name)
Definition: scip_expr.c:894
SCIP_DECL_EXPRMONOTONICITY(SCIPcallExprMonotonicity)
Definition: scip_expr.c:2194
SCIP_RETCODE SCIPcreateExprQuadratic(SCIP *scip, SCIP_EXPR **expr, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, int nquadterms, SCIP_VAR **quadvars1, SCIP_VAR **quadvars2, SCIP_Real *quadcoefs, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: scip_expr.c:1059
SCIP_RETCODE SCIPcreateExprMonomial(SCIP *scip, SCIP_EXPR **expr, int nfactors, SCIP_VAR **vars, SCIP_Real *exponents, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: scip_expr.c:1167
SCIP_RETCODE SCIPgetSymDataExpr(SCIP *scip, SCIP_EXPR *expr, SYM_EXPRDATA **symdata)
Definition: scip_expr.c:1817
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
SCIP_RETCODE SCIPappendExprChild(SCIP *scip, SCIP_EXPR *expr, SCIP_EXPR *child)
Definition: scip_expr.c:1256
SCIP_RETCODE SCIPevalExprHessianDir(SCIP *scip, SCIP_EXPR *expr, SCIP_SOL *sol, SCIP_Longint soltag, SCIP_SOL *direction)
Definition: scip_expr.c:1714
SCIP_RETCODE SCIPevalExpr(SCIP *scip, SCIP_EXPR *expr, SCIP_SOL *sol, SCIP_Longint soltag)
Definition: scip_expr.c:1661
int SCIPexprGetNChildren(SCIP_EXPR *expr)
Definition: expr.c:3872
SCIP_DECL_EXPRINTEVAL(SCIPcallExprInteval)
Definition: scip_expr.c:2261
SCIP_RETCODE SCIPprintExprQuadratic(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:2495
void SCIPexprGetQuadraticBilinTerm(SCIP_EXPR *expr, int termidx, SCIP_EXPR **expr1, SCIP_EXPR **expr2, SCIP_Real *coef, int *pos2, SCIP_EXPR **prodexpr)
Definition: expr.c:4226
SCIP_RETCODE SCIPcomputeExprIntegrality(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:2040
SCIP_DECL_EXPRPRINT(SCIPcallExprPrint)
Definition: scip_expr.c:2164
SCIP_Bool SCIPisExprProduct(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1490
SCIP_RETCODE SCIPevalExprGradient(SCIP *scip, SCIP_EXPR *expr, SCIP_SOL *sol, SCIP_Longint soltag)
Definition: scip_expr.c:1692
SCIP_RETCODE SCIPprintExprDotInit2(SCIP *scip, SCIP_EXPRPRINTDATA **printdata, const char *filename, SCIP_EXPRPRINT_WHAT whattoprint)
Definition: scip_expr.c:1543
SCIP_Bool SCIPexpriterIsEnd(SCIP_EXPRITER *iterator)
Definition: expriter.c:969
SCIP_Longint SCIPgetExprNewSoltag(SCIP *scip)
Definition: scip_expr.c:1677
void SCIPexprSetCurvature(SCIP_EXPR *expr, SCIP_EXPRCURV curvature)
Definition: expr.c:4080
SCIP_EXPR * SCIPexpriterSkipDFS(SCIP_EXPRITER *iterator)
Definition: expriter.c:930
SCIP_Bool SCIPisExprSum(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1479
SCIP_RETCODE SCIPgetExprMonomialData(SCIP *scip, SCIP_EXPR *expr, SCIP_Real *coef, SCIP_Real *exponents, SCIP_EXPR **factors)
Definition: scip_expr.c:2648
SCIP_RETCODE SCIPgetExprNVars(SCIP *scip, SCIP_EXPR *expr, int *nvars)
Definition: scip_expr.c:2083
SCIP_RETCODE SCIPduplicateExprShallow(SCIP *scip, SCIP_EXPR *expr, SCIP_EXPR **copyexpr, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: scip_expr.c:1327
void SCIPexprGetQuadraticData(SCIP_EXPR *expr, SCIP_Real *constant, int *nlinexprs, SCIP_EXPR ***linexprs, SCIP_Real **lincoefs, int *nquadexprs, int *nbilinexprs, SCIP_Real **eigenvalues, SCIP_Real **eigenvectors)
Definition: expr.c:4141
SCIP_RETCODE SCIPreplaceExprChild(SCIP *scip, SCIP_EXPR *expr, int childidx, SCIP_EXPR *newchild)
Definition: scip_expr.c:1274
SCIP_Bool SCIPisExprValue(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1468
SCIP_RETCODE SCIPcreateExpr2(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPRHDLR *exprhdlr, SCIP_EXPRDATA *exprdata, SCIP_EXPR *child1, SCIP_EXPR *child2, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: scip_expr.c:1021
void SCIPfreeExprQuadratic(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:2420
SCIP_RETCODE SCIPprintExprDot(SCIP *scip, SCIP_EXPRPRINTDATA *printdata, SCIP_EXPR *expr)
Definition: scip_expr.c:1559
int SCIPcompareExpr(SCIP *scip, SCIP_EXPR *expr1, SCIP_EXPR *expr2)
Definition: scip_expr.c:1759
SCIP_RETCODE SCIPreleaseExpr(SCIP *scip, SCIP_EXPR **expr)
Definition: scip_expr.c:1443
SCIP_EXPR * SCIPexpriterGetCurrent(SCIP_EXPRITER *iterator)
Definition: expriter.c:683
void SCIPexpriterSetStagesDFS(SCIP_EXPRITER *iterator, SCIP_EXPRITER_STAGE stopstages)
Definition: expriter.c:664
SCIP_Bool SCIPisExprVar(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1457
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 SCIPhashExpr(SCIP *scip, SCIP_EXPR *expr, unsigned int *hashval)
Definition: scip_expr.c:1771
SCIP_RETCODE SCIPcomputeExprQuadraticCurvature(SCIP *scip, SCIP_EXPR *expr, SCIP_EXPRCURV *curv, SCIP_HASHMAP *assumevarfixed, SCIP_Bool storeeigeninfo)
Definition: scip_expr.c:2611
SCIP_DECL_EXPRGETSYMDATA(SCIPcallExprGetSymData)
Definition: scip_expr.c:2340
SCIP_DECL_EXPRCURVATURE(SCIPcallExprCurvature)
Definition: scip_expr.c:2179
SCIP_RETCODE SCIPcallExprEval(SCIP *scip, SCIP_EXPR *expr, SCIP_Real *childrenvalues, SCIP_Real *val)
Definition: scip_expr.c:2210
SCIP_EXPR * SCIPexpriterRestartDFS(SCIP_EXPRITER *iterator, SCIP_EXPR *expr)
Definition: expriter.c:630
SCIP_RETCODE SCIPcreateExpriter(SCIP *scip, SCIP_EXPRITER **iterator)
Definition: scip_expr.c:2362
SCIP_RETCODE SCIPcallExprEvalFwdiff(SCIP *scip, SCIP_EXPR *expr, SCIP_Real *childrenvalues, SCIP_Real *direction, SCIP_Real *val, SCIP_Real *dot)
Definition: scip_expr.c:2237
SCIP_RETCODE SCIPprintExpr(SCIP *scip, SCIP_EXPR *expr, FILE *file)
Definition: scip_expr.c:1512
SCIP_EXPRCURV SCIPexprGetCurvature(SCIP_EXPR *expr)
Definition: expr.c:4070
SCIP_Real SCIPgetValueExprValue(SCIP_EXPR *expr)
Definition: expr_value.c:298
void SCIPexpriterSetCurrentUserData(SCIP_EXPRITER *iterator, SCIP_EXPRITER_USERDATA userdata)
Definition: expriter.c:806
SCIP_Bool SCIPisExprPower(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1501
SCIP_RETCODE SCIPreplaceCommonSubexpressions(SCIP *scip, SCIP_EXPR **exprs, int nexprs, SCIP_Bool *replacedroot)
Definition: scip_expr.c:1845
SCIP_EXPR * SCIPexpriterGetNext(SCIP_EXPRITER *iterator)
Definition: expriter.c:858
SCIP_DECL_EXPRSIMPLIFY(SCIPcallExprSimplify)
Definition: scip_expr.c:2310
SCIP_RETCODE SCIPcheckExprQuadratic(SCIP *scip, SCIP_EXPR *expr, SCIP_Bool *isquadratic)
Definition: scip_expr.c:2402
SCIP_EXPR ** SCIPexprGetChildren(SCIP_EXPR *expr)
Definition: expr.c:3882
SCIP_RETCODE SCIPprintExprDotFinal(SCIP *scip, SCIP_EXPRPRINTDATA **printdata)
Definition: scip_expr.c:1573
SCIP_RETCODE SCIPprintExprDotInit(SCIP *scip, SCIP_EXPRPRINTDATA **printdata, FILE *file, SCIP_EXPRPRINT_WHAT whattoprint)
Definition: scip_expr.c:1527
SCIP_DECL_EXPRESTIMATE(SCIPcallExprEstimate)
Definition: scip_expr.c:2276
SCIP_RETCODE SCIPcopyExpr(SCIP *sourcescip, SCIP *targetscip, SCIP_EXPR *expr, SCIP_EXPR **copyexpr, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, SCIP_Bool *valid)
Definition: scip_expr.c:1344
SCIP_VAR * SCIPgetVarExprVar(SCIP_EXPR *expr)
Definition: expr_var.c:424
SCIP_RETCODE SCIPshowExpr(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1595
SCIP_Real SCIPevalExprQuadratic(SCIP *scip, SCIP_EXPR *expr, SCIP_SOL *sol)
Definition: scip_expr.c:2435
SCIP_RETCODE SCIPcomputeExprCurvature(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1960
SCIP_DECL_EXPRREVERSEPROP(SCIPcallExprReverseprop)
Definition: scip_expr.c:2327
void SCIPexprGetQuadraticQuadTerm(SCIP_EXPR *quadexpr, int termidx, SCIP_EXPR **expr, SCIP_Real *lincoef, SCIP_Real *sqrcoef, int *nadjbilin, int **adjbilin, SCIP_EXPR **sqrexpr)
Definition: expr.c:4186
int SCIPexpriterGetChildIdxDFS(SCIP_EXPRITER *iterator)
Definition: expriter.c:707
SCIP_DECL_EXPRINITESTIMATES(SCIPcallExprInitestimates)
Definition: scip_expr.c:2292
void SCIPfreeExpriter(SCIP_EXPRITER **iterator)
Definition: scip_expr.c:2376
SCIP_EXPRITER_STAGE SCIPexpriterGetStageDFS(SCIP_EXPRITER *iterator)
Definition: expriter.c:696
void SCIPexprSetIntegrality(SCIP_EXPR *expr, SCIP_IMPLINTTYPE integrality)
Definition: expr.c:4111
SCIP_RETCODE SCIPduplicateExpr(SCIP *scip, SCIP_EXPR *expr, SCIP_EXPR **copyexpr, SCIP_DECL_EXPR_MAPEXPR((*mapexpr)), void *mapexprdata, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: scip_expr.c:1307
void SCIPcaptureExpr(SCIP_EXPR *expr)
Definition: scip_expr.c:1435
SCIP_RETCODE SCIPexpriterInit(SCIP_EXPRITER *iterator, SCIP_EXPR *expr, SCIP_EXPRITER_TYPE type, SCIP_Bool allowrevisit)
Definition: expriter.c:501
SCIP_RETCODE SCIPgetExprVarExprs(SCIP *scip, SCIP_EXPR *expr, SCIP_EXPR **varexprs, int *nvarexprs)
Definition: scip_expr.c:2121
SCIP_EXPRITER_USERDATA SCIPexpriterGetExprUserData(SCIP_EXPRITER *iterator, SCIP_EXPR *expr)
Definition: expriter.c:790
SCIP_RETCODE SCIPdismantleExpr(SCIP *scip, FILE *file, SCIP_EXPR *expr)
Definition: scip_expr.c:1634
SCIP_RETCODE SCIPremoveExprChildren(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1293
SCIP_RETCODE SCIPsimplifyExpr(SCIP *scip, SCIP_EXPR *rootexpr, SCIP_EXPR **simplified, SCIP_Bool *changed, SCIP_Bool *infeasible, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: scip_expr.c:1798
SCIP_RETCODE SCIPevalExprActivity(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1742
SCIP_EXPRHDLR * SCIPexprGetHdlr(SCIP_EXPR *expr)
Definition: expr.c:3895
SCIP_EXPR * SCIPexpriterGetChildExprDFS(SCIP_EXPRITER *iterator)
Definition: expriter.c:721
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:57
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip_mem.c:139
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:128
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1765
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_RETCODE SCIPparseVarName(SCIP *scip, const char *str, SCIP_VAR **var, char **endptr)
Definition: scip_var.c:728
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:23267
SCIP_Bool SCIPstrToRealValue(const char *str, SCIP_Real *value, char **endptr)
Definition: misc.c:10955
SCIP_RETCODE SCIPskipSpace(char **s)
Definition: misc.c:10816
#define BMSreallocBufferMemoryArray(mem, ptr, num)
Definition: memory.h:733
#define BMSfreeBufferMemoryArray(mem, ptr)
Definition: memory.h:742
#define BMSallocBufferMemoryArray(mem, ptr, num)
Definition: memory.h:731
internal miscellaneous methods
#define SCIPerrorMessage
Definition: pub_message.h:64
#define SCIPisFinite(x)
Definition: pub_misc.h:82
public methods for problem variables
public methods for problem copies
static SCIP_RETCODE parseFactor(SCIP *scip, SCIP_Bool isdenominator, SCIP_HASHMAP *vartoexprvarmap, const char *expr, const char **newpos, SCIP_EXPR **factortree, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: scip_expr.c:322
static SCIP_DECL_HASHKEYVAL(hashCommonSubexprKeyval)
Definition: scip_expr.c:754
static SCIP_RETCODE parseExpr(SCIP *scip, SCIP_HASHMAP *vartoexprvarmap, const char *expr, const char **newpos, SCIP_EXPR **exprtree, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: scip_expr.c:529
static SCIP_DECL_HASHGETKEY(hashCommonSubexprGetKey)
Definition: scip_expr.c:728
static SCIP_RETCODE hashExpr(SCIP_SET *set, BMS_BUFMEM *bufmem, SCIP_EXPR *expr, SCIP_EXPRITER *hashiterator, int *nvisitedexprs)
Definition: scip_expr.c:774
static SCIP_DECL_EXPR_MAPEXPR(copyVarExpr)
Definition: scip_expr.c:81
static SCIP_RETCODE findEqualExpr(SCIP_SET *set, SCIP_EXPR *expr, SCIP_MULTIHASH *key2expr, SCIP_EXPR **newexpr)
Definition: scip_expr.c:674
#define debugParse
Definition: scip_expr.c:144
static SCIP_RETCODE parseBase(SCIP *scip, SCIP_HASHMAP *vartoexprvarmap, const char *expr, const char **newpos, SCIP_EXPR **basetree, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: scip_expr.c:165
static SCIP_RETCODE parseTerm(SCIP *scip, SCIP_HASHMAP *vartoexprvarmap, const char *expr, const char **newpos, SCIP_EXPR **termtree, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: scip_expr.c:450
static SCIP_DECL_HASHKEYEQ(hashCommonSubexprEq)
Definition: scip_expr.c:735
public functions to work with algebraic expressions
public methods for memory management
public methods for message handling
public methods for global and local (sub)problems
public methods for solutions
public methods for SCIP variables
SCIP_EXPRHDLR * SCIPsetFindExprhdlr(SCIP_SET *set, const char *name)
Definition: set.c:5426
SCIP_RETCODE SCIPsetIncludeExprhdlr(SCIP_SET *set, SCIP_EXPRHDLR *exprhdlr)
Definition: set.c:5392
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:6080
internal methods for global SCIP settings
SCIP_EXPRITER * hashiterator
Definition: scip_expr.c:723
SCIP_HASHMAP * consmap
Definition: scip_expr.c:73
SCIP_Bool valid
Definition: scip_expr.c:76
SCIP_Bool global
Definition: scip_expr.c:75
SCIP_HASHMAP * varmap
Definition: scip_expr.c:71
BMS_BLKMEM * probmem
Definition: struct_mem.h:49
SCIP_MEM * mem
Definition: struct_scip.h:74
SCIP_STAT * stat
Definition: struct_scip.h:82
SCIP_SET * set
Definition: struct_scip.h:75
datastructures for block memory pools and memory buffers
SCIP main data structure.
datastructures for problem statistics
Definition: heur_padm.c:135
#define SCIP_DECL_EXPR_OWNERCREATE(x)
Definition: type_expr.h:143
struct SCIP_ExprhdlrData SCIP_EXPRHDLRDATA
Definition: type_expr.h:195
struct SCIP_ExprData SCIP_EXPRDATA
Definition: type_expr.h:54
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
#define SCIP_EXPRITER_VISITINGCHILD
Definition: type_expr.h:695
unsigned int SCIP_EXPRPRINT_WHAT
Definition: type_expr.h:742
#define SCIP_DECL_EXPREVAL(x)
Definition: type_expr.h:428
@ SCIP_EXPRITER_DFS
Definition: type_expr.h:718
struct SCIP_ExprPrintData SCIP_EXPRPRINTDATA
Definition: type_expr.h:743
#define SCIP_EXPRITER_LEAVEEXPR
Definition: type_expr.h:697
#define SCIP_EXPRPRINT_ALL
Definition: type_expr.h:740
@ SCIP_FILECREATEERROR
Definition: type_retcode.h:48
@ SCIP_READERROR
Definition: type_retcode.h:45
@ SCIP_INVALIDDATA
Definition: type_retcode.h:52
@ SCIP_OKAY
Definition: type_retcode.h:42
@ SCIP_ERROR
Definition: type_retcode.h:43
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
enum SCIP_ImplintType SCIP_IMPLINTTYPE
Definition: type_var.h:117
unsigned int uintval
Definition: type_expr.h:709