4 #include <bernstein/bernstein.h>
5 #include <barvinok/options.h>
6 #include <barvinok/bernstein.h>
7 #include <barvinok/util.h>
10 #include "evalue_read.h"
14 #ifdef HAVE_SYS_TIMES_H
16 #include <sys/times.h>
18 typedef clock_t my_clock_t
;
20 static my_clock_t
time_diff(struct tms
*before
, struct tms
*after
)
22 return after
->tms_utime
- before
->tms_utime
;
27 typedef int my_clock_t
;
30 static void times(struct tms
* time
)
33 static my_clock_t
time_diff(struct tms
*before
, struct tms
*after
)
43 using namespace GiNaC
;
44 using namespace bernstein
;
45 using namespace barvinok
;
50 { BV_BOUND_BERNSTEIN
},
54 #define nr_methods (sizeof(methods)/sizeof(*methods))
56 struct argp_option argp_options
[] = {
62 struct verify_options verify
;
66 static error_t
parse_opt(int key
, char *arg
, struct argp_state
*state
)
68 struct options
*options
= (struct options
*) state
->input
;
72 state
->child_inputs
[0] = options
->verify
.barvinok
;
73 state
->child_inputs
[1] = &options
->verify
;
80 return ARGP_ERR_UNKNOWN
;
87 double RE_sum
[nr_methods
];
89 my_clock_t ticks
[nr_methods
];
90 size_t size
[nr_methods
];
93 void result_data_init(struct result_data
*result
)
96 for (i
= 0; i
< nr_methods
; ++i
) {
97 result
->RE_sum
[i
] = 0;
101 isl_int_init(result
->n
);
104 void result_data_clear(struct result_data
*result
)
107 isl_int_clear(result
->n
);
110 void result_data_print(struct result_data
*result
, int n
)
114 fprintf(stderr
, "%d", result
->ticks
[0]/n
);
115 for (i
= 1; i
< nr_methods
; ++i
)
116 fprintf(stderr
, ", %d", result
->ticks
[i
]/n
);
117 fprintf(stderr
, "\n");
119 fprintf(stderr
, "%zd/%d", result
->size
[0], n
);
120 for (i
= 1; i
< nr_methods
; ++i
)
121 fprintf(stderr
, ", %zd/%d", result
->size
[i
], n
);
122 fprintf(stderr
, "\n");
124 fprintf(stderr
, "%g\n", isl_int_get_d(result
->n
));
125 fprintf(stderr
, "%g", result
->RE_sum
[0]/isl_int_get_d(result
->n
));
126 for (i
= 1; i
< nr_methods
; ++i
)
127 fprintf(stderr
, ", %g", result
->RE_sum
[i
]/isl_int_get_d(result
->n
));
128 fprintf(stderr
, "\n");
131 struct verify_point_bound
{
132 struct verify_point_data vpd
;
133 struct result_data
*result
;
134 isl_pw_qpolynomial
*pwqp
;
135 isl_pw_qpolynomial_fold
**pwf
;
138 static int verify_point(__isl_take isl_point
*pnt
, void *user
)
140 struct verify_point_bound
*vpb
= (struct verify_point_bound
*) user
;
141 const struct verify_options
*options
= vpb
->vpd
.options
;
144 isl_int max
, min
, exact
, approx
;
146 isl_qpolynomial
*opt
;
147 isl_pw_qpolynomial
*pwqp
;
155 isl_int_init(approx
);
159 pwqp
= isl_pw_qpolynomial_copy(vpb
->pwqp
);
161 nparam
= isl_pw_qpolynomial_dim(pwqp
, isl_dim_param
);
162 for (i
= 0; i
< nparam
; ++i
) {
163 isl_point_get_coordinate(pnt
, isl_dim_param
, i
, &n
);
164 pwqp
= isl_pw_qpolynomial_fix_dim(pwqp
, isl_dim_param
, i
, n
);
167 opt
= isl_pw_qpolynomial_max(isl_pw_qpolynomial_copy(pwqp
));
168 cst
= isl_qpolynomial_is_cst(opt
, &n
, &d
);
169 isl_qpolynomial_free(opt
);
171 isl_int_fdiv_q(max
, n
, d
);
173 opt
= isl_pw_qpolynomial_min(pwqp
);
174 cst
= isl_qpolynomial_is_cst(opt
, &n
, &d
);
175 isl_qpolynomial_free(opt
);
177 isl_int_cdiv_q(min
, n
, d
);
179 isl_int_sub(exact
, max
, min
);
180 isl_int_add_ui(exact
, exact
, 1);
182 if (options
->print_all
) {
183 fprintf(stderr
, "max: "); isl_int_print(stderr
, max
, 0);
184 fprintf(stderr
, ", min: "); isl_int_print(stderr
, min
, 0);
185 fprintf(stderr
, ", range: "); isl_int_print(stderr
, exact
, 0);
188 for (int i
= 0; i
< nr_methods
; ++i
) {
191 opt
= isl_pw_qpolynomial_fold_eval(
192 isl_pw_qpolynomial_fold_copy(vpb
->pwf
[2 * i
]),
193 isl_point_copy(pnt
));
194 cst
= isl_qpolynomial_is_cst(opt
, &n
, &d
);
195 isl_qpolynomial_free(opt
);
197 isl_int_fdiv_q(max
, n
, d
);
199 opt
= isl_pw_qpolynomial_fold_eval(
200 isl_pw_qpolynomial_fold_copy(vpb
->pwf
[2 * i
+ 1]),
201 isl_point_copy(pnt
));
202 cst
= isl_qpolynomial_is_cst(opt
, &n
, &d
);
203 isl_qpolynomial_free(opt
);
205 isl_int_cdiv_q(min
, n
, d
);
207 isl_int_sub(approx
, max
, min
);
208 isl_int_add_ui(approx
, approx
, 1);
209 if (options
->print_all
) {
210 fprintf(stderr
, ", "); isl_int_print(stderr
, approx
, 0);
213 assert(isl_int_ge(approx
, exact
));
214 isl_int_sub(approx
, approx
, exact
);
216 error
= fabs(isl_int_get_d(approx
)) / isl_int_get_d(exact
);
217 if (options
->print_all
)
218 fprintf(stderr
, " (%g)", error
);
219 vpb
->result
->RE_sum
[i
] += error
;
222 if (options
->print_all
) {
223 fprintf(stderr
, "\n");
224 } else if ((vpb
->vpd
.n
% vpb
->vpd
.s
) == 0) {
231 isl_int_clear(exact
);
232 isl_int_clear(approx
);
241 static void test(evalue
*EP
, unsigned nvar
,
242 const GiNaC::exvector
¶ms
,
243 piecewise_lst
**pl
, struct result_data
*result
,
244 struct verify_options
*options
)
246 struct verify_point_bound vpb
= { { options
}, result
};
247 isl_ctx
*ctx
= isl_ctx_alloc();
253 vpb
.pwf
= isl_alloc_array(ctx
, isl_pw_qpolynomial_fold
*, 2 * nr_methods
);
255 dim
= isl_dim_set_alloc(ctx
, params
.size(), 0);
256 for (i
= 0; i
< 2 * nr_methods
; ++i
)
257 vpb
.pwf
[i
] = isl_pw_qpolynomial_fold_from_ginac(isl_dim_copy(dim
),
260 dim
= isl_dim_set_alloc(ctx
, nvar
+ params
.size(), 0);
261 vpb
.pwqp
= isl_pw_qpolynomial_from_evalue(dim
, EP
);
262 vpb
.pwqp
= isl_pw_qpolynomial_move(vpb
.pwqp
, isl_dim_set
, 0,
263 isl_dim_param
, 0, nvar
);
264 context
= isl_pw_qpolynomial_domain(isl_pw_qpolynomial_copy(vpb
.pwqp
));
265 context
= isl_set_remove(context
, isl_dim_set
, 0, nvar
);
266 context
= verify_context_set_bounds(context
, options
);
268 r
= verify_point_data_init(&vpb
.vpd
, context
);
270 isl_int_set_si(result
->n
, vpb
.vpd
.n
);
272 isl_set_foreach_point(context
, verify_point
, &vpb
);
273 assert(!vpb
.vpd
.error
);
275 isl_set_free(context
);
276 isl_pw_qpolynomial_free(vpb
.pwqp
);
277 for (i
= 0; i
< 2 * nr_methods
; ++i
)
278 isl_pw_qpolynomial_fold_free(vpb
.pwf
[i
]);
282 verify_point_data_fini(&vpb
.vpd
);
286 static int number_of_polynomials(piecewise_lst
*pl
)
289 for (int i
= 0; i
< pl
->list
.size(); ++i
)
290 n
+= pl
->list
[i
].second
.nops();
294 void handle(FILE *in
, struct result_data
*result
, struct verify_options
*options
)
296 evalue
*EP
, *upper
, *lower
;
297 const char **all_vars
= NULL
;
302 piecewise_lst
*pl
[2*nr_methods
];
304 EP
= evalue_read_from_file(in
, NULL
, &all_vars
,
305 &nvar
, &nparam
, options
->barvinok
->MaxRays
);
307 if (EVALUE_IS_ZERO(*EP
)) {
309 Free_ParamNames(all_vars
, nvar
+nparam
);
313 upper
= evalue_dup(EP
);
314 lower
= evalue_dup(EP
);
315 evalue_frac2polynomial(upper
, 1, options
->barvinok
->MaxRays
);
316 evalue_frac2polynomial(lower
, -1, options
->barvinok
->MaxRays
);
318 U
= Universe_Polyhedron(nparam
);
319 params
= constructParameterVector(all_vars
+nvar
, nparam
);
321 for (int i
= 0; i
< nr_methods
; ++i
) {
326 for (int j
= 0; j
< 2; ++j
) {
327 evalue
*poly
= j
== 0 ? upper
: lower
;
328 int sign
= j
== 0 ? BV_BERNSTEIN_MAX
: BV_BERNSTEIN_MIN
;
329 options
->barvinok
->bernstein_optimize
= sign
;
330 if (methods
[i
].method
== BV_BOUND_BERNSTEIN
) {
331 pl
[2*i
+j
] = evalue_bernstein_coefficients(NULL
, poly
, U
, params
,
333 if (sign
== BV_BERNSTEIN_MIN
)
334 pl
[2*i
+j
]->minimize();
336 pl
[2*i
+j
]->maximize();
338 pl
[2*i
+j
] = evalue_range_propagation(NULL
, poly
, params
,
343 result
->ticks
[i
] = time_diff(&en_cpu
, &st_cpu
);
344 if (options
->barvinok
->verbose
)
345 for (int j
= 0; j
< 2; ++j
)
346 cerr
<< *pl
[2*i
+j
] << endl
;
347 result
->size
[i
] = number_of_polynomials(pl
[2*i
]);
348 result
->size
[i
] += number_of_polynomials(pl
[2*i
+1]);
350 test(EP
, nvar
, params
, pl
, result
, options
);
352 for (int i
= 0; i
< 2*nr_methods
; ++i
)
358 Free_ParamNames(all_vars
, nvar
+nparam
);
361 int main(int argc
, char **argv
)
363 struct barvinok_options
*bv_options
= barvinok_options_new_with_defaults();
364 char path
[PATH_MAX
+1];
365 struct result_data all_result
;
367 static struct argp_child argp_children
[] = {
368 { &barvinok_argp
, 0, 0, 0 },
369 { &verify_argp
, 0, "verification", BV_GRP_LAST
+1 },
372 static struct argp argp
= { argp_options
, parse_opt
, 0, 0, argp_children
};
373 struct options options
;
375 options
.verify
.barvinok
= bv_options
;
376 set_program_name(argv
[0]);
377 argp_parse(&argp
, argc
, argv
, 0, 0, &options
);
379 if (options
.verify
.M
== INT_MIN
)
380 options
.verify
.M
= 100;
381 if (options
.verify
.m
== INT_MAX
)
382 options
.verify
.m
= -100;
384 result_data_init(&all_result
);
386 while (fgets(path
, sizeof(path
), stdin
)) {
387 struct result_data result
;
392 result_data_init(&result
);
393 fprintf(stderr
, "%s", path
);
394 *strchr(path
, '\n') = '\0';
395 in
= fopen(path
, "r");
397 handle(in
, &result
, &options
.verify
);
401 result_data_print(&result
, 1);
403 isl_int_add(all_result
.n
, all_result
.n
, result
.n
);
404 for (i
= 0; i
< nr_methods
; ++i
) {
405 all_result
.RE_sum
[i
] += result
.RE_sum
[i
];
406 all_result
.ticks
[i
] += result
.ticks
[i
];
407 all_result
.size
[i
] += result
.size
[i
];
410 result_data_clear(&result
);
412 if (!options
.quiet
) {
413 fprintf(stderr
, "average\n");
414 result_data_print(&all_result
, n
);
418 result_data_clear(&all_result
);
420 barvinok_options_free(bv_options
);