SCIP Doxygen Documentation
 
Loading...
Searching...
No Matches
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-2023 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file expr.c
26 * @ingroup OTHER_CFILES
27 * @brief functions for algebraic expressions
28 * @author Ksenia Bestuzheva
29 * @author Benjamin Mueller
30 * @author Felipe Serrano
31 * @author Stefan Vigerske
32 */
33
34#include <assert.h>
35#include <ctype.h>
36
37#include "scip/expr.h"
38#include "scip/struct_expr.h"
39#include "scip/pub_misc.h"
40#include "scip/clock.h"
41#include "scip/set.h"
42#include "scip/pub_var.h"
43#include "scip/sol.h"
44#include "scip/tree.h"
45#include "scip/struct_set.h"
46#include "scip/struct_stat.h"
47#include "scip/nlpi_ipopt.h" /* for LAPACK */
48
49/*lint -e440*/
50/*lint -e441*/
51/*lint -e777*/
52
53/*
54 * Data structures
55 */
56
57/** printing to file data */
58struct SCIP_ExprPrintData
59{
60 FILE* file; /**< file to print to */
61 SCIP_EXPRITER* iterator; /**< iterator to use */
62 SCIP_Bool closefile; /**< whether file need to be closed when finished printing */
63 SCIP_HASHMAP* leaveexprs; /**< hashmap storing leave (no children) expressions */
64 SCIP_EXPRPRINT_WHAT whattoprint; /**< flags that indicate what to print for each expression */
65};
66
67/*
68 * Local methods
69 */
70
71/** frees an expression */
72static
74 BMS_BLKMEM* blkmem, /**< block memory */
75 SCIP_EXPR** expr /**< pointer to free the expression */
76 )
77{
78 assert(expr != NULL);
79 assert(*expr != NULL);
80 assert((*expr)->nuses == 1);
81 assert((*expr)->quaddata == NULL);
82 assert((*expr)->ownerdata == NULL);
83
84 /* free children array, if any */
85 BMSfreeBlockMemoryArrayNull(blkmem, &(*expr)->children, (*expr)->childrensize);
86
87 BMSfreeBlockMemory(blkmem, expr);
88 assert(*expr == NULL);
89
90 return SCIP_OKAY;
91}
92
93/*
94 * quadratic representation of expression
95 */
96
97/** first time seen quadratically and
98 * seen before linearly --> --nlinterms; assign 2; ++nquadterms
99 * not seen before linearly --> assing 1; ++nquadterms
100 *
101 * seen before --> assign += 1
102 */
103static
105 SCIP_EXPR* expr, /**< the expression */
106 SCIP_HASHMAP* seenexpr, /**< hash map */
107 int* nquadterms, /**< number of quadratic terms */
108 int* nlinterms /**< number of linear terms */
109 )
110{
111 if( SCIPhashmapExists(seenexpr, (void*)expr) )
112 {
113 int nseen = SCIPhashmapGetImageInt(seenexpr, (void*)expr);
114
115 if( nseen < 0 )
116 {
117 /* only seen linearly before */
118 assert(nseen == -1);
119
120 --*nlinterms;
121 ++*nquadterms;
122 SCIP_CALL( SCIPhashmapSetImageInt(seenexpr, (void*)expr, 2) );
123 }
124 else
125 {
126 assert(nseen > 0);
127 SCIP_CALL( SCIPhashmapSetImageInt(seenexpr, (void*)expr, nseen + 1) );
128 }
129 }
130 else
131 {
132 ++*nquadterms;
133 SCIP_CALL( SCIPhashmapInsertInt(seenexpr, (void*)expr, 1) );
134 }
135
136 return SCIP_OKAY;
137}
138
139/** returns a quadexprterm that contains the expr
140 *
141 * it either finds one that already exists or creates a new one
142 */
143static
145 BMS_BLKMEM* blkmem, /**< block memory */
146 SCIP_EXPR* expr, /**< the expression */
147 SCIP_HASHMAP* expr2idx, /**< map: expr to index in quadexpr->quadexprterms */
148 SCIP_HASHMAP* seenexpr, /**< map: expr to number of times it was seen */
149 SCIP_QUADEXPR* quadexpr, /**< data of quadratic representation of expression */
150 SCIP_QUADEXPR_QUADTERM** quadexprterm /**< buffer to store quadexprterm */
151 )
152{
153 assert(expr != NULL);
154 assert(expr2idx != NULL);
155 assert(quadexpr != NULL);
157
158 if( SCIPhashmapExists(expr2idx, (void*)expr) )
159 {
160 *quadexprterm = &quadexpr->quadexprterms[SCIPhashmapGetImageInt(expr2idx, (void*)expr)];
161 assert((*quadexprterm)->expr == expr);
162 }
163 else
164 {
165 SCIP_CALL( SCIPhashmapInsertInt(expr2idx, expr, quadexpr->nquadexprs) );
166 *quadexprterm = &quadexpr->quadexprterms[quadexpr->nquadexprs];
167 ++quadexpr->nquadexprs;
168
169 (*quadexprterm)->expr = expr;
170 (*quadexprterm)->sqrcoef = 0.0;
171 (*quadexprterm)->sqrexpr = NULL;
172 (*quadexprterm)->lincoef = 0.0;
173 (*quadexprterm)->nadjbilin = 0;
174 (*quadexprterm)->adjbilinsize = SCIPhashmapGetImageInt(seenexpr, (void*)expr);
175 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*quadexprterm)->adjbilin, (*quadexprterm)->adjbilinsize) );
176 }
177
178 return SCIP_OKAY;
179}
180
181
182/** evaluate and forward-differentiate expression
183 *
184 * also initializes derivative and bardot to 0.0
185 */
186static
188 SCIP_SET* set, /**< global SCIP settings */
189 SCIP_STAT* stat, /**< dynamic problem statistics */
190 BMS_BLKMEM* blkmem, /**< block memory */
191 SCIP_EXPR* expr, /**< expression to be evaluated */
192 SCIP_SOL* sol, /**< solution to be evaluated */
193 SCIP_Longint soltag, /**< tag that uniquely identifies the solution (with its values), or 0. */
194 SCIP_SOL* direction /**< direction for directional derivative */
195 )
196{
198
199 assert(set != NULL);
200 assert(stat != NULL);
201 assert(blkmem != NULL);
202 assert(expr != NULL);
203
204 /* assume we'll get a domain error, so we don't have to get this expr back if we abort the iteration
205 * if there is no domain error, then we will overwrite the evalvalue in the last leaveexpr stage
206 */
207 expr->evalvalue = SCIP_INVALID;
208 expr->evaltag = soltag;
209 expr->dot = SCIP_INVALID;
210
211 /* start a new difftag */
212 ++stat->exprlastdifftag;
213
214 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
217
219 {
220 /* evaluate expression only if necessary */
221 if( soltag == 0 || expr->evaltag != soltag )
222 {
223 SCIP_CALL( SCIPexprhdlrEvalExpr(expr->exprhdlr, set, NULL, expr, &expr->evalvalue, NULL, sol) );
224
225 expr->evaltag = soltag;
226 }
227
228 if( expr->evalvalue == SCIP_INVALID )
229 break;
230
231 if( expr->difftag != stat->exprlastdifftag )
232 {
233 /* compute forward diff */
234 SCIP_CALL( SCIPexprhdlrFwDiffExpr(expr->exprhdlr, set, expr, &expr->dot, direction) );
235
236 if( expr->dot == SCIP_INVALID )
237 break;
238
239 expr->derivative = 0.0;
240 expr->bardot = 0.0;
241 expr->difftag = stat->exprlastdifftag;
242 }
243 }
244
246
247 return SCIP_OKAY;
248}
249
250
251/*
252 * Public methods
253 */
254
255/* Undo the defines from pub_expr.h, which exist if NDEBUG is defined. */
256#ifdef NDEBUG
257#undef SCIPexprhdlrSetCopyFreeHdlr
258#undef SCIPexprhdlrSetCopyFreeData
259#undef SCIPexprhdlrSetPrint
260#undef SCIPexprhdlrSetParse
261#undef SCIPexprhdlrSetCurvature
262#undef SCIPexprhdlrSetMonotonicity
263#undef SCIPexprhdlrSetIntegrality
264#undef SCIPexprhdlrSetHash
265#undef SCIPexprhdlrSetCompare
266#undef SCIPexprhdlrSetDiff
267#undef SCIPexprhdlrSetIntEval
268#undef SCIPexprhdlrSetSimplify
269#undef SCIPexprhdlrSetReverseProp
270#undef SCIPexprhdlrSetEstimate
271#undef SCIPexprhdlrGetName
272#undef SCIPexprhdlrGetDescription
273#undef SCIPexprhdlrGetPrecedence
274#undef SCIPexprhdlrGetData
275#undef SCIPexprhdlrHasPrint
276#undef SCIPexprhdlrHasBwdiff
277#undef SCIPexprhdlrHasFwdiff
278#undef SCIPexprhdlrHasIntEval
279#undef SCIPexprhdlrHasEstimate
280#undef SCIPexprhdlrHasInitEstimates
281#undef SCIPexprhdlrHasSimplify
282#undef SCIPexprhdlrHasCurvature
283#undef SCIPexprhdlrHasMonotonicity
284#undef SCIPexprhdlrHasReverseProp
285#undef SCIPexprhdlrGetNCreated
286#undef SCIPexprhdlrGetNIntevalCalls
287#undef SCIPexprhdlrGetIntevalTime
288#undef SCIPexprhdlrGetNReversepropCalls
289#undef SCIPexprhdlrGetReversepropTime
290#undef SCIPexprhdlrGetNCutoffs
291#undef SCIPexprhdlrGetNDomainReductions
292#undef SCIPexprhdlrIncrementNDomainReductions
293#undef SCIPexprhdlrGetNEstimateCalls
294#undef SCIPexprhdlrGetEstimateTime
295#undef SCIPexprhdlrGetNBranchings
296#undef SCIPexprhdlrIncrementNBranchings
297#undef SCIPexprhdlrGetNSimplifyCalls
298#undef SCIPexprhdlrGetSimplifyTime
299#undef SCIPexprhdlrGetNSimplifications
300#endif
301
302/** create expression handler */
304 BMS_BLKMEM* blkmem, /**< block memory */
305 SCIP_EXPRHDLR** exprhdlr, /**< buffer where to store created expression handler */
306 const char* name, /**< name of expression handler (must not be NULL) */
307 const char* desc, /**< description of expression handler (can be NULL) */
308 unsigned int precedence, /**< precedence of expression operation (used for printing) */
309 SCIP_DECL_EXPREVAL((*eval)), /**< point evaluation callback (must not be NULL) */
310 SCIP_EXPRHDLRDATA* data /**< data of expression handler (can be NULL) */
311 )
312{
313 assert(exprhdlr != NULL);
314 assert(name != NULL);
315
316 SCIP_ALLOC( BMSallocClearBlockMemory(blkmem, exprhdlr) );
317
318 SCIP_ALLOC( BMSduplicateMemoryArray(&(*exprhdlr)->name, name, strlen(name)+1) );
319 if( desc != NULL )
320 {
321 SCIP_ALLOC( BMSduplicateMemoryArray(&(*exprhdlr)->desc, desc, strlen(desc)+1) );
322 }
323
324 (*exprhdlr)->precedence = precedence;
325 (*exprhdlr)->eval = eval;
326 (*exprhdlr)->data = data;
327
328 /* create clocks */
329 SCIP_CALL( SCIPclockCreate(&(*exprhdlr)->estimatetime, SCIP_CLOCKTYPE_DEFAULT) );
330 SCIP_CALL( SCIPclockCreate(&(*exprhdlr)->intevaltime, SCIP_CLOCKTYPE_DEFAULT) );
331 SCIP_CALL( SCIPclockCreate(&(*exprhdlr)->proptime, SCIP_CLOCKTYPE_DEFAULT) );
332 SCIP_CALL( SCIPclockCreate(&(*exprhdlr)->simplifytime, SCIP_CLOCKTYPE_DEFAULT) );
333
334 return SCIP_OKAY;
335}
336
337/** frees expression handler */
339 SCIP_EXPRHDLR** exprhdlr, /**< pointer to expression handler to be freed */
340 SCIP_SET* set, /**< global SCIP settings */
341 BMS_BLKMEM* blkmem /**< block memory */
342 )
343{
344 if( (*exprhdlr)->freehdlr != NULL )
345 {
346 SCIP_CALL( (*exprhdlr)->freehdlr(set->scip, *exprhdlr, &(*exprhdlr)->data) );
347 }
348
349 /* free clocks */
350 SCIPclockFree(&(*exprhdlr)->simplifytime);
351 SCIPclockFree(&(*exprhdlr)->intevaltime);
352 SCIPclockFree(&(*exprhdlr)->proptime);
353 SCIPclockFree(&(*exprhdlr)->estimatetime);
354
355 BMSfreeMemoryArrayNull(&(*exprhdlr)->desc);
356 BMSfreeMemoryArray(&(*exprhdlr)->name);
357
358 BMSfreeBlockMemory(blkmem, exprhdlr);
359
360 return SCIP_OKAY;
361}
362
363/**@addtogroup PublicExprHandlerMethods
364 * @{
365 */
366
367/** set the expression handler callbacks to copy and free an expression handler */
369 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
370 SCIP_DECL_EXPRCOPYHDLR((*copyhdlr)), /**< handler copy callback (can be NULL) */
371 SCIP_DECL_EXPRFREEHDLR((*freehdlr)) /**< handler free callback (can be NULL) */
372 )
373{
374 assert(exprhdlr != NULL);
375
376 exprhdlr->copyhdlr = copyhdlr;
377 exprhdlr->freehdlr = freehdlr;
378}
379
380/** set the expression handler callbacks to copy and free expression data */
382 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
383 SCIP_DECL_EXPRCOPYDATA((*copydata)), /**< expression data copy callback (can be NULL for expressions without data) */
384 SCIP_DECL_EXPRFREEDATA((*freedata)) /**< expression data free callback (can be NULL if data does not need to be freed) */
385 )
386{ /*lint --e{715}*/
387 assert(exprhdlr != NULL);
388
389 exprhdlr->copydata = copydata;
390 exprhdlr->freedata = freedata;
391}
392
393/** set the print callback of an expression handler */
395 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
396 SCIP_DECL_EXPRPRINT((*print)) /**< print callback (can be NULL) */
397 )
398{
399 assert(exprhdlr != NULL);
400
401 exprhdlr->print = print;
402}
403
404/** set the parse callback of an expression handler */
406 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
407 SCIP_DECL_EXPRPARSE((*parse)) /**< parse callback (can be NULL) */
408 )
409{
410 assert(exprhdlr != NULL);
411
412 exprhdlr->parse = parse;
413}
414
415/** set the curvature detection callback of an expression handler */
417 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
418 SCIP_DECL_EXPRCURVATURE((*curvature)) /**< curvature detection callback (can be NULL) */
419 )
420{
421 assert(exprhdlr != NULL);
422
423 exprhdlr->curvature = curvature;
424}
425
426/** set the monotonicity detection callback of an expression handler */
428 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
429 SCIP_DECL_EXPRMONOTONICITY((*monotonicity)) /**< monotonicity detection callback (can be NULL) */
430 )
431{
432 assert(exprhdlr != NULL);
433
434 exprhdlr->monotonicity = monotonicity;
435}
436
437/** set the integrality detection callback of an expression handler */
439 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
440 SCIP_DECL_EXPRINTEGRALITY((*integrality)) /**< integrality detection callback (can be NULL) */
441 )
442{
443 assert(exprhdlr != NULL);
444
445 exprhdlr->integrality = integrality;
446}
447
448/** set the hash callback of an expression handler */
450 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
451 SCIP_DECL_EXPRHASH((*hash)) /**< hash callback (can be NULL) */
452 )
453{
454 assert(exprhdlr != NULL);
455
456 exprhdlr->hash = hash;
457}
458
459/** set the compare callback of an expression handler */
461 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
462 SCIP_DECL_EXPRCOMPARE((*compare)) /**< compare callback (can be NULL) */
463 )
464{
465 assert(exprhdlr != NULL);
466
467 exprhdlr->compare = compare;
468}
469
470/** set differentiation callbacks of an expression handler */
472 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
473 SCIP_DECL_EXPRBWDIFF((*bwdiff)), /**< backward derivative evaluation callback (can be NULL) */
474 SCIP_DECL_EXPRFWDIFF((*fwdiff)), /**< forward derivative evaluation callback (can be NULL) */
475 SCIP_DECL_EXPRBWFWDIFF((*bwfwdiff)) /**< backward-forward derivative evaluation callback (can be NULL) */
476 )
477{
478 assert(exprhdlr != NULL);
479
480 exprhdlr->bwdiff = bwdiff;
481 exprhdlr->fwdiff = fwdiff;
482 exprhdlr->bwfwdiff = bwfwdiff;
483}
484
485/** set the interval evaluation callback of an expression handler */
487 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
488 SCIP_DECL_EXPRINTEVAL((*inteval)) /**< interval evaluation callback (can be NULL) */
489 )
490{
491 assert(exprhdlr != NULL);
492
493 exprhdlr->inteval = inteval;
494}
495
496/** set the simplify callback of an expression handler */
498 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
499 SCIP_DECL_EXPRSIMPLIFY((*simplify)) /**< simplify callback (can be NULL) */
500 )
501{
502 assert(exprhdlr != NULL);
503
504 exprhdlr->simplify = simplify;
505}
506
507/** set the reverse propagation callback of an expression handler */
509 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
510 SCIP_DECL_EXPRREVERSEPROP((*reverseprop)) /**< reverse propagation callback (can be NULL) */
511 )
512{
513 assert(exprhdlr != NULL);
514
515 exprhdlr->reverseprop = reverseprop;
516}
517
518/** set the estimation callbacks of an expression handler */
520 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
521 SCIP_DECL_EXPRINITESTIMATES((*initestimates)), /**< initial estimators callback (can be NULL) */
522 SCIP_DECL_EXPRESTIMATE((*estimate)) /**< estimator callback (can be NULL) */
523 )
524{
525 assert(exprhdlr != NULL);
526
527 exprhdlr->initestimates = initestimates;
528 exprhdlr->estimate = estimate;
529}
530
531/** gives the name of an expression handler */
533 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
534 )
535{
536 assert(exprhdlr != NULL);
537
538 return exprhdlr->name;
539}
540
541/** gives the description of an expression handler (can be NULL) */
543 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
544 )
545{
546 assert(exprhdlr != NULL);
547
548 return exprhdlr->desc;
549}
550
551/** gives the precedence of an expression handler */
553 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
554 )
555{
556 assert(exprhdlr != NULL);
557
558 return exprhdlr->precedence;
559}
560
561/** gives the data of an expression handler */
563 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
564 )
565{
566 assert(exprhdlr != NULL);
567
568 return exprhdlr->data;
569}
570
571/** returns whether expression handler implements the print callback */
573 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
574 )
575{
576 assert(exprhdlr != NULL);
577
578 return exprhdlr->print != NULL;
579}
580
581/** returns whether expression handler implements the backward differentiation callback */
583 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
584 )
585{
586 assert(exprhdlr != NULL);
587
588 return exprhdlr->bwdiff != NULL;
589}
590
591/** returns whether expression handler implements the forward differentiation callback */
593 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
594 )
595{
596 assert(exprhdlr != NULL);
597
598 return exprhdlr->fwdiff != NULL;
599}
600
601/** returns whether expression handler implements the interval evaluation callback */
603 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
604 )
605{
606 assert(exprhdlr != NULL);
607
608 return exprhdlr->inteval != NULL;
609}
610
611/** returns whether expression handler implements the estimator callback */
613 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
614 )
615{
616 assert(exprhdlr != NULL);
617
618 return exprhdlr->estimate != NULL;
619}
620
621/** returns whether expression handler implements the initial estimators callback */
623 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
624 )
625{
626 assert(exprhdlr != NULL);
627
628 return exprhdlr->initestimates != NULL;
629}
630
631/** returns whether expression handler implements the simplification callback */
633 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
634 )
635{
636 assert(exprhdlr != NULL);
637
638 return exprhdlr->simplify != NULL;
639}
640
641/** returns whether expression handler implements the curvature callback */
643 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
644 )
645{
646 assert(exprhdlr != NULL);
647
648 return exprhdlr->curvature != NULL;
649}
650
651/** returns whether expression handler implements the monotonicity callback */
653 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
654 )
655{
656 assert(exprhdlr != NULL);
657
658 return exprhdlr->monotonicity != NULL;
659}
660
661/** returns whether expression handler implements the reverse propagation callback */
663 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
664 )
665{
666 assert(exprhdlr != NULL);
667
668 return exprhdlr->reverseprop != NULL;
669}
670
671/** compares two expression handler w.r.t. their name */
676
677/** gets number of times an expression has been created with given expression handler */
679 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
680 )
681{
682 assert(exprhdlr != NULL);
683
684 return exprhdlr->ncreated;
685}
686
687/** gets number of times the interval evaluation callback was called */
689 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
690 )
691{
692 assert(exprhdlr != NULL);
693
694 return exprhdlr->nintevalcalls;
695}
696
697/** gets time spend in interval evaluation callback */
699 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
700 )
701{
702 assert(exprhdlr != NULL);
703
704 return SCIPclockGetTime(exprhdlr->intevaltime);
705}
706
707/** gets number of times the reverse propagation callback was called */
709 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
710 )
711{
712 assert(exprhdlr != NULL);
713
714 return exprhdlr->npropcalls;
715}
716
717/** gets time spend in reverse propagation callback */
719 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
720 )
721{
722 assert(exprhdlr != NULL);
723
724 return SCIPclockGetTime(exprhdlr->proptime);
725}
726
727/** gets number of times an empty interval was found in reverse propagation */
729 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
730 )
731{
732 assert(exprhdlr != NULL);
733
734 return exprhdlr->ncutoffs;
735}
736
737/** gets number of times a bound reduction was found in reverse propagation (and accepted by caller) */
739 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
740 )
741{
742 assert(exprhdlr != NULL);
743
744 return exprhdlr->ndomreds;
745}
746
747/** increments the domain reductions count of an expression handler */
749 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
750 int nreductions /**< number of reductions to add to counter */
751 )
752{
753 assert(exprhdlr != NULL);
754 assert(nreductions >= 0);
755
756 exprhdlr->ndomreds += nreductions;
757}
758
759/** gets number of times the estimation callback was called */
761 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
762 )
763{
764 assert(exprhdlr != NULL);
765
766 return exprhdlr->nestimatecalls;
767}
768
769/** gets time spend in estimation callback */
771 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
772 )
773{
774 assert(exprhdlr != NULL);
775
776 return SCIPclockGetTime(exprhdlr->estimatetime);
777}
778
779/** gets number of times branching candidates reported by of this expression handler were used to
780 * assemble branching candidates
781 *
782 * that is, how often did we consider branching on a child of this expression
783 */
785 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
786 )
787{
788 assert(exprhdlr != NULL);
789
790 return exprhdlr->nbranchscores;
791}
792
793/** increments the branching candidates count of an expression handler */
795 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
796 )
797{
798 assert(exprhdlr != NULL);
799
800 ++exprhdlr->nbranchscores;
801}
802
803/** gets number of times the simplify callback was called */
805 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
806 )
807{
808 assert(exprhdlr != NULL);
809
810 return exprhdlr->nsimplifycalls;
811}
812
813/** gets time spend in simplify callback */
815 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
816 )
817{
818 assert(exprhdlr != NULL);
819
820 return SCIPclockGetTime(exprhdlr->simplifytime);
821}
822
823/** gets number of times the simplify callback found a simplification */
825 SCIP_EXPRHDLR* exprhdlr /**< expression handler */
826 )
827{
828 assert(exprhdlr != NULL);
829
830 return exprhdlr->nsimplified;
831}
832
833/** @} */
834
835/** copies the given expression handler to a new scip */
837 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
838 SCIP_SET* targetset /**< SCIP_SET of SCIP to copy to */
839 )
840{
841 assert(exprhdlr != NULL);
843 assert(targetset->scip != NULL);
844
845 if( exprhdlr->copyhdlr != NULL )
846 {
847 SCIPsetDebugMsg(targetset, "including expression handler <%s> in subscip %p\n",
848 SCIPexprhdlrGetName(exprhdlr), (void*)targetset->scip);
849 SCIP_CALL( exprhdlr->copyhdlr(targetset->scip, exprhdlr) );
850 }
851 else
852 {
853 SCIPsetDebugMsg(targetset, "expression handler <%s> cannot be copied to subscip %p due "
854 "to missing copyhdlr callback\n", SCIPexprhdlrGetName(exprhdlr), (void*)targetset->scip);
855 }
856
857 return SCIP_OKAY;
858}
859
860/** initialization of expression handler (resets statistics) */
862 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
863 SCIP_SET* set /**< global SCIP settings */
864 )
865{
866 assert(exprhdlr != NULL);
867
868 if( set->misc_resetstat )
869 {
870 exprhdlr->ncreated = 0;
871 exprhdlr->nestimatecalls = 0;
872 exprhdlr->nintevalcalls = 0;
873 exprhdlr->npropcalls = 0;
874 exprhdlr->ncutoffs = 0;
875 exprhdlr->ndomreds = 0;
876 exprhdlr->nbranchscores = 0;
877 exprhdlr->nsimplifycalls = 0;
878 exprhdlr->nsimplified = 0;
879
880 SCIPclockReset(exprhdlr->estimatetime);
881 SCIPclockReset(exprhdlr->intevaltime);
882 SCIPclockReset(exprhdlr->proptime);
883 SCIPclockReset(exprhdlr->simplifytime);
884 }
885}
886
887/** calls the print callback of an expression handler
888 *
889 * The method prints an expression.
890 * It is called while iterating over the expression graph at different stages.
891 *
892 * @see SCIP_DECL_EXPRPRINT
893 */
895 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
896 SCIP_SET* set, /**< global SCIP settings */
897 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
898 SCIP_EXPR* expr, /**< expression */
899 SCIP_EXPRITER_STAGE stage, /**< stage of expression iteration */
900 int currentchild, /**< index of current child if in stage visitingchild or visitedchild */
901 unsigned int parentprecedence, /**< precedence of parent */
902 FILE* file /**< the file to print to */
903 )
904{
905 assert(exprhdlr != NULL);
906 assert(set != NULL);
907 assert(expr != NULL);
908 assert(expr->exprhdlr == exprhdlr);
909 assert(messagehdlr != NULL);
910
911 if( SCIPexprhdlrHasPrint(exprhdlr) )
912 {
913 SCIP_CALL( exprhdlr->print(set->scip, expr, stage, currentchild, parentprecedence, file) );
914 }
915 else
916 {
917 /* default: <hdlrname>(<child1>, <child2>, ...) */
918 switch( stage )
919 {
921 {
922 SCIPmessageFPrintInfo(messagehdlr, file, "%s", SCIPexprhdlrGetName(expr->exprhdlr));
923 if( expr->nchildren > 0 )
924 {
925 SCIPmessageFPrintInfo(messagehdlr, file, "(");
926 }
927 break;
928 }
929
931 {
932 assert(currentchild >= 0);
934 if( currentchild < expr->nchildren-1 )
935 {
936 SCIPmessageFPrintInfo(messagehdlr, file, ", ");
937 }
938 else
939 {
940 SCIPmessageFPrintInfo(messagehdlr, file, ")");
941 }
942
943 break;
944 }
945
948 default:
949 break;
950 }
951 }
952
953 return SCIP_OKAY;
954}
955
956/** calls the parse callback of an expression handler
957 *
958 * The method parses an expression.
959 * It should be called when parsing an expression and an operator with the expr handler name is found.
960 *
961 * @see SCIP_DECL_EXPRPARSE
962 */
964 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
965 SCIP_SET* set, /**< global SCIP settings */
966 const char* string, /**< string containing expression to be parse */
967 const char** endstring, /**< buffer to store the position of string after parsing */
968 SCIP_EXPR** expr, /**< buffer to store the parsed expression */
969 SCIP_Bool* success, /**< buffer to store whether the parsing was successful or not */
970 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call on expression copy to create ownerdata */
971 void* ownercreatedata /**< data to pass to ownercreate */
972 )
973{
974 assert(exprhdlr != NULL);
975 assert(set != NULL);
976 assert(expr != NULL);
977
978 *expr = NULL;
979
980 if( exprhdlr->parse == NULL )
981 {
982 /* TODO we could just look for a comma separated list of operands and try to initialize the expr with this one?
983 * That would be sufficient for sin, cos, exp, log, abs, for example.
984 */
985 SCIPdebugMessage("Expression handler <%s> has no parsing method.\n", SCIPexprhdlrGetName(exprhdlr));
986 *success = FALSE;
987 return SCIP_OKAY;
988 }
989
990 /* give control to exprhdlr's parser */
991 SCIP_CALL( exprhdlr->parse(set->scip, exprhdlr, string, endstring, expr, success, ownercreate, ownercreatedata) );
992
993 assert(*success || (*expr == NULL));
994
995 return SCIP_OKAY;
996}
997
998/** calls the curvature check callback of an expression handler
999 *
1000 * @see SCIP_DECL_EXPRCURVATURE
1001 */
1003 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1004 SCIP_SET* set, /**< global SCIP settings */
1005 SCIP_EXPR* expr, /**< expression to check the curvature for */
1006 SCIP_EXPRCURV exprcurvature, /**< desired curvature of this expression */
1007 SCIP_Bool* success, /**< buffer to store whether the desired curvature be obtained */
1008 SCIP_EXPRCURV* childcurv /**< array to store required curvature for each child */
1009 )
1010{
1011 assert(exprhdlr != NULL);
1012 assert(set != NULL);
1013 assert(expr != NULL);
1014 assert(expr->exprhdlr == exprhdlr);
1015 assert(success != NULL);
1016
1017 *success = FALSE;
1018
1019 if( exprhdlr->curvature != NULL )
1020 {
1021 SCIP_CALL( exprhdlr->curvature(set->scip, expr, exprcurvature, success, childcurv) );
1022 }
1023
1024 return SCIP_OKAY;
1025}
1026
1027/** calls the monotonicity check callback of an expression handler
1028 *
1029 * @see SCIP_DECL_EXPRMONOTONICITY
1030 */
1032 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1033 SCIP_SET* set, /**< global SCIP settings */
1034 SCIP_EXPR* expr, /**< expression to check the monotonicity for */
1035 int childidx, /**< index of the considered child expression */
1036 SCIP_MONOTONE* result /**< buffer to store the monotonicity */
1037 )
1038{
1039 assert(exprhdlr != NULL);
1040 assert(set != NULL);
1041 assert(expr != NULL);
1042 assert(expr->exprhdlr == exprhdlr);
1043 assert(result != NULL);
1044
1046
1047 /* check whether the expression handler implements the monotonicity callback */
1048 if( exprhdlr->monotonicity != NULL )
1049 {
1050 SCIP_CALL( exprhdlr->monotonicity(set->scip, expr, childidx, result) );
1051 }
1052
1053 return SCIP_OKAY;
1054}
1055
1056/** calls the integrality check callback of an expression handler
1057 *
1058 * @see SCIP_DECL_EXPRINTEGRALITY
1059 */
1061 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1062 SCIP_SET* set, /**< global SCIP settings */
1063 SCIP_EXPR* expr, /**< expression to check integrality for */
1064 SCIP_Bool* isintegral /**< buffer to store whether expression is integral */
1065 )
1066{
1067 assert(exprhdlr != NULL);
1068 assert(set != NULL);
1069 assert(expr != NULL);
1070 assert(expr->exprhdlr == exprhdlr);
1071 assert(isintegral != NULL);
1072
1073 *isintegral = FALSE;
1074
1075 /* check whether the expression handler implements the monotonicity callback */
1076 if( exprhdlr->integrality != NULL )
1077 {
1078 SCIP_CALL( exprhdlr->integrality(set->scip, expr, isintegral) );
1079 }
1080
1081 return SCIP_OKAY;
1082}
1083
1084/** calls the hash callback of an expression handler
1085 *
1086 * The method hashes an expression by taking the hashes of its children into account.
1087 *
1088 * @see SCIP_DECL_EXPRHASH
1089 */
1091 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1092 SCIP_SET* set, /**< global SCIP settings */
1093 SCIP_EXPR* expr, /**< expression to be hashed */
1094 unsigned int* hashkey, /**< buffer to store the hash value */
1095 unsigned int* childrenhashes /**< array with hash values of children */
1096 )
1097{
1098 assert(exprhdlr != NULL);
1099 assert(set != NULL);
1100 assert(expr != NULL);
1101 assert(expr->exprhdlr == exprhdlr);
1102 assert(hashkey != NULL);
1103 assert(childrenhashes != NULL || expr->nchildren == 0);
1104
1105 if( expr->exprhdlr->hash != NULL )
1106 {
1107 SCIP_CALL( expr->exprhdlr->hash(set->scip, expr, hashkey, childrenhashes) );
1108 }
1109 else
1110 {
1111 int i;
1112
1113 /* compute initial hash from expression handler name if callback is not implemented
1114 * this can lead to more collisions and thus a larger number of expensive expression compare calls
1115 */
1116 *hashkey = 0;
1117 for( i = 0; expr->exprhdlr->name[i] != '\0'; i++ )
1118 *hashkey += (unsigned int) expr->exprhdlr->name[i]; /*lint !e571*/
1119
1120 *hashkey = SCIPcalcFibHash((SCIP_Real)*hashkey);
1121
1122 /* now make use of the hashkeys of the children */
1123 for( i = 0; i < expr->nchildren; ++i )
1125 }
1126
1127 return SCIP_OKAY;
1128}
1129
1130/** calls the compare callback of an expression handler
1131 *
1132 * The method receives two expressions, expr1 and expr2, and returns
1133 * - -1 if expr1 < expr2,
1134 * - 0 if expr1 = expr2,
1135 * - 1 if expr1 > expr2.
1136 *
1137 * @see SCIP_DECL_EXPRCOMPARE
1138 */
1140 SCIP_SET* set, /**< global SCIP settings */
1141 SCIP_EXPR* expr1, /**< first expression in comparison */
1142 SCIP_EXPR* expr2 /**< second expression in comparison */
1143 )
1144{
1145 int i;
1146
1147 assert(expr1 != NULL);
1148 assert(expr2 != NULL);
1149 assert(expr1->exprhdlr == expr2->exprhdlr);
1150
1151 if( expr1->exprhdlr->compare != NULL )
1152 {
1153 /* enforces OR1-OR4 */
1154 return expr1->exprhdlr->compare(set->scip, expr1, expr2);
1155 }
1156
1157 /* enforces OR5: default comparison method of expressions of the same type:
1158 * expr1 < expr2 if and only if expr1_i = expr2_i for all i < k and expr1_k < expr2_k.
1159 * if there is no such k, use number of children to decide
1160 * if number of children is equal, both expressions are equal
1161 * @note: Warning, this method doesn't know about expression data. So if your expressions have special data,
1162 * you must implement the compare callback: SCIP_DECL_EXPRCOMPARE
1163 */
1164 for( i = 0; i < expr1->nchildren && i < expr2->nchildren; ++i )
1165 {
1166 int compareresult = SCIPexprCompare(set, expr1->children[i], expr2->children[i]);
1167 if( compareresult != 0 )
1168 return compareresult;
1169 }
1170
1171 return expr1->nchildren == expr2->nchildren ? 0 : expr1->nchildren < expr2->nchildren ? -1 : 1;
1172}
1173
1174/** calls the evaluation callback of an expression handler
1175 *
1176 * The method evaluates an expression by taking the values of its children into account.
1177 *
1178 * Further, allows to evaluate w.r.t. given expression and children values instead of those stored in children expressions.
1179 *
1180 * @see SCIP_DECL_EXPREVAL
1181 */
1183 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1184 SCIP_SET* set, /**< global SCIP settings */
1185 BMS_BUFMEM* bufmem, /**< buffer memory, can be NULL if childrenvals is NULL */
1186 SCIP_EXPR* expr, /**< expression to be evaluated */
1187 SCIP_Real* val, /**< buffer to store value of expression */
1188 SCIP_Real* childrenvals, /**< values for children, or NULL if values stored in children should be used */
1189 SCIP_SOL* sol /**< solution that is evaluated (can be NULL) */
1190 )
1191{
1192 SCIP_Real* origvals = NULL;
1193
1194 assert(exprhdlr != NULL);
1195 assert(set != NULL);
1196 assert(expr != NULL);
1197 assert(expr->exprhdlr == exprhdlr);
1198 assert(exprhdlr->eval != NULL);
1199 assert(val != NULL);
1200
1201 /* temporarily overwrite the evalvalue in all children with values from childrenvals */
1202 if( childrenvals != NULL && expr->nchildren > 0 )
1203 {
1204 int c;
1205
1206 assert(bufmem != NULL);
1207
1209
1210 for( c = 0; c < expr->nchildren; ++c )
1211 {
1212 origvals[c] = expr->children[c]->evalvalue;
1213 expr->children[c]->evalvalue = childrenvals[c];
1214 }
1215 }
1216
1217 /* call expression eval callback */
1218 SCIP_CALL( exprhdlr->eval(set->scip, expr, val, sol) );
1219
1220 /* if there was some evaluation error (e.g., overflow) that hasn't been caught yet, then do so now */
1221 if( !SCIPisFinite(*val) )
1222 *val = SCIP_INVALID;
1223
1224 /* restore original evalvalues in children */
1225 if( origvals != NULL )
1226 {
1227 int c;
1228 for( c = 0; c < expr->nchildren; ++c )
1229 expr->children[c]->evalvalue = origvals[c];
1230
1232 }
1233
1234 return SCIP_OKAY;
1235}
1236
1237/** calls the backward derivative evaluation callback of an expression handler
1238 *
1239 * The method should compute the partial derivative of expr w.r.t its child at childidx.
1240 * That is, it returns
1241 * \f[
1242 * \frac{\partial \text{expr}}{\partial \text{child}_{\text{childidx}}}
1243 * \f]
1244 *
1245 * Further, allows to differentiate w.r.t. given expression and children values instead of those stored in children expressions.
1246 *
1247 * @see SCIP_DECL_EXPRBWDIFF
1248 */
1250 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1251 SCIP_SET* set, /**< global SCIP settings */
1252 BMS_BUFMEM* bufmem, /**< buffer memory, can be NULL if childrenvals is NULL */
1253 SCIP_EXPR* expr, /**< expression to be differentiated */
1254 int childidx, /**< index of the child */
1255 SCIP_Real* derivative, /**< buffer to store the partial derivative w.r.t. the i-th children */
1256 SCIP_Real* childrenvals, /**< values for children, or NULL if values stored in children should be used */
1257 SCIP_Real exprval /**< value for expression, used only if childrenvals is not NULL */
1258 )
1259{
1260 SCIP_Real* origchildrenvals;
1261 SCIP_Real origexprval = SCIP_INVALID;
1262 int c;
1263
1264 assert(exprhdlr != NULL);
1265 assert(set != NULL);
1266 assert(expr != NULL);
1267 assert(expr->exprhdlr == exprhdlr);
1268 assert(derivative != NULL);
1269
1270 if( exprhdlr->bwdiff == NULL )
1271 {
1272 *derivative = SCIP_INVALID;
1273 return SCIP_OKAY;
1274 }
1275
1276 if( childrenvals != NULL )
1277 {
1278 /* temporarily overwrite the evalvalue in all children and expr with values from childrenvals and exprval, resp. */
1279 if( expr->nchildren > 0 )
1280 {
1281 assert(bufmem != NULL);
1283
1284 for( c = 0; c < expr->nchildren; ++c )
1285 {
1287 expr->children[c]->evalvalue = childrenvals[c];
1288 }
1289 }
1290
1291 origexprval = expr->evalvalue;
1292 expr->evalvalue = exprval;
1293 }
1294
1295 SCIP_CALL( expr->exprhdlr->bwdiff(set->scip, expr, childidx, derivative) );
1296
1297 /* if there was some evaluation error (e.g., overflow) that hasn't been caught yet, then do so now */
1298 if( !SCIPisFinite(*derivative) )
1299 *derivative = SCIP_INVALID;
1300
1301 /* restore original evalvalues in children */
1302 if( childrenvals != NULL )
1303 {
1304 if( expr->nchildren > 0 )
1305 {
1306 for( c = 0; c < expr->nchildren; ++c )
1307 expr->children[c]->evalvalue = origchildrenvals[c]; /*lint !e644*/
1308
1310 }
1311
1312 expr->evalvalue = origexprval;
1313 }
1314
1315 return SCIP_OKAY;
1316}
1317
1318/** calls the forward differentiation callback of an expression handler
1319 *
1320 * @see SCIP_DECL_EXPRFWDIFF
1321 */
1323 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1324 SCIP_SET* set, /**< global SCIP settings */
1325 SCIP_EXPR* expr, /**< expression to be differentiated */
1326 SCIP_Real* dot, /**< buffer to store derivative value */
1327 SCIP_SOL* direction /**< direction of the derivative (useful only for var expressions) */
1328 )
1329{
1330 assert(exprhdlr != NULL);
1331 assert(set != NULL);
1332 assert(expr != NULL);
1333 assert(expr->exprhdlr == exprhdlr);
1334 assert(dot != NULL);
1335
1336 if( exprhdlr->fwdiff == NULL )
1337 {
1338 *dot = SCIP_INVALID;
1339 return SCIP_OKAY;
1340 }
1341
1342 SCIP_CALL( exprhdlr->fwdiff(set->scip, expr, dot, direction) );
1343
1344 /* if there was some evaluation error (e.g., overflow) that hasn't been caught yet, then do so now */
1345 if( !SCIPisFinite(*dot) )
1346 *dot = SCIP_INVALID;
1347
1348 return SCIP_OKAY;
1349}
1350
1351/** calls the evaluation and forward-differentiation callback of an expression handler
1352 *
1353 * The method evaluates an expression by taking the values of its children into account.
1354 * The method differentiates an expression by taking the values and directional derivatives of its children into account.
1355 *
1356 * Further, allows to evaluate and differentiate w.r.t. given values for children instead of those stored in children expressions.
1357 *
1358 * It probably doesn't make sense to call this function for a variable-expression if sol and/or direction are not given.
1359 *
1360 * @see SCIP_DECL_EXPREVAL
1361 * @see SCIP_DECL_EXPRFWDIFF
1362 */
1364 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1365 SCIP_SET* set, /**< global SCIP settings */
1366 BMS_BUFMEM* bufmem, /**< buffer memory, can be NULL if childrenvals is NULL */
1367 SCIP_EXPR* expr, /**< expression to be evaluated */
1368 SCIP_Real* val, /**< buffer to store value of expression */
1369 SCIP_Real* dot, /**< buffer to store derivative value */
1370 SCIP_Real* childrenvals, /**< values for children, or NULL if values stored in children should be used */
1371 SCIP_SOL* sol, /**< solution that is evaluated (can be NULL) */
1372 SCIP_Real* childrendirs, /**< directional derivatives for children, or NULL if dot-values stored in children should be used */
1373 SCIP_SOL* direction /**< direction of the derivative (useful only for var expressions, can be NULL if childrendirs is given) */
1374 )
1375{
1376 SCIP_Real origval;
1377 SCIP_Real* origvals = NULL;
1378 SCIP_Real* origdots = NULL;
1379
1380 assert(exprhdlr != NULL);
1381 assert(set != NULL);
1382 assert(expr != NULL);
1383 assert(expr->exprhdlr == exprhdlr);
1384 assert(exprhdlr->eval != NULL);
1385 assert(val != NULL);
1386 assert(dot != NULL);
1387
1388 /* temporarily overwrite the evalvalue in all children with values from childrenvals */
1389 if( childrenvals != NULL && expr->nchildren > 0 )
1390 {
1391 int c;
1392
1393 assert(bufmem != NULL);
1394
1396
1397 for( c = 0; c < expr->nchildren; ++c )
1398 {
1399 origvals[c] = expr->children[c]->evalvalue;
1400 expr->children[c]->evalvalue = childrenvals[c];
1401 }
1402 }
1403
1404 /* temporarily overwrite the dot in all children with values from childrendirs */
1405 if( childrendirs != NULL && expr->nchildren > 0 )
1406 {
1407 int c;
1408
1409 assert(bufmem != NULL);
1410
1412
1413 for( c = 0; c < expr->nchildren; ++c )
1414 {
1415 origdots[c] = expr->children[c]->dot;
1416 expr->children[c]->dot = childrendirs[c];
1417 }
1418 }
1419
1420 /* remember original value */
1421 origval = expr->evalvalue;
1422
1423 /* call expression eval callback */
1424 SCIP_CALL( exprhdlr->eval(set->scip, expr, val, sol) );
1425
1426 /* if there was some evaluation error (e.g., overflow) that hasn't been caught yet, then do so now */
1427 if( !SCIPisFinite(*val) )
1428 *val = SCIP_INVALID;
1429
1430 /* temporarily overwrite evalvalue of expr, since some exprhdlr (e.g., product) access this value in fwdiff */
1431 expr->evalvalue = *val;
1432
1433 /* call forward-differentiation callback (if available) */
1434 SCIP_CALL( SCIPexprhdlrFwDiffExpr(exprhdlr, set, expr, dot, direction) );
1435
1436 /* restore original value */
1437 expr->evalvalue = origval;
1438
1439 /* restore original dots in children */
1440 if( origdots != NULL )
1441 {
1442 int c;
1443 for( c = 0; c < expr->nchildren; ++c )
1444 expr->children[c]->dot = origdots[c];
1445
1447 }
1448
1449 /* restore original evalvalues in children */
1450 if( origvals != NULL )
1451 {
1452 int c;
1453 for( c = 0; c < expr->nchildren; ++c )
1454 expr->children[c]->evalvalue = origvals[c];
1455
1457 }
1458
1459 return SCIP_OKAY;
1460}
1461
1462/** calls the evaluation callback for Hessian directions (backward over forward) of an expression handler
1463 *
1464 * @see SCIP_DECL_EXPRBWFWDIFF
1465 */
1467 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1468 SCIP_SET* set, /**< global SCIP settings */
1469 SCIP_EXPR* expr, /**< expression to be differentiated */
1470 int childidx, /**< index of the child */
1471 SCIP_Real* bardot, /**< buffer to store derivative value */
1472 SCIP_SOL* direction /**< direction of the derivative (useful only for var expressions) */
1473 )
1474{
1475 assert(exprhdlr != NULL);
1476 assert(set != NULL);
1477 assert(expr != NULL);
1478 assert(expr->exprhdlr == exprhdlr);
1479 assert(childidx >= 0);
1480 assert(childidx < expr->nchildren);
1481 assert(bardot != NULL);
1482
1483 if( exprhdlr->bwfwdiff == NULL )
1484 {
1485 *bardot = SCIP_INVALID;
1486 return SCIP_OKAY;
1487 }
1488
1489 SCIP_CALL( expr->exprhdlr->bwfwdiff(set->scip, expr, childidx, bardot, direction) );
1490
1491 /* if there was some evaluation error (e.g., overflow) that hasn't been caught yet, then do so now */
1492 if( !SCIPisFinite(*bardot) )
1493 *bardot = SCIP_INVALID;
1494
1495 return SCIP_OKAY;
1496}
1497
1498/** calls the interval evaluation callback of an expression handler
1499 *
1500 * @see SCIP_DECL_EXPRINTEVAL
1501 */
1503 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1504 SCIP_SET* set, /**< global SCIP settings */
1505 SCIP_EXPR* expr, /**< expression to be evaluated */
1506 SCIP_INTERVAL* interval, /**< buffer where to store interval */
1507 SCIP_DECL_EXPR_INTEVALVAR((*intevalvar)), /**< callback to be called when interval-evaluating a variable */
1508 void* intevalvardata /**< data to be passed to intevalvar callback */
1509 )
1510{
1511 assert(exprhdlr != NULL);
1512 assert(set != NULL);
1513 assert(expr != NULL);
1514 assert(expr->exprhdlr == exprhdlr);
1515 assert(interval != NULL);
1516
1517 if( exprhdlr->inteval != NULL )
1518 {
1519 SCIPclockStart(exprhdlr->intevaltime, set);
1520 SCIP_CALL( exprhdlr->inteval(set->scip, expr, interval, intevalvar, intevalvardata) );
1521 SCIPclockStop(exprhdlr->intevaltime, set);
1522
1523 ++exprhdlr->nintevalcalls;
1524 }
1525
1526 return SCIP_OKAY;
1527}
1528
1529/** calls the estimator callback of an expression handler
1530 *
1531 * @see SCIP_DECL_EXPRESTIMATE
1532 */
1534 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1535 SCIP_SET* set, /**< global SCIP settings */
1536 SCIP_EXPR* expr, /**< expression to be estimated */
1537 SCIP_INTERVAL* localbounds, /**< current bounds for children */
1538 SCIP_INTERVAL* globalbounds, /**< global bounds for children */
1539 SCIP_Real* refpoint, /**< children values for the reference point where to estimate */
1540 SCIP_Bool overestimate, /**< whether the expression needs to be over- or underestimated */
1541 SCIP_Real targetvalue, /**< a value that the estimator shall exceed, can be +/-infinity */
1542 SCIP_Real* coefs, /**< array to store coefficients of estimator */
1543 SCIP_Real* constant, /**< buffer to store constant part of estimator */
1544 SCIP_Bool* islocal, /**< buffer to store whether estimator is valid locally only */
1545 SCIP_Bool* success, /**< buffer to indicate whether an estimator could be computed */
1546 SCIP_Bool* branchcand /**< array to indicate which children (not) to consider for branching */
1547 )
1548{
1549 assert(exprhdlr != NULL);
1550 assert(set != NULL);
1551 assert(expr != NULL);
1552 assert(expr->exprhdlr == exprhdlr);
1553 assert(coefs != NULL);
1554 assert(islocal != NULL);
1555 assert(success != NULL);
1556
1557 *success = FALSE;
1558
1559 if( exprhdlr->estimate != NULL )
1560 {
1561 SCIPclockStart(exprhdlr->estimatetime, set);
1562 SCIP_CALL( exprhdlr->estimate(set->scip, expr, localbounds, globalbounds, refpoint, overestimate, targetvalue,
1563 coefs, constant, islocal, success, branchcand) );
1564 SCIPclockStop(exprhdlr->estimatetime, set);
1565
1566 /* update statistics */
1567 ++exprhdlr->nestimatecalls;
1568 }
1569
1570 return SCIP_OKAY;
1571}
1572
1573/** calls the intitial estimators callback of an expression handler
1574 *
1575 * @see SCIP_DECL_EXPRINITESTIMATES
1576 */
1578 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1579 SCIP_SET* set, /**< global SCIP settings */
1580 SCIP_EXPR* expr, /**< expression to be estimated */
1581 SCIP_INTERVAL* bounds, /**< bounds for children */
1582 SCIP_Bool overestimate, /**< whether the expression shall be overestimated or underestimated */
1583 SCIP_Real* coefs[SCIP_EXPR_MAXINITESTIMATES], /**< buffer to store coefficients of computed estimators */
1584 SCIP_Real constant[SCIP_EXPR_MAXINITESTIMATES], /**< buffer to store constant of computed estimators */
1585 int* nreturned /**< buffer to store number of estimators that have been computed */
1586 )
1587{
1588 assert(exprhdlr != NULL);
1589 assert(set != NULL);
1590 assert(expr != NULL);
1591 assert(expr->exprhdlr == exprhdlr);
1592 assert(nreturned != NULL);
1593
1594 *nreturned = 0;
1595
1596 if( exprhdlr->initestimates )
1597 {
1599 SCIP_CALL( exprhdlr->initestimates(set->scip, expr, bounds, overestimate, coefs, constant, nreturned) );
1601
1602 ++exprhdlr->nestimatecalls;
1603 }
1604
1605 return SCIP_OKAY;
1606}
1607
1608/** calls the simplification callback of an expression handler
1609 *
1610 * @see SCIP_DECL_EXPRSIMPLIFY
1611 */
1613 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1614 SCIP_SET* set, /**< global SCIP settings */
1615 SCIP_EXPR* expr, /**< expression to simplify */
1616 SCIP_EXPR** simplifiedexpr, /**< buffer to store the simplified expression */
1617 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call on expression copy to create ownerdata */
1618 void* ownercreatedata /**< data to pass to ownercreate */
1619 )
1620{
1621 assert(exprhdlr != NULL);
1622 assert(set != NULL);
1623 assert(expr != NULL);
1624 assert(expr->exprhdlr == exprhdlr);
1626
1627 if( exprhdlr->simplify != NULL )
1628 {
1630 SCIP_CALL( exprhdlr->simplify(set->scip, expr, simplifiedexpr, ownercreate, ownercreatedata) );
1632
1633 /* update statistics */
1634 ++exprhdlr->nsimplifycalls;
1635 if( expr != *simplifiedexpr )
1636 ++exprhdlr->nsimplified;
1637 }
1638 else
1639 {
1640 *simplifiedexpr = expr;
1641
1642 /* if an expression handler doesn't implement simplify, we assume that it is already simplified
1643 * we have to capture it, since it must simulate a "normal" simplified call in which a new expression is created
1644 */
1645 SCIPexprCapture(expr);
1646 }
1647
1648 return SCIP_OKAY;
1649}
1650
1651/** calls the reverse propagation callback of an expression handler
1652 *
1653 * The method propagates given bounds over the children of an expression.
1654 *
1655 * @see SCIP_DECL_EXPRREVERSEPROP
1656 */
1658 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1659 SCIP_SET* set, /**< global SCIP settings */
1660 SCIP_EXPR* expr, /**< expression to propagate */
1661 SCIP_INTERVAL bounds, /**< the bounds on the expression that should be propagated */
1662 SCIP_INTERVAL* childrenbounds, /**< array to store computed bounds for children, initialized with current activity */
1663 SCIP_Bool* infeasible /**< buffer to store whether a children bounds were propagated to an empty interval */
1664 )
1665{
1666 assert(exprhdlr != NULL);
1667 assert(set != NULL);
1668 assert(expr != NULL);
1669 assert(expr->exprhdlr == exprhdlr);
1670 assert(childrenbounds != NULL || expr->nchildren == 0);
1671 assert(infeasible != NULL);
1672
1673 *infeasible = FALSE;
1674
1675 if( exprhdlr->reverseprop != NULL )
1676 {
1677 SCIPclockStart(exprhdlr->proptime, set);
1678 SCIP_CALL( exprhdlr->reverseprop(set->scip, expr, bounds, childrenbounds, infeasible) );
1679 SCIPclockStop(exprhdlr->proptime, set);
1680
1681 /* update statistics */
1682 if( *infeasible )
1683 ++expr->exprhdlr->ncutoffs;
1684 ++expr->exprhdlr->npropcalls;
1685 }
1686
1687 return SCIP_OKAY;
1688}
1689
1690/**@name Expression Methods */
1691/**@{ */
1692
1693/* from expr.h */
1694
1695#ifdef NDEBUG
1696#undef SCIPexprCapture
1697#undef SCIPexprIsVar
1698#undef SCIPexprIsValue
1699#undef SCIPexprIsSum
1700#undef SCIPexprIsProduct
1701#undef SCIPexprIsPower
1702#endif
1703
1704/** creates and captures an expression with given expression data and children */
1706 SCIP_SET* set, /**< global SCIP settings */
1707 BMS_BLKMEM* blkmem, /**< block memory */
1708 SCIP_EXPR** expr, /**< pointer where to store expression */
1709 SCIP_EXPRHDLR* exprhdlr, /**< expression handler */
1710 SCIP_EXPRDATA* exprdata, /**< expression data (expression assumes ownership) */
1711 int nchildren, /**< number of children */
1712 SCIP_EXPR** children, /**< children (can be NULL if nchildren is 0) */
1713 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
1714 void* ownercreatedata /**< data to pass to ownercreate */
1715 )
1716{
1717 int c;
1718
1719 assert(set != NULL);
1720 assert(blkmem != NULL);
1721 assert(expr != NULL);
1722 assert(exprhdlr != NULL);
1723 assert(children != NULL || nchildren == 0);
1724 assert(exprdata == NULL || exprhdlr->copydata != NULL); /* copydata must be available if there is expression data */
1725 assert(exprdata == NULL || exprhdlr->freedata != NULL); /* freedata must be available if there is expression data */
1726
1727 SCIP_ALLOC( BMSallocClearBlockMemory(blkmem, expr) );
1728
1729 (*expr)->exprhdlr = exprhdlr;
1730 (*expr)->exprdata = exprdata;
1731 (*expr)->activitytag = -1; /* to be less than initial domchgcount */
1732 (*expr)->curvature = SCIP_EXPRCURV_UNKNOWN;
1733
1734 /* initialize activity to entire interval */
1735 SCIPintervalSetEntire(SCIP_INTERVAL_INFINITY, &(*expr)->activity);
1736
1737 if( nchildren > 0 )
1738 {
1739 SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*expr)->children, children, nchildren) );
1740 (*expr)->nchildren = nchildren;
1741 (*expr)->childrensize = nchildren;
1742
1743 for( c = 0; c < nchildren; ++c )
1744 SCIPexprCapture((*expr)->children[c]);
1745 }
1746
1747 SCIPexprCapture(*expr);
1748
1749 ++exprhdlr->ncreated;
1750
1751 /* initializes the ownerdata */
1752 if( ownercreate != NULL )
1753 {
1754 SCIP_CALL( ownercreate(set->scip, *expr, &(*expr)->ownerdata, &(*expr)->ownerfree, &(*expr)->ownerprint,
1755 &(*expr)->ownerevalactivity, ownercreatedata) );
1756 }
1757
1758 return SCIP_OKAY;
1759}
1760
1761/** appends child to the children list of expr */
1763 SCIP_SET* set, /**< global SCIP settings */
1764 BMS_BLKMEM* blkmem, /**< block memory */
1765 SCIP_EXPR* expr, /**< expression */
1766 SCIP_EXPR* child /**< expression to be appended */
1767 )
1768{
1769 assert(set != NULL);
1770 assert(blkmem != NULL);
1771 assert(child != NULL);
1772 assert(expr->nchildren <= expr->childrensize);
1773
1774 if( expr->nchildren == expr->childrensize )
1775 {
1777 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &expr->children, expr->nchildren, expr->childrensize) );
1778 }
1779
1780 expr->children[expr->nchildren] = child;
1781 ++expr->nchildren;
1782
1783 /* capture child */
1784 SCIPexprCapture(child);
1785
1786 return SCIP_OKAY;
1787}
1788
1789/** overwrites/replaces a child of an expressions
1790 *
1791 * @note the old child is released and the newchild is captured, unless they are the same (=same pointer)
1792 */
1794 SCIP_SET* set, /**< global SCIP settings */
1795 SCIP_STAT* stat, /**< dynamic problem statistics */
1796 BMS_BLKMEM* blkmem, /**< block memory */
1797 SCIP_EXPR* expr, /**< expression where a child is going to be replaced */
1798 int childidx, /**< index of child being replaced */
1799 SCIP_EXPR* newchild /**< the new child */
1800 )
1801{
1802 assert(set != NULL);
1803 assert(blkmem != NULL);
1804 assert(expr != NULL);
1805 assert(newchild != NULL);
1806 assert(childidx >= 0);
1807 assert(childidx < expr->nchildren);
1808
1809 /* do nothing if child is not changing */
1810 if( newchild == expr->children[childidx] )
1811 return SCIP_OKAY;
1812
1813 /* capture new child (do this before releasing the old child in case there are equal */
1815
1816 SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &(expr->children[childidx])) );
1817 expr->children[childidx] = newchild;
1818
1819 return SCIP_OKAY;
1820}
1821
1822/** remove all children of expr */
1824 SCIP_SET* set, /**< global SCIP settings */
1825 SCIP_STAT* stat, /**< dynamic problem statistics */
1826 BMS_BLKMEM* blkmem, /**< block memory */
1827 SCIP_EXPR* expr /**< expression */
1828 )
1829{
1830 int c;
1831
1832 assert(set != NULL);
1833 assert(blkmem != NULL);
1834 assert(expr != NULL);
1835
1836 for( c = 0; c < expr->nchildren; ++c )
1837 {
1838 assert(expr->children[c] != NULL);
1839 SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &(expr->children[c])) );
1840 }
1841
1842 expr->nchildren = 0;
1843
1844 return SCIP_OKAY;
1845}
1846
1847/** copies an expression including subexpressions
1848 *
1849 * @note If copying fails due to an expression handler not being available in the targetscip, then *targetexpr will be set to NULL.
1850 *
1851 * For all or some expressions, a mapping to an existing expression can be specified via the mapexpr callback.
1852 * The mapped expression (including its children) will not be copied in this case and its ownerdata will not be touched.
1853 * If, however, the mapexpr callback returns NULL for the targetexpr, then the expr will be copied in the usual way.
1854 */
1856 SCIP_SET* set, /**< global SCIP settings */
1857 SCIP_STAT* stat, /**< dynamic problem statistics */
1858 BMS_BLKMEM* blkmem, /**< block memory */
1859 SCIP_SET* targetset, /**< global SCIP settings data structure where target expression will live */
1860 SCIP_STAT* targetstat, /**< dynamic problem statistics in target SCIP */
1861 BMS_BLKMEM* targetblkmem, /**< block memory in target SCIP */
1862 SCIP_EXPR* sourceexpr, /**< expression to be copied */
1863 SCIP_EXPR** targetexpr, /**< buffer to store pointer to copy of source expression */
1864 SCIP_DECL_EXPR_MAPEXPR((*mapexpr)), /**< expression mapping function, or NULL for creating new expressions */
1865 void* mapexprdata, /**< data of expression mapping function */
1866 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call on expression copy to create ownerdata */
1867 void* ownercreatedata /**< data to pass to ownercreate */
1868 )
1869{
1872 SCIP_EXPR* expr;
1873 SCIP* sourcescip = set->scip; /* SCIP data structure corresponding to source expression */
1874 SCIP* targetscip = targetset->scip; /* SCIP data structure where target expression will live */
1875
1876 assert(set != NULL);
1877 assert(stat != NULL);
1878 assert(blkmem != NULL);
1879 assert(targetset != NULL);
1882 assert(sourcescip != NULL);
1884
1885 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
1886 SCIP_CALL( SCIPexpriterInit(it, sourceexpr, SCIP_EXPRITER_DFS, TRUE) ); /*TODO use FALSE, i.e., don't duplicate common subexpr? */
1888
1889 expr = sourceexpr;
1890 while( !SCIPexpriterIsEnd(it) )
1891 {
1892 switch( SCIPexpriterGetStageDFS(it) )
1893 {
1895 {
1896 /* create expr that will hold the copy */
1900
1901 if( mapexpr != NULL )
1902 {
1904 if( exprcopy != NULL )
1905 {
1906 /* map callback gave us an expression to use for the copy */
1907 /* store targetexpr */
1908 expriteruserdata.ptrval = exprcopy;
1910
1911 /* skip subexpression (assume that exprcopy is a complete copy) and continue */
1912 expr = SCIPexpriterSkipDFS(it);
1913 continue;
1914 }
1915 }
1916
1917 /* get the exprhdlr of the target scip */
1918 if( targetscip != sourcescip )
1919 {
1921
1922 if( targetexprhdlr == NULL )
1923 {
1924 /* expression handler not in target scip (probably did not have a copy callback) -> abort */
1925 expriteruserdata.ptrval = NULL;
1927
1928 expr = SCIPexpriterSkipDFS(it);
1929 continue;
1930 }
1931 }
1932 else
1933 {
1934 targetexprhdlr = expr->exprhdlr;
1935 }
1937
1938 /* copy expression data */
1939 if( expr->exprdata != NULL )
1940 {
1941 assert(expr->exprhdlr->copydata != NULL);
1942 SCIP_CALL( expr->exprhdlr->copydata(targetscip, targetexprhdlr, &targetexprdata, sourcescip, expr) );
1943 }
1944 else
1945 {
1947 }
1948
1949 /* create in targetexpr an expression of the same type as expr, but without children for now */
1952
1953 /* store targetexpr */
1954 expriteruserdata.ptrval = exprcopy;
1956
1957 break;
1958 }
1959
1961 {
1962 /* just visited child so a copy of himself should be available; append it */
1965
1967
1968 /* get copy of child */
1970 if( childcopy == NULL )
1971 {
1972 /* abort */
1973 /* release exprcopy (should free also the already copied children) */
1975
1976 expriteruserdata.ptrval = NULL;
1978
1979 expr = SCIPexpriterSkipDFS(it);
1980 continue;
1981 }
1982
1983 /* append child to exprcopy */
1985
1986 /* release childcopy (still captured by exprcopy) */
1988
1989 break;
1990 }
1991
1992 default:
1993 /* we should never be called in this stage */
1994 SCIPABORT();
1995 break;
1996 }
1997
1998 expr = SCIPexpriterGetNext(it);
1999 }
2000
2001 /* the target expression should be stored in the userdata of the sourceexpr (can be NULL if aborted) */
2003
2005
2006 return SCIP_OKAY;
2007}
2008
2009/** duplicates the given expression without its children */
2011 SCIP_SET* set, /**< global SCIP settings */
2012 BMS_BLKMEM* blkmem, /**< block memory */
2013 SCIP_EXPR* expr, /**< original expression */
2014 SCIP_EXPR** copyexpr, /**< buffer to store (shallow) duplicate of expr */
2015 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call on expression copy to create ownerdata */
2016 void* ownercreatedata /**< data to pass to ownercreate */
2017 )
2018{
2020
2021 assert(set != NULL);
2022 assert(blkmem != NULL);
2023 assert(expr != NULL);
2024 assert(copyexpr != NULL);
2025
2026 /* copy expression data */
2027 if( expr->exprdata != NULL )
2028 {
2029 assert(expr->exprhdlr->copydata != NULL);
2030 SCIP_CALL( expr->exprhdlr->copydata(set->scip, expr->exprhdlr, &exprdatacopy, set->scip, expr) );
2031 }
2032
2033 /* create expression with same handler and copied data, but without children */
2035 ownercreatedata) );
2036
2037 return SCIP_OKAY;
2038}
2039
2040/** captures an expression (increments usage count) */
2042 SCIP_EXPR* expr /**< expression */
2043 )
2044{
2045 assert(expr != NULL);
2046
2047 ++expr->nuses;
2048}
2049
2050/** releases an expression (decrements usage count and possibly frees expression) */
2052 SCIP_SET* set, /**< global SCIP settings */
2053 SCIP_STAT* stat, /**< dynamic problem statistics */
2054 BMS_BLKMEM* blkmem, /**< block memory */
2055 SCIP_EXPR** rootexpr /**< pointer to expression */
2056 )
2057{
2059 SCIP_EXPR* expr;
2060
2061 assert(rootexpr != NULL);
2062 assert(*rootexpr != NULL);
2063 assert((*rootexpr)->nuses > 0);
2064
2065 if( (*rootexpr)->nuses > 1 )
2066 {
2067 --(*rootexpr)->nuses;
2068 *rootexpr = NULL;
2069
2070 return SCIP_OKAY;
2071 }
2072
2073 /* handle the root expr separately: free ownerdata, quaddata, and exprdata first */
2074
2075 /* call ownerfree callback, if given
2076 * we intentially call this also if ownerdata is NULL, so owner can be notified without storing data
2077 */
2078 if( (*rootexpr)->ownerfree != NULL )
2079 {
2080 SCIP_CALL( (*rootexpr)->ownerfree(set->scip, *rootexpr, &(*rootexpr)->ownerdata) );
2081 assert((*rootexpr)->ownerdata == NULL);
2082 }
2083
2084 /* free quadratic info */
2086
2087 /* free expression data */
2088 if( (*rootexpr)->exprdata != NULL )
2089 {
2090 assert((*rootexpr)->exprhdlr->freedata != NULL);
2091 SCIP_CALL( (*rootexpr)->exprhdlr->freedata(set->scip, *rootexpr) );
2092 }
2093
2094 /* now release and free children, where no longer in use */
2095 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
2098 for( expr = SCIPexpriterGetCurrent(it); !SCIPexpriterIsEnd(it) ; )
2099 {
2100 /* expression should be used by its parent and maybe by the iterator (only the root!)
2101 * in VISITEDCHILD we assert that expression is only used by its parent
2102 */
2103 assert(expr != NULL);
2104 assert(0 <= expr->nuses && expr->nuses <= 2);
2105
2106 switch( SCIPexpriterGetStageDFS(it) )
2107 {
2109 {
2110 /* check whether a child needs to be visited (nuses == 1)
2111 * if not, then we still have to release it
2112 */
2113 SCIP_EXPR* child;
2114
2116 if( child->nuses > 1 )
2117 {
2118 /* child is not going to be freed: just release it */
2119 SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &child) );
2120 expr = SCIPexpriterSkipDFS(it);
2121 continue;
2122 }
2123
2124 assert(child->nuses == 1);
2125
2126 /* free child's quaddata, ownerdata, and exprdata when entering child */
2127 if( child->ownerfree != NULL )
2128 {
2129 SCIP_CALL( child->ownerfree(set->scip, child, &child->ownerdata) );
2130 assert(child->ownerdata == NULL);
2131 }
2132
2133 /* free quadratic info */
2134 SCIPexprFreeQuadratic(blkmem, child);
2135
2136 /* free expression data */
2137 if( child->exprdata != NULL )
2138 {
2139 assert(child->exprhdlr->freedata != NULL);
2140 SCIP_CALL( child->exprhdlr->freedata(set->scip, child) );
2141 assert(child->exprdata == NULL);
2142 }
2143
2144 break;
2145 }
2146
2148 {
2149 /* free child after visiting it */
2150 SCIP_EXPR* child;
2151
2153 /* child should only be used by its parent */
2154 assert(child->nuses == 1);
2155
2156 /* child should have no data associated */
2157 assert(child->exprdata == NULL);
2158
2159 /* free child expression */
2160 SCIP_CALL( freeExpr(blkmem, &child) );
2162
2163 break;
2164 }
2165
2166 default:
2167 SCIPABORT(); /* we should never be called in this stage */
2168 break;
2169 }
2170
2171 expr = SCIPexpriterGetNext(it);
2172 }
2173
2175
2176 /* handle the root expr separately: free its children and itself here */
2177 SCIP_CALL( freeExpr(blkmem, rootexpr) );
2178
2179 return SCIP_OKAY;
2180}
2181
2182/** returns whether an expression is a variable expression */
2184 SCIP_SET* set, /**< global SCIP settings */
2185 SCIP_EXPR* expr /**< expression */
2186 )
2187{
2188 assert(set != NULL);
2189 assert(expr != NULL);
2190
2191 return expr->exprhdlr == set->exprhdlrvar;
2192}
2193
2194/** returns whether an expression is a value expression */
2196 SCIP_SET* set, /**< global SCIP settings */
2197 SCIP_EXPR* expr /**< expression */
2198 )
2199{
2200 assert(set != NULL);
2201 assert(expr != NULL);
2202
2203 return expr->exprhdlr == set->exprhdlrval;
2204}
2205
2206/** returns whether an expression is a sum expression */
2208 SCIP_SET* set, /**< global SCIP settings */
2209 SCIP_EXPR* expr /**< expression */
2210 )
2211{
2212 assert(set != NULL);
2213 assert(expr != NULL);
2214
2215 return expr->exprhdlr == set->exprhdlrsum;
2216}
2217
2218/** returns whether an expression is a product expression */
2220 SCIP_SET* set, /**< global SCIP settings */
2221 SCIP_EXPR* expr /**< expression */
2222 )
2223{
2224 assert(set != NULL);
2225 assert(expr != NULL);
2226
2227 return expr->exprhdlr == set->exprhdlrproduct;
2228}
2229
2230/** returns whether an expression is a power expression */
2232 SCIP_SET* set, /**< global SCIP settings */
2233 SCIP_EXPR* expr /**< expression */
2234 )
2235{
2236 assert(set != NULL);
2237 assert(expr != NULL);
2238
2239 return expr->exprhdlr == set->exprhdlrpow;
2240}
2241
2242/** print an expression as info-message */
2244 SCIP_SET* set, /**< global SCIP settings */
2245 SCIP_STAT* stat, /**< dynamic problem statistics */
2246 BMS_BLKMEM* blkmem, /**< block memory */
2247 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
2248 FILE* file, /**< file to print to, or NULL for stdout */
2249 SCIP_EXPR* expr /**< expression to be printed */
2250 )
2251{
2253 SCIP_EXPRITER_STAGE stage;
2254 int currentchild;
2255 unsigned int parentprecedence;
2256
2257 assert(set != NULL);
2258 assert(blkmem != NULL);
2259 assert(expr != NULL);
2260
2261 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
2264
2265 while( !SCIPexpriterIsEnd(it) )
2266 {
2267 assert(expr->exprhdlr != NULL);
2268 stage = SCIPexpriterGetStageDFS(it);
2269
2271 currentchild = SCIPexpriterGetChildIdxDFS(it);
2272 else
2273 currentchild = -1;
2274
2277 else
2278 parentprecedence = 0;
2279
2280 SCIP_CALL( SCIPexprhdlrPrintExpr(expr->exprhdlr, set, messagehdlr, expr, stage, currentchild,
2281 parentprecedence, file) );
2282
2283 expr = SCIPexpriterGetNext(it);
2284 }
2285
2287
2288 return SCIP_OKAY;
2289}
2290
2291/** initializes printing of expressions in dot format to a give FILE* pointer */
2293 SCIP_SET* set, /**< global SCIP settings */
2294 SCIP_STAT* stat, /**< dynamic problem statistics */
2295 BMS_BLKMEM* blkmem, /**< block memory */
2296 SCIP_EXPRPRINTDATA** printdata, /**< buffer to store dot printing data */
2297 FILE* file, /**< file to print to, or NULL for stdout */
2298 SCIP_EXPRPRINT_WHAT whattoprint /**< info on what to print for each expression */
2299 )
2300{
2301 assert(set != NULL);
2302 assert(stat != NULL);
2303 assert(blkmem != NULL);
2304 assert(printdata != NULL);
2305
2306 if( file == NULL )
2307 file = stdout;
2308
2310
2311 (*printdata)->file = file;
2312 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &(*printdata)->iterator) );
2313 (*printdata)->closefile = FALSE;
2314 (*printdata)->whattoprint = whattoprint;
2315 SCIP_CALL( SCIPhashmapCreate(&(*printdata)->leaveexprs, blkmem, 100) );
2316
2317 fputs("strict digraph exprgraph {\n", file);
2318 fputs("node [fontcolor=white, style=filled, rankdir=LR]\n", file);
2319
2320 return SCIP_OKAY;
2321}
2322
2323/** initializes printing of expressions in dot format to a file with given filename */
2325 SCIP_SET* set, /**< global SCIP settings */
2326 SCIP_STAT* stat, /**< dynamic problem statistics */
2327 BMS_BLKMEM* blkmem, /**< block memory */
2328 SCIP_EXPRPRINTDATA** printdata, /**< buffer to store dot printing data */
2329 const char* filename, /**< name of file to print to */
2330 SCIP_EXPRPRINT_WHAT whattoprint /**< info on what to print for each expression */
2331 )
2332{
2333 FILE* f;
2334
2335 assert(set != NULL);
2336 assert(stat != NULL);
2337 assert(blkmem != NULL);
2338 assert(printdata != NULL);
2339 assert(filename != NULL);
2340
2341 f = fopen(filename, "w");
2342 if( f == NULL )
2343 {
2344 SCIPerrorMessage("could not open file <%s> for writing\n", filename); /* error code would be in errno */
2345 return SCIP_FILECREATEERROR;
2346 }
2347
2348 SCIP_CALL_FINALLY( SCIPexprPrintDotInit(set, stat, blkmem, printdata, f, whattoprint),
2349 fclose(f) );
2350 (*printdata)->closefile = TRUE;
2351
2352 return SCIP_OKAY;
2353} /*lint !e429*/
2354
2355/** main part of printing an expression in dot format */
2357 SCIP_SET* set, /**< global SCIP settings */
2358 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
2359 SCIP_EXPRPRINTDATA* printdata, /**< data as initialized by \ref SCIPprintExprDotInit() */
2360 SCIP_EXPR* expr /**< expression to be printed */
2361 )
2362{
2363 SCIP_Real color;
2364 int c;
2365
2366 assert(set != NULL);
2367 assert(printdata != NULL);
2368 assert(expr != NULL);
2369 assert(expr->exprhdlr != NULL);
2370
2372
2373 while( !SCIPexpriterIsEnd(printdata->iterator) )
2374 {
2375 /* print expression as dot node */
2376
2377 if( expr->nchildren == 0 )
2378 {
2379 SCIP_CALL( SCIPhashmapInsert(printdata->leaveexprs, (void*)expr, NULL) );
2380 }
2381
2382 /* make up some color from the expression type (it's name) */
2383 color = 0.0;
2384 for( c = 0; expr->exprhdlr->name[c] != '\0'; ++c )
2385 color += (tolower(expr->exprhdlr->name[c]) - 'a') / 26.0;
2386 color = SCIPsetFrac(set, color);
2387 fprintf(printdata->file, "n%p [fillcolor=\"%g,%g,%g\", label=\"", (void*)expr, color, color, color);
2388
2389 if( printdata->whattoprint & SCIP_EXPRPRINT_EXPRHDLR )
2390 {
2391 fprintf(printdata->file, "%s\\n", expr->exprhdlr->name);
2392 }
2393
2394 if( printdata->whattoprint & SCIP_EXPRPRINT_EXPRSTRING )
2395 {
2396 SCIP_CALL( SCIPexprhdlrPrintExpr(expr->exprhdlr, set, messagehdlr, expr, SCIP_EXPRITER_ENTEREXPR, -1, 0,
2397 printdata->file) );
2398 for( c = 0; c < expr->nchildren; ++c )
2399 {
2400 SCIP_CALL( SCIPexprhdlrPrintExpr(expr->exprhdlr, set, messagehdlr, expr, SCIP_EXPRITER_VISITINGCHILD,
2401 c, 0, printdata->file) );
2402 fprintf(printdata->file, "c%d", c);
2403 SCIP_CALL( SCIPexprhdlrPrintExpr(expr->exprhdlr, set, messagehdlr, expr, SCIP_EXPRITER_VISITEDCHILD,
2404 c, 0, printdata->file) );
2405 }
2406 SCIP_CALL( SCIPexprhdlrPrintExpr(expr->exprhdlr, set, messagehdlr, expr, SCIP_EXPRITER_LEAVEEXPR, -1, 0,
2407 printdata->file) );
2408
2409 fputs("\\n", printdata->file);
2410 }
2411
2412 if( printdata->whattoprint & SCIP_EXPRPRINT_NUSES )
2413 {
2414 /* print number of uses */
2415 fprintf(printdata->file, "%d uses\\n", expr->nuses);
2416 }
2417
2418 if( printdata->whattoprint & SCIP_EXPRPRINT_OWNER )
2419 {
2420 /* print ownerdata */
2421 if( expr->ownerprint != NULL )
2422 {
2423 SCIP_CALL( expr->ownerprint(set->scip, printdata->file, expr, expr->ownerdata) );
2424 }
2425 else if( expr->ownerdata != NULL )
2426 {
2427 fprintf(printdata->file, "owner=%p\\n", (void*)expr->ownerdata);
2428 }
2429 }
2430
2431 if( printdata->whattoprint & SCIP_EXPRPRINT_EVALVALUE )
2432 {
2433 /* print eval value */
2434 fprintf(printdata->file, "val=%g", expr->evalvalue);
2435
2437 {
2438 /* print also eval tag */
2439 fprintf(printdata->file, " (%" SCIP_LONGINT_FORMAT ")", expr->evaltag);
2440 }
2441 fputs("\\n", printdata->file);
2442 }
2443
2444 if( printdata->whattoprint & SCIP_EXPRPRINT_ACTIVITY )
2445 {
2446 /* print activity */
2447 fprintf(printdata->file, "[%g,%g]", expr->activity.inf, expr->activity.sup);
2448
2450 {
2451 /* print also activity eval tag */
2452 fprintf(printdata->file, " (%" SCIP_LONGINT_FORMAT ")", expr->activitytag);
2453 }
2454 fputs("\\n", printdata->file);
2455 }
2456
2457 fputs("\"]\n", printdata->file); /* end of label and end of node */
2458
2459 /* add edges from expr to its children */
2460 for( c = 0; c < expr->nchildren; ++c )
2461 fprintf(printdata->file, "n%p -> n%p [label=\"c%d\"]\n", (void*)expr, (void*)expr->children[c], c);
2462
2463 expr = SCIPexpriterGetNext(printdata->iterator);
2464 }
2465
2466 return SCIP_OKAY;
2467}
2468
2469/** finishes printing of expressions in dot format */
2471 SCIP_SET* set, /**< global SCIP settings */
2472 SCIP_STAT* stat, /**< dynamic problem statistics */
2473 BMS_BLKMEM* blkmem, /**< block memory */
2474 SCIP_EXPRPRINTDATA** printdata /**< buffer where dot printing data has been stored */
2475 )
2476{
2477 SCIP_EXPR* expr;
2479 FILE* file;
2480 int i;
2481
2482 assert(set != NULL);
2483 assert(stat != NULL);
2484 assert(blkmem != NULL);
2485 assert(printdata != NULL);
2486 assert(*printdata != NULL);
2487
2488 file = (*printdata)->file;
2489 assert(file != NULL);
2490
2491 /* iterate through all entries of the map */
2492 fputs("{rank=same;", file);
2493 for( i = 0; i < SCIPhashmapGetNEntries((*printdata)->leaveexprs); ++i )
2494 {
2495 entry = SCIPhashmapGetEntry((*printdata)->leaveexprs, i);
2496
2497 if( entry != NULL )
2498 {
2500 assert(expr != NULL);
2501 assert(expr->nchildren == 0);
2502
2503 fprintf(file, " n%p", (void*)expr);
2504 }
2505 }
2506 fprintf(file, "}\n");
2507
2508 fprintf(file, "}\n");
2509
2510 SCIPhashmapFree(&(*printdata)->leaveexprs);
2511
2512 SCIPexpriterFree(&(*printdata)->iterator);
2513
2514 if( (*printdata)->closefile )
2515 fclose((*printdata)->file);
2516
2518
2519 return SCIP_OKAY;
2520}
2521
2522/** prints structure of an expression a la Maple's dismantle */
2524 SCIP_SET* set, /**< global SCIP settings */
2525 SCIP_STAT* stat, /**< dynamic problem statistics */
2526 BMS_BLKMEM* blkmem, /**< block memory */
2527 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
2528 FILE* file, /**< file to print to, or NULL for stdout */
2529 SCIP_EXPR* expr /**< expression to dismantle */
2530 )
2531{
2533 int depth = -1;
2534
2535 assert(set != NULL);
2536 assert(stat != NULL);
2537 assert(blkmem != NULL);
2538 assert(messagehdlr != NULL);
2539 assert(expr != NULL);
2540
2541 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
2544
2545 for( ; !SCIPexpriterIsEnd(it); expr = SCIPexpriterGetNext(it) )
2546 {
2547 switch( SCIPexpriterGetStageDFS(it) )
2548 {
2550 {
2551 int nspaces;
2552
2553 ++depth;
2554 nspaces = 3 * depth;
2555
2556 /* use depth of expression to align output */
2557 SCIPmessageFPrintInfo(messagehdlr, file, "%*s[%s]: ", nspaces, "", expr->exprhdlr->name);
2558
2559 if( SCIPexprIsVar(set, expr) )
2560 {
2561 SCIP_VAR* var;
2562
2563 var = SCIPgetVarExprVar(expr);
2564 SCIPmessageFPrintInfo(messagehdlr, file, "%s in [%g, %g]", SCIPvarGetName(var), SCIPvarGetLbLocal(var),
2566 }
2567 else if( SCIPexprIsSum(set, expr) )
2568 SCIPmessageFPrintInfo(messagehdlr, file, "%g", SCIPgetConstantExprSum(expr));
2569 else if( SCIPexprIsProduct(set, expr) )
2570 SCIPmessageFPrintInfo(messagehdlr, file, "%g", SCIPgetCoefExprProduct(expr));
2571 else if( SCIPexprIsValue(set, expr) )
2572 SCIPmessageFPrintInfo(messagehdlr, file, "%g", SCIPgetValueExprValue(expr));
2573 else if( SCIPexprIsPower(set, expr) || strcmp(expr->exprhdlr->name, "signpower") == 0)
2574 SCIPmessageFPrintInfo(messagehdlr, file, "%g", SCIPgetExponentExprPow(expr));
2575
2576 SCIPmessageFPrintInfo(messagehdlr, file, "\n");
2577
2578 if( expr->ownerprint != NULL )
2579 {
2580 SCIPmessageFPrintInfo(messagehdlr, file, "%*s ", nspaces, "");
2581 SCIP_CALL( expr->ownerprint(set->scip, file, expr, expr->ownerdata) );
2582 }
2583
2584 break;
2585 }
2586
2588 {
2589 int nspaces = 3 * depth;
2590
2591 if( SCIPexprIsSum(set, expr) )
2592 {
2593 SCIPmessageFPrintInfo(messagehdlr, file, "%*s ", nspaces, "");
2594 SCIPmessageFPrintInfo(messagehdlr, file, "[coef]: %g\n", SCIPgetCoefsExprSum(expr)[SCIPexpriterGetChildIdxDFS(it)]);
2595 }
2596
2597 break;
2598 }
2599
2601 {
2602 --depth;
2603 break;
2604 }
2605
2606 default:
2607 /* shouldn't be here */
2608 SCIPABORT();
2609 break;
2610 }
2611 }
2612
2614
2615 return SCIP_OKAY;
2616}
2617
2618/** evaluate an expression in a point
2619 *
2620 * Iterates over expressions to also evaluate children, if necessary.
2621 * Value can be received via SCIPexprGetEvalValue().
2622 * If an evaluation error (division by zero, ...) occurs, this value will
2623 * be set to SCIP_INVALID.
2624 *
2625 * If a nonzero \p soltag is passed, then only (sub)expressions are
2626 * reevaluated that have a different solution tag. If a soltag of 0
2627 * is passed, then subexpressions are always reevaluated.
2628 * The tag is stored together with the value and can be received via
2629 * SCIPexprGetEvalTag().
2630 */
2632 SCIP_SET* set, /**< global SCIP settings */
2633 SCIP_STAT* stat, /**< dynamic problem statistics */
2634 BMS_BLKMEM* blkmem, /**< block memory */
2635 SCIP_EXPR* expr, /**< expression to be evaluated */
2636 SCIP_SOL* sol, /**< solution to be evaluated */
2637 SCIP_Longint soltag /**< tag that uniquely identifies the solution (with its values), or 0. */
2638 )
2639{
2641
2642 assert(set != NULL);
2643 assert(stat != NULL);
2644 assert(blkmem != NULL);
2645 assert(expr != NULL);
2646
2647 /* if value is up-to-date, then nothing to do */
2648 if( soltag != 0 && expr->evaltag == soltag )
2649 return SCIP_OKAY;
2650
2651 /* assume we'll get a domain error, so we don't have to get this expr back if we abort the iteration
2652 * if there is no domain error, then we will overwrite the evalvalue in the last leaveexpr stage
2653 */
2654 expr->evalvalue = SCIP_INVALID;
2655 expr->evaltag = soltag;
2656
2657 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
2660
2661 while( !SCIPexpriterIsEnd(it) )
2662 {
2663 switch( SCIPexpriterGetStageDFS(it) )
2664 {
2666 {
2667 SCIP_EXPR* child;
2668
2669 if( soltag == 0 )
2670 break;
2671
2672 /* check whether child has been evaluated for that solution already */
2674 if( soltag == child->evaltag )
2675 {
2676 if( child->evalvalue == SCIP_INVALID )
2677 goto TERMINATE;
2678
2679 /* skip this child
2680 * this already returns the next one, so continue with loop
2681 */
2682 expr = SCIPexpriterSkipDFS(it);
2683 continue;
2684 }
2685
2686 break;
2687 }
2688
2690 {
2691 SCIP_CALL( SCIPexprhdlrEvalExpr(expr->exprhdlr, set, NULL , expr, &expr->evalvalue, NULL, sol) );
2692 expr->evaltag = soltag;
2693
2694 if( expr->evalvalue == SCIP_INVALID )
2695 goto TERMINATE;
2696
2697 break;
2698 }
2699
2700 default :
2701 /* we should never be here */
2702 SCIPABORT();
2703 break;
2704 }
2705
2706 expr = SCIPexpriterGetNext(it);
2707 }
2708
2709TERMINATE:
2711
2712 return SCIP_OKAY;
2713}
2714
2715/** evaluates gradient of an expression for a given point
2716 *
2717 * Initiates an expression walk to also evaluate children, if necessary.
2718 * Value can be received via SCIPgetExprPartialDiffNonlinear().
2719 * If an error (division by zero, ...) occurs, this value will
2720 * be set to SCIP_INVALID.
2721 */
2723 SCIP_SET* set, /**< global SCIP settings */
2724 SCIP_STAT* stat, /**< dynamic problem statistics */
2725 BMS_BLKMEM* blkmem, /**< block memory */
2726 SCIP_EXPR* rootexpr, /**< expression to be evaluated */
2727 SCIP_SOL* sol, /**< solution to be evaluated (NULL for the current LP solution) */
2728 SCIP_Longint soltag /**< tag that uniquely identifies the solution (with its values), or 0. */
2729 )
2730{
2732 SCIP_EXPR* expr;
2733 SCIP_EXPR* child;
2734 SCIP_Real derivative;
2735 SCIP_Longint difftag;
2736
2737 assert(set != NULL);
2738 assert(stat != NULL);
2739 assert(blkmem != NULL);
2740 assert(rootexpr != NULL);
2741
2742 /* ensure expression is evaluated */
2743 SCIP_CALL( SCIPexprEval(set, stat, blkmem, rootexpr, sol, soltag) );
2744
2745 /* check if expression could not be evaluated */
2747 {
2748 rootexpr->derivative = SCIP_INVALID;
2749 return SCIP_OKAY;
2750 }
2751
2753 {
2754 rootexpr->derivative = 0.0;
2755 return SCIP_OKAY;
2756 }
2757
2758 difftag = ++(stat->exprlastdifftag);
2759
2760 rootexpr->derivative = 1.0;
2761 rootexpr->difftag = difftag;
2762
2763 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
2766
2768 {
2769 assert(expr->evalvalue != SCIP_INVALID);
2770
2772 assert(child != NULL);
2773
2774 /* reset the value of the partial derivative w.r.t. a variable expression if we see it for the first time */
2775 if( child->difftag != difftag && SCIPexprIsVar(set, child) )
2776 child->derivative = 0.0;
2777
2778 /* update differentiation tag of the child */
2779 child->difftag = difftag;
2780
2781 /* call backward differentiation callback */
2782 if( SCIPexprIsValue(set, child) )
2783 {
2784 derivative = 0.0;
2785 }
2786 else
2787 {
2788 derivative = SCIP_INVALID;
2790 &derivative, NULL, 0.0) );
2791
2792 if( derivative == SCIP_INVALID )
2793 {
2794 rootexpr->derivative = SCIP_INVALID;
2795 break;
2796 }
2797 }
2798
2799 /* update partial derivative stored in the child expression
2800 * for a variable, we have to sum up the partial derivatives of the root w.r.t. this variable over all parents
2801 * for other intermediate expressions, we only store the partial derivative of the root w.r.t. this expression
2802 */
2803 if( !SCIPexprIsVar(set, child) )
2804 child->derivative = expr->derivative * derivative;
2805 else
2806 child->derivative += expr->derivative * derivative;
2807 }
2808
2810
2811 return SCIP_OKAY;
2812}
2813
2814/** evaluates Hessian-vector product of an expression for a given point and direction
2815 *
2816 * Evaluates children, if necessary.
2817 * Value can be received via SCIPgetExprPartialDiffGradientDirNonlinear()
2818 * If an error (division by zero, ...) occurs, this value will
2819 * be set to SCIP_INVALID.
2820 */
2822 SCIP_SET* set, /**< global SCIP settings */
2823 SCIP_STAT* stat, /**< dynamic problem statistics */
2824 BMS_BLKMEM* blkmem, /**< block memory */
2825 SCIP_EXPR* rootexpr, /**< expression to be evaluated */
2826 SCIP_SOL* sol, /**< solution to be evaluated (NULL for the current LP solution) */
2827 SCIP_Longint soltag, /**< tag that uniquely identifies the solution (with its values), or 0. */
2828 SCIP_SOL* direction /**< direction */
2829 )
2830{
2832 SCIP_EXPR* expr;
2833 SCIP_EXPR* child;
2834 SCIP_Real derivative;
2835 SCIP_Real hessiandir;
2836
2837 assert(set != NULL);
2838 assert(stat != NULL);
2839 assert(blkmem != NULL);
2840 assert(rootexpr != NULL);
2841
2843 {
2844 rootexpr->dot = 0.0;
2845 rootexpr->bardot = 0.0;
2846 return SCIP_OKAY;
2847 }
2848
2849 /* evaluate expression and directional derivative */
2850 SCIP_CALL( evalAndDiff(set, stat, blkmem, rootexpr, sol, soltag, direction) );
2851
2852 if( rootexpr->evalvalue == SCIP_INVALID )
2853 {
2854 rootexpr->derivative = SCIP_INVALID;
2855 rootexpr->bardot = SCIP_INVALID;
2856 return SCIP_OKAY;
2857 }
2858
2859 rootexpr->derivative = 1.0;
2860
2861 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
2864
2865 /* compute reverse diff and bardots: i.e. hessian times direction */
2867 {
2868 assert(expr->evalvalue != SCIP_INVALID);
2869
2871 assert(child != NULL);
2872
2873 /* call backward and forward-backward differentiation callback */
2874 if( SCIPexprIsValue(set, child) )
2875 {
2876 derivative = 0.0;
2877 hessiandir = 0.0;
2878 }
2879 else
2880 {
2881 derivative = SCIP_INVALID;
2884 &derivative, NULL, SCIP_INVALID) );
2886 &hessiandir, NULL) );
2887
2888 if( derivative == SCIP_INVALID || hessiandir == SCIP_INVALID )
2889 {
2890 rootexpr->derivative = SCIP_INVALID;
2891 rootexpr->bardot = SCIP_INVALID;
2892 break;
2893 }
2894 }
2895
2896 /* update partial derivative and hessian stored in the child expression
2897 * for a variable, we have to sum up the partial derivatives of the root w.r.t. this variable over all parents
2898 * for other intermediate expressions, we only store the partial derivative of the root w.r.t. this expression
2899 */
2900 if( !SCIPexprIsVar(set, child) )
2901 {
2902 child->derivative = expr->derivative * derivative;
2903 child->bardot = expr->bardot * derivative + expr->derivative * hessiandir;
2904 }
2905 else
2906 {
2907 child->derivative += expr->derivative * derivative;
2908 child->bardot += expr->bardot * derivative + expr->derivative * hessiandir;
2909 }
2910 }
2911
2913
2914 return SCIP_OKAY;
2915}
2916
2917/** possibly reevaluates and then returns the activity of the expression
2918 *
2919 * Reevaluate activity if currently stored is no longer uptodate.
2920 * If the expr owner provided a evalactivity-callback, then call this.
2921 * Otherwise, loop over descendants and compare activitytag with stat's domchgcount, i.e.,
2922 * whether some bound was changed since last evaluation, to check whether exprhdlrs INTEVAL should be called.
2923 *
2924 * @note If expression is set to be integral, then activities are tightened to integral values.
2925 * Thus, ensure that the integrality information is valid (if set to TRUE; the default (FALSE) is always ok).
2926 */
2928 SCIP_SET* set, /**< global SCIP settings */
2929 SCIP_STAT* stat, /**< dynamic problem statistics */
2930 BMS_BLKMEM* blkmem, /**< block memory */
2931 SCIP_EXPR* rootexpr /**< expression */
2932 )
2933{
2935 SCIP_EXPR* expr;
2936
2937 assert(set != NULL);
2938 assert(stat != NULL);
2939 assert(blkmem != NULL);
2940 assert(rootexpr != NULL);
2941
2942 if( rootexpr->ownerevalactivity != NULL )
2943 {
2944 /* call owner callback for activity-eval */
2945 SCIP_CALL( rootexpr->ownerevalactivity(set->scip, rootexpr, rootexpr->ownerdata) );
2946
2947 return SCIP_OKAY;
2948 }
2949
2950 /* fallback if no callback is given */
2951
2952 assert(rootexpr->activitytag <= stat->domchgcount);
2953
2954 /* if value is up-to-date, then nothing to do */
2955 if( rootexpr->activitytag == stat->domchgcount )
2956 {
2957#ifdef DEBUG_PROP
2958 SCIPsetDebugMsg(set, "activitytag of root expr equals domchgcount (%u), skip evalactivity\n", stat->domchgcount);
2959#endif
2960
2961 return SCIP_OKAY;
2962 }
2963
2964 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
2967
2969 {
2970 switch( SCIPexpriterGetStageDFS(it) )
2971 {
2973 {
2974 /* skip child if it has been evaluated already */
2975 SCIP_EXPR* child;
2976
2978 if( child->activitytag == stat->domchgcount )
2979 {
2980 expr = SCIPexpriterSkipDFS(it);
2981 continue;
2982 }
2983
2984 break;
2985 }
2986
2988 {
2989 /* we should not have entered this expression if its activity was already uptodate */
2990 assert(expr->activitytag < stat->domchgcount);
2991
2992 /* reset activity to entire if invalid, so we can use it as starting point below */
2994
2995#ifdef DEBUG_PROP
2996 SCIPsetDebugMsg(set, "interval evaluation of expr %p ", (void*)expr);
2997 SCIP_CALL( SCIPprintExpr(set->scip, expr, NULL) );
2999#endif
3000
3001 /* call the inteval callback of the exprhdlr */
3002 SCIP_CALL( SCIPexprhdlrIntEvalExpr(expr->exprhdlr, set, expr, &expr->activity, NULL, NULL) );
3003#ifdef DEBUG_PROP
3004 SCIPsetDebugMsg(set, " exprhdlr <%s>::inteval = [%.20g, %.20g]", expr->exprhdlr->name, expr->activity.inf,
3005 expr->activity.sup);
3006#endif
3007
3008 /* if expression is integral, then we try to tighten the interval bounds a bit
3009 * this should undo the addition of some unnecessary safety added by use of nextafter() in interval
3010 * arithmetics, e.g., when doing pow() it would be ok to use ceil() and floor(), but for safety we
3011 * use SCIPceil and SCIPfloor for now the default intevalVar does not relax variables, so can omit
3012 * expressions without children (constants should be ok, too)
3013 */
3014 if( expr->isintegral && expr->nchildren > 0 )
3015 {
3016 if( expr->activity.inf > -SCIP_INTERVAL_INFINITY )
3017 expr->activity.inf = SCIPsetCeil(set, expr->activity.inf);
3018 if( expr->activity.sup < SCIP_INTERVAL_INFINITY )
3019 expr->activity.sup = SCIPsetFloor(set, expr->activity.sup);
3020#ifdef DEBUG_PROP
3021 SCIPsetDebugMsg(set, " applying integrality: [%.20g, %.20g]\n", expr->activity.inf, expr->activity.sup);
3022#endif
3023 }
3024
3025 /* mark activity as empty if either the lower/upper bound is above/below +/- SCIPinfinity()
3026 * TODO this is a problem if dual-presolve fixed a variable to +/- infinity
3027 */
3028 if( SCIPsetIsInfinity(set, expr->activity.inf) || SCIPsetIsInfinity(set, -expr->activity.sup) )
3029 {
3030 SCIPsetDebugMsg(set, "treat activity [%g,%g] as empty as beyond infinity\n", expr->activity.inf, expr->activity.sup);
3031 SCIPintervalSetEmpty(&expr->activity);
3032 }
3033
3034 /* remember that activity is uptodate now */
3035 expr->activitytag = stat->domchgcount;
3036
3037 break;
3038 }
3039
3040 default:
3041 /* you should never be here */
3042 SCIPABORT();
3043 break;
3044 }
3045
3046 expr = SCIPexpriterGetNext(it);
3047 }
3048
3050
3051 return SCIP_OKAY;
3052}
3053
3054/** compare expressions
3055 *
3056 * @return -1, 0 or 1 if expr1 <, =, > expr2, respectively
3057 * @note The given expressions are assumed to be simplified.
3058 */
3060 SCIP_SET* set, /**< global SCIP settings */
3061 SCIP_EXPR* expr1, /**< first expression */
3062 SCIP_EXPR* expr2 /**< second expression */
3063 )
3064{
3067 int retval;
3068
3069 exprhdlr1 = expr1->exprhdlr;
3070 exprhdlr2 = expr2->exprhdlr;
3071
3072 /* expressions are of the same kind/type; use compare callback or default method */
3073 if( exprhdlr1 == exprhdlr2 )
3074 return SCIPexprhdlrCompareExpr(set, expr1, expr2);
3075
3076 /* expressions are of different kind/type */
3077 /* enforces OR6 */
3078 if( SCIPexprIsValue(set, expr1) )
3079 {
3080 return -1;
3081 }
3082 /* enforces OR12 */
3083 if( SCIPexprIsValue(set, expr2) )
3084 return -SCIPexprCompare(set, expr2, expr1);
3085
3086 /* enforces OR7 */
3087 if( SCIPexprIsSum(set, expr1) )
3088 {
3089 int compareresult;
3090 int nchildren;
3091
3092 nchildren = expr1->nchildren;
3093 compareresult = SCIPexprCompare(set, expr1->children[nchildren-1], expr2);
3094
3095 if( compareresult != 0 )
3096 return compareresult;
3097
3098 /* "base" of the largest expression of the sum is equal to expr2, coefficient might tell us that
3099 * expr2 is larger */
3100 if( SCIPgetCoefsExprSum(expr1)[nchildren-1] < 1.0 )
3101 return -1;
3102
3103 /* largest expression of sum is larger or equal than expr2 => expr1 > expr2 */
3104 return 1;
3105 }
3106 /* enforces OR12 */
3107 if( SCIPexprIsSum(set, expr2) )
3108 return -SCIPexprCompare(set, expr2, expr1);
3109
3110 /* enforces OR8 */
3111 if( SCIPexprIsProduct(set, expr1) )
3112 {
3113 int compareresult;
3114 int nchildren;
3115
3116 nchildren = expr1->nchildren;
3117 compareresult = SCIPexprCompare(set, expr1->children[nchildren-1], expr2);
3118
3119 if( compareresult != 0 )
3120 return compareresult;
3121
3122 /* largest expression of product is larger or equal than expr2 => expr1 > expr2 */
3123 return 1;
3124 }
3125 /* enforces OR12 */
3126 if( SCIPexprIsProduct(set, expr2) )
3127 return -SCIPexprCompare(set, expr2, expr1);
3128
3129 /* enforces OR9 */
3130 if( SCIPexprIsPower(set, expr1) )
3131 {
3132 int compareresult;
3133
3134 compareresult = SCIPexprCompare(set, expr1->children[0], expr2);
3135
3136 if( compareresult != 0 )
3137 return compareresult;
3138
3139 /* base equal to expr2, exponent might tell us that expr2 is larger */
3140 if( SCIPgetExponentExprPow(expr1) < 1.0 )
3141 return -1;
3142
3143 /* power expression is larger => expr1 > expr2 */
3144 return 1;
3145 }
3146 /* enforces OR12 */
3147 if( SCIPexprIsPower(set, expr2) )
3148 return -SCIPexprCompare(set, expr2, expr1);
3149
3150 /* enforces OR10 */
3151 if( SCIPexprIsVar(set, expr1) )
3152 return -1;
3153 /* enforces OR12 */
3154 if( SCIPexprIsVar(set, expr2) )
3155 return -SCIPexprCompare(set, expr2, expr1);
3156
3157 /* enforces OR11 */
3159 return retval == 0 ? 0 : retval < 0 ? -1 : 1;
3160}
3161
3162/** simplifies an expression
3163 *
3164 * @see SCIPsimplifyExpr
3165 */
3167 SCIP_SET* set, /**< global SCIP settings */
3168 SCIP_STAT* stat, /**< dynamic problem statistics */
3169 BMS_BLKMEM* blkmem, /**< block memory */
3170 SCIP_EXPR* rootexpr, /**< expression to be simplified */
3171 SCIP_EXPR** simplified, /**< buffer to store simplified expression */
3172 SCIP_Bool* changed, /**< buffer to store if rootexpr actually changed */
3173 SCIP_Bool* infeasible, /**< buffer to store whether infeasibility has been detected */
3174 SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
3175 void* ownercreatedata /**< data to pass to ownercreate */
3176 )
3177{
3178 SCIP_EXPR* expr;
3180
3181 assert(rootexpr != NULL);
3183 assert(changed != NULL);
3184 assert(infeasible != NULL);
3185
3186 /* simplify bottom up
3187 * when leaving an expression it simplifies it and stores the simplified expr in its iterators expression data
3188 * after the child was visited, it is replaced with the simplified expr
3189 */
3190 SCIP_CALL( SCIPexpriterCreate(stat, blkmem, &it) );
3191 SCIP_CALL( SCIPexpriterInit(it, rootexpr, SCIP_EXPRITER_DFS, TRUE) ); /* TODO can we set allowrevisited to FALSE?*/
3193
3194 *changed = FALSE;
3195 *infeasible = FALSE;
3197 {
3198 switch( SCIPexpriterGetStageDFS(it) )
3199 {
3201 {
3203 SCIP_EXPR* child;
3204
3207 assert(newchild != NULL);
3208
3209 /* if child got simplified, replace it with the new child */
3210 if( newchild != child )
3211 {
3213 }
3214
3215 /* we do not need to hold newchild anymore */
3216 SCIP_CALL( SCIPexprRelease(set, stat, blkmem, &newchild) );
3217
3218 break;
3219 }
3220
3222 {
3224 SCIP_EXPRITER_USERDATA iterdata;
3225
3226 /* TODO we should do constant folding (handle that all children are value-expressions) here in a generic way
3227 * instead of reimplementing it in every handler
3228 */
3229
3230 /* use simplification of expression handlers */
3232 assert(refexpr != NULL);
3233 if( expr != refexpr )
3234 *changed = TRUE;
3235
3236 iterdata.ptrval = (void*) refexpr;
3238
3239 break;
3240 }
3241
3242 default:
3243 SCIPABORT(); /* we should never be called in this stage */
3244 break;
3245 }
3246 }
3247
3249 assert(*simplified != NULL);
3250
3252
3253 return SCIP_OKAY;
3254}
3255
3256/** checks whether an expression is quadratic
3257 *
3258 * An expression is quadratic if it is either a power expression with exponent 2.0, a product of two expressions,
3259 * or a sum of terms where at least one is a square or a product of two.
3260 *
3261 * Use \ref SCIPexprGetQuadraticData to get data about the representation as quadratic.
3262 */
3264 SCIP_SET* set, /**< global SCIP settings */
3265 BMS_BLKMEM* blkmem, /**< block memory */
3266 SCIP_EXPR* expr, /**< expression */
3267 SCIP_Bool* isquadratic /**< buffer to store result */
3268 )
3269{
3272 int nquadterms = 0;
3273 int nlinterms = 0;
3274 int nbilinterms = 0;
3275 int c;
3276
3277 assert(set != NULL);
3278 assert(blkmem != NULL);
3279 assert(expr != NULL);
3281
3282 if( expr->quadchecked )
3283 {
3284 *isquadratic = expr->quaddata != NULL;
3285 return SCIP_OKAY;
3286 }
3287 assert(expr->quaddata == NULL);
3288
3289 expr->quadchecked = TRUE;
3290 *isquadratic = FALSE;
3291
3292 /* check if expression is a quadratic expression */
3293 SCIPsetDebugMsg(set, "checking if expr %p is quadratic\n", (void*)expr);
3294
3295 /* handle single square term */
3296 if( SCIPexprIsPower(set, expr) && SCIPgetExponentExprPow(expr) == 2.0 )
3297 {
3298 SCIPsetDebugMsg(set, "expr %p looks like square: fill data structures\n", (void*)expr);
3299 SCIP_ALLOC( BMSallocClearBlockMemory(blkmem, &expr->quaddata) );
3300
3301 expr->quaddata->nquadexprs = 1;
3302 SCIP_ALLOC( BMSallocClearBlockMemoryArray(blkmem, &expr->quaddata->quadexprterms, 1) );
3303 expr->quaddata->quadexprterms[0].expr = expr->children[0];
3304 expr->quaddata->quadexprterms[0].sqrcoef = 1.0;
3305
3306 expr->quaddata->allexprsarevars = SCIPexprIsVar(set, expr->quaddata->quadexprterms[0].expr);
3307
3308 *isquadratic = TRUE;
3309 return SCIP_OKAY;
3310 }
3311
3312 /* handle single bilinear term */
3313 if( SCIPexprIsProduct(set, expr) && SCIPexprGetNChildren(expr) == 2 )
3314 {
3315 SCIPsetDebugMsg(set, "expr %p looks like bilinear product: fill data structures\n", (void*)expr);
3316 SCIP_ALLOC( BMSallocClearBlockMemory(blkmem, &expr->quaddata) );
3317 expr->quaddata->nquadexprs = 2;
3318
3319 SCIP_ALLOC( BMSallocClearBlockMemoryArray(blkmem, &expr->quaddata->quadexprterms, 2) );
3320 expr->quaddata->quadexprterms[0].expr = SCIPexprGetChildren(expr)[0];
3321 expr->quaddata->quadexprterms[0].nadjbilin = 1;
3322 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &expr->quaddata->quadexprterms[0].adjbilin, 1) );
3323 expr->quaddata->quadexprterms[0].adjbilin[0] = 0;
3324
3325 expr->quaddata->quadexprterms[1].expr = SCIPexprGetChildren(expr)[1];
3326 expr->quaddata->quadexprterms[1].nadjbilin = 1;
3327 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &expr->quaddata->quadexprterms[1].adjbilin, 1) );
3328 expr->quaddata->quadexprterms[1].adjbilin[0] = 0;
3329
3330 expr->quaddata->nbilinexprterms = 1;
3331 SCIP_ALLOC( BMSallocClearBlockMemoryArray(blkmem, &expr->quaddata->bilinexprterms, 1) );
3332 expr->quaddata->bilinexprterms[0].expr1 = SCIPexprGetChildren(expr)[1];
3333 expr->quaddata->bilinexprterms[0].expr2 = SCIPexprGetChildren(expr)[0];
3334 expr->quaddata->bilinexprterms[0].coef = 1.0;
3335
3336 expr->quaddata->allexprsarevars = SCIPexprIsVar(set, expr->quaddata->quadexprterms[0].expr)
3337 && SCIPexprIsVar(set, expr->quaddata->quadexprterms[1].expr);
3338
3339 *isquadratic = TRUE;
3340 return SCIP_OKAY;
3341 }
3342
3343 /* neither a sum, nor a square, nor a bilinear term */
3344 if( !SCIPexprIsSum(set, expr) )
3345 return SCIP_OKAY;
3346
3348 for( c = 0; c < SCIPexprGetNChildren(expr); ++c )
3349 {
3350 SCIP_EXPR* child;
3351
3352 child = SCIPexprGetChildren(expr)[c];
3353 assert(child != NULL);
3354
3355 if( SCIPexprIsPower(set, child) && SCIPgetExponentExprPow(child) == 2.0 ) /* quadratic term */
3356 {
3358 }
3359 else if( SCIPexprIsProduct(set, child) && SCIPexprGetNChildren(child) == 2 ) /* bilinear term */
3360 {
3361 ++nbilinterms;
3364 }
3365 else
3366 {
3367 /* first time seen linearly --> assign -1; ++nlinterms
3368 * not first time --> assign +=1;
3369 */
3370 if( SCIPhashmapExists(seenexpr, (void*)child) )
3371 {
3372 assert(SCIPhashmapGetImageInt(seenexpr, (void*)child) > 0);
3373
3374 SCIP_CALL( SCIPhashmapSetImageInt(seenexpr, (void*)child, SCIPhashmapGetImageInt(seenexpr, (void*)child) + 1) );
3375 }
3376 else
3377 {
3378 ++nlinterms;
3379 SCIP_CALL( SCIPhashmapInsertInt(seenexpr, (void*)child, -1) );
3380 }
3381 }
3382 }
3383
3384 if( nquadterms == 0 )
3385 {
3386 /* only linear sum */
3388 return SCIP_OKAY;
3389 }
3390
3391 SCIPsetDebugMsg(set, "expr %p looks quadratic: fill data structures\n", (void*)expr);
3392
3393 /* expr2idx maps expressions to indices; if index > 0, it is its index in the linexprs array, otherwise -index-1 is
3394 * its index in the quadexprterms array
3395 */
3397
3398 /* allocate memory, etc */
3399 SCIP_ALLOC( BMSallocClearBlockMemory(blkmem, &expr->quaddata) );
3403 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &expr->quaddata->bilinexprterms, nbilinterms) );
3404
3406
3407 expr->quaddata->allexprsarevars = TRUE;
3408 /* for every term of the sum-expr */
3409 for( c = 0; c < SCIPexprGetNChildren(expr); ++c )
3410 {
3411 SCIP_EXPR* child;
3412 SCIP_Real coef;
3413
3414 child = SCIPexprGetChildren(expr)[c];
3415 coef = SCIPgetCoefsExprSum(expr)[c];
3416
3417 assert(child != NULL);
3418 assert(coef != 0.0);
3419
3420 if( SCIPexprIsPower(set, child) && SCIPgetExponentExprPow(child) == 2.0 ) /* quadratic term */
3421 {
3423 assert(SCIPexprGetNChildren(child) == 1);
3424
3425 child = SCIPexprGetChildren(child)[0];
3426 assert(SCIPhashmapGetImageInt(seenexpr, (void *)child) > 0);
3427
3429 assert(quadexprterm->expr == child);
3430 quadexprterm->sqrcoef = coef;
3431 quadexprterm->sqrexpr = SCIPexprGetChildren(expr)[c];
3432
3433 if( expr->quaddata->allexprsarevars )
3435 }
3436 else if( SCIPexprIsProduct(set, child) && SCIPexprGetNChildren(child) == 2 ) /* bilinear term */
3437 {
3440 SCIP_EXPR* expr1;
3441 SCIP_EXPR* expr2;
3442
3443 assert(SCIPgetCoefExprProduct(child) == 1.0);
3444
3445 expr1 = SCIPexprGetChildren(child)[0];
3446 expr2 = SCIPexprGetChildren(child)[1];
3447 assert(expr1 != NULL && expr2 != NULL);
3448
3450
3451 bilinexprterm->coef = coef;
3452 if( SCIPhashmapGetImageInt(seenexpr, (void*)expr1) >= SCIPhashmapGetImageInt(seenexpr, (void*)expr2) )
3453 {
3454 bilinexprterm->expr1 = expr1;
3455 bilinexprterm->expr2 = expr2;
3456 }
3457 else
3458 {
3459 bilinexprterm->expr1 = expr2;
3460 bilinexprterm->expr2 = expr1;
3461 }
3462 bilinexprterm->prodexpr = child;
3463
3465 assert(quadexprterm->expr == expr1);
3466 quadexprterm->adjbilin[quadexprterm->nadjbilin] = expr->quaddata->nbilinexprterms;
3467 ++quadexprterm->nadjbilin;
3468
3469 if( expr->quaddata->allexprsarevars )
3471
3473 assert(quadexprterm->expr == expr2);
3474 quadexprterm->adjbilin[quadexprterm->nadjbilin] = expr->quaddata->nbilinexprterms;
3475 ++quadexprterm->nadjbilin;
3476
3477 if( expr->quaddata->allexprsarevars )
3479
3480 ++expr->quaddata->nbilinexprterms;
3481
3482 /* store position of second factor in quadexprterms */
3484 }
3485 else /* linear term */
3486 {
3487 if( SCIPhashmapGetImageInt(seenexpr, (void*)child) < 0 )
3488 {
3489 assert(SCIPhashmapGetImageInt(seenexpr, (void*)child) == -1);
3490
3491 /* expression only appears linearly */
3492 expr->quaddata->linexprs[expr->quaddata->nlinexprs] = child;
3493 expr->quaddata->lincoefs[expr->quaddata->nlinexprs] = coef;
3494 expr->quaddata->nlinexprs++;
3495
3496 if( expr->quaddata->allexprsarevars )
3497 expr->quaddata->allexprsarevars = SCIPexprIsVar(set, child);
3498 }
3499 else
3500 {
3501 /* expression appears non-linearly: set lin coef */
3503 assert(SCIPhashmapGetImageInt(seenexpr, (void*)child) > 0);
3504
3506 assert(quadexprterm->expr == child);
3507 quadexprterm->lincoef = coef;
3508
3509 if( expr->quaddata->allexprsarevars )
3511 }
3512 }
3513 }
3516 assert(expr->quaddata->nbilinexprterms == nbilinterms);
3517
3520
3521 *isquadratic = TRUE;
3522
3523 return SCIP_OKAY;
3524}
3525
3526/** frees information on quadratic representation of an expression
3527 *
3528 * Reverts SCIPexprCheckQuadratic().
3529 * Before doing changes to an expression, it can be useful to call this function.
3530 */
3532 BMS_BLKMEM* blkmem, /**< block memory */
3533 SCIP_EXPR* expr /**< expression */
3534 )
3535{
3536 int i;
3537 int n;
3538
3539 assert(blkmem != NULL);
3540 assert(expr != NULL);
3541
3542 expr->quadchecked = FALSE;
3543
3544 if( expr->quaddata == NULL )
3545 return;
3546
3547 n = expr->quaddata->nquadexprs;
3548
3553 BMSfreeBlockMemoryArrayNull(blkmem, &expr->quaddata->eigenvectors, n * n); /*lint !e647*/
3554
3555 for( i = 0; i < n; ++i )
3556 {
3559 }
3561
3562 BMSfreeBlockMemory(blkmem, &expr->quaddata);
3563}
3564
3565/** Checks the curvature of the quadratic function stored in quaddata
3566 *
3567 * For this, it builds the matrix Q of quadratic coefficients and computes its eigenvalues using LAPACK.
3568 * If Q is
3569 * - semidefinite positive -> curv is set to convex,
3570 * - semidefinite negative -> curv is set to concave,
3571 * - otherwise -> curv is set to unknown.
3572 *
3573 * If `assumevarfixed` is given and some expressions in quadratic terms correspond to variables present in
3574 * this hashmap, then the corresponding rows and columns are ignored in the matrix Q.
3575 */
3577 SCIP_SET* set, /**< global SCIP settings */
3578 BMS_BLKMEM* blkmem, /**< block memory */
3579 BMS_BUFMEM* bufmem, /**< buffer memory */
3580 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
3581 SCIP_EXPR* expr, /**< quadratic expression */
3582 SCIP_EXPRCURV* curv, /**< pointer to store the curvature of quadratics */
3583 SCIP_HASHMAP* assumevarfixed, /**< hashmap containing variables that should be assumed to be fixed, or NULL */
3584 SCIP_Bool storeeigeninfo /**< whether the eigenvalues and eigenvectors should be stored */
3585 )
3586{
3587 SCIP_QUADEXPR* quaddata;
3589 double* matrix;
3590 double* alleigval;
3591 int nvars;
3592 int nn;
3593 int n;
3594 int i;
3595
3596 assert(set != NULL);
3597 assert(blkmem != NULL);
3598 assert(bufmem != NULL);
3599 assert(messagehdlr != NULL);
3600 assert(expr != NULL);
3601 assert(curv != NULL);
3602
3603 quaddata = expr->quaddata;
3604 assert(quaddata != NULL);
3605
3606 /* do not store eigen information if we are not considering full matrix */
3607 if( assumevarfixed != NULL )
3609
3610 if( quaddata->eigeninfostored || (quaddata->curvaturechecked && !storeeigeninfo) )
3611 {
3612 *curv = quaddata->curvature;
3613 /* if we are convex or concave on the full set of variables, then we will also be so on a subset */
3614 if( assumevarfixed == NULL || quaddata->curvature != SCIP_EXPRCURV_UNKNOWN )
3615 return SCIP_OKAY;
3616 }
3618 || (storeeigeninfo && !quaddata->eigeninfostored));
3619
3620 *curv = SCIP_EXPRCURV_UNKNOWN;
3621
3622 n = quaddata->nquadexprs;
3623
3624 /* do not check curvature if nn will be too large
3625 * we want nn * sizeof(real) to fit into an unsigned int, so n must be <= sqrt(unit_max/sizeof(real))
3626 * sqrt(2*214748364/8) = 7327.1475350234
3627 */
3628 if( n > 7000 )
3629 {
3630 SCIPmessageFPrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL, NULL,
3631 "number of quadratic variables is too large (%d) to check the curvature\n", n);
3632 return SCIP_OKAY;
3633 }
3634
3635 /* TODO do some simple tests first; like diagonal entries don't change sign, etc */
3636
3638 return SCIP_OKAY;
3639
3640 nn = n * n;
3641 assert(nn > 0);
3642 assert((unsigned)nn < UINT_MAX / sizeof(SCIP_Real));
3643
3644 if( storeeigeninfo )
3645 {
3646 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &quaddata->eigenvalues, n));
3648
3649 alleigval = quaddata->eigenvalues;
3650 matrix = quaddata->eigenvectors;
3651 }
3652 else
3653 {
3656 }
3657
3658 SCIP_CALL( SCIPhashmapCreate(&expr2matrix, blkmem, n) );
3659
3660 /* fill matrix's diagonal */
3661 nvars = 0;
3662 for( i = 0; i < n; ++i )
3663 {
3665
3666 quadexprterm = quaddata->quadexprterms[i];
3667
3669
3670 /* skip expr if it is a variable mentioned in assumevarfixed */
3673 continue;
3674
3675 if( quadexprterm.sqrcoef == 0.0 && ! storeeigeninfo )
3676 {
3677 assert(quadexprterm.nadjbilin > 0);
3678 /* SCIPdebugMsg(scip, "var <%s> appears in bilinear term but is not squared
3679 * --> indefinite quadratic\n", SCIPvarGetName(quadexprterm.var)); */
3680 goto CLEANUP;
3681 }
3682
3683 matrix[nvars * n + nvars] = quadexprterm.sqrcoef;
3684
3685 /* remember row of variable in matrix */
3686 SCIP_CALL( SCIPhashmapInsert(expr2matrix, (void *)quadexprterm.expr, (void *)(size_t)nvars) );
3687 nvars++;
3688 }
3689
3690 /* fill matrix's upper-diagonal */
3691 for( i = 0; i < quaddata->nbilinexprterms; ++i )
3692 {
3694 int col;
3695 int row;
3696
3697 bilinexprterm = quaddata->bilinexprterms[i];
3698
3699 /* each factor should have been added to expr2matrix unless it corresponds to a variable mentioned in assumevarfixed */
3706
3707 /* skip bilinear terms where at least one of the factors should be assumed to be fixed
3708 * (i.e., not present in expr2matrix map) */
3709 if( !SCIPhashmapExists(expr2matrix, (void*)bilinexprterm.expr1)
3710 || !SCIPhashmapExists(expr2matrix, (void*)bilinexprterm.expr2) )
3711 continue;
3712
3713 row = (int)(size_t)SCIPhashmapGetImage(expr2matrix, bilinexprterm.expr1);
3714 col = (int)(size_t)SCIPhashmapGetImage(expr2matrix, bilinexprterm.expr2);
3715
3716 assert(row != col);
3717
3718 if( row < col )
3719 matrix[row * n + col] = bilinexprterm.coef / 2.0;
3720 else
3721 matrix[col * n + row] = bilinexprterm.coef / 2.0;
3722 }
3723
3724 /* compute eigenvalues */
3726 {
3727 SCIPmessagePrintWarning(messagehdlr, "Failed to compute eigenvalues of quadratic coefficient "
3728 "matrix --> don't know curvature\n");
3729 goto CLEANUP;
3730 }
3731
3732 /* check convexity */
3733 if( !SCIPsetIsNegative(set, alleigval[0]) )
3734 *curv = SCIP_EXPRCURV_CONVEX;
3735 else if( !SCIPsetIsPositive(set, alleigval[n-1]) )
3736 *curv = SCIP_EXPRCURV_CONCAVE;
3737
3738CLEANUP:
3740
3741 if( !storeeigeninfo )
3742 {
3745 }
3746 else
3747 {
3748 assert(!quaddata->eigeninfostored);
3749 quaddata->eigeninfostored = TRUE;
3750 }
3751
3752 /* if checked convexity on full Q matrix, then remember it
3753 * if indefinite on submatrix, then it will also be indefinite on full matrix, so can remember that, too */
3754 if( assumevarfixed == NULL || *curv == SCIP_EXPRCURV_UNKNOWN )
3755 {
3756 quaddata->curvature = *curv;
3757 quaddata->curvaturechecked = TRUE;
3758 }
3759
3760 return SCIP_OKAY;
3761}
3762
3763
3764/* from pub_expr.h */
3765
3766#ifdef NDEBUG
3767#undef SCIPexprGetNUses
3768#undef SCIPexprGetNChildren
3769#undef SCIPexprGetChildren
3770#undef SCIPexprGetHdlr
3771#undef SCIPexprGetData
3772#undef SCIPexprSetData
3773#undef SCIPexprGetOwnerData
3774#undef SCIPexprGetEvalValue
3775#undef SCIPexprGetEvalTag
3776#undef SCIPexprGetDerivative
3777#undef SCIPexprGetDot
3778#undef SCIPexprGetBardot
3779#undef SCIPexprGetDiffTag
3780#undef SCIPexprGetActivity
3781#undef SCIPexprGetActivityTag
3782#undef SCIPexprSetActivity
3783#undef SCIPexprGetCurvature
3784#undef SCIPexprSetCurvature
3785#undef SCIPexprIsIntegral
3786#undef SCIPexprSetIntegrality
3787#undef SCIPexprAreQuadraticExprsVariables
3788#endif
3789
3790/** gets the number of times the expression is currently captured */
3792 SCIP_EXPR* expr /**< expression */
3793 )
3794{
3795 assert(expr != NULL);
3796
3797 return expr->nuses;
3798}
3799
3800/** gives the number of children of an expression */
3802 SCIP_EXPR* expr /**< expression */
3803 )
3804{
3805 assert(expr != NULL);
3806
3807 return expr->nchildren;
3808}
3809
3810/** gives the children of an expression (can be NULL if no children) */
3812 SCIP_EXPR* expr /**< expression */
3813 )
3814{
3815 assert(expr != NULL);
3816
3817 return expr->children;
3818}
3819
3820/** gets the expression handler of an expression
3821 *
3822 * This identifies the type of the expression (sum, variable, ...).
3823 */
3825 SCIP_EXPR* expr /**< expression */
3826 )
3827{
3828 assert(expr != NULL);
3829
3830 return expr->exprhdlr;
3831}
3832
3833/** gets the expression data of an expression */
3835 SCIP_EXPR* expr /**< expression */
3836 )
3837{
3838 assert(expr != NULL);
3839
3840 return expr->exprdata;
3841}
3842
3843/** sets the expression data of an expression
3844 *
3845 * The pointer to possible old data is overwritten and the
3846 * freedata-callback is not called before.
3847 * This function is intended to be used by expression handler only.
3848 */
3850 SCIP_EXPR* expr, /**< expression */
3851 SCIP_EXPRDATA* exprdata /**< expression data to be set (can be NULL) */
3852 )
3853{
3854 assert(expr != NULL);
3855 assert(exprdata == NULL || expr->exprhdlr->copydata != NULL); /* copydata must be available if there is expression data */
3856 assert(exprdata == NULL || expr->exprhdlr->freedata != NULL); /* freedata must be available if there is expression data */
3857
3858 expr->exprdata = exprdata;
3859}
3860
3861/** gets the data that the owner of an expression has stored in an expression */
3863 SCIP_EXPR* expr /**< expression */
3864 )
3865{
3866 assert(expr != NULL);
3867
3868 return expr->ownerdata;
3869}
3870
3871/** gives the value from the last evaluation of an expression (or SCIP_INVALID if there was an eval error)
3872 *
3873 * @see SCIPevalExpr to evaluate the expression at a given solution.
3874 */
3876 SCIP_EXPR* expr /**< expression */
3877 )
3878{
3879 assert(expr != NULL);
3880
3881 return expr->evalvalue;
3882}
3883
3884/** gives the evaluation tag from the last evaluation, or 0
3885 *
3886 * @see SCIPevalExpr
3887 */
3889 SCIP_EXPR* expr /**< expression */
3890 )
3891{
3892 assert(expr != NULL);
3893
3894 return expr->evaltag;
3895}
3896
3897/** returns the derivative stored in an expression (or SCIP_INVALID if there was an evaluation error)
3898 *
3899 * @see SCIPevalExprGradient
3900 */
3902 SCIP_EXPR* expr /**< expression */
3903 )
3904{
3905 assert(expr != NULL);
3906
3907 return expr->derivative;
3908}
3909
3910/** gives the value of directional derivative from the last evaluation of a directional derivative of
3911 * expression (or SCIP_INVALID if there was an error)
3912 *
3913 * @see SCIPevalExprHessianDir
3914 */
3916 SCIP_EXPR* expr /**< expression */
3917 )
3918{
3919 assert(expr != NULL);
3920
3921 return expr->dot;
3922}
3923
3924/** gives the value of directional derivative from the last evaluation of a directional derivative of
3925 * derivative of root (or SCIP_INVALID if there was an error)
3926 *
3927 * @see SCIPevalExprHessianDir
3928 */
3930 SCIP_EXPR* expr /**< expression */
3931 )
3932{
3933 assert(expr != NULL);
3934
3935 return expr->bardot;
3936}
3937
3938/** returns the difftag stored in an expression
3939 *
3940 * can be used to check whether partial derivative value is valid
3941 *
3942 * @see SCIPevalExprGradient
3943 */
3945 SCIP_EXPR* expr /**< expression */
3946 )
3947{
3948 assert(expr != NULL);
3949
3950 return expr->difftag;
3951}
3952
3953/** returns the activity that is currently stored for an expression
3954 *
3955 * @see SCIPevalExprActivity
3956 */
3958 SCIP_EXPR* expr /**< expression */
3959 )
3960{
3961 assert(expr != NULL);
3962
3963 return expr->activity;
3964}
3965
3966/** returns the tag associated with the activity of the expression
3967 *
3968 * It can depend on the owner of the expression how to interpret this tag.
3969 * SCIPevalExprActivity() compares with `stat->domchgcount`.
3970 *
3971 * @see SCIPevalExprActivity
3972 */
3974 SCIP_EXPR* expr /**< expression */
3975 )
3976{
3977 assert(expr != NULL);
3978
3979 return expr->activitytag;
3980}
3981
3982/** set the activity with tag for an expression */
3984 SCIP_EXPR* expr, /**< expression */
3985 SCIP_INTERVAL activity, /**< new activity */
3986 SCIP_Longint activitytag /**< tag associated with activity */
3987 )
3988{
3989 assert(expr != NULL);
3990
3991 expr->activity = activity;
3992 expr->activitytag = activitytag;
3993}
3994
3995/** returns the curvature of an expression
3996 *
3997 * @note Call SCIPcomputeExprCurvature() before calling this function.
3998 */
4000 SCIP_EXPR* expr /**< expression */
4001 )
4002{
4003 assert(expr != NULL);
4004
4005 return expr->curvature;
4006}
4007
4008/** sets the curvature of an expression */
4010 SCIP_EXPR* expr, /**< expression */
4011 SCIP_EXPRCURV curvature /**< curvature of the expression */
4012 )
4013{
4014 assert(expr != NULL);
4015
4016 expr->curvature = curvature;
4017}
4018
4019/** returns whether an expression is integral */
4021 SCIP_EXPR* expr /**< expression */
4022 )
4023{
4024 assert(expr != NULL);
4025
4026 return expr->isintegral;
4027}
4028
4029/** sets the integrality flag of an expression */
4031 SCIP_EXPR* expr, /**< expression */
4032 SCIP_Bool isintegral /**< integrality of the expression */
4033 )
4034{
4035 assert(expr != NULL);
4036
4037 expr->isintegral = isintegral;
4038}
4039
4040/** gives the coefficients and expressions that define a quadratic expression
4041 *
4042 * It can return the constant part, the number, arguments, and coefficients of the purely linear part
4043 * and the number of quadratic terms and bilinear terms.
4044 * Note that for arguments that appear in the quadratic part, a linear coefficient is
4045 * stored with the quadratic term.
4046 * Use SCIPexprGetQuadraticQuadTerm() and SCIPexprGetQuadraticBilinTerm()
4047 * to access the data for a quadratic or bilinear term.
4048 *
4049 * It can also return the eigenvalues and the eigenvectors of the matrix \f$Q\f$ when the quadratic is written
4050 * as \f$x^T Q x + b^T x + c^T y + d\f$, where \f$c^T y\f$ defines the purely linear part.
4051 * Note, however, that to have access to them one needs to call SCIPcomputeExprQuadraticCurvature()
4052 * with `storeeigeninfo=TRUE`. If the eigen information was not stored or it failed to be computed,
4053 * `eigenvalues` and `eigenvectors` will be set to NULL.
4054 *
4055 * This function returns pointers to internal data in linexprs and lincoefs.
4056 * The user must not change this data.
4057 *
4058 * @attention SCIPcheckExprQuadratic() needs to be called first to check whether expression is quadratic and initialize the data of the quadratic representation.
4059 */
4061 SCIP_EXPR* expr, /**< quadratic expression */
4062 SCIP_Real* constant, /**< buffer to store constant term, or NULL */
4063 int* nlinexprs, /**< buffer to store number of expressions that appear linearly, or NULL */
4064 SCIP_EXPR*** linexprs, /**< buffer to store pointer to array of expressions that appear linearly, or NULL */
4065 SCIP_Real** lincoefs, /**< buffer to store pointer to array of coefficients of expressions that appear linearly, or NULL */
4066 int* nquadexprs, /**< buffer to store number of expressions in quadratic terms, or NULL */
4067 int* nbilinexprs, /**< buffer to store number of bilinear expressions terms, or NULL */
4068 SCIP_Real** eigenvalues, /**< buffer to store pointer to array of eigenvalues of Q, or NULL */
4069 SCIP_Real** eigenvectors /**< buffer to store pointer to array of eigenvectors of Q, or NULL */
4070 )
4071{
4072 SCIP_QUADEXPR* quaddata;
4073
4074 assert(expr != NULL);
4075
4076 quaddata = expr->quaddata;
4077 assert(quaddata != NULL);
4078
4079 if( constant != NULL )
4080 *constant = quaddata->constant;
4081 if( nlinexprs != NULL )
4082 *nlinexprs = quaddata->nlinexprs;
4083 if( linexprs != NULL )
4084 *linexprs = quaddata->linexprs;
4085 if( lincoefs != NULL )
4086 *lincoefs = quaddata->lincoefs;
4087 if( nquadexprs != NULL )
4088 *nquadexprs = quaddata->nquadexprs;
4089 if( nbilinexprs != NULL )
4090 *nbilinexprs = quaddata->nbilinexprterms;
4091 if( eigenvalues != NULL )
4092 *eigenvalues = quaddata->eigenvalues;
4093 if( eigenvectors != NULL )
4094 *eigenvectors = quaddata->eigenvectors;
4095}
4096
4097/** gives the data of a quadratic expression term
4098 *
4099 * For a term \f$a \cdot \text{expr}^2 + b \cdot \text{expr} + \sum_i (c_i \cdot \text{expr} \cdot \text{otherexpr}_i)\f$, returns
4100 * `expr`, \f$a\f$, \f$b\f$, the number of summands, and indices of bilinear terms in the quadratic expressions `bilinexprterms`.
4101 *
4102 * This function returns pointers to internal data in adjbilin.
4103 * The user must not change this data.
4104 */
4106 SCIP_EXPR* quadexpr, /**< quadratic expression */
4107 int termidx, /**< index of quadratic term */
4108 SCIP_EXPR** expr, /**< buffer to store pointer to argument expression (the 'x') of this term, or NULL */
4109 SCIP_Real* lincoef, /**< buffer to store linear coefficient of variable, or NULL */
4110 SCIP_Real* sqrcoef, /**< buffer to store square coefficient of variable, or NULL */
4111 int* nadjbilin, /**< buffer to store number of bilinear terms this variable is involved in, or NULL */
4112 int** adjbilin, /**< buffer to store pointer to indices of associated bilinear terms, or NULL */
4113 SCIP_EXPR** sqrexpr /**< buffer to store pointer to square expression (the 'x^2') of this term or NULL if no square expression, or NULL */
4114 )
4115{
4117
4118 assert(quadexpr != NULL);
4119 assert(quadexpr->quaddata != NULL);
4120 assert(quadexpr->quaddata->quadexprterms != NULL);
4121 assert(termidx >= 0);
4122 assert(termidx < quadexpr->quaddata->nquadexprs);
4123
4124 quadexprterm = &quadexpr->quaddata->quadexprterms[termidx];
4125
4126 if( expr != NULL )
4127 *expr = quadexprterm->expr;
4128 if( lincoef != NULL )
4129 *lincoef = quadexprterm->lincoef;
4130 if( sqrcoef != NULL )
4131 *sqrcoef = quadexprterm->sqrcoef;
4132 if( nadjbilin != NULL )
4133 *nadjbilin = quadexprterm->nadjbilin;
4134 if( adjbilin != NULL )
4135 *adjbilin = quadexprterm->adjbilin;
4136 if( sqrexpr != NULL )
4137 *sqrexpr = quadexprterm->sqrexpr;
4138}
4139
4140/** gives the data of a bilinear expression term
4141 *
4142 * For a term a*expr1*expr2, returns expr1, expr2, a, and
4143 * the position of the quadratic expression term that uses expr2 in the quadratic expressions `quadexprterms`.
4144 */
4146 SCIP_EXPR* expr, /**< quadratic expression */
4147 int termidx, /**< index of bilinear term */
4148 SCIP_EXPR** expr1, /**< buffer to store first factor, or NULL */
4149 SCIP_EXPR** expr2, /**< buffer to store second factor, or NULL */
4150 SCIP_Real* coef, /**< buffer to coefficient, or NULL */
4151 int* pos2, /**< buffer to position of expr2 in quadexprterms array of quadratic expression, or NULL */
4152 SCIP_EXPR** prodexpr /**< buffer to store pointer to expression that is product if first and second factor, or NULL */
4153 )
4154{
4156
4157 assert(expr != NULL);
4158 assert(expr->quaddata != NULL);
4160 assert(termidx >= 0);
4161 assert(termidx < expr->quaddata->nbilinexprterms);
4162
4164
4165 if( expr1 != NULL )
4166 *expr1 = bilinexprterm->expr1;
4167 if( expr2 != NULL )
4168 *expr2 = bilinexprterm->expr2;
4169 if( coef != NULL )
4170 *coef = bilinexprterm->coef;
4171 if( pos2 != NULL )
4172 *pos2 = bilinexprterm->pos2;
4173 if( prodexpr != NULL )
4174 *prodexpr = bilinexprterm->prodexpr;
4175}
4176
4177/** returns whether all expressions that are used in a quadratic expression are variable expressions
4178 *
4179 * @return TRUE iff all `linexprs` and `quadexprterms[.].expr` are variable expressions
4180 */
4182 SCIP_EXPR* expr /**< quadratic expression */
4183 )
4184{
4185 assert(expr != NULL);
4186 assert(expr->quaddata != NULL);
4187
4188 return expr->quaddata->allexprsarevars;
4189}
4190
4191/**@} */
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition clock.c:360
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition clock.c:290
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition clock.c:438
void SCIPclockReset(SCIP_CLOCK *clck)
Definition clock.c:209
void SCIPclockFree(SCIP_CLOCK **clck)
Definition clock.c:185
SCIP_RETCODE SCIPclockCreate(SCIP_CLOCK **clck, SCIP_CLOCKTYPE clocktype)
Definition clock.c:170
internal methods for clocks and timing issues
#define SCIP_INVALID
Definition def.h:206
#define SCIP_INTERVAL_INFINITY
Definition def.h:208
#define SCIP_ALLOC(x)
Definition def.h:399
#define TRUE
Definition def.h:95
#define FALSE
Definition def.h:96
#define SCIPABORT()
Definition def.h:360
#define SCIP_CALL(x)
Definition def.h:388
#define SCIP_CALL_FINALLY(x, y)
Definition def.h:430
SCIP_RETCODE SCIPexprPrint(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_MESSAGEHDLR *messagehdlr, FILE *file, SCIP_EXPR *expr)
Definition expr.c:2243
SCIP_Bool SCIPexprIsPower(SCIP_SET *set, SCIP_EXPR *expr)
Definition expr.c:2231
SCIP_RETCODE SCIPexprhdlrBwDiffExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, BMS_BUFMEM *bufmem, SCIP_EXPR *expr, int childidx, SCIP_Real *derivative, SCIP_Real *childrenvals, SCIP_Real exprval)
Definition expr.c:1249
SCIP_RETCODE SCIPexprEvalActivity(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *rootexpr)
Definition expr.c:2927
static SCIP_RETCODE evalAndDiff(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, SCIP_SOL *sol, SCIP_Longint soltag, SCIP_SOL *direction)
Definition expr.c:187
SCIP_RETCODE SCIPexprPrintDotInit(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPRPRINTDATA **printdata, FILE *file, SCIP_EXPRPRINT_WHAT whattoprint)
Definition expr.c:2292
SCIP_RETCODE SCIPexprhdlrIntegralityExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_Bool *isintegral)
Definition expr.c:1060
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:1855
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:2324
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:3166
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:1577
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:3576
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:1612
SCIP_RETCODE SCIPexprEvalGradient(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *rootexpr, SCIP_SOL *sol, SCIP_Longint soltag)
Definition expr.c:2722
SCIP_RETCODE SCIPexprReplaceChild(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, int childidx, SCIP_EXPR *newchild)
Definition expr.c:1793
SCIP_RETCODE SCIPexprhdlrReversePropExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_INTERVAL bounds, SCIP_INTERVAL *childrenbounds, SCIP_Bool *infeasible)
Definition expr.c:1657
SCIP_Bool SCIPexprIsVar(SCIP_SET *set, SCIP_EXPR *expr)
Definition expr.c:2183
static SCIP_RETCODE freeExpr(BMS_BLKMEM *blkmem, SCIP_EXPR **expr)
Definition expr.c:73
SCIP_RETCODE SCIPexprCheckQuadratic(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, SCIP_Bool *isquadratic)
Definition expr.c:3263
SCIP_RETCODE SCIPexprhdlrFree(SCIP_EXPRHDLR **exprhdlr, SCIP_SET *set, BMS_BLKMEM *blkmem)
Definition expr.c:338
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:894
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:2821
int SCIPexprCompare(SCIP_SET *set, SCIP_EXPR *expr1, SCIP_EXPR *expr2)
Definition expr.c:3059
SCIP_RETCODE SCIPexprhdlrMonotonicityExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, int childidx, SCIP_MONOTONE *result)
Definition expr.c:1031
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:1182
void SCIPexprhdlrInit(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set)
Definition expr.c:861
SCIP_RETCODE SCIPexprRemoveChildren(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *expr)
Definition expr.c:1823
SCIP_RETCODE SCIPexprhdlrCopyInclude(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *targetset)
Definition expr.c:836
SCIP_RETCODE SCIPexprhdlrHashExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, unsigned int *hashkey, unsigned int *childrenhashes)
Definition expr.c:1090
SCIP_Bool SCIPexprIsValue(SCIP_SET *set, SCIP_EXPR *expr)
Definition expr.c:2195
SCIP_RETCODE SCIPexprhdlrFwDiffExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_Real *dot, SCIP_SOL *direction)
Definition expr.c:1322
void SCIPexprCapture(SCIP_EXPR *expr)
Definition expr.c:2041
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:1502
static SCIP_RETCODE quadDetectProcessExpr(SCIP_EXPR *expr, SCIP_HASHMAP *seenexpr, int *nquadterms, int *nlinterms)
Definition expr.c:104
SCIP_RETCODE SCIPexprhdlrBwFwDiffExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, int childidx, SCIP_Real *bardot, SCIP_SOL *direction)
Definition expr.c:1466
SCIP_RETCODE SCIPexprPrintDotFinal(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPRPRINTDATA **printdata)
Definition expr.c:2470
SCIP_RETCODE SCIPexprAppendChild(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, SCIP_EXPR *child)
Definition expr.c:1762
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:2010
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:963
int SCIPexprhdlrCompareExpr(SCIP_SET *set, SCIP_EXPR *expr1, SCIP_EXPR *expr2)
Definition expr.c:1139
SCIP_RETCODE SCIPexprhdlrCurvatureExpr(SCIP_EXPRHDLR *exprhdlr, SCIP_SET *set, SCIP_EXPR *expr, SCIP_EXPRCURV exprcurvature, SCIP_Bool *success, SCIP_EXPRCURV *childcurv)
Definition expr.c:1002
SCIP_RETCODE SCIPexprDismantle(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_MESSAGEHDLR *messagehdlr, FILE *file, SCIP_EXPR *expr)
Definition expr.c:2523
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:1705
SCIP_Bool SCIPexprIsProduct(SCIP_SET *set, SCIP_EXPR *expr)
Definition expr.c:2219
SCIP_RETCODE SCIPexprPrintDot(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_EXPRPRINTDATA *printdata, SCIP_EXPR *expr)
Definition expr.c:2356
SCIP_Bool SCIPexprIsSum(SCIP_SET *set, SCIP_EXPR *expr)
Definition expr.c:2207
SCIP_RETCODE SCIPexprRelease(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR **rootexpr)
Definition expr.c:2051
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:1533
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:1363
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:303
static SCIP_RETCODE quadDetectGetQuadexprterm(BMS_BLKMEM *blkmem, SCIP_EXPR *expr, SCIP_HASHMAP *expr2idx, SCIP_HASHMAP *seenexpr, SCIP_QUADEXPR *quadexpr, SCIP_QUADEXPR_QUADTERM **quadexprterm)
Definition expr.c:144
void SCIPexprFreeQuadratic(BMS_BLKMEM *blkmem, SCIP_EXPR *expr)
Definition expr.c:3531
SCIP_RETCODE SCIPexprEval(SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPR *expr, SCIP_SOL *sol, SCIP_Longint soltag)
Definition expr.c:2631
private functions to work with algebraic expressions
void SCIPexpriterFree(SCIP_EXPRITER **iterator)
Definition expriter.c:445
SCIP_RETCODE SCIPexpriterCreate(SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_EXPRITER **iterator)
Definition expriter.c:426
static SCIP_RETCODE eval(SCIP *scip, SCIP_EXPR *expr, SCIP_EXPRINTDATA *exprintdata, const vector< Type > &x, Type &val)
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition misc.c:3058
int SCIPhashmapGetImageInt(SCIP_HASHMAP *hashmap, void *origin)
Definition misc.c:3231
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition misc.c:3211
SCIP_RETCODE SCIPhashmapInsert(SCIP_HASHMAP *hashmap, void *origin, void *image)
Definition misc.c:3106
int SCIPhashmapGetNEntries(SCIP_HASHMAP *hashmap)
Definition misc.c:3491
SCIP_HASHMAPENTRY * SCIPhashmapGetEntry(SCIP_HASHMAP *hashmap, int entryidx)
Definition misc.c:3499
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition misc.c:3024
void * SCIPhashmapEntryGetOrigin(SCIP_HASHMAPENTRY *entry)
Definition misc.c:3510
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition misc.c:3373
SCIP_RETCODE SCIPhashmapInsertInt(SCIP_HASHMAP *hashmap, void *origin, int image)
Definition misc.c:3142
SCIP_RETCODE SCIPhashmapSetImageInt(SCIP_HASHMAP *hashmap, void *origin, int image)
Definition misc.c:3307
SCIP_RETCODE SCIPcallLapackDsyevIpopt(SCIP_Bool computeeigenvectors, int N, SCIP_Real *a, SCIP_Real *w)
SCIP_Bool SCIPisIpoptAvailableIpopt(void)
#define SCIPisFinite(x)
Definition pub_misc.h:1901
unsigned int SCIPcalcFibHash(SCIP_Real v)
Definition misc.c:10258
const char * SCIPexprhdlrGetName(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:532
SCIP_Real SCIPexprhdlrGetEstimateTime(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:770
SCIP_Bool SCIPexprhdlrHasSimplify(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:632
SCIP_Longint SCIPexprhdlrGetNDomainReductions(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:738
void SCIPexprhdlrSetCompare(SCIP_EXPRHDLR *exprhdlr,)
Definition expr.c:460
void SCIPexprhdlrSetIntegrality(SCIP_EXPRHDLR *exprhdlr,)
Definition expr.c:438
void SCIPexprhdlrSetCurvature(SCIP_EXPRHDLR *exprhdlr,)
Definition expr.c:416
SCIP_Bool SCIPexprhdlrHasCurvature(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:642
void SCIPexprhdlrSetParse(SCIP_EXPRHDLR *exprhdlr,)
Definition expr.c:405
void SCIPexprhdlrIncrementNDomainReductions(SCIP_EXPRHDLR *exprhdlr, int nreductions)
Definition expr.c:748
SCIP_EXPRHDLRDATA * SCIPexprhdlrGetData(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:562
SCIP_Real SCIPexprhdlrGetReversepropTime(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:718
unsigned int SCIPexprhdlrGetPrecedence(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:552
void SCIPexprhdlrIncrementNBranchings(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:794
SCIP_Longint SCIPexprhdlrGetNReversepropCalls(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:708
void SCIPexprhdlrSetIntEval(SCIP_EXPRHDLR *exprhdlr,)
Definition expr.c:486
void SCIPexprhdlrSetMonotonicity(SCIP_EXPRHDLR *exprhdlr,)
Definition expr.c:427
const char * SCIPexprhdlrGetDescription(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:542
SCIP_Bool SCIPexprhdlrHasFwdiff(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:592
SCIP_Bool SCIPexprhdlrHasMonotonicity(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:652
void SCIPexprhdlrSetReverseProp(SCIP_EXPRHDLR *exprhdlr,)
Definition expr.c:508
SCIP_Bool SCIPexprhdlrHasReverseProp(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:662
unsigned int SCIPexprhdlrGetNCreated(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:678
SCIP_Bool SCIPexprhdlrHasInitEstimates(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:622
SCIP_Longint SCIPexprhdlrGetNBranchings(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:784
SCIP_Bool SCIPexprhdlrHasPrint(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:572
SCIP_Longint SCIPexprhdlrGetNSimplifyCalls(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:804
SCIP_Real SCIPexprhdlrGetIntevalTime(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:698
void SCIPexprhdlrSetHash(SCIP_EXPRHDLR *exprhdlr,)
Definition expr.c:449
SCIP_Bool SCIPexprhdlrHasEstimate(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:612
SCIP_Real SCIPexprhdlrGetSimplifyTime(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:814
SCIP_Longint SCIPexprhdlrGetNIntevalCalls(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:688
SCIP_Longint SCIPexprhdlrGetNSimplifications(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:824
void SCIPexprhdlrSetSimplify(SCIP_EXPRHDLR *exprhdlr,)
Definition expr.c:497
SCIP_Longint SCIPexprhdlrGetNCutoffs(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:728
void SCIPexprhdlrSetDiff(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRBWDIFF((*bwdiff)), SCIP_DECL_EXPRFWDIFF((*fwdiff)),)
Definition expr.c:471
void SCIPexprhdlrSetCopyFreeHdlr(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRCOPYHDLR((*copyhdlr)),)
Definition expr.c:368
void SCIPexprhdlrSetPrint(SCIP_EXPRHDLR *exprhdlr,)
Definition expr.c:394
SCIP_Bool SCIPexprhdlrHasIntEval(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:602
SCIP_Bool SCIPexprhdlrHasBwdiff(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:582
SCIP_Longint SCIPexprhdlrGetNEstimateCalls(SCIP_EXPRHDLR *exprhdlr)
Definition expr.c:760
void SCIPexprhdlrSetCopyFreeData(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRCOPYDATA((*copydata)),)
Definition expr.c:381
void SCIPexprhdlrSetEstimate(SCIP_EXPRHDLR *exprhdlr, SCIP_DECL_EXPRINITESTIMATES((*initestimates)),)
Definition expr.c:519
void SCIPexprSetActivity(SCIP_EXPR *expr, SCIP_INTERVAL activity, SCIP_Longint activitytag)
Definition expr.c:3983
void SCIPexprSetData(SCIP_EXPR *expr, SCIP_EXPRDATA *exprdata)
Definition expr.c:3849
int SCIPexprGetNChildren(SCIP_EXPR *expr)
Definition expr.c:3801
void SCIPexprGetQuadraticBilinTerm(SCIP_EXPR *expr, int termidx, SCIP_EXPR **expr1, SCIP_EXPR **expr2, SCIP_Real *coef, int *pos2, SCIP_EXPR **prodexpr)
Definition expr.c:4145
SCIP_Real SCIPgetExponentExprPow(SCIP_EXPR *expr)
Definition expr_pow.c:3351
SCIP_Bool SCIPexpriterIsEnd(SCIP_EXPRITER *iterator)
Definition expriter.c:968
void SCIPexprSetCurvature(SCIP_EXPR *expr, SCIP_EXPRCURV curvature)
Definition expr.c:4009
SCIP_EXPR * SCIPexpriterSkipDFS(SCIP_EXPRITER *iterator)
Definition expriter.c:929
SCIP_EXPR_OWNERDATA * SCIPexprGetOwnerData(SCIP_EXPR *expr)
Definition expr.c:3862
SCIP_Real SCIPexprGetDerivative(SCIP_EXPR *expr)
Definition expr.c:3901
SCIP_Longint SCIPexprGetEvalTag(SCIP_EXPR *expr)
Definition expr.c:3888
SCIP_Bool SCIPexprIsIntegral(SCIP_EXPR *expr)
Definition expr.c:4020
SCIP_Bool SCIPexprAreQuadraticExprsVariables(SCIP_EXPR *expr)
Definition expr.c:4181
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:4060
SCIP_Real * SCIPgetCoefsExprSum(SCIP_EXPR *expr)
Definition expr_sum.c:1166
SCIP_EXPRITER_USERDATA SCIPexpriterGetCurrentUserData(SCIP_EXPRITER *iterator)
Definition expriter.c:755
SCIP_Real SCIPgetCoefExprProduct(SCIP_EXPR *expr)
SCIP_EXPR * SCIPexpriterGetCurrent(SCIP_EXPRITER *iterator)
Definition expriter.c:682
void SCIPexpriterSetStagesDFS(SCIP_EXPRITER *iterator, SCIP_EXPRITER_STAGE stopstages)
Definition expriter.c:663
SCIP_Real SCIPexprGetDot(SCIP_EXPR *expr)
Definition expr.c:3915
SCIP_EXPRDATA * SCIPexprGetData(SCIP_EXPR *expr)
Definition expr.c:3834
void SCIPexprSetIntegrality(SCIP_EXPR *expr, SCIP_Bool isintegral)
Definition expr.c:4030
SCIP_RETCODE SCIPprintExpr(SCIP *scip, SCIP_EXPR *expr, FILE *file)
Definition scip_expr.c:1476
SCIP_EXPRCURV SCIPexprGetCurvature(SCIP_EXPR *expr)
Definition expr.c:3999
SCIP_EXPR * SCIPexpriterGetParentDFS(SCIP_EXPRITER *iterator)
Definition expriter.c:739
SCIP_Real SCIPgetValueExprValue(SCIP_EXPR *expr)
Definition expr_value.c:294
void SCIPexpriterSetCurrentUserData(SCIP_EXPRITER *iterator, SCIP_EXPRITER_USERDATA userdata)
Definition expriter.c:805
SCIP_Real SCIPexprGetEvalValue(SCIP_EXPR *expr)
Definition expr.c:3875
SCIP_Longint SCIPexprGetActivityTag(SCIP_EXPR *expr)
Definition expr.c:3973
SCIP_EXPR * SCIPexpriterGetNext(SCIP_EXPRITER *iterator)
Definition expriter.c:857
SCIP_Real SCIPexprGetBardot(SCIP_EXPR *expr)
Definition expr.c:3929
SCIP_EXPR ** SCIPexprGetChildren(SCIP_EXPR *expr)
Definition expr.c:3811
SCIP_Real SCIPgetConstantExprSum(SCIP_EXPR *expr)
Definition expr_sum.c:1181
SCIP_VAR * SCIPgetVarExprVar(SCIP_EXPR *expr)
Definition expr_var.c:416
SCIP_INTERVAL SCIPexprGetActivity(SCIP_EXPR *expr)
Definition expr.c:3957
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:4105
int SCIPexpriterGetChildIdxDFS(SCIP_EXPRITER *iterator)
Definition expriter.c:706
SCIP_EXPRITER_USERDATA SCIPexpriterGetChildUserDataDFS(SCIP_EXPRITER *iterator)
Definition expriter.c:770
SCIP_EXPRITER_STAGE SCIPexpriterGetStageDFS(SCIP_EXPRITER *iterator)
Definition expriter.c:695
SCIP_RETCODE SCIPexpriterInit(SCIP_EXPRITER *iterator, SCIP_EXPR *expr, SCIP_EXPRITER_TYPE type, SCIP_Bool allowrevisit)
Definition expriter.c:500
int SCIPexprGetNUses(SCIP_EXPR *expr)
Definition expr.c:3791
SCIP_EXPRITER_USERDATA SCIPexpriterGetExprUserData(SCIP_EXPRITER *iterator, SCIP_EXPR *expr)
Definition expriter.c:789
SCIP_Longint SCIPexprGetDiffTag(SCIP_EXPR *expr)
Definition expr.c:3944
SCIP_EXPRHDLR * SCIPexprGetHdlr(SCIP_EXPR *expr)
Definition expr.c:3824
SCIP_EXPR * SCIPexpriterGetChildExprDFS(SCIP_EXPRITER *iterator)
Definition expriter.c:720
void SCIPintervalSetEntire(SCIP_Real infinity, SCIP_INTERVAL *resultant)
void SCIPintervalSetEmpty(SCIP_INTERVAL *resultant)
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition var.c:17966
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:17241
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition var.c:17956
return SCIP_OKAY
int c
int depth
static SCIP_SOL * sol
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
SCIP_VAR * var
#define NULL
Definition lpi_spx1.cpp:161
#define BMSduplicateBlockMemoryArray(mem, ptr, source, num)
Definition memory.h:464
#define BMSfreeBlockMemory(mem, ptr)
Definition memory.h:467
#define BMSallocBlockMemory(mem, ptr)
Definition memory.h:453
#define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
Definition memory.h:470
#define BMSduplicateMemoryArray(ptr, source, num)
Definition memory.h:145
#define BMSfreeBufferMemoryArray(mem, ptr)
Definition memory.h:744
#define BMSfreeMemoryArray(ptr)
Definition memory.h:149
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition memory.h:456
#define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
Definition memory.h:460
#define BMSallocClearBlockMemoryArray(mem, ptr, num)
Definition memory.h:457
#define BMSallocBufferMemoryArray(mem, ptr, num)
Definition memory.h:733
#define BMSallocClearBlockMemory(mem, ptr)
Definition memory.h:454
#define BMSallocClearBufferMemoryArray(mem, ptr, num)
Definition memory.h:734
struct BMS_BlkMem BMS_BLKMEM
Definition memory.h:439
#define BMSfreeMemoryArrayNull(ptr)
Definition memory.h:150
void SCIPmessageFPrintVerbInfo(SCIP_MESSAGEHDLR *messagehdlr, SCIP_VERBLEVEL verblevel, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition message.c:706
void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
Definition message.c:618
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition message.c:427
Ipopt NLP interface.
#define SCIPerrorMessage
Definition pub_message.h:64
#define SCIPdebugMessage
Definition pub_message.h:96
public data structures and miscellaneous methods
public methods for problem variables
SCIP_Real SCIPsetFloor(SCIP_SET *set, SCIP_Real val)
Definition set.c:6320
SCIP_EXPRHDLR * SCIPsetFindExprhdlr(SCIP_SET *set, const char *name)
Definition set.c:5058
SCIP_Real SCIPsetCeil(SCIP_SET *set, SCIP_Real val)
Definition set.c:6331
SCIP_Bool SCIPsetIsPositive(SCIP_SET *set, SCIP_Real val)
Definition set.c:6256
SCIP_Real SCIPsetFrac(SCIP_SET *set, SCIP_Real val)
Definition set.c:6353
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition set.c:6133
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition set.c:5712
SCIP_Bool SCIPsetIsNegative(SCIP_SET *set, SCIP_Real val)
Definition set.c:6267
internal methods for global SCIP settings
#define SCIPsetDebugMsgPrint
Definition set.h:1771
#define SCIPsetDebugMsg
Definition set.h:1770
internal methods for storing primal CIP solutions
SCIP_Real dot
SCIP_EXPRCURV curvature
SCIP_EXPRDATA * exprdata
SCIP_Real evalvalue
SCIP_INTERVAL activity
SCIP_Longint difftag
SCIP_EXPRHDLR * exprhdlr
SCIP_EXPR_OWNERDATA * ownerdata
SCIP_Bool quadchecked
SCIP_Longint evaltag
SCIP_Longint activitytag
int childrensize
SCIP_Real derivative
SCIP_EXPR ** children
SCIP_Real bardot
SCIP_QUADEXPR * quaddata
SCIP_Bool isintegral
SCIP_Longint nsimplifycalls
Definition struct_expr.h:79
SCIP_CLOCK * intevaltime
Definition struct_expr.h:84
SCIP_Longint npropcalls
Definition struct_expr.h:76
SCIP_Longint nestimatecalls
Definition struct_expr.h:74
SCIP_CLOCK * simplifytime
Definition struct_expr.h:86
unsigned int precedence
Definition struct_expr.h:48
SCIP_Longint ncutoffs
Definition struct_expr.h:77
unsigned int ncreated
Definition struct_expr.h:73
SCIP_Longint nsimplified
Definition struct_expr.h:80
SCIP_CLOCK * proptime
Definition struct_expr.h:85
SCIP_Longint ndomreds
Definition struct_expr.h:78
SCIP_CLOCK * estimatetime
Definition struct_expr.h:83
SCIP_Longint nintevalcalls
Definition struct_expr.h:75
SCIP_Longint nbranchscores
Definition struct_expr.h:81
SCIP_EXPRHDLRDATA * data
Definition struct_expr.h:47
SCIP_Bool curvaturechecked
SCIP_QUADEXPR_QUADTERM * quadexprterms
SCIP_Bool eigeninfostored
SCIP_Real * lincoefs
SCIP_EXPR ** linexprs
SCIP_Bool allexprsarevars
SCIP_Real constant
SCIP_EXPRCURV curvature
SCIP_QUADEXPR_BILINTERM * bilinexprterms
SCIP_Real * eigenvalues
SCIP_Real * eigenvectors
SCIP_Longint domchgcount
SCIP_Longint exprlastdifftag
structure definitions related to algebraic expressions
datastructures for global SCIP settings
datastructures for problem statistics
internal methods for branch and bound tree
@ SCIP_CLOCKTYPE_DEFAULT
Definition type_clock.h:43
#define SCIP_DECL_EXPR_OWNERCREATE(x)
Definition type_expr.h:140
#define SCIP_DECL_EXPRREVERSEPROP(x)
Definition type_expr.h:654
#define SCIP_DECL_EXPRINITESTIMATES(x)
Definition type_expr.h:605
#define SCIP_DECL_EXPRBWFWDIFF(x)
Definition type_expr.h:517
#define SCIP_DECL_EXPRCURVATURE(x)
Definition type_expr.h:337
struct SCIP_ExprhdlrData SCIP_EXPRHDLRDATA
Definition type_expr.h:192
struct SCIP_ExprData SCIP_EXPRDATA
Definition type_expr.h:53
#define SCIP_EXPRPRINT_EXPRSTRING
Definition type_expr.h:712
#define SCIP_DECL_EXPRFREEDATA(x)
Definition type_expr.h:265
SCIP_EXPRCURV
Definition type_expr.h:58
@ SCIP_EXPRCURV_CONVEX
Definition type_expr.h:60
@ SCIP_EXPRCURV_UNKNOWN
Definition type_expr.h:59
@ SCIP_EXPRCURV_CONCAVE
Definition type_expr.h:61
#define SCIP_EXPR_MAXINITESTIMATES
Definition type_expr.h:195
#define SCIP_DECL_EXPRPARSE(x)
Definition type_expr.h:309
#define SCIP_DECL_EXPRBWDIFF(x)
Definition type_expr.h:446
#define SCIP_DECL_EXPRINTEVAL(x)
Definition type_expr.h:536
#define SCIP_EXPRPRINT_OWNER
Definition type_expr.h:719
#define SCIP_EXPRPRINT_ACTIVITYTAG
Definition type_expr.h:718
#define SCIP_DECL_EXPRMONOTONICITY(x)
Definition type_expr.h:355
#define SCIP_EXPRITER_VISITINGCHILD
Definition type_expr.h:677
struct SCIP_Expr_OwnerData SCIP_EXPR_OWNERDATA
Definition type_expr.h:77
SCIP_MONOTONE
Definition type_expr.h:67
@ SCIP_MONOTONE_UNKNOWN
Definition type_expr.h:68
unsigned int SCIP_EXPRPRINT_WHAT
Definition type_expr.h:724
#define SCIP_DECL_EXPR_INTEVALVAR(x)
Definition type_expr.h:160
#define SCIP_DECL_EXPRCOMPARE(x)
Definition type_expr.h:407
#define SCIP_DECL_EXPRSIMPLIFY(x)
Definition type_expr.h:629
#define SCIP_DECL_EXPREVAL(x)
Definition type_expr.h:423
#define SCIP_DECL_EXPRFWDIFF(x)
Definition type_expr.h:477
@ SCIP_EXPRITER_DFS
Definition type_expr.h:700
#define SCIP_EXPRPRINT_ACTIVITY
Definition type_expr.h:717
#define SCIP_DECL_EXPRHASH(x)
Definition type_expr.h:388
#define SCIP_DECL_EXPRCOPYHDLR(x)
Definition type_expr.h:207
#define SCIP_DECL_EXPRPRINT(x)
Definition type_expr.h:286
#define SCIP_EXPRPRINT_EVALVALUE
Definition type_expr.h:715
#define SCIP_DECL_EXPRFREEHDLR(x)
Definition type_expr.h:221
#define SCIP_DECL_EXPR_MAPEXPR(x)
Definition type_expr.h:179
#define SCIP_EXPRPRINT_EXPRHDLR
Definition type_expr.h:713
#define SCIP_EXPRPRINT_EVALTAG
Definition type_expr.h:716
#define SCIP_DECL_EXPRINTEGRALITY(x)
Definition type_expr.h:372
#define SCIP_EXPRPRINT_NUSES
Definition type_expr.h:714
#define SCIP_EXPRITER_VISITEDCHILD
Definition type_expr.h:678
struct SCIP_ExprPrintData SCIP_EXPRPRINTDATA
Definition type_expr.h:725
#define SCIP_DECL_EXPRCOPYDATA(x)
Definition type_expr.h:246
#define SCIP_EXPRITER_LEAVEEXPR
Definition type_expr.h:679
#define SCIP_EXPRITER_ALLSTAGES
Definition type_expr.h:680
#define SCIP_DECL_EXPRESTIMATE(x)
Definition type_expr.h:572
#define SCIP_EXPRITER_ENTEREXPR
Definition type_expr.h:676
unsigned int SCIP_EXPRITER_STAGE
Definition type_expr.h:683
@ SCIP_VERBLEVEL_FULL
#define SCIP_DECL_SORTPTRCOMP(x)
Definition type_misc.h:188
@ SCIP_FILECREATEERROR
enum SCIP_Retcode SCIP_RETCODE