LCOV - code coverage report
Current view: top level - metalib_isl - isl_bernstein.c (source / functions) Hit Total Coverage
Test: 2018-10-31_point_maint_greina16.lcov Lines: 0 271 0.0 %
Date: 2018-11-01 11:27:00 Functions: 0 11 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2006-2007 Universiteit Leiden
       3             :  * Copyright 2008-2009 Katholieke Universiteit Leuven
       4             :  * Copyright 2010      INRIA Saclay
       5             :  *
       6             :  * Use of this software is governed by the MIT license
       7             :  *
       8             :  * Written by Sven Verdoolaege, Leiden Institute of Advanced Computer Science,
       9             :  * Universiteit Leiden, Niels Bohrweg 1, 2333 CA Leiden, The Netherlands
      10             :  * and K.U.Leuven, Departement Computerwetenschappen, Celestijnenlaan 200A,
      11             :  * B-3001 Leuven, Belgium
      12             :  * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
      13             :  * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France
      14             :  */
      15             : 
      16             : #include <isl_ctx_private.h>
      17             : #include <isl_map_private.h>
      18             : #include <isl/set.h>
      19             : #include <isl_seq.h>
      20             : #include <isl_morph.h>
      21             : #include <isl_factorization.h>
      22             : #include <isl_vertices_private.h>
      23             : #include <isl_polynomial_private.h>
      24             : #include <isl_options_private.h>
      25             : #include <isl_vec_private.h>
      26             : #include <isl_bernstein.h>
      27             : 
      28             : struct bernstein_data {
      29             :         enum isl_fold type;
      30             :         isl_qpolynomial *poly;
      31             :         int check_tight;
      32             : 
      33             :         isl_cell *cell;
      34             : 
      35             :         isl_qpolynomial_fold *fold;
      36             :         isl_qpolynomial_fold *fold_tight;
      37             :         isl_pw_qpolynomial_fold *pwf;
      38             :         isl_pw_qpolynomial_fold *pwf_tight;
      39             : };
      40             : 
      41           0 : static int vertex_is_integral(__isl_keep isl_basic_set *vertex)
      42             : {
      43             :         unsigned nvar;
      44             :         unsigned nparam;
      45             :         int i;
      46             : 
      47           0 :         nvar = isl_basic_set_dim(vertex, isl_dim_set);
      48           0 :         nparam = isl_basic_set_dim(vertex, isl_dim_param);
      49           0 :         for (i = 0; i < nvar; ++i) {
      50           0 :                 int r = nvar - 1 - i;
      51           0 :                 if (!isl_int_is_one(vertex->eq[r][1 + nparam + i]) &&
      52           0 :                     !isl_int_is_negone(vertex->eq[r][1 + nparam + i]))
      53           0 :                         return 0;
      54             :         }
      55             : 
      56           0 :         return 1;
      57             : }
      58             : 
      59           0 : static __isl_give isl_qpolynomial *vertex_coordinate(
      60             :         __isl_keep isl_basic_set *vertex, int i, __isl_take isl_space *dim)
      61             : {
      62             :         unsigned nvar;
      63             :         unsigned nparam;
      64             :         int r;
      65             :         isl_int denom;
      66             :         isl_qpolynomial *v;
      67             : 
      68           0 :         nvar = isl_basic_set_dim(vertex, isl_dim_set);
      69           0 :         nparam = isl_basic_set_dim(vertex, isl_dim_param);
      70           0 :         r = nvar - 1 - i;
      71             : 
      72           0 :         isl_int_init(denom);
      73           0 :         isl_int_set(denom, vertex->eq[r][1 + nparam + i]);
      74           0 :         isl_assert(vertex->ctx, !isl_int_is_zero(denom), goto error);
      75             : 
      76           0 :         if (isl_int_is_pos(denom))
      77           0 :                 isl_seq_neg(vertex->eq[r], vertex->eq[r],
      78           0 :                                 1 + isl_basic_set_total_dim(vertex));
      79             :         else
      80           0 :                 isl_int_neg(denom, denom);
      81             : 
      82           0 :         v = isl_qpolynomial_from_affine(dim, vertex->eq[r], denom);
      83           0 :         isl_int_clear(denom);
      84             : 
      85           0 :         return v;
      86             : error:
      87           0 :         isl_space_free(dim);
      88           0 :         isl_int_clear(denom);
      89           0 :         return NULL;
      90             : }
      91             : 
      92             : /* Check whether the bound associated to the selection "k" is tight,
      93             :  * which is the case if we select exactly one vertex and if that vertex
      94             :  * is integral for all values of the parameters.
      95             :  */
      96           0 : static int is_tight(int *k, int n, int d, isl_cell *cell)
      97             : {
      98             :         int i;
      99             : 
     100           0 :         for (i = 0; i < n; ++i) {
     101             :                 int v;
     102           0 :                 if (k[i] != d) {
     103           0 :                         if (k[i])
     104           0 :                                 return 0;
     105           0 :                         continue;
     106             :                 }
     107           0 :                 v = cell->ids[n - 1 - i];
     108           0 :                 return vertex_is_integral(cell->vertices->v[v].vertex);
     109             :         }
     110             : 
     111           0 :         return 0;
     112             : }
     113             : 
     114           0 : static void add_fold(__isl_take isl_qpolynomial *b, __isl_keep isl_set *dom,
     115             :         int *k, int n, int d, struct bernstein_data *data)
     116             : {
     117             :         isl_qpolynomial_fold *fold;
     118             : 
     119           0 :         fold = isl_qpolynomial_fold_alloc(data->type, b);
     120             : 
     121           0 :         if (data->check_tight && is_tight(k, n, d, data->cell))
     122           0 :                 data->fold_tight = isl_qpolynomial_fold_fold_on_domain(dom,
     123             :                                                         data->fold_tight, fold);
     124             :         else
     125           0 :                 data->fold = isl_qpolynomial_fold_fold_on_domain(dom,
     126             :                                                         data->fold, fold);
     127           0 : }
     128             : 
     129             : /* Extract the coefficients of the Bernstein base polynomials and store
     130             :  * them in data->fold and data->fold_tight.
     131             :  *
     132             :  * In particular, the coefficient of each monomial
     133             :  * of multi-degree (k[0], k[1], ..., k[n-1]) is divided by the corresponding
     134             :  * multinomial coefficient d!/k[0]! k[1]! ... k[n-1]!
     135             :  *
     136             :  * c[i] contains the coefficient of the selected powers of the first i+1 vars.
     137             :  * multinom[i] contains the partial multinomial coefficient.
     138             :  */
     139           0 : static void extract_coefficients(isl_qpolynomial *poly,
     140             :         __isl_keep isl_set *dom, struct bernstein_data *data)
     141             : {
     142             :         int i;
     143             :         int d;
     144             :         int n;
     145             :         isl_ctx *ctx;
     146           0 :         isl_qpolynomial **c = NULL;
     147           0 :         int *k = NULL;
     148           0 :         int *left = NULL;
     149           0 :         isl_vec *multinom = NULL;
     150             : 
     151           0 :         if (!poly)
     152           0 :                 return;
     153             : 
     154           0 :         ctx = isl_qpolynomial_get_ctx(poly);
     155           0 :         n = isl_qpolynomial_dim(poly, isl_dim_in);
     156           0 :         d = isl_qpolynomial_degree(poly);
     157           0 :         isl_assert(ctx, n >= 2, return);
     158             : 
     159           0 :         c = isl_calloc_array(ctx, isl_qpolynomial *, n);
     160           0 :         k = isl_alloc_array(ctx, int, n);
     161           0 :         left = isl_alloc_array(ctx, int, n);
     162           0 :         multinom = isl_vec_alloc(ctx, n);
     163           0 :         if (!c || !k || !left || !multinom)
     164             :                 goto error;
     165             : 
     166           0 :         isl_int_set_si(multinom->el[0], 1);
     167           0 :         for (k[0] = d; k[0] >= 0; --k[0]) {
     168           0 :                 int i = 1;
     169           0 :                 isl_qpolynomial_free(c[0]);
     170           0 :                 c[0] = isl_qpolynomial_coeff(poly, isl_dim_in, n - 1, k[0]);
     171           0 :                 left[0] = d - k[0];
     172           0 :                 k[1] = -1;
     173           0 :                 isl_int_set(multinom->el[1], multinom->el[0]);
     174           0 :                 while (i > 0) {
     175           0 :                         if (i == n - 1) {
     176             :                                 int j;
     177             :                                 isl_space *dim;
     178             :                                 isl_qpolynomial *b;
     179             :                                 isl_qpolynomial *f;
     180           0 :                                 for (j = 2; j <= left[i - 1]; ++j)
     181           0 :                                         isl_int_divexact_ui(multinom->el[i],
     182             :                                                 multinom->el[i], j);
     183           0 :                                 b = isl_qpolynomial_coeff(c[i - 1], isl_dim_in,
     184           0 :                                         n - 1 - i, left[i - 1]);
     185           0 :                                 b = isl_qpolynomial_project_domain_on_params(b);
     186           0 :                                 dim = isl_qpolynomial_get_domain_space(b);
     187           0 :                                 f = isl_qpolynomial_rat_cst_on_domain(dim, ctx->one,
     188           0 :                                         multinom->el[i]);
     189           0 :                                 b = isl_qpolynomial_mul(b, f);
     190           0 :                                 k[n - 1] = left[n - 2];
     191           0 :                                 add_fold(b, dom, k, n, d, data);
     192           0 :                                 --i;
     193           0 :                                 continue;
     194             :                         }
     195           0 :                         if (k[i] >= left[i - 1]) {
     196           0 :                                 --i;
     197           0 :                                 continue;
     198             :                         }
     199           0 :                         ++k[i];
     200           0 :                         if (k[i])
     201           0 :                                 isl_int_divexact_ui(multinom->el[i],
     202             :                                         multinom->el[i], k[i]);
     203           0 :                         isl_qpolynomial_free(c[i]);
     204           0 :                         c[i] = isl_qpolynomial_coeff(c[i - 1], isl_dim_in,
     205           0 :                                         n - 1 - i, k[i]);
     206           0 :                         left[i] = left[i - 1] - k[i];
     207           0 :                         k[i + 1] = -1;
     208           0 :                         isl_int_set(multinom->el[i + 1], multinom->el[i]);
     209           0 :                         ++i;
     210             :                 }
     211           0 :                 isl_int_mul_ui(multinom->el[0], multinom->el[0], k[0]);
     212             :         }
     213             : 
     214           0 :         for (i = 0; i < n; ++i)
     215           0 :                 isl_qpolynomial_free(c[i]);
     216             : 
     217           0 :         isl_vec_free(multinom);
     218           0 :         free(left);
     219           0 :         free(k);
     220           0 :         free(c);
     221           0 :         return;
     222             : error:
     223           0 :         isl_vec_free(multinom);
     224           0 :         free(left);
     225           0 :         free(k);
     226           0 :         if (c)
     227           0 :                 for (i = 0; i < n; ++i)
     228           0 :                         isl_qpolynomial_free(c[i]);
     229           0 :         free(c);
     230           0 :         return;
     231             : }
     232             : 
     233             : /* Perform bernstein expansion on the parametric vertices that are active
     234             :  * on "cell".
     235             :  *
     236             :  * data->poly has been homogenized in the calling function.
     237             :  *
     238             :  * We plug in the barycentric coordinates for the set variables
     239             :  *
     240             :  *              \vec x = \sum_i \alpha_i v_i(\vec p)
     241             :  *
     242             :  * and the constant "1 = \sum_i \alpha_i" for the homogeneous dimension.
     243             :  * Next, we extract the coefficients of the Bernstein base polynomials.
     244             :  */
     245           0 : static isl_stat bernstein_coefficients_cell(__isl_take isl_cell *cell,
     246             :         void *user)
     247             : {
     248             :         int i, j;
     249           0 :         struct bernstein_data *data = (struct bernstein_data *)user;
     250             :         isl_space *dim_param;
     251             :         isl_space *dim_dst;
     252           0 :         isl_qpolynomial *poly = data->poly;
     253             :         unsigned nvar;
     254             :         int n_vertices;
     255             :         isl_qpolynomial **subs;
     256             :         isl_pw_qpolynomial_fold *pwf;
     257             :         isl_set *dom;
     258             :         isl_ctx *ctx;
     259             : 
     260           0 :         if (!poly)
     261           0 :                 goto error;
     262             : 
     263           0 :         nvar = isl_qpolynomial_dim(poly, isl_dim_in) - 1;
     264           0 :         n_vertices = cell->n_vertices;
     265             : 
     266           0 :         ctx = isl_qpolynomial_get_ctx(poly);
     267           0 :         if (n_vertices > nvar + 1 && ctx->opt->bernstein_triangulate)
     268           0 :                 return isl_cell_foreach_simplex(cell,
     269             :                                             &bernstein_coefficients_cell, user);
     270             : 
     271           0 :         subs = isl_alloc_array(ctx, isl_qpolynomial *, 1 + nvar);
     272           0 :         if (!subs)
     273           0 :                 goto error;
     274             : 
     275           0 :         dim_param = isl_basic_set_get_space(cell->dom);
     276           0 :         dim_dst = isl_qpolynomial_get_domain_space(poly);
     277           0 :         dim_dst = isl_space_add_dims(dim_dst, isl_dim_set, n_vertices);
     278             : 
     279           0 :         for (i = 0; i < 1 + nvar; ++i)
     280           0 :                 subs[i] = isl_qpolynomial_zero_on_domain(isl_space_copy(dim_dst));
     281             : 
     282           0 :         for (i = 0; i < n_vertices; ++i) {
     283             :                 isl_qpolynomial *c;
     284           0 :                 c = isl_qpolynomial_var_on_domain(isl_space_copy(dim_dst), isl_dim_set,
     285           0 :                                         1 + nvar + i);
     286           0 :                 for (j = 0; j < nvar; ++j) {
     287           0 :                         int k = cell->ids[i];
     288             :                         isl_qpolynomial *v;
     289           0 :                         v = vertex_coordinate(cell->vertices->v[k].vertex, j,
     290             :                                                 isl_space_copy(dim_param));
     291           0 :                         v = isl_qpolynomial_add_dims(v, isl_dim_in,
     292           0 :                                                         1 + nvar + n_vertices);
     293           0 :                         v = isl_qpolynomial_mul(v, isl_qpolynomial_copy(c));
     294           0 :                         subs[1 + j] = isl_qpolynomial_add(subs[1 + j], v);
     295             :                 }
     296           0 :                 subs[0] = isl_qpolynomial_add(subs[0], c);
     297             :         }
     298           0 :         isl_space_free(dim_dst);
     299             : 
     300           0 :         poly = isl_qpolynomial_copy(poly);
     301             : 
     302           0 :         poly = isl_qpolynomial_add_dims(poly, isl_dim_in, n_vertices);
     303           0 :         poly = isl_qpolynomial_substitute(poly, isl_dim_in, 0, 1 + nvar, subs);
     304           0 :         poly = isl_qpolynomial_drop_dims(poly, isl_dim_in, 0, 1 + nvar);
     305             : 
     306           0 :         data->cell = cell;
     307           0 :         dom = isl_set_from_basic_set(isl_basic_set_copy(cell->dom));
     308           0 :         data->fold = isl_qpolynomial_fold_empty(data->type, isl_space_copy(dim_param));
     309           0 :         data->fold_tight = isl_qpolynomial_fold_empty(data->type, dim_param);
     310           0 :         extract_coefficients(poly, dom, data);
     311             : 
     312           0 :         pwf = isl_pw_qpolynomial_fold_alloc(data->type, isl_set_copy(dom),
     313             :                                             data->fold);
     314           0 :         data->pwf = isl_pw_qpolynomial_fold_fold(data->pwf, pwf);
     315           0 :         pwf = isl_pw_qpolynomial_fold_alloc(data->type, dom, data->fold_tight);
     316           0 :         data->pwf_tight = isl_pw_qpolynomial_fold_fold(data->pwf_tight, pwf);
     317             : 
     318           0 :         isl_qpolynomial_free(poly);
     319           0 :         isl_cell_free(cell);
     320           0 :         for (i = 0; i < 1 + nvar; ++i)
     321           0 :                 isl_qpolynomial_free(subs[i]);
     322           0 :         free(subs);
     323           0 :         return isl_stat_ok;
     324             : error:
     325           0 :         isl_cell_free(cell);
     326           0 :         return isl_stat_error;
     327             : }
     328             : 
     329             : /* Base case of applying bernstein expansion.
     330             :  *
     331             :  * We compute the chamber decomposition of the parametric polytope "bset"
     332             :  * and then perform bernstein expansion on the parametric vertices
     333             :  * that are active on each chamber.
     334             :  */
     335           0 : static __isl_give isl_pw_qpolynomial_fold *bernstein_coefficients_base(
     336             :         __isl_take isl_basic_set *bset,
     337             :         __isl_take isl_qpolynomial *poly, struct bernstein_data *data, int *tight)
     338             : {
     339             :         unsigned nvar;
     340             :         isl_space *dim;
     341             :         isl_pw_qpolynomial_fold *pwf;
     342             :         isl_vertices *vertices;
     343             :         int covers;
     344             : 
     345           0 :         nvar = isl_basic_set_dim(bset, isl_dim_set);
     346           0 :         if (nvar == 0) {
     347             :                 isl_set *dom;
     348             :                 isl_qpolynomial_fold *fold;
     349             : 
     350           0 :                 fold = isl_qpolynomial_fold_alloc(data->type, poly);
     351           0 :                 dom = isl_set_from_basic_set(bset);
     352           0 :                 if (tight)
     353           0 :                         *tight = 1;
     354           0 :                 pwf = isl_pw_qpolynomial_fold_alloc(data->type, dom, fold);
     355           0 :                 return isl_pw_qpolynomial_fold_project_domain_on_params(pwf);
     356             :         }
     357             : 
     358           0 :         if (isl_qpolynomial_is_zero(poly)) {
     359             :                 isl_set *dom;
     360             :                 isl_qpolynomial_fold *fold;
     361           0 :                 fold = isl_qpolynomial_fold_alloc(data->type, poly);
     362           0 :                 dom = isl_set_from_basic_set(bset);
     363           0 :                 pwf = isl_pw_qpolynomial_fold_alloc(data->type, dom, fold);
     364           0 :                 if (tight)
     365           0 :                         *tight = 1;
     366           0 :                 return isl_pw_qpolynomial_fold_project_domain_on_params(pwf);
     367             :         }
     368             : 
     369           0 :         dim = isl_basic_set_get_space(bset);
     370           0 :         dim = isl_space_params(dim);
     371           0 :         dim = isl_space_from_domain(dim);
     372           0 :         dim = isl_space_add_dims(dim, isl_dim_set, 1);
     373           0 :         data->pwf = isl_pw_qpolynomial_fold_zero(isl_space_copy(dim), data->type);
     374           0 :         data->pwf_tight = isl_pw_qpolynomial_fold_zero(dim, data->type);
     375           0 :         data->poly = isl_qpolynomial_homogenize(isl_qpolynomial_copy(poly));
     376           0 :         vertices = isl_basic_set_compute_vertices(bset);
     377           0 :         if (isl_vertices_foreach_disjoint_cell(vertices,
     378             :                                         &bernstein_coefficients_cell, data) < 0)
     379           0 :                 data->pwf = isl_pw_qpolynomial_fold_free(data->pwf);
     380           0 :         isl_vertices_free(vertices);
     381           0 :         isl_qpolynomial_free(data->poly);
     382             : 
     383           0 :         isl_basic_set_free(bset);
     384           0 :         isl_qpolynomial_free(poly);
     385             : 
     386           0 :         covers = isl_pw_qpolynomial_fold_covers(data->pwf_tight, data->pwf);
     387           0 :         if (covers < 0)
     388           0 :                 goto error;
     389             : 
     390           0 :         if (tight)
     391           0 :                 *tight = covers;
     392             : 
     393           0 :         if (covers) {
     394           0 :                 isl_pw_qpolynomial_fold_free(data->pwf);
     395           0 :                 return data->pwf_tight;
     396             :         }
     397             : 
     398           0 :         data->pwf = isl_pw_qpolynomial_fold_fold(data->pwf, data->pwf_tight);
     399             : 
     400           0 :         return data->pwf;
     401             : error:
     402           0 :         isl_pw_qpolynomial_fold_free(data->pwf_tight);
     403           0 :         isl_pw_qpolynomial_fold_free(data->pwf);
     404           0 :         return NULL;
     405             : }
     406             : 
     407             : /* Apply bernstein expansion recursively by working in on len[i]
     408             :  * set variables at a time, with i ranging from n_group - 1 to 0.
     409             :  */
     410           0 : static __isl_give isl_pw_qpolynomial_fold *bernstein_coefficients_recursive(
     411             :         __isl_take isl_pw_qpolynomial *pwqp,
     412             :         int n_group, int *len, struct bernstein_data *data, int *tight)
     413             : {
     414             :         int i;
     415             :         unsigned nparam;
     416             :         unsigned nvar;
     417             :         isl_pw_qpolynomial_fold *pwf;
     418             : 
     419           0 :         if (!pwqp)
     420           0 :                 return NULL;
     421             : 
     422           0 :         nparam = isl_pw_qpolynomial_dim(pwqp, isl_dim_param);
     423           0 :         nvar = isl_pw_qpolynomial_dim(pwqp, isl_dim_in);
     424             : 
     425           0 :         pwqp = isl_pw_qpolynomial_move_dims(pwqp, isl_dim_param, nparam,
     426           0 :                                         isl_dim_in, 0, nvar - len[n_group - 1]);
     427           0 :         pwf = isl_pw_qpolynomial_bound(pwqp, data->type, tight);
     428             : 
     429           0 :         for (i = n_group - 2; i >= 0; --i) {
     430           0 :                 nparam = isl_pw_qpolynomial_fold_dim(pwf, isl_dim_param);
     431           0 :                 pwf = isl_pw_qpolynomial_fold_move_dims(pwf, isl_dim_in, 0,
     432           0 :                                 isl_dim_param, nparam - len[i], len[i]);
     433           0 :                 if (tight && !*tight)
     434           0 :                         tight = NULL;
     435           0 :                 pwf = isl_pw_qpolynomial_fold_bound(pwf, tight);
     436             :         }
     437             : 
     438           0 :         return pwf;
     439             : }
     440             : 
     441           0 : static __isl_give isl_pw_qpolynomial_fold *bernstein_coefficients_factors(
     442             :         __isl_take isl_basic_set *bset,
     443             :         __isl_take isl_qpolynomial *poly, struct bernstein_data *data, int *tight)
     444             : {
     445             :         isl_factorizer *f;
     446             :         isl_set *set;
     447             :         isl_pw_qpolynomial *pwqp;
     448             :         isl_pw_qpolynomial_fold *pwf;
     449             : 
     450           0 :         f = isl_basic_set_factorizer(bset);
     451           0 :         if (!f)
     452           0 :                 goto error;
     453           0 :         if (f->n_group == 0) {
     454           0 :                 isl_factorizer_free(f);
     455           0 :                 return  bernstein_coefficients_base(bset, poly, data, tight);
     456             :         }
     457             : 
     458           0 :         set = isl_set_from_basic_set(bset);
     459           0 :         pwqp = isl_pw_qpolynomial_alloc(set, poly);
     460           0 :         pwqp = isl_pw_qpolynomial_morph_domain(pwqp, isl_morph_copy(f->morph));
     461             : 
     462           0 :         pwf = bernstein_coefficients_recursive(pwqp, f->n_group, f->len, data,
     463             :                                                 tight);
     464             : 
     465           0 :         isl_factorizer_free(f);
     466             : 
     467           0 :         return pwf;
     468             : error:
     469           0 :         isl_basic_set_free(bset);
     470           0 :         isl_qpolynomial_free(poly);
     471           0 :         return NULL;
     472             : }
     473             : 
     474           0 : static __isl_give isl_pw_qpolynomial_fold *bernstein_coefficients_full_recursive(
     475             :         __isl_take isl_basic_set *bset,
     476             :         __isl_take isl_qpolynomial *poly, struct bernstein_data *data, int *tight)
     477             : {
     478             :         int i;
     479             :         int *len;
     480             :         unsigned nvar;
     481             :         isl_pw_qpolynomial_fold *pwf;
     482             :         isl_set *set;
     483             :         isl_pw_qpolynomial *pwqp;
     484             : 
     485           0 :         if (!bset || !poly)
     486             :                 goto error;
     487             : 
     488           0 :         nvar = isl_basic_set_dim(bset, isl_dim_set);
     489             :         
     490           0 :         len = isl_alloc_array(bset->ctx, int, nvar);
     491           0 :         if (nvar && !len)
     492           0 :                 goto error;
     493             : 
     494           0 :         for (i = 0; i < nvar; ++i)
     495           0 :                 len[i] = 1;
     496             : 
     497           0 :         set = isl_set_from_basic_set(bset);
     498           0 :         pwqp = isl_pw_qpolynomial_alloc(set, poly);
     499             : 
     500           0 :         pwf = bernstein_coefficients_recursive(pwqp, nvar, len, data, tight);
     501             : 
     502           0 :         free(len);
     503             : 
     504           0 :         return pwf;
     505             : error:
     506           0 :         isl_basic_set_free(bset);
     507           0 :         isl_qpolynomial_free(poly);
     508           0 :         return NULL;
     509             : }
     510             : 
     511             : /* Compute a bound on the polynomial defined over the parametric polytope
     512             :  * using bernstein expansion and store the result
     513             :  * in bound->pwf and bound->pwf_tight.
     514             :  *
     515             :  * If bernstein_recurse is set to ISL_BERNSTEIN_FACTORS, we check if
     516             :  * the polytope can be factorized and apply bernstein expansion recursively
     517             :  * on the factors.
     518             :  * If bernstein_recurse is set to ISL_BERNSTEIN_INTERVALS, we apply
     519             :  * bernstein expansion recursively on each dimension.
     520             :  * Otherwise, we apply bernstein expansion on the entire polytope.
     521             :  */
     522           0 : isl_stat isl_qpolynomial_bound_on_domain_bernstein(
     523             :         __isl_take isl_basic_set *bset, __isl_take isl_qpolynomial *poly,
     524             :         struct isl_bound *bound)
     525             : {
     526             :         struct bernstein_data data;
     527             :         isl_pw_qpolynomial_fold *pwf;
     528             :         unsigned nvar;
     529           0 :         int tight = 0;
     530           0 :         int *tp = bound->check_tight ? &tight : NULL;
     531             : 
     532           0 :         if (!bset || !poly)
     533             :                 goto error;
     534             : 
     535           0 :         data.type = bound->type;
     536           0 :         data.check_tight = bound->check_tight;
     537             : 
     538           0 :         nvar = isl_basic_set_dim(bset, isl_dim_set);
     539             : 
     540           0 :         if (bset->ctx->opt->bernstein_recurse & ISL_BERNSTEIN_FACTORS)
     541           0 :                 pwf = bernstein_coefficients_factors(bset, poly, &data, tp);
     542           0 :         else if (nvar > 1 &&
     543           0 :             (bset->ctx->opt->bernstein_recurse & ISL_BERNSTEIN_INTERVALS))
     544           0 :                 pwf = bernstein_coefficients_full_recursive(bset, poly, &data, tp);
     545             :         else
     546           0 :                 pwf = bernstein_coefficients_base(bset, poly, &data, tp);
     547             : 
     548           0 :         if (tight)
     549           0 :                 bound->pwf_tight = isl_pw_qpolynomial_fold_fold(bound->pwf_tight, pwf);
     550             :         else
     551           0 :                 bound->pwf = isl_pw_qpolynomial_fold_fold(bound->pwf, pwf);
     552             : 
     553           0 :         return isl_stat_ok;
     554             : error:
     555           0 :         isl_basic_set_free(bset);
     556           0 :         isl_qpolynomial_free(poly);
     557           0 :         return isl_stat_error;
     558             : }

Generated by: LCOV version 1.12