isl_multi_templ.c \
isl_multi_templ.h \
print_templ.c \
+ isl_power_templ.c \
isl_pw_templ.c \
isl_union_templ.c \
isl.py \
=item * Power
+ __isl_give isl_map *isl_map_fixed_power(
+ __isl_take isl_map *map, isl_int exp);
+ __isl_give isl_union_map *isl_union_map_fixed_power(
+ __isl_take isl_union_map *umap, isl_int exp);
+
+Compute the given power of C<map>, where C<exp> is assumed to be non-zero.
+If the exponent C<exp> is negative, then the -C<exp> th power of the inverse
+of C<map> is computed.
+
__isl_give isl_map *isl_map_power(__isl_take isl_map *map,
int *exact);
__isl_give isl_union_map *isl_union_map_power(
__isl_give isl_map *isl_set_lifting(__isl_take isl_set *set);
+__isl_give isl_map *isl_map_fixed_power(__isl_take isl_map *map, isl_int exp);
__isl_give isl_map *isl_map_power(__isl_take isl_map *map, int *exact);
__isl_give isl_map *isl_map_reaching_path_lengths(__isl_take isl_map *map,
int *exact);
__isl_give isl_basic_map *isl_union_map_sample(__isl_take isl_union_map *umap);
+__isl_give isl_union_map *isl_union_map_fixed_power(
+ __isl_take isl_union_map *umap, isl_int exp);
__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(
--- /dev/null
+#define xFN(TYPE,NAME) TYPE ## _ ## NAME
+#define FN(TYPE,NAME) xFN(TYPE,NAME)
+
+/* Compute the given non-zero power of "map" and return the result.
+ * If the exponent "exp" is negative, then the -exp th power of the inverse
+ * relation is computed.
+ */
+__isl_give TYPE *FN(TYPE,fixed_power)(__isl_take TYPE *map, isl_int exp)
+{
+ isl_ctx *ctx;
+ TYPE *res = NULL;
+ isl_int r;
+
+ if (!map)
+ return NULL;
+
+ ctx = FN(TYPE,get_ctx)(map);
+ if (isl_int_is_zero(exp))
+ isl_die(ctx, isl_error_invalid,
+ "expecting non-zero exponent", goto error);
+
+ if (isl_int_is_neg(exp)) {
+ isl_int_neg(exp, exp);
+ map = FN(TYPE,reverse)(map);
+ return FN(TYPE,fixed_power)(map, exp);
+ }
+
+ isl_int_init(r);
+ for (;;) {
+ isl_int_fdiv_r(r, exp, ctx->two);
+
+ if (!isl_int_is_zero(r)) {
+ if (!res)
+ res = FN(TYPE,copy)(map);
+ else {
+ res = FN(TYPE,apply_range)(res,
+ FN(TYPE,copy)(map));
+ res = FN(TYPE,coalesce)(res);
+ }
+ if (!res)
+ break;
+ }
+
+ isl_int_fdiv_q(exp, exp, ctx->two);
+ if (isl_int_is_zero(exp))
+ break;
+
+ map = FN(TYPE,apply_range)(map, FN(TYPE,copy)(map));
+ map = FN(TYPE,coalesce)(map);
+ }
+ isl_int_clear(r);
+
+ FN(TYPE,free)(map);
+ return res;
+error:
+ FN(TYPE,free)(map);
+ return NULL;
+}
return equal;
}
+static int map_check_equal(__isl_keep isl_map *map, const char *str)
+{
+ int equal;
+
+ equal = map_is_equal(map, str);
+ if (equal < 0)
+ return -1;
+ if (!equal)
+ isl_die(isl_map_get_ctx(map), isl_error_unknown,
+ "result not as expected", return -1);
+ return 0;
+}
+
void test_dep(struct isl_ctx *ctx)
{
const char *str;
return 0;
}
+int test_fixed_power(isl_ctx *ctx)
+{
+ const char *str;
+ isl_map *map;
+ isl_int exp;
+ int equal;
+
+ isl_int_init(exp);
+ str = "{ [i] -> [i + 1] }";
+ map = isl_map_read_from_str(ctx, str);
+ isl_int_set_si(exp, 23);
+ map = isl_map_fixed_power(map, exp);
+ equal = map_check_equal(map, "{ [i] -> [i + 23] }");
+ isl_int_clear(exp);
+ isl_map_free(map);
+ if (equal < 0)
+ return -1;
+
+ return 0;
+}
+
int main()
{
struct isl_ctx *ctx;
assert(srcdir);
ctx = isl_ctx_alloc();
+ if (test_fixed_power(ctx) < 0)
+ goto error;
if (test_sample(ctx) < 0)
goto error;
if (test_output(ctx) < 0)
return umap;
}
+
+#undef TYPE
+#define TYPE isl_map
+#include "isl_power_templ.c"
+
+#undef TYPE
+#define TYPE isl_union_map
+#include "isl_power_templ.c"