add isl_union_map_power
authorSven Verdoolaege <skimo@kotnet.org>
Sun, 6 Mar 2011 21:06:57 +0000 (22:06 +0100)
committerSven Verdoolaege <skimo@kotnet.org>
Sat, 12 Mar 2011 10:09:37 +0000 (11:09 +0100)
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
doc/user.pod
include/isl/union_map.h
isl_transitive_closure.c

index bf68cb7..c5d09ff 100644 (file)
@@ -1446,6 +1446,8 @@ per space.
 
        __isl_give isl_map *isl_map_power(__isl_take isl_map *map,
                int *exact);
+       __isl_give isl_union_map *isl_union_map_power(
+               __isl_take isl_union_map *umap, int *exact);
 
 Compute a parametric representation for all positive powers I<k> of C<map>.
 The result maps I<k> to a nested relation corresponding to the
index 1ac18fa..bd79494 100644 (file)
@@ -100,6 +100,8 @@ __isl_give isl_map *isl_union_map_extract_map(__isl_keep isl_union_map *umap,
 
 __isl_give isl_basic_map *isl_union_map_sample(__isl_take isl_union_map *umap);
 
+__isl_give isl_union_map *isl_union_map_power(__isl_take isl_union_map *umap,
+       int *exact);
 __isl_give isl_union_map *isl_union_map_transitive_closure(
        __isl_take isl_union_map *umap, int *exact);
 
index 37b5142..1e68574 100644 (file)
@@ -3017,3 +3017,87 @@ error:
        isl_union_map_free(umap);
        return NULL;
 }
+
+struct isl_union_power {
+       isl_union_map *pow;
+       int *exact;
+};
+
+static int power(__isl_take isl_map *map, void *user)
+{
+       struct isl_union_power *up = user;
+
+       map = isl_map_power(map, up->exact);
+       up->pow = isl_union_map_from_map(map);
+
+       return -1;
+}
+
+/* Construct a map [x] -> [x+1], with parameters prescribed by "dim".
+ */
+static __isl_give isl_union_map *increment(__isl_take isl_dim *dim)
+{
+       int k;
+       isl_basic_map *bmap;
+
+       dim = isl_dim_add(dim, isl_dim_in, 1);
+       dim = isl_dim_add(dim, isl_dim_out, 1);
+       bmap = isl_basic_map_alloc_dim(dim, 0, 1, 0);
+       k = isl_basic_map_alloc_equality(bmap);
+       if (k < 0)
+               goto error;
+       isl_seq_clr(bmap->eq[k], isl_basic_map_total_dim(bmap));
+       isl_int_set_si(bmap->eq[k][0], 1);
+       isl_int_set_si(bmap->eq[k][isl_basic_map_offset(bmap, isl_dim_in)], 1);
+       isl_int_set_si(bmap->eq[k][isl_basic_map_offset(bmap, isl_dim_out)], -1);
+       return isl_union_map_from_map(isl_map_from_basic_map(bmap));
+error:
+       isl_basic_map_free(bmap);
+       return NULL;
+}
+
+/* Construct a map [[x]->[y]] -> [y-x], with parameters prescribed by "dim".
+ */
+static __isl_give isl_union_map *deltas_map(__isl_take isl_dim *dim)
+{
+       isl_basic_map *bmap;
+
+       dim = isl_dim_add(dim, isl_dim_in, 1);
+       dim = isl_dim_add(dim, isl_dim_out, 1);
+       bmap = isl_basic_map_universe(dim);
+       bmap = isl_basic_map_deltas_map(bmap);
+
+       return isl_union_map_from_map(isl_map_from_basic_map(bmap));
+}
+
+/* Compute the positive powers of "map", or an overapproximation.
+ * The result maps the exponent to a nested copy of the corresponding power.
+ * If the result is exact, then *exact is set to 1.
+ */
+__isl_give isl_union_map *isl_union_map_power(__isl_take isl_union_map *umap,
+       int *exact)
+{
+       int n;
+       isl_union_map *inc;
+       isl_union_map *dm;
+
+       if (!umap)
+               return NULL;
+       n = isl_union_map_n_map(umap);
+       if (n == 0)
+               return umap;
+       if (n == 1) {
+               struct isl_union_power up = { NULL, exact };
+               isl_union_map_foreach_map(umap, &power, &up);
+               isl_union_map_free(umap);
+               return up.pow;
+       }
+       inc = increment(isl_union_map_get_dim(umap));
+       umap = isl_union_map_product(inc, umap);
+       umap = isl_union_map_transitive_closure(umap, exact);
+       umap = isl_union_map_zip(umap);
+       dm = deltas_map(isl_union_map_get_dim(umap));
+       umap = isl_union_map_apply_domain(umap, dm);
+       
+       return umap;
+}