From 1d96ac54cd08c03a66400b998bce9cbfd4da98b0 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Sat, 26 Apr 2008 15:56:47 +0200 Subject: [PATCH] summate.c: barvinok_summate: move common parts of summation functions --- bernoulli.c | 133 ++++++++++++++++---------------------------------------- bernoulli.h | 6 ++- euler.cc | 38 +++------------- euler.h | 4 +- evalue.c | 118 ++++++++++++++++++++++++++++--------------------- laurent.cc | 37 +++------------- laurent.h | 4 +- section_array.h | 39 +++++++++++++++++ summate.c | 71 +++++++++++++++++++++++++++--- summate.h | 1 + testlib.cc | 18 +++++--- 11 files changed, 244 insertions(+), 225 deletions(-) create mode 100644 section_array.h diff --git a/bernoulli.c b/bernoulli.c index c40c5a2..a1835d8 100644 --- a/bernoulli.c +++ b/bernoulli.c @@ -1,12 +1,13 @@ #include +#include #include #include #include "bernoulli.h" #include "lattice_point.h" +#include "section_array.h" #define ALLOC(type) (type*)malloc(sizeof(type)) #define ALLOCN(type,n) (type*)malloc((n) * sizeof(type)) -#define REALLOCN(ptr,type,n) (type*)realloc(ptr, (n) * sizeof(type)) static struct bernoulli_coef bernoulli_coef; static struct poly_list bernoulli; @@ -243,9 +244,7 @@ static void bound_constraint(Value *c, unsigned dim, struct Bernoulli_data { struct barvinok_options *options; - struct evalue_section *s; - int size; - int ns; + struct evalue_section_array *sections; const evalue *e; }; @@ -324,11 +323,7 @@ static void Bernoulli_init(unsigned n, void *cb_data) int exact = data->options->approximation_method == BV_APPROX_NONE; int cases = exact ? 3 : 5; - if (cases * n <= data->size) - return; - - data->size = cases * (n + 16); - data->s = REALLOCN(data->s, struct evalue_section, data->size); + evalue_section_array_ensure(data->sections, cases * n); } static void Bernoulli_cb(Matrix *M, Value *lower, Value *upper, void *cb_data); @@ -418,6 +413,7 @@ static void transform_to_single_case(Matrix *M, Value *lower, Value *upper, static void Bernoulli_cb(Matrix *M, Value *lower, Value *upper, void *cb_data) { struct Bernoulli_data *data = (struct Bernoulli_data *)cb_data; + struct evalue_section_array *sections = data->sections; Matrix *M2; Polyhedron *T; const evalue *factor = NULL; @@ -431,7 +427,7 @@ static void Bernoulli_cb(Matrix *M, Value *lower, Value *upper, void *cb_data) assert(lower); assert(upper); - assert(data->ns + cases <= data->size); + evalue_section_array_ensure(sections, sections->ns + cases); M2 = Matrix_Copy(M); T = Constraints2Polyhedron(M2, data->options->MaxRays); @@ -482,9 +478,7 @@ static void Bernoulli_cb(Matrix *M, Value *lower, Value *upper, void *cb_data) linear = linear_term(factor, lower, upper, row, tmp, exact); if (constant) { - data->s[data->ns].E = linear; - data->s[data->ns].D = T; - ++data->ns; + evalue_section_array_add(sections, T, linear); data->options->stats->bernoulli_sums++; } else { evalue *poly_u = NULL, *poly_l = NULL; @@ -523,9 +517,7 @@ static void Bernoulli_cb(Matrix *M, Value *lower, Value *upper, void *cb_data) eadd(poly_u, extra); eadd(linear, extra); - data->s[data->ns].E = extra; - data->s[data->ns].D = D; - ++data->ns; + evalue_section_array_add(sections, D, extra); data->options->stats->bernoulli_sums++; } @@ -550,9 +542,7 @@ static void Bernoulli_cb(Matrix *M, Value *lower, Value *upper, void *cb_data) eadd(poly_l, extra); eadd(linear, extra); - data->s[data->ns].E = extra; - data->s[data->ns].D = D; - ++data->ns; + evalue_section_array_add(sections, D, extra); data->options->stats->bernoulli_sums++; } @@ -567,17 +557,17 @@ static void Bernoulli_cb(Matrix *M, Value *lower, Value *upper, void *cb_data) if (emptyQ2(D)) Polyhedron_Free(D); else { + evalue *e; poly_l = compute_poly_l(poly_l, lower, row, dim, faulhaber, data); poly_u = compute_poly_u(poly_u, upper, row, dim, tmp, faulhaber, data); - data->s[data->ns].E = ALLOC(evalue); - value_init(data->s[data->ns].E->d); - evalue_copy(data->s[data->ns].E, poly_u); - eadd(poly_l, data->s[data->ns].E); - eadd(linear, data->s[data->ns].E); - data->s[data->ns].D = D; - ++data->ns; + e = ALLOC(evalue); + value_init(e->d); + evalue_copy(e, poly_u); + eadd(poly_l, e); + eadd(linear, e); + evalue_section_array_add(sections, D, e); data->options->stats->bernoulli_sums++; } @@ -598,10 +588,8 @@ static void Bernoulli_cb(Matrix *M, Value *lower, Value *upper, void *cb_data) poly_u = compute_poly_u(poly_u, upper, row, dim, tmp, faulhaber, data); eadd(linear, poly_u); - data->s[data->ns].E = poly_u; + evalue_section_array_add(sections, D, poly_u); poly_u = NULL; - data->s[data->ns].D = D; - ++data->ns; data->options->stats->bernoulli_sums++; } @@ -621,10 +609,8 @@ static void Bernoulli_cb(Matrix *M, Value *lower, Value *upper, void *cb_data) poly_l = compute_poly_l(poly_l, lower, row, dim, faulhaber, data); eadd(linear, poly_l); - data->s[data->ns].E = poly_l; + evalue_section_array_add(sections, D, poly_l); poly_l = NULL; - data->s[data->ns].D = D; - ++data->ns; data->options->stats->bernoulli_sums++; } } @@ -806,22 +792,25 @@ static void move_best_to_front(Polyhedron **P_p, evalue **E_p, unsigned nvar, } static evalue *sum_over_polytope_base(Polyhedron *P, evalue *E, unsigned nvar, - struct Bernoulli_data *data, + struct evalue_section_array *sections, struct barvinok_options *options) { evalue *res; + struct Bernoulli_data data; assert(P->NbEq == 0); - data->ns = 0; - data->e = E; + sections->ns = 0; + data.options = options; + data.sections = sections; + data.e = E; - for_each_lower_upper_bound(P, Bernoulli_init, Bernoulli_cb, data); + for_each_lower_upper_bound(P, Bernoulli_init, Bernoulli_cb, &data); - res = evalue_from_section_array(data->s, data->ns); + res = evalue_from_section_array(sections->s, sections->ns); if (nvar > 1) { - evalue *tmp = Bernoulli_sum_evalue(res, nvar-1, options); + evalue *tmp = barvinok_summate(res, nvar-1, options); evalue_free(res); res = tmp; } @@ -829,13 +818,9 @@ static evalue *sum_over_polytope_base(Polyhedron *P, evalue *E, unsigned nvar, return res; } -static evalue *sum_over_polytope(Polyhedron *P, evalue *E, unsigned nvar, - struct Bernoulli_data *data, - struct barvinok_options *options); - static evalue *sum_over_polytope_with_equalities(Polyhedron *P, evalue *E, unsigned nvar, - struct Bernoulli_data *data, + struct evalue_section_array *sections, struct barvinok_options *options) { unsigned dim = P->Dimension; @@ -887,7 +872,7 @@ static evalue *sum_over_polytope_with_equalities(Polyhedron *P, evalue *E, free(subs); if (new_dim-new_nparam > 0) { - sum = sum_over_polytope(P, E, new_dim-new_nparam, data, options); + sum = bernoulli_summate(P, E, new_dim-new_nparam, sections, options); evalue_free(E); Polyhedron_Free(P); } else { @@ -918,7 +903,7 @@ static evalue *sum_over_polytope_with_equalities(Polyhedron *P, evalue *E, static evalue *sum_over_polytope_slices(Polyhedron *P, evalue *E, unsigned nvar, Value period, - struct Bernoulli_data *data, + struct evalue_section_array *sections, struct barvinok_options *options) { evalue *sum = evalue_zero(); @@ -952,9 +937,9 @@ static evalue *sum_over_polytope_slices(Polyhedron *P, evalue *E, reduce_evalue(e); if (S->NbEq) - tmp = sum_over_polytope_with_equalities(S, e, nvar, data, options); + tmp = sum_over_polytope_with_equalities(S, e, nvar, sections, options); else - tmp = sum_over_polytope_base(S, e, nvar, data, options); + tmp = sum_over_polytope_base(S, e, nvar, sections, options); assert(tmp); eadd(tmp, sum); @@ -978,8 +963,8 @@ static evalue *sum_over_polytope_slices(Polyhedron *P, evalue *E, return sum; } -static evalue *sum_over_polytope(Polyhedron *P, evalue *E, unsigned nvar, - struct Bernoulli_data *data, +evalue *bernoulli_summate(Polyhedron *P, evalue *E, unsigned nvar, + struct evalue_section_array *sections, struct barvinok_options *options) { Polyhedron *P_orig = P; @@ -989,15 +974,15 @@ static evalue *sum_over_polytope(Polyhedron *P, evalue *E, unsigned nvar, int exact = options->approximation_method == BV_APPROX_NONE; if (P->NbEq) - return sum_over_polytope_with_equalities(P, E, nvar, data, options); + return sum_over_polytope_with_equalities(P, E, nvar, sections, options); value_init(period); move_best_to_front(&P, &E, nvar, exact ? &period : NULL); if (exact && value_notone_p(period)) - sum = sum_over_polytope_slices(P, E, nvar, period, data, options); + sum = sum_over_polytope_slices(P, E, nvar, period, sections, options); else - sum = sum_over_polytope_base(P, E, nvar, data, options); + sum = sum_over_polytope_base(P, E, nvar, sections, options); if (P != P_orig) Polyhedron_Free(P); @@ -1008,47 +993,3 @@ static evalue *sum_over_polytope(Polyhedron *P, evalue *E, unsigned nvar, return sum; } - -evalue *Bernoulli_sum_evalue(evalue *e, unsigned nvar, - struct barvinok_options *options) -{ - struct Bernoulli_data data; - int i, j; - evalue *sum = evalue_zero(); - - if (EVALUE_IS_ZERO(*e)) - return sum; - - if (nvar == 0) { - eadd(e, sum); - return sum; - } - - assert(value_zero_p(e->d)); - assert(e->x.p->type == partition); - - data.size = 16; - data.s = ALLOCN(struct evalue_section, data.size); - data.options = options; - - for (i = 0; i < e->x.p->size/2; ++i) { - Polyhedron *D; - for (D = EVALUE_DOMAIN(e->x.p->arr[2*i]); D; D = D->next) { - Polyhedron *next = D->next; - evalue *tmp; - D->next = NULL; - - tmp = sum_over_polytope(D, &e->x.p->arr[2*i+1], nvar, &data, options); - assert(tmp); - eadd(tmp, sum); - evalue_free(tmp); - - D->next = next; - } - } - - free(data.s); - - reduce_evalue(sum); - return sum; -} diff --git a/bernoulli.h b/bernoulli.h index bd53fb5..fb07af6 100644 --- a/bernoulli.h +++ b/bernoulli.h @@ -1,4 +1,5 @@ #include +#include "section_array.h" #if defined(__cplusplus) extern "C" { @@ -38,8 +39,9 @@ struct poly_list *faulhaber_compute(int n); */ struct poly_list *bernoulli_compute(int n); -evalue *Bernoulli_sum_evalue(evalue *e, unsigned nvar, - struct barvinok_options *options); +evalue *bernoulli_summate(Polyhedron *P, evalue *E, unsigned nvar, + struct evalue_section_array *sections, + struct barvinok_options *options); #if defined(__cplusplus) } diff --git a/euler.cc b/euler.cc index 81874fb..39a22a6 100644 --- a/euler.cc +++ b/euler.cc @@ -919,7 +919,7 @@ static unsigned *active_constraints(Param_Polyhedron *PP, Param_Domain *D) return facets; } -static evalue *summate_over_domain(evalue *e, int nvar, Polyhedron *D, +evalue *euler_summate(Polyhedron *P, evalue *e, unsigned nvar, struct barvinok_options *options) { Polyhedron *U; @@ -930,16 +930,18 @@ static evalue *summate_over_domain(evalue *e, int nvar, Polyhedron *D, struct evalue_section *s; Param_Domain *PD; + assert(nvar <= 2); + MaxRays = options->MaxRays; POL_UNSET(options->MaxRays, POL_INTEGER); - U = Universe_Polyhedron(D->Dimension - nvar); - PP = Polyhedron2Param_Polyhedron(D, U, options); + U = Universe_Polyhedron(P->Dimension - nvar); + PP = Polyhedron2Param_Polyhedron(P, U, options); for (nd = 0, PD = PP->D; PD; ++nd, PD = PD->next); s = ALLOCN(struct evalue_section, nd); - Polyhedron *TC = true_context(D, U, MaxRays); + Polyhedron *TC = true_context(P, U, MaxRays); FORALL_REDUCED_DOMAIN(PP, TC, nd, options, i, PD, rVD) unsigned *facets; @@ -970,31 +972,3 @@ static evalue *summate_over_domain(evalue *e, int nvar, Polyhedron *D, return res; } - -evalue *euler_summate(evalue *e, unsigned nvar, - struct barvinok_options *options) -{ - int i; - evalue *res; - - assert(nvar <= 2); - - assert(nvar >= 0); - if (nvar == 0 || EVALUE_IS_ZERO(*e)) - return evalue_dup(e); - - assert(value_zero_p(e->d)); - assert(e->x.p->type == partition); - - res = evalue_zero(); - - for (i = 0; i < e->x.p->size/2; ++i) { - evalue *t; - t = summate_over_domain(&e->x.p->arr[2*i+1], nvar, - EVALUE_DOMAIN(e->x.p->arr[2*i]), options); - eadd(t, res); - evalue_free(t); - } - - return res; -} diff --git a/euler.h b/euler.h index 4be0e59..233637f 100644 --- a/euler.h +++ b/euler.h @@ -6,8 +6,8 @@ extern "C" { struct barvinok_options; -evalue *euler_summate(evalue *e, unsigned nvar, - struct barvinok_options *options); +evalue *euler_summate(Polyhedron *P, evalue *e, unsigned nvar, + struct barvinok_options *options); #if defined(__cplusplus) } diff --git a/evalue.c b/evalue.c index 4d89a37..36a125d 100644 --- a/evalue.c +++ b/evalue.c @@ -16,6 +16,7 @@ #include #include #include +#include "summate.h" #ifndef value_pmodulus #define value_pmodulus(ref,val1,val2) (mpz_fdiv_r((ref),(val1),(val2))) @@ -951,7 +952,8 @@ static void _reduce_evalue_in_domain(evalue *e, Polyhedron *D, struct subst *s) void reduce_evalue_in_domain(evalue *e, Polyhedron *D) { struct subst s = { NULL, 0, 0 }; - if (emptyQ2(D)) { + POL_ENSURE_VERTICES(D); + if (emptyQ(D)) { if (EVALUE_IS_ZERO(*e)) return; free_evalue_refs(e); @@ -3532,6 +3534,53 @@ static evalue *esum_over_domain(evalue *e, int nvar, Polyhedron *D, return res; } +static Polyhedron_Insert(Polyhedron ***next, Polyhedron *Q) +{ + if (emptyQ(Q)) + Polyhedron_Free(Q); + else { + **next = Q; + *next = &(Q->next); + } +} + +static Polyhedron *Polyhedron_Split_Into_Orthants(Polyhedron *P, + unsigned MaxRays) +{ + int i = 0; + Polyhedron *D = P; + Vector *c = Vector_Alloc(1 + P->Dimension + 1); + value_set_si(c->p[0], 1); + + if (P->Dimension == 0) + return Polyhedron_Copy(P); + + for (i = 0; i < P->Dimension; ++i) { + Polyhedron *L = NULL; + Polyhedron **next = &L; + Polyhedron *I; + + for (I = D; I; I = I->next) { + Polyhedron *Q; + value_set_si(c->p[1+i], 1); + value_set_si(c->p[1+P->Dimension], 0); + Q = AddConstraints(c->p, 1, I, MaxRays); + Polyhedron_Insert(&next, Q); + value_set_si(c->p[1+i], -1); + value_set_si(c->p[1+P->Dimension], -1); + Q = AddConstraints(c->p, 1, I, MaxRays); + Polyhedron_Insert(&next, Q); + value_set_si(c->p[1+i], 0); + } + if (D != P) + Domain_Free(D); + D = L; + } + Vector_Free(c); + return D; +} + +/* Make arguments of all floors non-negative */ static void shift_floor_in_domain(evalue *e, Polyhedron *D) { Value d, m; @@ -3593,57 +3642,28 @@ static void shift_floor_in_domain(evalue *e, Polyhedron *D) value_clear(m); } -/* Make arguments of all floors non-negative */ -static void shift_floor_arguments(evalue *e) +evalue *box_summate(Polyhedron *P, evalue *E, unsigned nvar, unsigned MaxRays) { - int i; - - if (value_notzero_p(e->d) || e->x.p->type != partition) - return; - - for (i = 0; i < e->x.p->size/2; ++i) - shift_floor_in_domain(&e->x.p->arr[2*i+1], - EVALUE_DOMAIN(e->x.p->arr[2*i])); -} - -evalue *evalue_sum(evalue *e, int nvar, unsigned MaxRays) -{ - int i; - evalue *res = ALLOC(evalue); - value_init(res->d); - - assert(nvar >= 0); - if (nvar == 0 || EVALUE_IS_ZERO(*e)) { - evalue_copy(res, e); - return res; - } - - evalue_split_domains_into_orthants(e, MaxRays); - reduce_evalue(e); - evalue_frac2floor2(e, 0); - evalue_set_si(res, 0, 1); - - assert(value_zero_p(e->d)); - assert(e->x.p->type == partition); - shift_floor_arguments(e); - - for (i = 0; i < e->x.p->size/2; ++i) { + evalue *sum = evalue_zero(); + Polyhedron *D = Polyhedron_Split_Into_Orthants(P, MaxRays); + for (P = D; P; P = P->next) { evalue *t; - t = esum_over_domain(&e->x.p->arr[2*i+1], nvar, - EVALUE_DOMAIN(e->x.p->arr[2*i]), NULL, 0, - MaxRays); - eadd(t, res); - evalue_free(t); + evalue *fe = evalue_dup(E); + Polyhedron *next = P->next; + P->next = NULL; + reduce_evalue_in_domain(fe, P); + evalue_frac2floor2(fe, 0); + shift_floor_in_domain(fe, P); + t = esum_over_domain(fe, nvar, P, NULL, NULL, MaxRays); + if (t) { + eadd(t, sum); + evalue_free(t); + } + evalue_free(fe); + P->next = next; } - - reduce_evalue(res); - - return res; -} - -evalue *esum(evalue *e, int nvar) -{ - return evalue_sum(e, nvar, 0); + Domain_Free(D); + return sum; } /* Initial silly implementation */ diff --git a/laurent.cc b/laurent.cc index 314778c..70b382a 100644 --- a/laurent.cc +++ b/laurent.cc @@ -756,9 +756,8 @@ void laurent_summator::handle(const signed_cone& sc, barvinok_options *options) vc.clear(); } -static evalue *summate_over_domain(const evalue *e, unsigned nvar, - Polyhedron *D, - struct barvinok_options *options) +evalue *laurent_summate(Polyhedron *P, evalue *e, unsigned nvar, + struct barvinok_options *options) { Polyhedron *U, *TC; Param_Polyhedron *PP; @@ -767,13 +766,13 @@ static evalue *summate_over_domain(const evalue *e, unsigned nvar, Param_Domain *PD; evalue *sum; - U = Universe_Polyhedron(D->Dimension - nvar); - PP = Polyhedron2Param_Polyhedron(D, U, options); + U = Universe_Polyhedron(P->Dimension - nvar); + PP = Polyhedron2Param_Polyhedron(P, U, options); for (nd = 0, PD = PP->D; PD; ++nd, PD = PD->next); s = ALLOCN(struct evalue_section, nd); - TC = true_context(D, U, options->MaxRays); + TC = true_context(P, U, options->MaxRays); FORALL_REDUCED_DOMAIN(PP, TC, nd, options, i, PD, rVD) Param_Vertices *V; laurent_summator ls(e, nvar, PP); @@ -795,29 +794,3 @@ static evalue *summate_over_domain(const evalue *e, unsigned nvar, return sum; } - -evalue *laurent_summate(evalue *e, unsigned nvar, - struct barvinok_options *options) -{ - int i; - evalue *res; - - assert(nvar >= 0); - if (nvar == 0 || EVALUE_IS_ZERO(*e)) - return evalue_dup(e); - - assert(value_zero_p(e->d)); - assert(e->x.p->type == partition); - - res = evalue_zero(); - - for (i = 0; i < e->x.p->size/2; ++i) { - evalue *t; - t = summate_over_domain(&e->x.p->arr[2*i+1], nvar, - EVALUE_DOMAIN(e->x.p->arr[2*i]), options); - eadd(t, res); - evalue_free(t); - } - - return res; -} diff --git a/laurent.h b/laurent.h index b0b0404..57bfaeb 100644 --- a/laurent.h +++ b/laurent.h @@ -6,8 +6,8 @@ extern "C" { struct barvinok_options; -evalue *laurent_summate(evalue *e, unsigned nvar, - struct barvinok_options *options); +evalue *laurent_summate(Polyhedron *P, evalue *e, unsigned nvar, + struct barvinok_options *options); #if defined(__cplusplus) } diff --git a/section_array.h b/section_array.h new file mode 100644 index 0000000..01f9a9c --- /dev/null +++ b/section_array.h @@ -0,0 +1,39 @@ +#ifndef SECTION_ARRAY_H +#define SECTION_ARRAY_H + +#include + +#define REALLOCN(ptr,type,n) (type*)realloc(ptr, (n) * sizeof(type)) + +struct evalue_section_array { + struct evalue_section *s; + int size; + int ns; +}; + +static void evalue_section_array_init(struct evalue_section_array *sections) +{ + sections->size = 0; + sections->ns = 0; + sections->s = NULL; +} + +static void evalue_section_array_ensure(struct evalue_section_array *sections, + int size) +{ + if (size <= sections->size) + return; + + sections->size = size + 32; + sections->s = REALLOCN(sections->s, struct evalue_section, sections->size); +} + +static void evalue_section_array_add(struct evalue_section_array *sections, + Polyhedron *D, evalue *e) +{ + sections->s[sections->ns].E = e; + sections->s[sections->ns].D = D; + ++sections->ns; +} + +#endif diff --git a/summate.c b/summate.c index e2be5ba..881578a 100644 --- a/summate.c +++ b/summate.c @@ -3,17 +3,78 @@ #include "euler.h" #include "laurent.h" #include "summate.h" +#include "section_array.h" -evalue *barvinok_summate(evalue *e, int nvar, struct barvinok_options *options) +static evalue *sum_over_polytope(Polyhedron *P, evalue *E, unsigned nvar, + struct evalue_section_array *sections, + struct barvinok_options *options) { if (options->summation == BV_SUM_EULER) - return euler_summate(e, nvar, options); + return euler_summate(P, E, nvar, options); else if (options->summation == BV_SUM_LAURENT) - return laurent_summate(e, nvar, options); + return laurent_summate(P, E, nvar, options); else if (options->summation == BV_SUM_BERNOULLI) - return Bernoulli_sum_evalue(e, nvar, options); + return bernoulli_summate(P, E, nvar, sections, options); else - return evalue_sum(e, nvar, options->MaxRays); + return box_summate(P, E, nvar, options->MaxRays); +} + +evalue *barvinok_summate(evalue *e, int nvar, struct barvinok_options *options) +{ + int i; + struct evalue_section_array sections; + evalue *sum; + + assert(nvar >= 0); + if (nvar == 0 || EVALUE_IS_ZERO(*e)) + return evalue_dup(e); + + assert(value_zero_p(e->d)); + assert(e->x.p->type == partition); + + evalue_section_array_init(§ions); + sum = evalue_zero(); + + for (i = 0; i < e->x.p->size/2; ++i) { + Polyhedron *D; + for (D = EVALUE_DOMAIN(e->x.p->arr[2*i]); D; D = D->next) { + Polyhedron *next = D->next; + evalue *tmp; + D->next = NULL; + + tmp = sum_over_polytope(D, &e->x.p->arr[2*i+1], nvar, + §ions, options); + assert(tmp); + eadd(tmp, sum); + evalue_free(tmp); + + D->next = next; + } + } + + free(sections.s); + + reduce_evalue(sum); + return sum; +} + +evalue *evalue_sum(evalue *E, int nvar, unsigned MaxRays) +{ + evalue *sum; + struct barvinok_options *options = barvinok_options_new_with_defaults(); + options->MaxRays = MaxRays; + sum = barvinok_summate(E, nvar, options); + barvinok_options_free(options); + return sum; +} + +evalue *esum(evalue *e, int nvar) +{ + evalue *sum; + struct barvinok_options *options = barvinok_options_new_with_defaults(); + sum = barvinok_summate(e, nvar, options); + barvinok_options_free(options); + return sum; } /* Turn unweighted counting problem into "weighted" counting problem diff --git a/summate.h b/summate.h index 2352167..f4d983f 100644 --- a/summate.h +++ b/summate.h @@ -6,6 +6,7 @@ struct barvinok_options; extern "C" { #endif +evalue *box_summate(Polyhedron *P, evalue *E, unsigned nvar, unsigned MaxRays); evalue *barvinok_summate_unweighted(Polyhedron *P, Polyhedron *C, struct barvinok_options *options); diff --git a/testlib.cc b/testlib.cc index 586a2db..f49e6b5 100644 --- a/testlib.cc +++ b/testlib.cc @@ -541,6 +541,9 @@ int test_bernoulli(struct barvinok_options *options) int test_bernoulli_sum(struct barvinok_options *options) { + int summation = options->summation; + options->summation = BV_SUM_BERNOULLI; + unsigned nvar, nparam; char **all_vars; evalue *e, *sum1, *sum2; @@ -549,7 +552,7 @@ int test_bernoulli_sum(struct barvinok_options *options) options->MaxRays); Free_ParamNames(all_vars, nvar+nparam); - sum1 = Bernoulli_sum_evalue(e, 1, options); + sum1 = barvinok_summate(e, 1, options); sum2 = evalue_read_from_str("n -1 >= 0\n\n (1/3 * n^3 + 2/3 * n)", NULL, &all_vars, &nvar, &nparam, options->MaxRays); @@ -565,7 +568,7 @@ int test_bernoulli_sum(struct barvinok_options *options) "i", &all_vars, &nvar, &nparam, options->MaxRays); Free_ParamNames(all_vars, nvar+nparam); - sum1 = Bernoulli_sum_evalue(e, 1, options); + sum1 = barvinok_summate(e, 1, options); evalue_negate(sum1); eadd(sum2, sum1); reduce_evalue(sum1); @@ -579,7 +582,7 @@ int test_bernoulli_sum(struct barvinok_options *options) "i", &all_vars, &nvar, &nparam, options->MaxRays); Free_ParamNames(all_vars, nvar+nparam); - sum1 = Bernoulli_sum_evalue(e, 1, options); + sum1 = barvinok_summate(e, 1, options); sum2 = evalue_read_from_str("n + 0 >= 0\n\n (1/2 * n^2 + 1/2 * n + (-10))\n" "n + 4 >= 0\n -n -1 >= 0\n\n (1/2 * n^2 + 1/2 * n + (-10))", NULL, &all_vars, &nvar, &nparam, @@ -598,7 +601,7 @@ int test_bernoulli_sum(struct barvinok_options *options) "i,j,k", &all_vars, &nvar, &nparam, options->MaxRays); Free_ParamNames(all_vars, nvar+nparam); - sum1 = Bernoulli_sum_evalue(e, 3, options); + sum1 = barvinok_summate(e, 3, options); sum2 = evalue_read_from_str("n -5 >= 0\n\n" "1/6 * n^3 + 1/2 * n^2 + 1/3 * n + -20", NULL, &all_vars, &nvar, &nparam, @@ -611,6 +614,8 @@ int test_bernoulli_sum(struct barvinok_options *options) evalue_free(e); evalue_free(sum1); evalue_free(sum2); + + options->summation = summation; } int test_hilbert(struct barvinok_options *options) @@ -732,7 +737,10 @@ static int test_laurent(struct barvinok_options *options) options->MaxRays); Free_ParamNames(all_vars, nvar+nparam); - sum = laurent_summate(e, nvar, options); + int summation = options->summation; + options->summation = BV_SUM_LAURENT; + sum = barvinok_summate(e, nvar, options); + options->summation = summation; res = evalue_read_from_str("(6 * N + 4 * M)", "", &all_vars, &nvar, &nparam, -- 2.11.4.GIT