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 Domain 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*/
35 POL_ENSURE_INEQUALITIES(P
);
39 /* P->Constraint constraint matrice of polyhedron P */
40 for(row
=0;row
<P
->NbConstraints
;row
++) {
41 value_assign(v
,P
->Constraint
[row
][P
->Dimension
+1]); /*constant part*/
42 for(col
=1;col
<P
->Dimension
+1;col
++) {
43 value_addmul(v
, P
->Constraint
[row
][col
], list_args
[col
-1]);
45 if (value_notzero_p(P
->Constraint
[row
][0])) {
47 /*if v is not >=0 then this constraint is not respected */
50 return( in_domain(P
->next
, list_args
) );
55 /*if v is not = 0 then this constraint is not respected */
56 if (value_notzero_p(v
)) {
58 return( in_domain(P
->next
, list_args
) );
63 /* if not return before this point => all the constraints are respected */
68 /****************************************************/
69 /* function compute enode */
70 /* compute the value of enode p with parameters */
72 /* compute the polynomial or the periodic */
73 /****************************************************/
75 static double compute_enode(enode
*p
, Value
*list_args
) {
87 if (p
->type
== polynomial
) {
89 value_assign(param
,list_args
[p
->pos
-1]);
91 /* Compute the polynomial using Horner's rule */
92 for (i
=p
->size
-1;i
>0;i
--) {
93 res
+=compute_evalue(&p
->arr
[i
],list_args
);
94 res
*=VALUE_TO_DOUBLE(param
);
96 res
+=compute_evalue(&p
->arr
[0],list_args
);
98 else if (p
->type
== periodic
) {
99 value_assign(m
,list_args
[p
->pos
-1]);
101 /* Choose the right element of the periodic */
102 value_set_si(param
,p
->size
);
103 value_pmodulus(m
,m
,param
);
104 res
= compute_evalue(&p
->arr
[VALUE_TO_INT(m
)],list_args
);
109 } /* compute_enode */
111 /*************************************************/
112 /* return the value of Ehrhart Polynomial */
113 /* It returns a double, because since it is */
114 /* a recursive function, some intermediate value */
115 /* might not be integral */
116 /*************************************************/
118 double compute_evalue(evalue
*e
,Value
*list_args
) {
122 if (value_notzero_p(e
->d
)) {
123 if (value_notone_p(e
->d
))
124 res
= VALUE_TO_DOUBLE(e
->x
.n
) / VALUE_TO_DOUBLE(e
->d
);
126 res
= VALUE_TO_DOUBLE(e
->x
.n
);
129 res
= compute_enode(e
->x
.p
,list_args
);
131 } /* compute_evalue */
134 /****************************************************/
135 /* function compute_poly : */
136 /* Check for the good validity domain */
137 /* return the number of point in the Polyhedron */
138 /* in allocated memory */
139 /* Using the Ehrhart pseudo-polynomial */
140 /****************************************************/
141 Value
*compute_poly(Enumeration
*en
,Value
*list_args
) {
144 /* double d; int i; */
146 tmp
= (Value
*) malloc (sizeof(Value
));
149 value_set_si(*tmp
,0);
152 return(tmp
); /* no ehrhart polynomial */
153 if(en
->ValidityDomain
) {
154 if(!en
->ValidityDomain
->Dimension
) { /* no parameters */
155 value_set_double(*tmp
,compute_evalue(&en
->EP
,list_args
)+.25);
160 return(tmp
); /* no Validity Domain */
162 if(in_domain(en
->ValidityDomain
,list_args
)) {
164 #ifdef EVAL_EHRHART_DEBUG
165 Print_Domain(stdout
,en
->ValidityDomain
,NULL
);
166 print_evalue(stdout
,&en
->EP
,NULL
);
169 /* d = compute_evalue(&en->EP,list_args);
171 printf("(double)%lf = %d\n", d, i ); */
172 value_set_double(*tmp
,compute_evalue(&en
->EP
,list_args
)+.25);
178 value_set_si(*tmp
,0);
179 return(tmp
); /* no compatible domain with the arguments */