free(qp);
}
+__isl_give struct isl_upoly *isl_upoly_pow(isl_ctx *ctx, int pos, int power)
+{
+ int i;
+ struct isl_upoly *up;
+ struct isl_upoly_rec *rec;
+ struct isl_upoly_cst *cst;
+
+ rec = isl_upoly_alloc_rec(ctx, pos, 1 + power);
+ if (!rec)
+ return NULL;
+ for (i = 0; i < 1 + power; ++i) {
+ rec->p[i] = isl_upoly_zero(ctx);
+ if (!rec->p[i])
+ goto error;
+ rec->n++;
+ }
+ cst = isl_upoly_as_cst(rec->p[power]);
+ isl_int_set_si(cst->n, 1);
+
+ return &rec->up;
+error:
+ isl_upoly_free(&rec->up);
+ return NULL;
+}
+
+/* r array maps original positions to new positions.
+ */
+static __isl_give struct isl_upoly *reorder(__isl_take struct isl_upoly *up,
+ int *r)
+{
+ int i;
+ struct isl_upoly_rec *rec;
+ struct isl_upoly *base;
+ struct isl_upoly *res;
+
+ if (isl_upoly_is_cst(up))
+ return up;
+
+ rec = isl_upoly_as_rec(up);
+ if (!rec)
+ goto error;
+
+ isl_assert(up->ctx, rec->n >= 1, goto error);
+
+ base = isl_upoly_pow(up->ctx, r[up->var], 1);
+ res = reorder(isl_upoly_copy(rec->p[rec->n - 1]), r);
+
+ for (i = rec->n - 2; i >= 0; --i) {
+ res = isl_upoly_mul(res, isl_upoly_copy(base));
+ res = isl_upoly_sum(res, reorder(isl_upoly_copy(rec->p[i]), r));
+ }
+
+ isl_upoly_free(base);
+ isl_upoly_free(up);
+
+ return res;
+error:
+ isl_upoly_free(up);
+ return NULL;
+}
+
static int compatible_divs(__isl_keep isl_mat *div1, __isl_keep isl_mat *div2)
{
int n_row, n_col;
return cmp_row(i1->div, i1->row, i2->row);
}
-static __isl_give isl_mat *sort_divs(__isl_take isl_mat *div)
+static __isl_give isl_qpolynomial *sort_divs(__isl_take isl_qpolynomial *qp)
{
int i;
struct isl_div_sort_info *array = NULL;
int *pos = NULL;
+ int *reordering = NULL;
+ unsigned div_pos;
- if (!div)
+ if (!qp)
return NULL;
- if (div->n_row <= 1)
- return div;
+ if (qp->div->n_row <= 1)
+ return qp;
+
+ div_pos = isl_dim_total(qp->dim);
- array = isl_alloc_array(div->ctx, struct isl_div_sort_info, div->n_row);
- pos = isl_alloc_array(div->ctx, int, div->n_row);
- if (!array || !pos)
+ array = isl_alloc_array(qp->div->ctx, struct isl_div_sort_info,
+ qp->div->n_row);
+ pos = isl_alloc_array(qp->div->ctx, int, qp->div->n_row);
+ reordering = isl_alloc_array(qp->div->ctx, int, qp->div->n_col - 2);
+ if (!array || !pos || !reordering)
goto error;
- for (i = 0; i < div->n_row; ++i) {
- array[i].div = div;
+ for (i = 0; i < qp->div->n_row; ++i) {
+ array[i].div = qp->div;
array[i].row = i;
pos[i] = i;
}
- qsort(array, div->n_row, sizeof(struct isl_div_sort_info),
+ qsort(array, qp->div->n_row, sizeof(struct isl_div_sort_info),
div_sort_cmp);
- for (i = 0; i < div->n_row; ++i) {
+ for (i = 0; i < div_pos; ++i)
+ reordering[i] = i;
+
+ for (i = 0; i < qp->div->n_row; ++i)
+ reordering[div_pos + array[i].row] = div_pos + i;
+
+ for (i = 0; i < qp->div->n_row; ++i) {
int t;
if (pos[array[i].row] == i)
continue;
- div = isl_mat_cow(div);
- div = isl_mat_swap_rows(div, i, pos[array[i].row]);
+ qp->div = isl_mat_cow(qp->div);
+ qp->div = isl_mat_swap_rows(qp->div, i, pos[array[i].row]);
t = pos[array[i].row];
pos[array[i].row] = pos[i];
pos[i] = t;
}
+ qp->upoly = reorder(qp->upoly, reordering);
+
+ if (!qp->upoly || !qp->div)
+ goto error;
+
+ free(pos);
free(array);
+ free(reordering);
- return div;
+ return qp;
error:
free(pos);
free(array);
- isl_mat_free(div);
+ free(reordering);
+ isl_qpolynomial_free(qp);
return NULL;
}
upoly_update_den(qp->upoly, d);
}
-__isl_give struct isl_upoly *isl_upoly_pow(isl_ctx *ctx, int pos, int power)
-{
- int i;
- struct isl_upoly *up;
- struct isl_upoly_rec *rec;
- struct isl_upoly_cst *cst;
-
- rec = isl_upoly_alloc_rec(ctx, pos, 1 + power);
- if (!rec)
- return NULL;
- for (i = 0; i < 1 + power; ++i) {
- rec->p[i] = isl_upoly_zero(ctx);
- if (!rec->p[i])
- goto error;
- rec->n++;
- }
- cst = isl_upoly_as_cst(rec->p[power]);
- isl_int_set_si(cst->n, 1);
-
- return &rec->up;
-error:
- isl_upoly_free(&rec->up);
- return NULL;
-}
-
__isl_give isl_qpolynomial *isl_qpolynomial_pow(__isl_take isl_dim *dim,
int pos, int power)
{
return reordering;
}
-static __isl_give struct isl_upoly *reorder(__isl_take struct isl_upoly *up,
- int *r)
-{
- int i;
- struct isl_upoly_rec *rec;
- struct isl_upoly *base;
- struct isl_upoly *res;
-
- if (isl_upoly_is_cst(up))
- return up;
-
- rec = isl_upoly_as_rec(up);
- if (!rec)
- goto error;
-
- isl_assert(up->ctx, rec->n >= 1, goto error);
-
- base = isl_upoly_pow(up->ctx, r[up->var], 1);
- res = reorder(isl_upoly_copy(rec->p[rec->n - 1]), r);
-
- for (i = rec->n - 2; i >= 0; --i) {
- res = isl_upoly_mul(res, isl_upoly_copy(base));
- res = isl_upoly_sum(res, reorder(isl_upoly_copy(rec->p[i]), r));
- }
-
- isl_upoly_free(base);
- isl_upoly_free(up);
-
- return res;
-error:
- isl_upoly_free(up);
- return NULL;
-}
-
__isl_give isl_qpolynomial *isl_qpolynomial_move_dims(
__isl_take isl_qpolynomial *qp,
enum isl_dim_type dst_type, unsigned dst_pos,
g_dst_pos -= n;
qp->div = isl_mat_move_cols(qp->div, 2 + g_dst_pos, 2 + g_src_pos, n);
- qp->div = sort_divs(qp->div);
if (!qp->div)
goto error;
+ qp = sort_divs(qp);
+ if (!qp)
+ goto error;
reordering = reordering_move(qp->dim->ctx,
qp->div->n_col - 2, g_dst_pos, g_src_pos, n);