add basic isl_pw_qpolynomial_fold_coalesce
authorSven Verdoolaege <skimo@kotnet.org>
Wed, 17 Mar 2010 16:23:03 +0000 (17:23 +0100)
committerSven Verdoolaege <skimo@kotnet.org>
Thu, 18 Mar 2010 22:16:34 +0000 (23:16 +0100)
include/isl_polynomial.h
isl_polynomial.c
isl_pw_templ.c

index 719d56f..f5be4ed 100644 (file)
@@ -26,6 +26,8 @@ __isl_give isl_qpolynomial *isl_qpolynomial_var(__isl_take isl_dim *dim,
 __isl_give isl_qpolynomial *isl_qpolynomial_copy(__isl_keep isl_qpolynomial *qp);
 void isl_qpolynomial_free(__isl_take isl_qpolynomial *qp);
 
+int isl_qpolynomial_is_equal(__isl_keep isl_qpolynomial *qp1,
+       __isl_keep isl_qpolynomial *qp2);
 int isl_qpolynomial_is_cst(__isl_keep isl_qpolynomial *qp,
        isl_int *n, isl_int *d);
 void isl_qpolynomial_get_den(__isl_keep isl_qpolynomial *qp, isl_int *d);
@@ -139,6 +141,8 @@ __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_copy(
 void isl_qpolynomial_fold_free(__isl_take isl_qpolynomial_fold *fold);
 
 int isl_qpolynomial_fold_is_empty(__isl_keep isl_qpolynomial_fold *fold);
+int isl_qpolynomial_fold_is_equal(__isl_keep isl_qpolynomial_fold *fold1,
+       __isl_keep isl_qpolynomial_fold *fold2);
 
 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_fold(
        __isl_take isl_qpolynomial_fold *fold1,
@@ -187,6 +191,8 @@ __isl_give isl_printer *isl_printer_print_pw_qpolynomial_fold(
 void isl_pw_qpolynomial_fold_print(__isl_keep isl_pw_qpolynomial_fold *pwf,
        FILE *out, unsigned output_format);
 
+__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_coalesce(
+       __isl_take isl_pw_qpolynomial_fold *pwf);
 __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_gist(
        __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_set *context);
 
index 21c4867..f73d83f 100644 (file)
@@ -32,6 +32,45 @@ __isl_keep struct isl_upoly_rec *isl_upoly_as_rec(__isl_keep struct isl_upoly *u
        return (struct isl_upoly_rec *)up;
 }
 
+int isl_upoly_is_equal(__isl_keep struct isl_upoly *up1,
+       __isl_keep struct isl_upoly *up2)
+{
+       int i;
+       struct isl_upoly_rec *rec1, *rec2;
+
+       if (!up1 || !up2)
+               return -1;
+       if (up1 == up2)
+               return 1;
+       if (up1->var != up2->var)
+               return 0;
+       if (isl_upoly_is_cst(up1)) {
+               struct isl_upoly_cst *cst1, *cst2;
+               cst1 = isl_upoly_as_cst(up1);
+               cst2 = isl_upoly_as_cst(up2);
+               if (!cst1 || !cst2)
+                       return -1;
+               return isl_int_eq(cst1->n, cst2->n) &&
+                      isl_int_eq(cst1->d, cst2->d);
+       }
+
+       rec1 = isl_upoly_as_rec(up1);
+       rec2 = isl_upoly_as_rec(up2);
+       if (!rec1 || !rec2)
+               return -1;
+
+       if (rec1->n != rec2->n)
+               return 0;
+
+       for (i = 0; i < rec1->n; ++i) {
+               int eq = isl_upoly_is_equal(rec1->p[i], rec2->p[i]);
+               if (eq < 0 || !eq)
+                       return eq;
+       }
+
+       return 1;
+}
+
 int isl_upoly_is_zero(__isl_keep struct isl_upoly *up)
 {
        struct isl_upoly_cst *cst;
@@ -1176,6 +1215,15 @@ int isl_qpolynomial_is_cst(__isl_keep isl_qpolynomial *qp,
        return 1;
 }
 
+int isl_qpolynomial_is_equal(__isl_keep isl_qpolynomial *qp1,
+       __isl_keep isl_qpolynomial *qp2)
+{
+       if (!qp1 || !qp2)
+               return -1;
+
+       return isl_upoly_is_equal(qp1->upoly, qp2->upoly);
+}
+
 static void upoly_update_den(__isl_keep struct isl_upoly *up, isl_int *d)
 {
        int i;
@@ -1630,6 +1678,27 @@ error:
        return NULL;
 }
 
+int isl_qpolynomial_fold_is_equal(__isl_keep isl_qpolynomial_fold *fold1,
+       __isl_keep isl_qpolynomial_fold *fold2)
+{
+       int i;
+
+       if (!fold1 || !fold2)
+               return -1;
+
+       if (fold1->n != fold2->n)
+               return 0;
+
+       /* We probably want to sort the qps first... */
+       for (i = 0; i < fold1->n; ++i) {
+               int eq = isl_qpolynomial_is_equal(fold1->qp[i], fold2->qp[i]);
+               if (eq < 0 || !eq)
+                       return eq;
+       }
+
+       return 1;
+}
+
 __isl_give isl_qpolynomial *isl_qpolynomial_fold_eval(
        __isl_take isl_qpolynomial_fold *fold, __isl_take isl_point *pnt)
 {
index 9333ef6..db7e1d7 100644 (file)
@@ -362,6 +362,40 @@ error:
        return NULL;
 }
 
+__isl_give PW *FN(PW,coalesce)(__isl_take PW *pw)
+{
+       int i, j;
+
+       if (!pw)
+               return NULL;
+       if (pw->n == 0)
+               return pw;
+
+       for (i = pw->n - 1; i >= 0; --i) {
+               for (j = i - 1; j >= 0; --j) {
+                       if (!FN(EL,is_equal)(pw->p[i].FIELD, pw->p[j].FIELD))
+                               continue;
+                       pw->p[j].set = isl_set_union(pw->p[j].set,
+                                                       pw->p[i].set);
+                       FN(EL,free)(pw->p[i].FIELD);
+                       if (i != pw->n - 1)
+                               pw->p[i] = pw->p[pw->n - 1];
+                       pw->n--;
+                       break;
+               }
+               if (j >= 0)
+                       continue;
+               pw->p[i].set = isl_set_coalesce(pw->p[i].set);
+               if (!pw->p[i].set)
+                       goto error;
+       }
+
+       return pw;
+error:
+       FN(PW,free)(pw);
+       return NULL;
+}
+
 isl_ctx *FN(PW,get_ctx)(__isl_keep PW *pw)
 {
        return pw ? pw->dim->ctx : NULL;