1 #include <bernstein/bernstein.h>
2 #include <bernstein/piecewise_lst.h>
3 #include <barvinok/barvinok.h>
4 #include <barvinok/util.h>
5 #include <barvinok/bernstein.h>
7 #ifdef HAVE_GROWING_CHERNIKOVA
8 #define MAXRAYS POL_NO_DUAL
13 using namespace GiNaC
;
14 using namespace bernstein
;
18 ex
evalue2ex(evalue
*e
, const exvector
& vars
)
20 if (value_notzero_p(e
->d
))
21 return value2numeric(e
->x
.n
)/value2numeric(e
->d
);
22 if (e
->x
.p
->type
!= polynomial
)
25 for (int i
= e
->x
.p
->size
-1; i
>= 0; --i
) {
26 poly
*= vars
[e
->x
.p
->pos
-1];
27 ex t
= evalue2ex(&e
->x
.p
->arr
[i
], vars
);
28 if (is_exactly_a
<fail
>(t
))
35 /* if the evalue is a relation, we use the relation to cut off the
36 * the edges of the domain
38 static void evalue_extract_poly(evalue
*e
, int i
, Polyhedron
**D
, evalue
**poly
)
40 *D
= EVALUE_DOMAIN(e
->x
.p
->arr
[2*i
]);
41 *poly
= e
= &e
->x
.p
->arr
[2*i
+1];
42 if (value_notzero_p(e
->d
))
44 if (e
->x
.p
->type
!= relation
)
48 evalue
*fr
= &e
->x
.p
->arr
[0];
49 assert(value_zero_p(fr
->d
));
50 assert(fr
->x
.p
->type
== fractional
);
51 assert(fr
->x
.p
->size
== 3);
52 Matrix
*T
= Matrix_Alloc(2, (*D
)->Dimension
+1);
53 value_set_si(T
->p
[1][(*D
)->Dimension
], 1);
55 /* convert argument of fractional to polylib */
56 /* the argument is assumed to be linear */
57 evalue
*p
= &fr
->x
.p
->arr
[0];
58 evalue_denom(p
, &T
->p
[1][(*D
)->Dimension
]);
59 for (;value_zero_p(p
->d
); p
= &p
->x
.p
->arr
[0]) {
60 assert(p
->x
.p
->type
== polynomial
);
61 assert(p
->x
.p
->size
== 2);
62 assert(value_notzero_p(p
->x
.p
->arr
[1].d
));
63 int pos
= p
->x
.p
->pos
- 1;
64 value_assign(T
->p
[0][pos
], p
->x
.p
->arr
[1].x
.n
);
65 value_multiply(T
->p
[0][pos
], T
->p
[0][pos
], T
->p
[1][(*D
)->Dimension
]);
66 value_division(T
->p
[0][pos
], T
->p
[0][pos
], p
->x
.p
->arr
[1].d
);
68 int pos
= (*D
)->Dimension
;
69 value_assign(T
->p
[0][pos
], p
->x
.n
);
70 value_multiply(T
->p
[0][pos
], T
->p
[0][pos
], T
->p
[1][(*D
)->Dimension
]);
71 value_division(T
->p
[0][pos
], T
->p
[0][pos
], p
->d
);
74 for (Polyhedron
*P
= *D
; P
; P
= P
->next
) {
75 Polyhedron
*I
= Polyhedron_Image(P
, T
, MAXRAYS
);
76 I
= DomainConstraintSimplify(I
, MAXRAYS
);
77 Polyhedron
*R
= Polyhedron_Preimage(I
, T
, MAXRAYS
);
79 Polyhedron
*next
= P
->next
;
81 Polyhedron
*S
= DomainIntersection(P
, R
, MAXRAYS
);
87 E
= DomainConcat(S
, E
);
92 *poly
= &e
->x
.p
->arr
[1];
95 piecewise_lst
*evalue_bernstein_coefficients(piecewise_lst
*pl_all
, evalue
*e
,
96 Polyhedron
*ctx
, const exvector
& params
)
98 unsigned nparam
= ctx
->Dimension
;
99 if (EVALUE_IS_ZERO(*e
))
101 assert(value_zero_p(e
->d
));
102 assert(e
->x
.p
->type
== partition
);
103 assert(e
->x
.p
->size
>= 2);
104 unsigned nvars
= EVALUE_DOMAIN(e
->x
.p
->arr
[0])->Dimension
- nparam
;
106 exvector vars
= constructVariableVector(nvars
, "v");
107 exvector allvars
= vars
;
108 allvars
.insert(allvars
.end(), params
.begin(), params
.end());
110 for (int i
= 0; i
< e
->x
.p
->size
/2; ++i
) {
111 Param_Polyhedron
*PP
;
114 evalue_extract_poly(e
, i
, &E
, &EP
);
115 ex poly
= evalue2ex(EP
, allvars
);
116 if (is_exactly_a
<fail
>(poly
)) {
117 if (E
!= EVALUE_DOMAIN(e
->x
.p
->arr
[2*i
]))
122 for (Polyhedron
*P
= E
; P
; P
= P
->next
) {
123 Polyhedron
*next
= P
->next
;
124 piecewise_lst
*pl
= new piecewise_lst(params
);
127 PP
= Polyhedron2Param_Domain(P
, ctx
, 0);
128 for (Param_Domain
*Q
= PP
->D
; Q
; Q
= Q
->next
) {
129 matrix VM
= domainVertices(PP
, Q
, params
);
130 lst coeffs
= bernsteinExpansion(VM
, poly
, vars
, params
);
131 pl
->list
.push_back(guarded_lst(Polyhedron_Copy(Q
->Domain
), coeffs
));
133 Param_Polyhedron_Free(PP
);
137 pl_all
->combine(*pl
);
142 if (E
!= EVALUE_DOMAIN(e
->x
.p
->arr
[2*i
]))