2 * Copyright 2010 INRIA Saclay
4 * Use of this software is governed by the GNU LGPLv2.1 license
6 * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
7 * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
11 #include <isl_polynomial_private.h>
12 #include <isl_point_private.h>
13 #include <isl_dim_private.h>
14 #include <isl_map_private.h>
16 int isl_qpolynomial_fold_involves_dims(__isl_keep isl_qpolynomial_fold *fold,
17 enum isl_dim_type type, unsigned first, unsigned n)
23 if (fold->n == 0 || n == 0)
26 for (i = 0; i < fold->n; ++i) {
27 int involves = isl_qpolynomial_involves_dims(fold->qp[i],
29 if (involves < 0 || involves)
35 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_drop_dims(
36 __isl_take isl_qpolynomial_fold *fold,
37 enum isl_dim_type type, unsigned first, unsigned n)
46 fold = isl_qpolynomial_fold_cow(fold);
49 fold->dim = isl_dim_drop(fold->dim, type, first, n);
53 for (i = 0; i < fold->n; ++i) {
54 fold->qp[i] = isl_qpolynomial_drop_dims(fold->qp[i],
62 isl_qpolynomial_fold_free(fold);
67 #define PW isl_pw_qpolynomial_fold
69 #define EL isl_qpolynomial_fold
71 #define IS_ZERO is_empty
77 #include <isl_pw_templ.c>
79 static __isl_give isl_qpolynomial_fold *qpolynomial_fold_alloc(
80 enum isl_fold type, __isl_take isl_dim *dim, int n)
82 isl_qpolynomial_fold *fold;
87 isl_assert(dim->ctx, n >= 0, goto error);
88 fold = isl_alloc(dim->ctx, struct isl_qpolynomial_fold,
89 sizeof(struct isl_qpolynomial_fold) +
90 (n - 1) * sizeof(struct isl_qpolynomial *));
106 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_empty(enum isl_fold type,
107 __isl_take isl_dim *dim)
109 return qpolynomial_fold_alloc(type, dim, 0);
112 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_alloc(
113 enum isl_fold type, __isl_take isl_qpolynomial *qp)
115 isl_qpolynomial_fold *fold;
120 fold = qpolynomial_fold_alloc(type, isl_dim_copy(qp->dim), 1);
129 isl_qpolynomial_fold_free(fold);
130 isl_qpolynomial_free(qp);
134 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_copy(
135 __isl_keep isl_qpolynomial_fold *fold)
144 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_dup(
145 __isl_keep isl_qpolynomial_fold *fold)
148 isl_qpolynomial_fold *dup;
152 dup = qpolynomial_fold_alloc(fold->type,
153 isl_dim_copy(fold->dim), fold->n);
157 for (i = 0; i < fold->n; ++i) {
158 dup->qp[i] = isl_qpolynomial_copy(fold->qp[i]);
165 isl_qpolynomial_fold_free(dup);
169 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_cow(
170 __isl_take isl_qpolynomial_fold *fold)
178 return isl_qpolynomial_fold_dup(fold);
181 void isl_qpolynomial_fold_free(__isl_take isl_qpolynomial_fold *fold)
190 for (i = 0; i < fold->n; ++i)
191 isl_qpolynomial_free(fold->qp[i]);
192 isl_dim_free(fold->dim);
196 int isl_qpolynomial_fold_is_empty(__isl_keep isl_qpolynomial_fold *fold)
204 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_fold(
205 __isl_take isl_qpolynomial_fold *fold1,
206 __isl_take isl_qpolynomial_fold *fold2)
209 struct isl_qpolynomial_fold *res = NULL;
211 if (!fold1 || !fold2)
214 isl_assert(fold1->dim->ctx, fold1->type == fold2->type, goto error);
215 isl_assert(fold1->dim->ctx, isl_dim_equal(fold1->dim, fold2->dim),
218 if (isl_qpolynomial_fold_is_empty(fold1)) {
219 isl_qpolynomial_fold_free(fold1);
223 if (isl_qpolynomial_fold_is_empty(fold2)) {
224 isl_qpolynomial_fold_free(fold2);
228 res = qpolynomial_fold_alloc(fold1->type, isl_dim_copy(fold1->dim),
229 fold1->n + fold2->n);
233 for (i = 0; i < fold1->n; ++i) {
234 res->qp[res->n] = isl_qpolynomial_copy(fold1->qp[i]);
235 if (!res->qp[res->n])
240 for (i = 0; i < fold2->n; ++i) {
241 res->qp[res->n] = isl_qpolynomial_copy(fold2->qp[i]);
242 if (!res->qp[res->n])
247 isl_qpolynomial_fold_free(fold1);
248 isl_qpolynomial_fold_free(fold2);
252 isl_qpolynomial_fold_free(res);
253 isl_qpolynomial_fold_free(fold1);
254 isl_qpolynomial_fold_free(fold2);
258 __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_from_pw_qpolynomial(
259 enum isl_fold type, __isl_take isl_pw_qpolynomial *pwqp)
262 isl_pw_qpolynomial_fold *pwf;
267 pwf = isl_pw_qpolynomial_fold_alloc_(isl_dim_copy(pwqp->dim), pwqp->n);
269 for (i = 0; i < pwqp->n; ++i)
270 pwf = isl_pw_qpolynomial_fold_add_piece(pwf,
271 isl_set_copy(pwqp->p[i].set),
272 isl_qpolynomial_fold_alloc(type,
273 isl_qpolynomial_copy(pwqp->p[i].qp)));
275 isl_pw_qpolynomial_free(pwqp);
280 int isl_qpolynomial_fold_is_equal(__isl_keep isl_qpolynomial_fold *fold1,
281 __isl_keep isl_qpolynomial_fold *fold2)
285 if (!fold1 || !fold2)
288 if (fold1->n != fold2->n)
291 /* We probably want to sort the qps first... */
292 for (i = 0; i < fold1->n; ++i) {
293 int eq = isl_qpolynomial_is_equal(fold1->qp[i], fold2->qp[i]);
301 __isl_give isl_qpolynomial *isl_qpolynomial_fold_eval(
302 __isl_take isl_qpolynomial_fold *fold, __isl_take isl_point *pnt)
308 isl_assert(pnt->dim->ctx, isl_dim_equal(pnt->dim, fold->dim), goto error);
309 isl_assert(pnt->dim->ctx,
310 fold->type == isl_fold_max || fold->type == isl_fold_min,
314 qp = isl_qpolynomial_zero(isl_dim_copy(fold->dim));
317 qp = isl_qpolynomial_eval(isl_qpolynomial_copy(fold->qp[0]),
318 isl_point_copy(pnt));
319 for (i = 1; i < fold->n; ++i) {
320 isl_qpolynomial *qp_i;
321 qp_i = isl_qpolynomial_eval(
322 isl_qpolynomial_copy(fold->qp[i]),
323 isl_point_copy(pnt));
324 if (fold->type == isl_fold_max)
325 qp = isl_qpolynomial_max_cst(qp, qp_i);
327 qp = isl_qpolynomial_min_cst(qp, qp_i);
330 isl_qpolynomial_fold_free(fold);
335 isl_qpolynomial_fold_free(fold);