privately export isl_basic_set_sample_with_cone
[platform/upstream/isl.git] / isl_sample.c
index 51eea13..1a27222 100644 (file)
@@ -328,7 +328,7 @@ static struct isl_basic_set *basic_set_reduced(struct isl_basic_set *bset,
                return NULL;
 
        gbr_only_first = bset->ctx->gbr_only_first;
-       bset->ctx->gbr_only_first = 1;
+       bset->ctx->gbr_only_first = bset->ctx->gbr == ISL_GBR_ONCE;
        *T = isl_basic_set_reduced_basis(bset);
        bset->ctx->gbr_only_first = gbr_only_first;
 
@@ -418,6 +418,8 @@ error:
 static struct isl_vec *sample_bounded(struct isl_basic_set *bset)
 {
        unsigned dim;
+       unsigned gbr;
+       struct isl_ctx *ctx;
        struct isl_vec *sample;
        struct isl_vec *obj = NULL;
        struct isl_mat *T = NULL;
@@ -438,6 +440,9 @@ static struct isl_vec *sample_bounded(struct isl_basic_set *bset)
        if (bset->n_eq > 0)
                return sample_eq(bset, sample_bounded);
 
+       ctx = bset->ctx;
+       gbr = ctx->gbr;
+
        isl_int_init(min);
        isl_int_init(max);
        obj = isl_vec_alloc(bset->ctx, 1 + dim);
@@ -460,7 +465,10 @@ static struct isl_vec *sample_bounded(struct isl_basic_set *bset)
                goto out;
        }
 
-       if (isl_int_ne(min, max)) {
+       if (ctx->gbr != ISL_GBR_NEVER && isl_int_ne(min, max)) {
+               if (ctx->gbr == ISL_GBR_ONCE)
+                       ctx->gbr = ISL_GBR_NEVER;
+
                bset = basic_set_reduced(bset, &T);
                if (!bset)
                        goto error;
@@ -491,8 +499,10 @@ out:
        isl_vec_free(obj);
        isl_int_clear(min);
        isl_int_clear(max);
+       ctx->gbr = gbr;
        return sample;
 error:
+       ctx->gbr = gbr;
        isl_mat_free(T);
        isl_basic_set_free(bset);
        isl_vec_free(obj);
@@ -566,24 +576,6 @@ static struct isl_vec *rational_sample(struct isl_basic_set *bset)
        return sample;
 }
 
-/* Given a rational vector, with the denominator in the first element
- * of the vector, round up all coordinates.
- */
-struct isl_vec *isl_vec_ceil(struct isl_vec *vec)
-{
-       int i;
-
-       vec = isl_vec_cow(vec);
-       if (!vec)
-               return NULL;
-
-       isl_seq_cdiv_q(vec->el + 1, vec->el + 1, vec->el[0], vec->size - 1);
-
-       isl_int_set_si(vec->el[0], 1);
-
-       return vec;
-}
-
 /* Given a linear cone "cone" and a rational point "vec",
  * construct a polyhedron with shifted copies of the constraints in "cone",
  * i.e., a polyhedron with "cone" as its recession cone, such that each
@@ -796,8 +788,8 @@ static struct isl_basic_set *drop_constraints_involving
  * then combined into a single sample point and transformed back
  * to the original space.
  */
-static struct isl_vec *sample_with_cone(struct isl_basic_set *bset,
-       struct isl_basic_set *cone)
+__isl_give isl_vec *isl_basic_set_sample_with_cone(
+       __isl_take isl_basic_set *bset, __isl_take isl_basic_set *cone)
 {
        unsigned total;
        unsigned cone_dim;
@@ -861,7 +853,7 @@ static struct isl_vec *gbr_sample(struct isl_basic_set *bset)
        cone = isl_basic_set_recession_cone(isl_basic_set_copy(bset));
 
        if (cone->n_eq < dim)
-               return sample_with_cone(bset, cone);
+               return isl_basic_set_sample_with_cone(bset, cone);
 
        isl_basic_set_free(cone);
        return sample_bounded(bset);
@@ -888,7 +880,7 @@ static struct isl_vec *pip_sample(struct isl_basic_set *bset)
        return sample;
 }
 
-struct isl_vec *basic_set_sample(struct isl_basic_set *bset, int bounded)
+static struct isl_vec *basic_set_sample(struct isl_basic_set *bset, int bounded)
 {
        struct isl_ctx *ctx;
        unsigned dim;
@@ -917,7 +909,7 @@ struct isl_vec *basic_set_sample(struct isl_basic_set *bset, int bounded)
        bset->sample = NULL;
 
        if (bset->n_eq > 0)
-               return sample_eq(bset, isl_basic_set_sample);
+               return sample_eq(bset, isl_basic_set_sample_vec);
        if (dim == 0)
                return zero_sample(bset);
        if (dim == 1)
@@ -935,7 +927,7 @@ error:
        return NULL;
 }
 
-struct isl_vec *isl_basic_set_sample(struct isl_basic_set *bset)
+__isl_give isl_vec *isl_basic_set_sample_vec(__isl_take isl_basic_set *bset)
 {
        return basic_set_sample(bset, 0);
 }
@@ -947,3 +939,90 @@ struct isl_vec *isl_basic_set_sample_bounded(struct isl_basic_set *bset)
 {
        return basic_set_sample(bset, 1);
 }
+
+__isl_give isl_basic_set *isl_basic_set_from_vec(__isl_take isl_vec *vec)
+{
+       int i;
+       int k;
+       struct isl_basic_set *bset = NULL;
+       struct isl_ctx *ctx;
+       unsigned dim;
+
+       if (!vec)
+               return NULL;
+       ctx = vec->ctx;
+       isl_assert(ctx, vec->size != 0, goto error);
+
+       bset = isl_basic_set_alloc(ctx, 0, vec->size - 1, 0, vec->size - 1, 0);
+       if (!bset)
+               goto error;
+       dim = isl_basic_set_n_dim(bset);
+       for (i = dim - 1; i >= 0; --i) {
+               k = isl_basic_set_alloc_equality(bset);
+               if (k < 0)
+                       goto error;
+               isl_seq_clr(bset->eq[k], 1 + dim);
+               isl_int_neg(bset->eq[k][0], vec->el[1 + i]);
+               isl_int_set(bset->eq[k][1 + i], vec->el[0]);
+       }
+       isl_vec_free(vec);
+
+       return bset;
+error:
+       isl_basic_set_free(bset);
+       isl_vec_free(vec);
+       return NULL;
+}
+
+__isl_give isl_basic_map *isl_basic_map_sample(__isl_take isl_basic_map *bmap)
+{
+       struct isl_basic_set *bset;
+       struct isl_vec *sample_vec;
+
+       bset = isl_basic_map_underlying_set(isl_basic_map_copy(bmap));
+       sample_vec = isl_basic_set_sample_vec(bset);
+       if (!sample_vec)
+               goto error;
+       if (sample_vec->size == 0) {
+               struct isl_basic_map *sample;
+               sample = isl_basic_map_empty_like(bmap);
+               isl_vec_free(sample_vec);
+               isl_basic_map_free(bmap);
+               return sample;
+       }
+       bset = isl_basic_set_from_vec(sample_vec);
+       return isl_basic_map_overlying_set(bset, bmap);
+error:
+       isl_basic_map_free(bmap);
+       return NULL;
+}
+
+__isl_give isl_basic_map *isl_map_sample(__isl_take isl_map *map)
+{
+       int i;
+       isl_basic_map *sample = NULL;
+
+       if (!map)
+               goto error;
+
+       for (i = 0; i < map->n; ++i) {
+               sample = isl_basic_map_sample(isl_basic_map_copy(map->p[i]));
+               if (!sample)
+                       goto error;
+               if (!ISL_F_ISSET(sample, ISL_BASIC_MAP_EMPTY))
+                       break;
+               isl_basic_map_free(sample);
+       }
+       if (i == map->n)
+               sample = isl_basic_map_empty_like_map(map);
+       isl_map_free(map);
+       return sample;
+error:
+       isl_map_free(map);
+       return NULL;
+}
+
+__isl_give isl_basic_set *isl_set_sample(__isl_take isl_set *set)
+{
+       return (isl_basic_set *) isl_map_sample((isl_map *)set);
+}