add isl_pw_qpolynomial_fold_eval
authorSven Verdoolaege <skimo@kotnet.org>
Tue, 9 Mar 2010 10:47:02 +0000 (11:47 +0100)
committerSven Verdoolaege <skimo@kotnet.org>
Tue, 9 Mar 2010 14:54:42 +0000 (15:54 +0100)
include/isl_polynomial.h
isl_polynomial.c
isl_pw_templ.c

index fea6c84..58fc372 100644 (file)
@@ -51,6 +51,9 @@ __isl_give isl_div *isl_term_get_div(__isl_keep isl_term *term, unsigned pos);
 int isl_qpolynomial_foreach_term(__isl_keep isl_qpolynomial *qp,
        int (*fn)(__isl_take isl_term *term, void *user), void *user);
 
+__isl_give isl_qpolynomial *isl_qpolynomial_eval(
+       __isl_take isl_qpolynomial *qp, __isl_take isl_point *pnt);
+
 void isl_qpolynomial_print(__isl_keep isl_qpolynomial *qp, FILE *out,
        unsigned output_format);
 
@@ -125,6 +128,9 @@ __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_fold(
        __isl_take isl_qpolynomial_fold *fold1,
        __isl_take isl_qpolynomial_fold *fold2);
 
+__isl_give isl_qpolynomial *isl_qpolynomial_fold_eval(
+       __isl_take isl_qpolynomial_fold *fold, __isl_take isl_point *pnt);
+
 void isl_qpolynomial_fold_print(__isl_keep isl_qpolynomial_fold *fold, FILE *out,
        unsigned output_format);
 
@@ -150,6 +156,9 @@ __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_add_disjoint(
        __isl_take isl_pw_qpolynomial_fold *pwf1,
        __isl_take isl_pw_qpolynomial_fold *pwf2);
 
+__isl_give isl_qpolynomial *isl_pw_qpolynomial_fold_eval(
+       __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_point *pnt);
+
 void isl_pw_qpolynomial_fold_print(__isl_keep isl_pw_qpolynomial_fold *pwf,
        FILE *out, unsigned output_format);
 
index 23e42e1..c8a971a 100644 (file)
@@ -1522,34 +1522,108 @@ error:
        return NULL;
 }
 
-__isl_give isl_qpolynomial *isl_pw_qpolynomial_eval(
-       __isl_take isl_pw_qpolynomial *pwqp, __isl_take isl_point *pnt)
+int isl_upoly_cmp(__isl_keep struct isl_upoly_cst *cst1,
+       __isl_keep struct isl_upoly_cst *cst2)
 {
-       int i;
-       int found;
-       isl_qpolynomial *qp;
+       int cmp;
+       isl_int t;
+       isl_int_init(t);
+       isl_int_mul(t, cst1->n, cst2->d);
+       isl_int_submul(t, cst2->n, cst1->d);
+       cmp = isl_int_sgn(t);
+       isl_int_clear(t);
+       return cmp;
+}
+
+static __isl_give isl_qpolynomial *qpolynomial_min(
+       __isl_take isl_qpolynomial *qp1, __isl_take isl_qpolynomial *qp2)
+{
+       struct isl_upoly_cst *cst1, *cst2;
+       int cmp;
 
-       if (!pwqp || !pnt)
+       if (!qp1 || !qp2)
                goto error;
-       isl_assert(pnt->dim->ctx, isl_dim_equal(pnt->dim, pwqp->dim), goto error);
+       isl_assert(qp1->dim->ctx, isl_upoly_is_cst(qp1->upoly), goto error);
+       isl_assert(qp2->dim->ctx, isl_upoly_is_cst(qp2->upoly), goto error);
+       cst1 = isl_upoly_as_cst(qp1->upoly);
+       cst2 = isl_upoly_as_cst(qp2->upoly);
+       cmp = isl_upoly_cmp(cst1, cst2);
+
+       if (cmp <= 0) {
+               isl_qpolynomial_free(qp2);
+       } else {
+               isl_qpolynomial_free(qp1);
+               qp1 = qp2;
+       }
+       return qp1;
+error:
+       isl_qpolynomial_free(qp1);
+       isl_qpolynomial_free(qp2);
+       return NULL;
+}
 
