1181
1162
isl_basic_map_affine_hull((struct isl_basic_map *)bset);
1184
struct isl_basic_map *isl_map_affine_hull(struct isl_map *map)
1165
/* Given a rational affine matrix "M", add stride constraints to "bmap"
1170
* is an integer vector. The variables x include all the variables
1171
* of "bmap" except the unknown divs.
1173
* If d is the common denominator of M, then we need to impose that
1179
* exists alpha : d M(x) = d alpha
1181
* This function is similar to add_strides in isl_morph.c
1183
static __isl_give isl_basic_map *add_strides(__isl_take isl_basic_map *bmap,
1184
__isl_keep isl_mat *M, int n_known)
1189
if (isl_int_is_one(M->row[0][0]))
1192
bmap = isl_basic_map_extend_space(bmap, isl_space_copy(bmap->dim),
1193
M->n_row - 1, M->n_row - 1, 0);
1196
for (i = 1; i < M->n_row; ++i) {
1197
isl_seq_gcd(M->row[i], M->n_col, &gcd);
1198
if (isl_int_is_divisible_by(gcd, M->row[0][0]))
1200
div = isl_basic_map_alloc_div(bmap);
1203
isl_int_set_si(bmap->div[div][0], 0);
1204
k = isl_basic_map_alloc_equality(bmap);
1207
isl_seq_cpy(bmap->eq[k], M->row[i], M->n_col);
1208
isl_seq_clr(bmap->eq[k] + M->n_col, bmap->n_div - n_known);
1209
isl_int_set(bmap->eq[k][M->n_col - n_known + div],
1217
isl_basic_map_free(bmap);
1221
/* If there are any equalities that involve (multiple) unknown divs,
1222
* then extract the stride information encoded by those equalities
1223
* and make it explicitly available in "bmap".
1225
* We first sort the divs so that the unknown divs appear last and
1226
* then we count how many equalities involve these divs.
1228
* Let these equalities be of the form
1232
* where y represents the unknown divs and x the remaining variables.
1233
* Let [H 0] be the Hermite Normal Form of B, i.e.,
1237
* Then x is a solution of the equalities iff
1239
* H^-1 A(x) (= - [I 0] Q y)
1241
* is an integer vector. Let d be the common denominator of H^-1.
1244
* d H^-1 A(x) = d alpha
1246
* in add_strides, with alpha fresh existentially quantified variables.
1248
static __isl_give isl_basic_map *isl_basic_map_make_strides_explicit(
1249
__isl_take isl_basic_map *bmap)
1258
known = isl_basic_map_divs_known(bmap);
1260
return isl_basic_map_free(bmap);
1263
bmap = isl_basic_map_sort_divs(bmap);
1264
bmap = isl_basic_map_gauss(bmap, NULL);
1268
for (n_known = 0; n_known < bmap->n_div; ++n_known)
1269
if (isl_int_is_zero(bmap->div[n_known][0]))
1271
ctx = isl_basic_map_get_ctx(bmap);
1272
total = isl_space_dim(bmap->dim, isl_dim_all);
1273
for (n = 0; n < bmap->n_eq; ++n)
1274
if (isl_seq_first_non_zero(bmap->eq[n] + 1 + total + n_known,
1275
bmap->n_div - n_known) == -1)
1279
B = isl_mat_sub_alloc6(ctx, bmap->eq, 0, n, 0, 1 + total + n_known);
1280
n_col = bmap->n_div - n_known;
1281
A = isl_mat_sub_alloc6(ctx, bmap->eq, 0, n, 1 + total + n_known, n_col);
1282
A = isl_mat_left_hermite(A, 0, NULL, NULL);
1283
A = isl_mat_drop_cols(A, n, n_col - n);
1284
A = isl_mat_lin_to_aff(A);
1285
A = isl_mat_right_inverse(A);
1286
B = isl_mat_insert_zero_rows(B, 0, 1);
1287
B = isl_mat_set_element_si(B, 0, 0, 1);
1288
M = isl_mat_product(A, B);
1290
return isl_basic_map_free(bmap);
1291
bmap = add_strides(bmap, M, n_known);
1292
bmap = isl_basic_map_gauss(bmap, NULL);
1298
/* Compute the affine hull of each basic map in "map" separately
1299
* and make all stride information explicit so that we can remove
1300
* all unknown divs without losing this information.
1301
* The result is also guaranteed to be gaussed.
1303
* In simple cases where a div is determined by an equality,
1304
* calling isl_basic_map_gauss is enough to make the stride information
1305
* explicit, as it will derive an explicit representation for the div
1306
* from the equality. If, however, the stride information
1307
* is encoded through multiple unknown divs then we need to make
1308
* some extra effort in isl_basic_map_make_strides_explicit.
1310
static __isl_give isl_map *isl_map_local_affine_hull(__isl_take isl_map *map)
1314
map = isl_map_cow(map);
1318
for (i = 0; i < map->n; ++i) {
1319
map->p[i] = isl_basic_map_affine_hull(map->p[i]);
1320
map->p[i] = isl_basic_map_gauss(map->p[i], NULL);
1321
map->p[i] = isl_basic_map_make_strides_explicit(map->p[i]);
1323
return isl_map_free(map);
1329
static __isl_give isl_set *isl_set_local_affine_hull(__isl_take isl_set *set)
1331
return isl_map_local_affine_hull(set);
1334
/* Compute the affine hull of "map".
1336
* We first compute the affine hull of each basic map separately.
1337
* Then we align the divs and recompute the affine hulls of the basic
1338
* maps since some of them may now have extra divs.
1339
* In order to avoid performing parametric integer programming to
1340
* compute explicit expressions for the divs, possible leading to
1341
* an explosion in the number of basic maps, we first drop all unknown
1342
* divs before aligning the divs. Note that isl_map_local_affine_hull tries
1343
* to make sure that all stride information is explicitly available
1344
* in terms of known divs. This involves calling isl_basic_set_gauss,
1345
* which is also needed because affine_hull assumes its input has been gaussed,
1346
* while isl_map_affine_hull may be called on input that has not been gaussed,
1347
* in particular from initial_facet_constraint.
1348
* Similarly, align_divs may reorder some divs so that we need to
1349
* gauss the result again.
1350
* Finally, we combine the individual affine hulls into a single
1353
__isl_give isl_basic_map *isl_map_affine_hull(__isl_take isl_map *map)
1187
1355
struct isl_basic_map *model = NULL;
1188
1356
struct isl_basic_map *hull = NULL;
1189
1357
struct isl_set *set;
1358
isl_basic_set *bset;
1191
1360
map = isl_map_detect_equalities(map);
1361
map = isl_map_local_affine_hull(map);
1362
map = isl_map_remove_empty_parts(map);
1363
map = isl_map_remove_unknown_divs(map);
1192
1364
map = isl_map_align_divs(map);