4 #include <barvinok/barvinok.h>
8 #ifdef HAVE_SYS_TIMES_H
10 #include <sys/times.h>
12 typedef clock_t my_clock_t
;
14 static my_clock_t
time_diff(struct tms
*before
, struct tms
*after
)
16 return after
->tms_utime
- before
->tms_utime
;
21 typedef int my_clock_t
;
23 struct tms
{ int dummy
; };
24 static void times(struct tms
* time
)
27 static my_clock_t
time_diff(struct tms
*before
, struct tms
*after
)
39 { BV_APPROX_SIGN_NONE
, BV_APPROX_NONE
, 0 },
40 { BV_APPROX_SIGN_APPROX
, BV_APPROX_BERNOULLI
, 0 },
41 { BV_APPROX_SIGN_APPROX
, BV_APPROX_DROP
, 0 },
42 { BV_APPROX_SIGN_APPROX
, BV_APPROX_VOLUME
, BV_VOL_LIFT
},
43 { BV_APPROX_SIGN_APPROX
, BV_APPROX_VOLUME
, BV_VOL_VERTEX
},
44 { BV_APPROX_SIGN_APPROX
, BV_APPROX_VOLUME
, BV_VOL_BARYCENTER
},
45 { BV_APPROX_SIGN_APPROX
, BV_APPROX_SCALE
, 0 },
46 { BV_APPROX_SIGN_APPROX
, BV_APPROX_SCALE
, BV_APPROX_SCALE_CHAMBER
},
47 { BV_APPROX_SIGN_APPROX
, BV_APPROX_SCALE
, BV_APPROX_SCALE_FAST
},
48 { BV_APPROX_SIGN_APPROX
, BV_APPROX_SCALE
, BV_APPROX_SCALE_FAST
| BV_APPROX_SCALE_CHAMBER
},
49 { BV_APPROX_SIGN_LOWER
, BV_APPROX_DROP
, 0 },
50 { BV_APPROX_SIGN_LOWER
, BV_APPROX_VOLUME
, BV_VOL_LIFT
},
51 { BV_APPROX_SIGN_LOWER
, BV_APPROX_VOLUME
, BV_VOL_VERTEX
},
52 { BV_APPROX_SIGN_LOWER
, BV_APPROX_VOLUME
, BV_VOL_BARYCENTER
},
53 { BV_APPROX_SIGN_LOWER
, BV_APPROX_SCALE
, 0 },
54 { BV_APPROX_SIGN_LOWER
, BV_APPROX_SCALE
, BV_APPROX_SCALE_CHAMBER
},
55 { BV_APPROX_SIGN_LOWER
, BV_APPROX_SCALE
, BV_APPROX_SCALE_FAST
},
56 { BV_APPROX_SIGN_LOWER
, BV_APPROX_SCALE
, BV_APPROX_SCALE_FAST
| BV_APPROX_SCALE_CHAMBER
},
57 { BV_APPROX_SIGN_LOWER
, BV_APPROX_SCALE
, BV_APPROX_SCALE_NARROW
},
58 { BV_APPROX_SIGN_LOWER
, BV_APPROX_SCALE
, BV_APPROX_SCALE_NARROW
| BV_APPROX_SCALE_CHAMBER
},
59 { BV_APPROX_SIGN_LOWER
, BV_APPROX_SCALE
, BV_APPROX_SCALE_FAST
| BV_APPROX_SCALE_NARROW
},
60 { BV_APPROX_SIGN_LOWER
, BV_APPROX_SCALE
, BV_APPROX_SCALE_FAST
| BV_APPROX_SCALE_NARROW
| BV_APPROX_SCALE_CHAMBER
},
61 { BV_APPROX_SIGN_LOWER
, BV_APPROX_SCALE
, BV_APPROX_SCALE_NARROW2
},
62 { BV_APPROX_SIGN_LOWER
, BV_APPROX_SCALE
, BV_APPROX_SCALE_NARROW2
| BV_APPROX_SCALE_CHAMBER
},
63 { BV_APPROX_SIGN_LOWER
, BV_APPROX_SCALE
, BV_APPROX_SCALE_FAST
| BV_APPROX_SCALE_NARROW2
},
64 { BV_APPROX_SIGN_LOWER
, BV_APPROX_SCALE
, BV_APPROX_SCALE_FAST
| BV_APPROX_SCALE_NARROW2
| BV_APPROX_SCALE_CHAMBER
},
65 { BV_APPROX_SIGN_UPPER
, BV_APPROX_DROP
, 0 },
66 { BV_APPROX_SIGN_UPPER
, BV_APPROX_VOLUME
, BV_VOL_LIFT
},
67 { BV_APPROX_SIGN_UPPER
, BV_APPROX_VOLUME
, BV_VOL_VERTEX
},
68 { BV_APPROX_SIGN_UPPER
, BV_APPROX_VOLUME
, BV_VOL_BARYCENTER
},
69 { BV_APPROX_SIGN_UPPER
, BV_APPROX_SCALE
, 0 },
70 { BV_APPROX_SIGN_UPPER
, BV_APPROX_SCALE
, BV_APPROX_SCALE_CHAMBER
},
71 { BV_APPROX_SIGN_UPPER
, BV_APPROX_SCALE
, BV_APPROX_SCALE_FAST
},
72 { BV_APPROX_SIGN_UPPER
, BV_APPROX_SCALE
, BV_APPROX_SCALE_FAST
| BV_APPROX_SCALE_CHAMBER
},
73 { BV_APPROX_SIGN_UPPER
, BV_APPROX_SCALE
, BV_APPROX_SCALE_NARROW
},
74 { BV_APPROX_SIGN_UPPER
, BV_APPROX_SCALE
, BV_APPROX_SCALE_NARROW
| BV_APPROX_SCALE_CHAMBER
},
75 { BV_APPROX_SIGN_UPPER
, BV_APPROX_SCALE
, BV_APPROX_SCALE_FAST
| BV_APPROX_SCALE_NARROW
},
76 { BV_APPROX_SIGN_UPPER
, BV_APPROX_SCALE
, BV_APPROX_SCALE_FAST
| BV_APPROX_SCALE_NARROW
| BV_APPROX_SCALE_CHAMBER
},
77 { BV_APPROX_SIGN_UPPER
, BV_APPROX_SCALE
, BV_APPROX_SCALE_NARROW2
},
78 { BV_APPROX_SIGN_UPPER
, BV_APPROX_SCALE
, BV_APPROX_SCALE_NARROW2
| BV_APPROX_SCALE_CHAMBER
},
79 { BV_APPROX_SIGN_UPPER
, BV_APPROX_SCALE
, BV_APPROX_SCALE_FAST
| BV_APPROX_SCALE_NARROW2
},
80 { BV_APPROX_SIGN_UPPER
, BV_APPROX_SCALE
, BV_APPROX_SCALE_FAST
| BV_APPROX_SCALE_NARROW2
| BV_APPROX_SCALE_CHAMBER
},
83 #define nr_methods (sizeof(methods)/sizeof(*methods))
87 struct verify_options
*verify
;
90 ISL_ARGS_START(struct options
, options_args
)
91 ISL_ARG_CHILD(struct options
, verify
, NULL
, &verify_options_args
, NULL
)
92 ISL_ARG_BOOL(struct options
, quiet
, 'q', "quiet", 0, NULL
)
95 ISL_ARG_DEF(options
, struct options
, options_args
)
99 double RE_sum
[nr_methods
];
101 my_clock_t ticks
[nr_methods
];
102 size_t size
[nr_methods
];
105 void result_data_init(struct result_data
*result
)
108 for (i
= 0; i
< nr_methods
; ++i
) {
109 result
->RE_sum
[i
] = 0;
110 result
->ticks
[i
] = 0;
113 value_init(result
->n
);
116 void result_data_clear(struct result_data
*result
)
119 value_clear(result
->n
);
122 void result_data_print(struct result_data
*result
, int n
)
126 fprintf(stderr
, "%g", (double)result
->ticks
[0]/n
);
127 for (i
= 1; i
< nr_methods
; ++i
)
128 fprintf(stderr
, ", %g", (double)result
->ticks
[i
]/n
);
129 fprintf(stderr
, "\n");
131 fprintf(stderr
, "%zd", result
->size
[0]/n
);
132 for (i
= 1; i
< nr_methods
; ++i
)
133 fprintf(stderr
, ", %zd", result
->size
[i
]/n
);
134 fprintf(stderr
, "\n");
136 fprintf(stderr
, "%g\n", VALUE_TO_DOUBLE(result
->n
));
137 fprintf(stderr
, "%g", result
->RE_sum
[0]/VALUE_TO_DOUBLE(result
->n
));
138 for (i
= 1; i
< nr_methods
; ++i
)
139 fprintf(stderr
, ", %g", result
->RE_sum
[i
]/VALUE_TO_DOUBLE(result
->n
));
140 fprintf(stderr
, "\n");
143 struct test_approx_data
{
144 struct check_poly_data cp
;
146 struct result_data
*result
;
149 static void eval(const evalue
*EP
, Value
*z
, int sign
, Value
*v
)
153 res
= evalue_eval(EP
, z
);
154 if (sign
== BV_APPROX_SIGN_LOWER
)
155 mpz_cdiv_q(*v
, res
->x
.n
, res
->d
);
156 else if (sign
== BV_APPROX_SIGN_UPPER
)
157 mpz_fdiv_q(*v
, res
->x
.n
, res
->d
);
158 else if (sign
== BV_APPROX_SIGN_APPROX
)
159 mpz_tdiv_q(*v
, res
->x
.n
, res
->d
);
161 assert(value_one_p(res
->d
));
162 value_assign(*v
, res
->x
.n
);
167 static int test_approx(const struct check_poly_data
*data
, int nparam
, Value
*z
,
168 const struct verify_options
*options
)
170 struct test_approx_data
* ta_data
= (struct test_approx_data
*) data
;
177 eval(ta_data
->EP
[0], z
, BV_APPROX_SIGN_NONE
, &exact
);
180 value_print(stderr, VALUE_FMT, exact);
183 value_increment(ta_data
->result
->n
, ta_data
->result
->n
);
184 for (i
= 1; i
< nr_methods
; ++i
) {
186 eval(ta_data
->EP
[i
], z
, methods
[i
].sign
, &approx
);
188 fprintf(stderr, ", ");
189 value_print(stderr, VALUE_FMT, approx);
191 if (methods
[i
].sign
== BV_APPROX_SIGN_LOWER
)
192 assert(value_le(approx
, exact
));
193 if (methods
[i
].sign
== BV_APPROX_SIGN_UPPER
)
194 assert(value_ge(approx
, exact
));
195 value_subtract(approx
, approx
, exact
);
196 if (value_zero_p(exact
))
197 error
= abs(VALUE_TO_DOUBLE(approx
));
199 error
= abs(VALUE_TO_DOUBLE(approx
)) / VALUE_TO_DOUBLE(exact
);
200 ta_data
->result
->RE_sum
[i
] += error
;
204 fprintf(stderr, "\n");
212 static void test(Polyhedron
*P
, Polyhedron
*C
, evalue
**EP
,
213 struct result_data
*result
,
214 struct verify_options
*options
)
218 unsigned nparam
= C
->Dimension
;
219 struct test_approx_data data
;
221 CS
= check_poly_context_scan(P
, &C
, C
->Dimension
, options
);
223 p
= Vector_Alloc(P
->Dimension
+2);
224 value_set_si(p
->p
[P
->Dimension
+1], 1);
226 check_poly_init(C
, options
);
229 data
.cp
.check
= test_approx
;
231 data
.result
= result
;
232 check_poly(CS
, &data
.cp
, nparam
, 0, p
->p
+P
->Dimension
-nparam
+1,
234 if (!options
->print_all
)
244 void Matrix_File_Read_Input(FILE *in
, Matrix
*Mat
)
248 char *c
, s
[1024],str
[1024];
251 for (i
=0;i
<Mat
->NbRows
;i
++) {
253 c
= fgets(s
, 1024, in
);
254 while(isspace(*c
) && *c
!='\n')
256 } while(c
&& (*c
=='#' || *c
== '\n'));
259 errormsg1( "Matrix_Read", "baddim", "not enough rows" );
262 for (j
=0;j
<Mat
->NbColumns
;j
++) {
263 if(!c
|| *c
=='\n' || *c
=='#') {
264 errormsg1("Matrix_Read", "baddim", "not enough columns");
267 if (sscanf(c
,"%s%n",str
,&n
) == 0) {
268 errormsg1( "Matrix_Read", "baddim", "not enough columns" );
271 value_read(*(p
++),str
);
275 } /* Matrix_Read_Input */
278 * Read the contents of the matrix 'Mat' from standard input.
279 * A '#' in the first column is a comment line
281 Matrix
*Matrix_File_Read(FILE *in
)
284 unsigned NbRows
, NbColumns
;
288 while ((*s
=='#' || *s
=='\n') ||
289 (sscanf(s
, "%d %d", &NbRows
, &NbColumns
)<2))
291 Mat
= Matrix_Alloc(NbRows
,NbColumns
);
293 errormsg1("Matrix_Read", "outofmem", "out of memory space");
296 Matrix_File_Read_Input(in
, Mat
);
300 void handle(FILE *in
, struct result_data
*result
, struct verify_options
*options
)
305 const char **param_name
;
306 evalue
*EP
[nr_methods
];
308 M
= Matrix_File_Read(in
);
309 A
= Constraints2Polyhedron(M
, options
->barvinok
->MaxRays
);
311 M
= Matrix_File_Read(in
);
312 C
= Constraints2Polyhedron(M
, options
->barvinok
->MaxRays
);
314 param_name
= Read_ParamNames(in
, C
->Dimension
);
316 for (i
= 0; i
< nr_methods
; ++i
) {
319 options
->barvinok
->approx
->approximation
= methods
[i
].sign
;
320 options
->barvinok
->approx
->method
= methods
[i
].method
;
321 if (methods
[i
].method
== BV_APPROX_SCALE
)
322 options
->barvinok
->approx
->scale_flags
= methods
[i
].flags
;
323 else if (methods
[i
].method
== BV_APPROX_VOLUME
)
324 options
->barvinok
->approx
->volume_triangulate
= methods
[i
].flags
;
327 EP
[i
] = barvinok_enumerate_with_options(A
, C
, options
->barvinok
);
329 result
->ticks
[i
] = time_diff(&en_cpu
, &st_cpu
);
331 print_evalue(stdout, EP[i], param_name);
334 for (i
= 0; i
< nr_methods
; ++i
)
335 result
->size
[i
] = evalue_size(EP
[i
])/4;
336 test(A
, C
, EP
, result
, options
);
337 for (i
= 0; i
< nr_methods
; ++i
)
340 Free_ParamNames(param_name
, C
->Dimension
);
345 int main(int argc
, char **argv
)
347 char path
[PATH_MAX
+1];
348 struct result_data all_result
;
350 struct options
*options
= options_new_with_defaults();
352 argc
= options_parse(options
, argc
, argv
, ISL_ARG_ALL
);
354 if (options
->verify
->M
== INT_MIN
)
355 options
->verify
->M
= 100;
356 if (options
->verify
->m
== INT_MAX
)
357 options
->verify
->m
= -100;
359 result_data_init(&all_result
);
361 while (fgets(path
, sizeof(path
), stdin
)) {
362 struct result_data result
;
367 result_data_init(&result
);
368 fprintf(stderr
, "%s", path
);
369 *strchr(path
, '\n') = '\0';
370 in
= fopen(path
, "r");
372 handle(in
, &result
, options
->verify
);
376 result_data_print(&result
, 1);
378 value_addto(all_result
.n
, all_result
.n
, result
.n
);
379 for (i
= 0; i
< nr_methods
; ++i
) {
380 all_result
.RE_sum
[i
] += result
.RE_sum
[i
];
381 all_result
.ticks
[i
] += result
.ticks
[i
];
382 all_result
.size
[i
] += result
.size
[i
];
385 result_data_clear(&result
);
387 if (!options
->quiet
) {
388 fprintf(stderr
, "average\n");
389 result_data_print(&all_result
, n
);
393 result_data_clear(&all_result
);
395 options_free(options
);