-       for (i = 0; i < pwqp->n; ++i) {
-               found = isl_set_contains_point(pwqp->p[i].set, pnt);
-               if (found < 0)
-                       goto error;
-               if (found)
-                       break;
+static __isl_give isl_qpolynomial *qpolynomial_max(
+       __isl_take isl_qpolynomial *qp1, __isl_take isl_qpolynomial *qp2)
+{
+       struct isl_upoly_cst *cst1, *cst2;
+       int cmp;
+
+       if (!qp1 || !qp2)
+               goto error;
+       isl_assert(qp1->dim->ctx, isl_upoly_is_cst(qp1->upoly), goto error);
+       isl_assert(qp2->dim->ctx, isl_upoly_is_cst(qp2->upoly), goto error);
+       cst1 = isl_upoly_as_cst(qp1->upoly);
+       cst2 = isl_upoly_as_cst(qp2->upoly);
+       cmp = isl_upoly_cmp(cst1, cst2);
+
+       if (cmp >= 0) {
+               isl_qpolynomial_free(qp2);
+       } else {
+               isl_qpolynomial_free(qp1);
+               qp1 = qp2;
        }
-       if (found)
-               qp = isl_qpolynomial_eval(isl_qpolynomial_copy(pwqp->p[i].qp),
+       return qp1;
+error:
+       isl_qpolynomial_free(qp1);
+       isl_qpolynomial_free(qp2);
+       return NULL;
+}
+
+__isl_give isl_qpolynomial *isl_qpolynomial_fold_eval(
+       __isl_take isl_qpolynomial_fold *fold, __isl_take isl_point *pnt)
+{
+       isl_qpolynomial *qp;
+
+       if (!fold || !pnt)
+               goto error;
+       isl_assert(pnt->dim->ctx, isl_dim_equal(pnt->dim, fold->dim), goto error);
+       isl_assert(pnt->dim->ctx,
+               fold->type == isl_fold_max || fold->type == isl_fold_min,
+               goto error);
+
+       if (fold->n == 0)
+               qp = isl_qpolynomial_zero(isl_dim_copy(fold->dim));
+       else {
+               int i;
+               qp = isl_qpolynomial_eval(isl_qpolynomial_copy(fold->qp[0]),
+                                               isl_point_copy(pnt));
+               for (i = 1; i < fold->n; ++i) {
+                       isl_qpolynomial *qp_i;
+                       qp_i = isl_qpolynomial_eval(
+                                           isl_qpolynomial_copy(fold->qp[i]),
                                            isl_point_copy(pnt));
-       else
-               qp = isl_qpolynomial_zero(isl_dim_copy(pwqp->dim));
-       isl_pw_qpolynomial_free(pwqp);
+                       if (fold->type == isl_fold_max)
+                               qp = qpolynomial_max(qp, qp_i);
+                       else
+                               qp = qpolynomial_min(qp, qp_i);
+               }
+       }
+       isl_qpolynomial_fold_free(fold);
        isl_point_free(pnt);
+
        return qp;
 error:
-       isl_pw_qpolynomial_free(pwqp);
+       isl_qpolynomial_fold_free(fold);
        isl_point_free(pnt);
        return NULL;
 }
index 0262a89..d585e2f 100644 (file)
@@ -234,3 +234,35 @@ error:
        FN(PW,free)(pw2);
        return NULL;
 }
+
+__isl_give isl_qpolynomial *FN(PW,eval)(__isl_take PW *pw,
+       __isl_take isl_point *pnt)
+{
+       int i;
+       int found;
+       isl_qpolynomial *qp;
+
+       if (!pw || !pnt)
+               goto error;
+       isl_assert(pnt->dim->ctx, isl_dim_equal(pnt->dim, pw->dim), goto error);
+
+       for (i = 0; i < pw->n; ++i) {
+               found = isl_set_contains_point(pw->p[i].set, pnt);
+               if (found < 0)
+                       goto error;
+               if (found)
+                       break;
+       }
+       if (found)
+               qp = FN(EL,eval)(FN(EL,copy)(pw->p[i].FIELD),
+                                           isl_point_copy(pnt));
+       else
+               qp = isl_qpolynomial_zero(isl_dim_copy(pw->dim));
+       FN(PW,free)(pw);
+       isl_point_free(pnt);
+       return qp;
+error:
+       FN(PW,free)(pw);
+       isl_point_free(pnt);
+       return NULL;
+}