1 /*************************************************/
3 /* program to compare effective number of points */
4 /* in a polytope with the corresponding */
5 /* evaluation of the Ehrhart polynomial. */
6 /* Parameters vary in range -RANGE to RANGE */
7 /* (define below) by default. */
8 /* Can be overridden by specifying */
9 /* -r<RANGE>, or -m<min> and -M<max> */
11 /* written by Vincent Loechner (c) 2000. */
12 /* loechner@icps.u-strasbg.fr */
13 /*************************************************/
20 #include <polylib/polylibgmp.h>
26 #ifdef HAVE_GROWING_CHERNIKOVA
33 #define getopt_long(a,b,c,d,e) getopt(a,b,c)
36 struct option options
[] = {
37 { "min", no_argument
, 0, 'm' },
38 { "max", no_argument
, 0, 'M' },
39 { "range", no_argument
, 0, 'r' },
40 { "pip", no_argument
, 0, 'p' },
41 { "version", no_argument
, 0, 'V' },
46 /* define this to print all the results */
47 /* else, only a progress bar is printed */
48 /* #define PRINT_ALL_RESULTS
49 /* define this to continue the test after first error found */
50 /* #define DONT_BREAK_ON_ERROR */
52 /* RANGE : normal range for evalutations (-RANGE -> RANGE) */
55 /* SRANGE : small range for evalutations */
58 /* if dimension >= BIDDIM, use SRANGE */
61 /* VSRANGE : very small range for evalutations */
64 /* if dimension >= VBIDDIM, use VSRANGE */
71 #ifdef DONT_BREAK_ON_ERROR
72 #define PRINT_ALL_RESULTS
75 #ifndef PRINT_ALL_RESULTS
79 /****************************************************/
80 /* function check_poly : */
81 /* scans the parameter space from min to max (all */
82 /* directions). Computes the number of points in */
83 /* the polytope using both methods, and compare them*/
84 /* returns 1 on success */
85 /****************************************************/
87 int check_poly(Polyhedron
*S
, Polyhedron
*C
, evalue
*EP
,
88 int exist
, int nparam
, int pos
, Value
*z
) {
93 value_init(c
); value_init(tmp
);
97 /* Computes the ehrhart polynomial */
98 value_set_double(c
, compute_evalue(EP
,&z
[S
->Dimension
-nparam
+1])+.25);
99 /* if c=0 we may be out of context. */
100 /* scanning is useless in this case*/
101 if(!in_domain(C
,&z
[S
->Dimension
-nparam
+1])) {
107 #ifdef PRINT_ALL_RESULTS
109 value_print(stdout
,VALUE_FMT
,z
[S
->Dimension
-nparam
+1]);
110 for(k
=S
->Dimension
-nparam
+2;k
<=S
->Dimension
;++k
) {
112 value_print(stdout
,VALUE_FMT
,z
[k
]);
115 value_print(stdout
,VALUE_FMT
,c
);
119 /* Manually count the number of points */
120 count_points_e(1, S
, exist
, nparam
, z
, &tmp
);
121 #ifdef PRINT_ALL_RESULTS
122 printf(", count = ");
123 value_print(stdout
, P_VALUE_FMT
, tmp
);
127 if(value_ne(tmp
,c
)) {
130 fprintf(stderr
,"Error !\n");
131 fprintf(stderr
,"EP( ");
132 value_print(stderr
,VALUE_FMT
,z
[S
->Dimension
-nparam
+1]);
133 for(k
=S
->Dimension
-nparam
+2;k
<=S
->Dimension
;++k
) {
134 fprintf(stderr
,", ");
135 value_print(stderr
,VALUE_FMT
,z
[k
]);
137 fprintf(stderr
," ) should be ");
138 value_print(stderr
,VALUE_FMT
,tmp
);
139 fprintf(stderr
,", while EP eval gives ");
140 value_print(stderr
,VALUE_FMT
,c
);
141 fprintf(stderr
,".\n");
142 print_evalue(stderr
, EP
, params
);
143 #ifndef DONT_BREAK_ON_ERROR
144 value_clear(c
); value_clear(tmp
);
149 #ifdef PRINT_ALL_RESULTS
156 for(value_assign(tmp
,min
); value_le(tmp
,max
); value_increment(tmp
,tmp
)) {
158 #ifndef PRINT_ALL_RESULTS
159 k
= VALUE_TO_INT(tmp
);
160 if(!pos
&& !(k
%st
)) {
166 value_assign(z
[pos
+S
->Dimension
-nparam
+1],tmp
);
167 if(!check_poly(S
, C
, EP
, exist
, nparam
, pos
+1, z
)) {
168 value_clear(c
); value_clear(tmp
);
172 value_clear(c
); value_clear(tmp
);
176 int main(int argc
,char *argv
[])
179 Polyhedron
*C
, *P
, *S
;
182 int m
= INT_MAX
, M
= INT_MIN
, r
;
190 while ((c
= getopt_long(argc
, argv
, "pm:M:r:V", options
, &ind
)) != -1) {
206 printf(barvinok_version());
212 /******* Read the input *********/
215 fgets(s
, 128, stdin
);
216 while ((*s
=='#') || (sscanf(s
, "E %d", &exist
)<1))
217 fgets(s
, 128, stdin
);
219 fgets(s
, 128, stdin
);
220 while ((*s
=='#') || (sscanf(s
, "P %d", &nparam
)<1))
221 fgets(s
, 128, stdin
);
223 P
= Constraints2Polyhedron(P1
,MAXRAYS
);
224 params
= Read_ParamNames(stdin
, nparam
);
227 /******* Read the options: initialize Min and Max ********/
228 if(P
->Dimension
>= VBIGDIM
)
230 else if(P
->Dimension
>= BIGDIM
)
240 fprintf(stderr
,"Nothing to do: min > max !\n");
249 /******* Compute true context *******/
250 C1
= Matrix_Alloc(nparam
+1,P
->Dimension
+1);
252 for(i
=0;i
<C1
->NbRows
;i
++)
253 for(j
=0;j
<C1
->NbColumns
;j
++)
254 if(i
==j
-P
->Dimension
+nparam
)
255 value_set_si(C1
->p
[i
][j
],1);
257 value_set_si(C1
->p
[i
][j
],0);
258 C
= Polyhedron_Image(P
,C1
,MAXRAYS
);
261 /******* Compute EP *********/
263 EP
= barvinok_enumerate_pip(P
, exist
, nparam
, MAXRAYS
);
265 EP
= barvinok_enumerate_e(P
, exist
, nparam
, MAXRAYS
);
267 /******* Initializations for check *********/
268 p
= (Value
*)malloc(sizeof(Value
) * (P
->Dimension
+2));
269 for(i
=0;i
<=P
->Dimension
;i
++) {
271 value_set_si(p
[i
],0);
274 value_set_si(p
[i
],1);
276 /* S = scanning list of polyhedra */
277 S
= Polyhedron_Scan(P
,C
,MAXRAYS
);
279 #ifndef PRINT_ALL_RESULTS
280 if(C
->Dimension
> 0) {
281 value_subtract(tmp
,max
,min
);
282 if (VALUE_TO_INT(tmp
) > 80)
283 st
= 1+(VALUE_TO_INT(tmp
))/80;
286 for(i
=VALUE_TO_INT(min
);i
<=VALUE_TO_INT(max
);i
+=st
)
293 /******* CHECK NOW *********/
295 if(S
&& !check_poly(S
, C
, EP
, exist
, nparam
, 0, p
)) {
296 fprintf(stderr
,"Check failed !\n");
300 #ifndef PRINT_ALL_RESULTS
304 for(i
=0;i
<=(P
->Dimension
+1);i
++)
308 Free_ParamNames(params
, C
->Dimension
);
312 free_evalue_refs(EP
);