1 #include <isl_set_polylib.h>
2 #include <barvinok/options.h>
3 #include <barvinok/util.h>
7 #include "laurent_old.h"
9 #include "section_array.h"
10 #include "remove_equalities.h"
12 extern evalue
*evalue_outer_floor(evalue
*e
);
13 extern int evalue_replace_floor(evalue
*e
, const evalue
*floor
, int var
);
14 extern void evalue_drop_floor(evalue
*e
, const evalue
*floor
);
16 #define ALLOC(type) (type*)malloc(sizeof(type))
17 #define ALLOCN(type,n) (type*)malloc((n) * sizeof(type))
19 /* Apply the variable transformation specified by T and CP on
20 * the polynomial e. T expresses the old variables in terms
21 * of the new variables (and optionally also the new parameters),
22 * while CP expresses the old parameters in terms of the new
25 static void transform_polynomial(evalue
*E
, Matrix
*T
, Matrix
*CP
,
26 unsigned nvar
, unsigned nparam
,
27 unsigned new_nvar
, unsigned new_nparam
)
32 subs
= ALLOCN(evalue
*, nvar
+nparam
);
34 for (j
= 0; j
< nvar
; ++j
) {
36 subs
[j
] = affine2evalue(T
->p
[j
], T
->p
[T
->NbRows
-1][T
->NbColumns
-1],
39 subs
[j
] = evalue_var(j
);
41 for (j
= 0; j
< nparam
; ++j
) {
43 subs
[nvar
+j
] = affine2evalue(CP
->p
[j
], CP
->p
[nparam
][new_nparam
],
46 subs
[nvar
+j
] = evalue_var(j
);
47 evalue_shift_variables(subs
[nvar
+j
], 0, new_nvar
);
50 evalue_substitute(E
, subs
);
53 for (j
= 0; j
< nvar
+nparam
; ++j
)
58 static evalue
*sum_over_polytope_with_equalities(Polyhedron
*P
, evalue
*E
,
60 struct evalue_section_array
*sections
,
61 struct barvinok_options
*options
)
63 unsigned dim
= P
->Dimension
;
64 unsigned new_dim
, new_nparam
;
65 Matrix
*T
= NULL
, *CP
= NULL
;
73 remove_all_equalities(&P
, NULL
, &CP
, &T
, dim
-nvar
, options
->MaxRays
);
80 new_nparam
= CP
? CP
->NbColumns
-1 : dim
- nvar
;
81 new_dim
= T
? T
->NbColumns
-1 : nvar
+ new_nparam
;
83 /* We can avoid these substitutions if E is a constant */
85 transform_polynomial(E
, T
, CP
, nvar
, dim
-nvar
,
86 new_dim
-new_nparam
, new_nparam
);
88 if (new_dim
-new_nparam
> 0) {
89 sum
= barvinok_sum_over_polytope(P
, E
, new_dim
-new_nparam
,
96 sum
->x
.p
= new_enode(partition
, 2, new_dim
);
97 EVALUE_SET_DOMAIN(sum
->x
.p
->arr
[0], P
);
98 value_clear(sum
->x
.p
->arr
[1].d
);
99 sum
->x
.p
->arr
[1] = *E
;
104 evalue_backsubstitute(sum
, CP
, options
->MaxRays
);
114 static evalue
*sum_base(Polyhedron
*P
, evalue
*E
, unsigned nvar
,
115 struct barvinok_options
*options
)
117 if (options
->summation
== BV_SUM_EULER
)
118 return euler_summate(P
, E
, nvar
, options
);
119 else if (options
->summation
== BV_SUM_LAURENT
)
120 return laurent_summate(P
, E
, nvar
, options
);
121 else if (options
->summation
== BV_SUM_LAURENT_OLD
)
122 return laurent_summate_old(P
, E
, nvar
, options
);
126 /* Count the number of non-zero terms in e when viewed as a polynomial
127 * in only the first nvar variables. "count" is the number counted
130 static int evalue_count_terms(const evalue
*e
, unsigned nvar
, int count
)
134 if (EVALUE_IS_ZERO(*e
))
137 if (value_zero_p(e
->d
))
138 assert(e
->x
.p
->type
== polynomial
);
139 if (value_notzero_p(e
->d
) || e
->x
.p
->pos
>= nvar
+1)
142 for (i
= 0; i
< e
->x
.p
->size
; ++i
)
143 count
= evalue_count_terms(&e
->x
.p
->arr
[i
], nvar
, count
);
148 /* Create placeholder structure for unzipping.
149 * A "polynomial" is created with size terms in variable pos,
150 * with each term having itself as coefficient.
152 static evalue
*create_placeholder(int size
, int pos
)
155 evalue
*E
= ALLOC(evalue
);
157 E
->x
.p
= new_enode(polynomial
, size
, pos
+1);
158 for (i
= 0; i
< size
; ++i
) {
159 E
->x
.p
->arr
[i
].x
.p
= new_enode(polynomial
, i
+1, pos
+1);
160 for (j
= 0; j
< i
; ++j
)
161 evalue_set_si(&E
->x
.p
->arr
[i
].x
.p
->arr
[j
], 0, 1);
162 evalue_set_si(&E
->x
.p
->arr
[i
].x
.p
->arr
[i
], 1, 1);
167 /* Interchange each non-zero term in e (when viewed as a polynomial
168 * in only the first nvar variables) with a placeholder in ph (created
169 * by create_placeholder), resulting in two polynomials in the
170 * placeholder variable such that for each non-zero term in e
171 * there is a power of the placeholder variable such that the factors
172 * in the first nvar variables form the coefficient of that power in
173 * the first polynomial (e) and the factors in the remaining variables
174 * form the coefficient of that power in the second polynomial (ph).
176 static int evalue_unzip_terms(evalue
*e
, evalue
*ph
, unsigned nvar
, int count
)
180 if (EVALUE_IS_ZERO(*e
))
183 if (value_zero_p(e
->d
))
184 assert(e
->x
.p
->type
== polynomial
);
185 if (value_notzero_p(e
->d
) || e
->x
.p
->pos
>= nvar
+1) {
187 *e
= ph
->x
.p
->arr
[count
];
188 ph
->x
.p
->arr
[count
] = t
;
192 for (i
= 0; i
< e
->x
.p
->size
; ++i
)
193 count
= evalue_unzip_terms(&e
->x
.p
->arr
[i
], ph
, nvar
, count
);
198 /* Remove n variables at pos (0-based) from the polyhedron P.
199 * Each of these variables is assumed to be completely free,
200 * i.e., there is a line in the polyhedron corresponding to
201 * each of these variables.
203 static Polyhedron
*Polyhedron_Remove_Columns(Polyhedron
*P
, unsigned pos
,
207 unsigned NbConstraints
= 0;
214 assert(pos
<= P
->Dimension
);
216 if (POL_HAS(P
, POL_INEQUALITIES
))
217 NbConstraints
= P
->NbConstraints
;
218 if (POL_HAS(P
, POL_POINTS
))
219 NbRays
= P
->NbRays
- n
;
221 Q
= Polyhedron_Alloc(P
->Dimension
- n
, NbConstraints
, NbRays
);
222 if (POL_HAS(P
, POL_INEQUALITIES
)) {
224 for (i
= 0; i
< P
->NbConstraints
; ++i
) {
225 Vector_Copy(P
->Constraint
[i
], Q
->Constraint
[i
], 1+pos
);
226 Vector_Copy(P
->Constraint
[i
]+1+pos
+n
, Q
->Constraint
[i
]+1+pos
,
230 if (POL_HAS(P
, POL_POINTS
)) {
231 Q
->NbBid
= P
->NbBid
- n
;
232 for (i
= 0; i
< n
; ++i
)
233 value_set_si(Q
->Ray
[i
][1+pos
+i
], 1);
234 for (i
= 0, j
= 0; i
< P
->NbRays
; ++i
) {
235 int line
= First_Non_Zero(P
->Ray
[i
], 1+P
->Dimension
+1);
237 if (line
-1 >= pos
&& line
-1 < pos
+n
) {
242 assert(i
-j
< Q
->NbRays
);
243 Vector_Copy(P
->Ray
[i
], Q
->Ray
[i
-j
], 1+pos
);
244 Vector_Copy(P
->Ray
[i
]+1+pos
+n
, Q
->Ray
[i
-j
]+1+pos
,
248 POL_SET(Q
, POL_VALID
);
249 if (POL_HAS(P
, POL_INEQUALITIES
))
250 POL_SET(Q
, POL_INEQUALITIES
);
251 if (POL_HAS(P
, POL_POINTS
))
252 POL_SET(Q
, POL_POINTS
);
253 if (POL_HAS(P
, POL_VERTICES
))
254 POL_SET(Q
, POL_VERTICES
);
258 /* Remove n variables at pos (0-based) from the union of polyhedra P.
259 * Each of these variables is assumed to be completely free,
260 * i.e., there is a line in the polyhedron corresponding to
261 * each of these variables.
263 static Polyhedron
*Domain_Remove_Columns(Polyhedron
*P
, unsigned pos
,
267 Polyhedron
**next
= &R
;
269 for (; P
; P
= P
->next
) {
270 *next
= Polyhedron_Remove_Columns(P
, pos
, n
);
271 next
= &(*next
)->next
;
276 /* Drop n parameters starting at first from partition evalue e */
277 static void drop_parameters(evalue
*e
, int first
, int n
)
281 if (EVALUE_IS_ZERO(*e
))
284 assert(value_zero_p(e
->d
) && e
->x
.p
->type
== partition
);
285 for (i
= 0; i
< e
->x
.p
->size
/2; ++i
) {
286 Polyhedron
*P
= EVALUE_DOMAIN(e
->x
.p
->arr
[2*i
]);
287 Polyhedron
*Q
= Domain_Remove_Columns(P
, first
, n
);
288 EVALUE_SET_DOMAIN(e
->x
.p
->arr
[2*i
], Q
);
290 evalue_shift_variables(&e
->x
.p
->arr
[2*i
+1], first
, -n
);
295 static void extract_term_into(const evalue
*src
, int var
, int exp
, evalue
*dst
)
299 if (value_notzero_p(src
->d
) ||
300 src
->x
.p
->type
!= polynomial
||
301 src
->x
.p
->pos
> var
+1) {
303 evalue_copy(dst
, src
);
305 evalue_set_si(dst
, 0, 1);
309 if (src
->x
.p
->pos
== var
+1) {
310 if (src
->x
.p
->size
> exp
)
311 evalue_copy(dst
, &src
->x
.p
->arr
[exp
]);
313 evalue_set_si(dst
, 0, 1);
317 dst
->x
.p
= new_enode(polynomial
, src
->x
.p
->size
, src
->x
.p
->pos
);
318 for (i
= 0; i
< src
->x
.p
->size
; ++i
)
319 extract_term_into(&src
->x
.p
->arr
[i
], var
, exp
,
323 /* Extract the coefficient of var^exp.
325 static evalue
*extract_term(const evalue
*e
, int var
, int exp
)
330 if (EVALUE_IS_ZERO(*e
))
331 return evalue_zero();
333 assert(value_zero_p(e
->d
) && e
->x
.p
->type
== partition
);
336 res
->x
.p
= new_enode(partition
, e
->x
.p
->size
, e
->x
.p
->pos
);
337 for (i
= 0; i
< e
->x
.p
->size
/2; ++i
) {
338 EVALUE_SET_DOMAIN(res
->x
.p
->arr
[2*i
],
339 Domain_Copy(EVALUE_DOMAIN(e
->x
.p
->arr
[2*i
])));
340 extract_term_into(&e
->x
.p
->arr
[2*i
+1], var
, exp
,
341 &res
->x
.p
->arr
[2*i
+1]);
342 reduce_evalue(&res
->x
.p
->arr
[2*i
+1]);
347 /* Insert n free variables at pos (0-based) in the polyhedron P.
349 static Polyhedron
*Polyhedron_Insert_Columns(Polyhedron
*P
, unsigned pos
,
353 unsigned NbConstraints
= 0;
362 assert(pos
<= P
->Dimension
);
364 if (POL_HAS(P
, POL_INEQUALITIES
))
365 NbConstraints
= P
->NbConstraints
;
366 if (POL_HAS(P
, POL_POINTS
))
367 NbRays
= P
->NbRays
+ n
;
369 Q
= Polyhedron_Alloc(P
->Dimension
+n
, NbConstraints
, NbRays
);
370 if (POL_HAS(P
, POL_INEQUALITIES
)) {
372 for (i
= 0; i
< P
->NbConstraints
; ++i
) {
373 Vector_Copy(P
->Constraint
[i
], Q
->Constraint
[i
], 1+pos
);
374 Vector_Copy(P
->Constraint
[i
]+1+pos
, Q
->Constraint
[i
]+1+pos
+n
,
378 if (POL_HAS(P
, POL_POINTS
)) {
379 Q
->NbBid
= P
->NbBid
+ n
;
380 for (i
= 0; i
< n
; ++i
)
381 value_set_si(Q
->Ray
[i
][1+pos
+i
], 1);
382 for (i
= 0; i
< P
->NbRays
; ++i
) {
383 Vector_Copy(P
->Ray
[i
], Q
->Ray
[n
+i
], 1+pos
);
384 Vector_Copy(P
->Ray
[i
]+1+pos
, Q
->Ray
[n
+i
]+1+pos
+n
,
388 POL_SET(Q
, POL_VALID
);
389 if (POL_HAS(P
, POL_INEQUALITIES
))
390 POL_SET(Q
, POL_INEQUALITIES
);
391 if (POL_HAS(P
, POL_POINTS
))
392 POL_SET(Q
, POL_POINTS
);
393 if (POL_HAS(P
, POL_VERTICES
))
394 POL_SET(Q
, POL_VERTICES
);
398 /* Perform summation of e over a list of 1 or more factors F, with context C.
399 * nvar is the total number of variables in the remaining factors.
400 * extra is the number of placeholder parameters introduced in e,
401 * but not (yet) in F or C.
403 * If there is only one factor left, F is intersected with the
404 * context C, the placeholder variables are added, and then
405 * e is summed over the resulting parametric polytope.
407 * If there is more than one factor left, we create two polynomials
408 * in a new placeholder variable (which is placed after the regular
409 * parameters, but before any previously introduced placeholder
410 * variables) that has the factors of the variables in the first
411 * factor of F and the factor of the remaining variables of
412 * each term as its coefficients.
413 * These two polynomials are then summed over their domains
414 * and afterwards the results are combined and the placeholder
415 * variable is removed again.
417 static evalue
*sum_factors(Polyhedron
*F
, Polyhedron
*C
, evalue
*e
,
418 unsigned nvar
, unsigned extra
,
419 struct barvinok_options
*options
)
422 unsigned nparam
= C
->Dimension
;
423 unsigned F_var
= F
->Dimension
- C
->Dimension
;
429 Polyhedron
*CA
= align_context(C
, nvar
+nparam
, options
->MaxRays
);
430 Polyhedron
*P
= DomainIntersection(F
, CA
, options
->MaxRays
);
431 Polyhedron
*Q
= Polyhedron_Insert_Columns(P
, nvar
+nparam
, extra
);
435 evalue
*sum
= sum_base(Q
, e
, nvar
, options
);
440 n
= evalue_count_terms(e
, F_var
, 0);
441 ph
= create_placeholder(n
, nvar
+nparam
);
442 evalue_shift_variables(e
, nvar
+nparam
, 1);
443 evalue_unzip_terms(e
, ph
, F_var
, 0);
444 evalue_shift_variables(e
, nvar
, -(nvar
-F_var
));
445 evalue_reorder_terms(ph
);
446 evalue_shift_variables(ph
, 0, -F_var
);
448 s2
= sum_factors(F
->next
, C
, ph
, nvar
-F_var
, extra
+1, options
);
451 s1
= sum_factors(F
, C
, e
, F_var
, extra
+1, options
);
454 /* remove placeholder "polynomial" */
458 drop_parameters(s2
, nparam
, 1);
463 for (i
= 0; i
< n
; ++i
) {
465 t1
= extract_term(s1
, nparam
, i
);
466 t2
= extract_term(s2
, nparam
, i
);
475 drop_parameters(s
, nparam
, 1);
479 /* Perform summation over a product of factors F, obtained using
480 * variable transformation T from the original problem specification.
482 * We first perform the corresponding transformation on the polynomial E,
483 * compute the common context over all factors and then perform
484 * the actual summation over the factors.
486 static evalue
*sum_product(Polyhedron
*F
, evalue
*E
, Matrix
*T
, unsigned nparam
,
487 struct barvinok_options
*options
)
491 unsigned nvar
= T
->NbRows
;
495 assert(nvar
== T
->NbColumns
);
496 T2
= Matrix_Alloc(nvar
+1, nvar
+1);
497 for (i
= 0; i
< nvar
; ++i
)
498 Vector_Copy(T
->p
[i
], T2
->p
[i
], nvar
);
499 value_set_si(T2
->p
[nvar
][nvar
], 1);
501 transform_polynomial(E
, T2
, NULL
, nvar
, nparam
, nvar
, nparam
);
503 C
= Factor_Context(F
, nparam
, options
->MaxRays
);
504 if (F
->Dimension
== nparam
) {
510 sum
= sum_factors(F
, C
, E
, nvar
, 0, options
);
518 /* Add two constraints corresponding to floor = floor(e/d),
521 * -e + d t + d-1 >= 0
523 * e is assumed to be an affine expression.
525 Polyhedron
*add_floor_var(Polyhedron
*P
, unsigned nvar
, const evalue
*floor
,
526 struct barvinok_options
*options
)
529 unsigned dim
= P
->Dimension
+1;
530 Matrix
*M
= Matrix_Alloc(P
->NbConstraints
+2, 2+dim
);
532 Value
*d
= &M
->p
[0][1+nvar
];
533 evalue_extract_affine(floor
, M
->p
[0]+1, M
->p
[0]+1+dim
, d
);
534 value_oppose(*d
, *d
);
535 value_set_si(M
->p
[0][0], 1);
536 value_set_si(M
->p
[1][0], 1);
537 Vector_Oppose(M
->p
[0]+1, M
->p
[1]+1, M
->NbColumns
-1);
538 value_subtract(M
->p
[1][1+dim
], M
->p
[1][1+dim
], *d
);
539 value_decrement(M
->p
[1][1+dim
], M
->p
[1][1+dim
]);
541 for (i
= 0; i
< P
->NbConstraints
; ++i
) {
542 Vector_Copy(P
->Constraint
[i
], M
->p
[i
+2], 1+nvar
);
543 Vector_Copy(P
->Constraint
[i
]+1+nvar
, M
->p
[i
+2]+1+nvar
+1, dim
-nvar
-1+1);
546 CP
= Constraints2Polyhedron(M
, options
->MaxRays
);
551 static evalue
*evalue_add(evalue
*a
, evalue
*b
)
562 /* Compute sum of a step-polynomial over a polytope by grouping
563 * terms containing the same floor-expressions and introducing
564 * new variables for each such expression.
565 * In particular, while there is any floor-expression left,
566 * the step-polynomial is split into a polynomial containing
567 * the expression, which is then converted to a new variable,
568 * and a polynomial not containing the expression.
570 static evalue
*sum_step_polynomial(Polyhedron
*P
, evalue
*E
, unsigned nvar
,
571 struct barvinok_options
*options
)
578 while ((floor
= evalue_outer_floor(cur
))) {
581 evalue
*converted_floor
;
583 /* Ignore floors that do not depend on variables. */
584 if (value_notzero_p(floor
->d
) || floor
->x
.p
->pos
>= nvar
+1)
587 converted
= evalue_dup(cur
);
588 converted_floor
= evalue_dup(floor
);
589 evalue_shift_variables(converted
, nvar
, 1);
590 evalue_shift_variables(converted_floor
, nvar
, 1);
591 evalue_replace_floor(converted
, converted_floor
, nvar
);
592 CP
= add_floor_var(P
, nvar
, converted_floor
, options
);
593 evalue_free(converted_floor
);
594 t
= sum_step_polynomial(CP
, converted
, nvar
+1, options
);
595 evalue_free(converted
);
597 sum
= evalue_add(t
, sum
);
600 cur
= evalue_dup(cur
);
601 evalue_drop_floor(cur
, floor
);
605 evalue_floor2frac(cur
);
609 if (EVALUE_IS_ZERO(*cur
))
613 unsigned nparam
= P
->Dimension
- nvar
;
614 Polyhedron
*F
= Polyhedron_Factor(P
, nparam
, &T
, options
->MaxRays
);
616 t
= sum_base(P
, cur
, nvar
, options
);
619 cur
= evalue_dup(cur
);
620 t
= sum_product(F
, cur
, T
, nparam
, options
);
627 return evalue_add(t
, sum
);
630 evalue
*barvinok_sum_over_polytope(Polyhedron
*P
, evalue
*E
, unsigned nvar
,
631 struct evalue_section_array
*sections
,
632 struct barvinok_options
*options
)
635 return sum_over_polytope_with_equalities(P
, E
, nvar
, sections
, options
);
637 if (options
->summation
== BV_SUM_BERNOULLI
)
638 return bernoulli_summate(P
, E
, nvar
, sections
, options
);
639 else if (options
->summation
== BV_SUM_BOX
)
640 return box_summate(P
, E
, nvar
, options
->MaxRays
);
642 evalue_frac2floor2(E
, 0);
644 return sum_step_polynomial(P
, E
, nvar
, options
);
647 evalue
*barvinok_summate(evalue
*e
, int nvar
, struct barvinok_options
*options
)
650 struct evalue_section_array sections
;
654 if (nvar
== 0 || EVALUE_IS_ZERO(*e
))
655 return evalue_dup(e
);
657 assert(value_zero_p(e
->d
));
658 assert(e
->x
.p
->type
== partition
);
660 evalue_section_array_init(§ions
);
663 for (i
= 0; i
< e
->x
.p
->size
/2; ++i
) {
665 for (D
= EVALUE_DOMAIN(e
->x
.p
->arr
[2*i
]); D
; D
= D
->next
) {
666 Polyhedron
*next
= D
->next
;
670 tmp
= barvinok_sum_over_polytope(D
, &e
->x
.p
->arr
[2*i
+1], nvar
,
686 static int add_guarded_qp(__isl_take isl_set
*set
, __isl_take isl_qpolynomial
*qp
,
690 isl_pw_qpolynomial
**sum
= (isl_pw_qpolynomial
**) user
;
691 struct barvinok_options
*options
;
692 struct evalue_section_array sections
;
697 options
= barvinok_options_new_with_defaults();
702 e
= isl_qpolynomial_to_evalue(qp
);
706 dim
= isl_set_get_dim(set
);
707 nvar
= isl_dim_size(dim
, isl_dim_set
);
708 dim
= isl_dim_drop(dim
, isl_dim_set
, 0, nvar
);
710 evalue_section_array_init(§ions
);
712 set
= isl_set_make_disjoint(set
);
713 D
= isl_set_to_polylib(set
);
715 for (P
= D
; P
; P
= P
->next
) {
716 Polyhedron
*next
= P
->next
;
718 isl_pw_qpolynomial
*pwqp
;
722 tmp
= barvinok_sum_over_polytope(P
, e
, nvar
, §ions
, options
);
724 pwqp
= isl_pw_qpolynomial_from_evalue(isl_dim_copy(dim
), tmp
);
726 *sum
= isl_pw_qpolynomial_add(*sum
, pwqp
);
740 isl_qpolynomial_free(qp
);
742 barvinok_options_free(options
);
747 isl_qpolynomial_free(qp
);
748 barvinok_options_free(options
);
752 __isl_give isl_pw_qpolynomial
*isl_pw_qpolynomial_sum(
753 __isl_take isl_pw_qpolynomial
*pwqp
)
757 isl_pw_qpolynomial
*sum
;
762 nvar
= isl_pw_qpolynomial_dim(pwqp
, isl_dim_set
);
764 return isl_pw_qpolynomial_drop_dims(pwqp
, isl_dim_set
, 0, 0);
766 dim
= isl_pw_qpolynomial_get_dim(pwqp
);
767 dim
= isl_dim_drop(dim
, isl_dim_set
, 0, nvar
);
769 sum
= isl_pw_qpolynomial_zero(dim
);
771 if (isl_pw_qpolynomial_foreach_lifted_piece(pwqp
, add_guarded_qp
, &sum
) < 0)
774 isl_pw_qpolynomial_free(pwqp
);
778 isl_pw_qpolynomial_free(pwqp
);
779 isl_pw_qpolynomial_free(sum
);
783 static int pw_qpolynomial_sum(__isl_take isl_pw_qpolynomial
*pwqp
, void *user
)
785 isl_union_pw_qpolynomial
**res
= (isl_union_pw_qpolynomial
**)user
;
786 isl_pw_qpolynomial
*sum
;
788 sum
= isl_pw_qpolynomial_sum(pwqp
);
789 *res
= isl_union_pw_qpolynomial_add_pw_qpolynomial(*res
, sum
);
794 __isl_give isl_union_pw_qpolynomial
*isl_union_pw_qpolynomial_sum(
795 __isl_take isl_union_pw_qpolynomial
*upwqp
)
798 isl_union_pw_qpolynomial
*res
;
800 dim
= isl_union_pw_qpolynomial_get_dim(upwqp
);
801 res
= isl_union_pw_qpolynomial_zero(dim
);
802 if (isl_union_pw_qpolynomial_foreach_pw_qpolynomial(upwqp
,
803 &pw_qpolynomial_sum
, &res
) < 0)
805 isl_union_pw_qpolynomial_free(upwqp
);
809 isl_union_pw_qpolynomial_free(upwqp
);
810 isl_union_pw_qpolynomial_free(res
);
814 evalue
*evalue_sum(evalue
*E
, int nvar
, unsigned MaxRays
)
817 struct barvinok_options
*options
= barvinok_options_new_with_defaults();
818 options
->MaxRays
= MaxRays
;
819 sum
= barvinok_summate(E
, nvar
, options
);
820 barvinok_options_free(options
);
824 evalue
*esum(evalue
*e
, int nvar
)
827 struct barvinok_options
*options
= barvinok_options_new_with_defaults();
828 sum
= barvinok_summate(e
, nvar
, options
);
829 barvinok_options_free(options
);
833 /* Turn unweighted counting problem into "weighted" counting problem
834 * with weight equal to 1 and call barvinok_summate on this weighted problem.
836 evalue
*barvinok_summate_unweighted(Polyhedron
*P
, Polyhedron
*C
,
837 struct barvinok_options
*options
)
843 if (emptyQ(P
) || emptyQ(C
))
844 return evalue_zero();
846 CA
= align_context(C
, P
->Dimension
, options
->MaxRays
);
847 D
= DomainIntersection(P
, CA
, options
->MaxRays
);
852 return evalue_zero();
856 e
.x
.p
= new_enode(partition
, 2, P
->Dimension
);
857 EVALUE_SET_DOMAIN(e
.x
.p
->arr
[0], D
);
858 evalue_set_si(&e
.x
.p
->arr
[1], 1, 1);
859 sum
= barvinok_summate(&e
, P
->Dimension
- C
->Dimension
, options
);
860 free_evalue_refs(&e
);