1 /************************************************/
3 /* functions to evaluate an Ehrhart polynomial. */
4 /* written by Emmanuel Jeannot (c) 1997. */
5 /* Emmanuel.Jeannot@ens-lyon.fr */
6 /* http://www.ens-lyon.fr/~ejeannot */
8 /* modified 1998, 2000, Vincent Loechner */
9 /* (ArithmetiqueLib, Param_Names) */
10 /************************************************/
17 #include <polylib/polylib.h>
19 /* #define EVAL_EHRHART_DEBUG */
21 /********************************************************/
22 /* function in domain */
23 /* check if the parameters in list_args */
24 /* verifies the constraints of Polyhedron P */
25 /********************************************************/
26 int in_domain(Polyhedron
*P
, Value
*list_args
) {
29 Value v
; /* value of the constraint of a row when
30 parameters are instanciated*/
36 /*P->Constraint constraint matrice of polyhedron P*/
37 for(row
=0;row
<P
->NbConstraints
;row
++) {
38 value_assign(v
,P
->Constraint
[row
][P
->Dimension
+1]); /*constant part*/
39 for(col
=1;col
<P
->Dimension
+1;col
++) {
40 value_multiply(tmp
,P
->Constraint
[row
][col
],list_args
[col
-1]);
43 if (value_notzero_p(P
->Constraint
[row
][0])) {
45 /*if v is not >=0 then this constraint is not respected */
54 /*if v is not = 0 then this constraint is not respected */
55 if (value_notzero_p(v
)) {
63 /*if not return before this point => all
64 the constraints are respected */
70 /****************************************************/
71 /* function compute enode */
72 /* compute the value of enode p with parameters */
74 /* compute the polynomial or the periodic */
75 /****************************************************/
77 static double compute_enode(enode
*p
, Value
*list_args
) {
89 if (p
->type
== polynomial
) {
91 value_assign(param
,list_args
[p
->pos
-1]);
93 /* Compute the polynomial using Horner's rule */
94 for (i
=p
->size
-1;i
>0;i
--) {
95 res
+=compute_evalue(&p
->arr
[i
],list_args
);
96 res
*=VALUE_TO_DOUBLE(param
);
98 res
+=compute_evalue(&p
->arr
[0],list_args
);
100 else if (p
->type
== periodic
) {
101 value_assign(param
,list_args
[p
->pos
-1]);
103 /* Choose the right element of the periodic */
104 value_absolute(m
,param
);
105 value_set_si(param
,p
->size
);
106 value_modulus(m
,m
,param
);
107 res
= compute_evalue(&p
->arr
[VALUE_TO_INT(m
)],list_args
);
112 } /* compute_enode */
114 /*************************************************/
115 /* return the value of Ehrhart Polynomial */
116 /* It returns a double, because since it is */
117 /* a recursive function, some intermediate value */
118 /* might not be integral */
119 /*************************************************/
121 double compute_evalue(evalue
*e
,Value
*list_args
) {
125 if (value_notzero_p(e
->d
)) {
126 if (value_notone_p(e
->d
))
127 res
= VALUE_TO_DOUBLE(e
->x
.n
) / VALUE_TO_DOUBLE(e
->d
);
129 res
= VALUE_TO_DOUBLE(e
->x
.n
);
132 res
= compute_enode(e
->x
.p
,list_args
);
134 } /* compute_evalue */
137 /****************************************************/
138 /* function compute_poly : */
139 /* Check for the good validity domain */
140 /* return the number of point in the Polyhedron */
141 /* in allocated memory */
142 /* Using the Ehrhart pseudo-polynomial */
143 /****************************************************/
144 Value
*compute_poly(Enumeration
*en
,Value
*list_args
) {
147 /* double d; int i; */
149 tmp
= (Value
*) malloc (sizeof(Value
));
152 value_set_si(*tmp
,0);
155 return(tmp
); /* no ehrhart polynomial */
156 if(en
->ValidityDomain
) {
157 if(!en
->ValidityDomain
->Dimension
) { /* no parameters */
158 value_set_double(*tmp
,compute_evalue(&en
->EP
,list_args
)+.25);
163 return(tmp
); /* no Validity Domain */
165 if(in_domain(en
->ValidityDomain
,list_args
)) {
167 #ifdef EVAL_EHRHART_DEBUG
168 Print_Domain(stdout
,en
->ValidityDomain
);
169 print_evalue(stdout
,&en
->EP
);
172 /* d = compute_evalue(&en->EP,list_args);
174 printf("(double)%lf = %d\n", d, i ); */
175 value_set_double(*tmp
,compute_evalue(&en
->EP
,list_args
)+.25);
181 value_set_si(*tmp
,0);
182 return(tmp
); /* no compatible domain with the arguments */