separate out isl_tab_reduced_basis from isl_basic_set_reduced_basis
authorSven Verdoolaege <skimo@kotnet.org>
Sat, 26 Sep 2009 11:20:40 +0000 (13:20 +0200)
committerSven Verdoolaege <skimo@kotnet.org>
Fri, 9 Oct 2009 08:41:15 +0000 (10:41 +0200)
This allows us to compute a reduced basis on a set given in tableau form.

basis_reduction_tab.c
basis_reduction_templ.c
isl_basis_reduction.h

index afe51fe..a3053d8 100644 (file)
@@ -20,7 +20,7 @@ struct tab_lp {
        int              is_fixed;
 };
 
-static struct tab_lp *init_lp(struct isl_basic_set *bset);
+static struct tab_lp *init_lp(struct isl_tab *tab);
 static void set_lp_obj(struct tab_lp *lp, isl_int *row, int dim);
 static int solve_lp(struct tab_lp *lp);
 static void get_obj_val(struct tab_lp* lp, mpq_t *F);
@@ -58,21 +58,17 @@ static int cut_lp_to_hyperplane(struct tab_lp *lp, isl_int *row);
  * This could be optimized by first setting up a tableau for bset
  * and then performing the Cartesian product on the tableau.
  */
-static struct isl_tab *gbr_tab(struct isl_basic_set *bset,
-       struct isl_vec *row)
+static struct isl_tab *gbr_tab(struct isl_tab *tab, struct isl_vec *row)
 {
        int i, j;
        unsigned dim;
-       struct isl_tab *tab;
        struct isl_tab *prod;
 
-       if (!bset || !row)
+       if (!tab || !row)
                return NULL;
 
-       dim = isl_basic_set_total_dim(bset);
-       tab = isl_tab_from_basic_set(bset);
+       dim = tab->n_var;
        prod = isl_tab_product(tab, tab);
-       isl_tab_free(tab);
        if (isl_tab_extend_cons(prod, 3 * dim + 1) < 0) {
                isl_tab_free(prod);
                return NULL;
@@ -80,16 +76,14 @@ static struct isl_tab *gbr_tab(struct isl_basic_set *bset,
        return prod;
 }
 
-static struct tab_lp *init_lp(struct isl_basic_set *bset)
+static struct tab_lp *init_lp(struct isl_tab *tab)
 {
        struct tab_lp *lp = NULL;
 
-       if (!bset)
+       if (!tab)
                return NULL;
 
-       isl_assert(bset->ctx, bset->n_eq == 0, return NULL);
-
-       lp = isl_calloc_type(bset->ctx, struct tab_lp);
+       lp = isl_calloc_type(tab->mat->ctx, struct tab_lp);
        if (!lp)
                return NULL;
 
@@ -98,9 +92,9 @@ static struct tab_lp *init_lp(struct isl_basic_set *bset)
        isl_int_init(lp->tmp);
        isl_int_init(lp->tmp2);
 
-       lp->dim = isl_basic_set_total_dim(bset);
+       lp->dim = tab->n_var;
 
-       lp->ctx = bset->ctx;
+       lp->ctx = tab->mat->ctx;
        isl_ctx_ref(lp->ctx);
 
        lp->stack = isl_alloc_array(lp->ctx, struct isl_tab_undo *, lp->dim);
@@ -108,7 +102,7 @@ static struct tab_lp *init_lp(struct isl_basic_set *bset)
        lp->row = isl_vec_alloc(lp->ctx, 1 + 2 * lp->dim);
        if (!lp->row)
                goto error;
-       lp->tab = gbr_tab(bset, lp->row);
+       lp->tab = gbr_tab(tab, lp->row);
        if (!lp->tab)
                goto error;
        lp->con_offset = lp->tab->n_con;
index 988bde1..56aac95 100644 (file)
@@ -18,9 +18,10 @@ static void save_alpha(GBR_LP *lp, int first, int n, GBR_type *alpha)
  * in the first direction.  In this case we stop the basis reduction when
  * the width in the first direction becomes smaller than 2.
  */
-struct isl_mat *isl_basic_set_reduced_basis(struct isl_basic_set *bset)
+struct isl_mat *isl_tab_reduced_basis(struct isl_tab *tab)
 {
        unsigned dim;
+       struct isl_ctx *ctx;
        struct isl_mat *basis;
        int unbounded;
        int i;
@@ -44,11 +45,12 @@ struct isl_mat *isl_basic_set_reduced_basis(struct isl_basic_set *bset)
        int fixed_saved = 0;
        int mu_fixed[2];
 
-       if (!bset)
+       if (!tab)
                return NULL;
 
-       dim = isl_basic_set_total_dim(bset);
-       basis = isl_mat_identity(bset->ctx, dim);
+       ctx = tab->mat->ctx;
+       dim = tab->n_var;
+       basis = isl_mat_identity(ctx, dim);
        if (!basis)
                return NULL;
 
@@ -68,13 +70,13 @@ struct isl_mat *isl_basic_set_reduced_basis(struct isl_basic_set *bset)
        GBR_init(two);
        GBR_init(one);
 
-       b_tmp = isl_vec_alloc(bset->ctx, dim);
+       b_tmp = isl_vec_alloc(ctx, dim);
        if (!b_tmp)
                goto error;
 
-       F = isl_alloc_array(bset->ctx, GBR_type, dim);
-       alpha_buffer[0] = isl_alloc_array(bset->ctx, GBR_type, dim);
-       alpha_buffer[1] = isl_alloc_array(bset->ctx, GBR_type, dim);
+       F = isl_alloc_array(ctx, GBR_type, dim);
+       alpha_buffer[0] = isl_alloc_array(ctx, GBR_type, dim);
+       alpha_buffer[1] = isl_alloc_array(ctx, GBR_type, dim);
        alpha_saved = alpha_buffer[0];
 
        if (!F || !alpha_buffer[0] || !alpha_buffer[1])
@@ -89,16 +91,16 @@ struct isl_mat *isl_basic_set_reduced_basis(struct isl_basic_set *bset)
        GBR_set_ui(two, 2);
        GBR_set_ui(one, 1);
 
-       lp = GBR_lp_init(bset);
+       lp = GBR_lp_init(tab);
        if (!lp)
                goto error;
 
        i = 0;
 
        GBR_lp_set_obj(lp, basis->row[0], dim);
-       bset->ctx->stats->gbr_solved_lps++;
+       ctx->stats->gbr_solved_lps++;
        unbounded = GBR_lp_solve(lp);
-       isl_assert(bset->ctx, !unbounded, goto error);
+       isl_assert(ctx, !unbounded, goto error);
        GBR_lp_get_obj_val(lp, &F[0]);
 
        if (GBR_lt(F[0], one)) {
@@ -114,9 +116,9 @@ struct isl_mat *isl_basic_set_reduced_basis(struct isl_basic_set *bset)
        do {
                if (i+1 == n_zero) {
                        GBR_lp_set_obj(lp, basis->row[i+1], dim);
-                       bset->ctx->stats->gbr_solved_lps++;
+                       ctx->stats->gbr_solved_lps++;
                        unbounded = GBR_lp_solve(lp);
-                       isl_assert(bset->ctx, !unbounded, goto error);
+                       isl_assert(ctx, !unbounded, goto error);
                        GBR_lp_get_obj_val(lp, &F_new);
                        fixed = GBR_lp_is_fixed(lp);
                        GBR_set_ui(alpha, 0);
@@ -129,9 +131,9 @@ struct isl_mat *isl_basic_set_reduced_basis(struct isl_basic_set *bset)
                } else {
                        row = GBR_lp_add_row(lp, basis->row[i], dim);
                        GBR_lp_set_obj(lp, basis->row[i+1], dim);
-                       bset->ctx->stats->gbr_solved_lps++;
+                       ctx->stats->gbr_solved_lps++;
                        unbounded = GBR_lp_solve(lp);
-                       isl_assert(bset->ctx, !unbounded, goto error);
+                       isl_assert(ctx, !unbounded, goto error);
                        GBR_lp_get_obj_val(lp, &F_new);
                        fixed = GBR_lp_is_fixed(lp);
 
@@ -155,12 +157,12 @@ struct isl_mat *isl_basic_set_reduced_basis(struct isl_basic_set *bset)
                        for (j = 0; j <= 1; ++j) {
                                isl_int_set(tmp, mu[j]);
                                isl_seq_combine(b_tmp->el,
-                                               bset->ctx->one, basis->row[i+1],
+                                               ctx->one, basis->row[i+1],
                                                tmp, basis->row[i], dim);
                                GBR_lp_set_obj(lp, b_tmp->el, dim);
-                               bset->ctx->stats->gbr_solved_lps++;
+                               ctx->stats->gbr_solved_lps++;
                                unbounded = GBR_lp_solve(lp);
-                               isl_assert(bset->ctx, !unbounded, goto error);
+                               isl_assert(ctx, !unbounded, goto error);
                                GBR_lp_get_obj_val(lp, &mu_F[j]);
                                mu_fixed[j] = GBR_lp_is_fixed(lp);
                                if (i > 0)
@@ -177,8 +179,7 @@ struct isl_mat *isl_basic_set_reduced_basis(struct isl_basic_set *bset)
                        fixed = mu_fixed[j];
                        alpha_saved = alpha_buffer[j];
                }
-               isl_seq_combine(basis->row[i+1],
-                               bset->ctx->one, basis->row[i+1],
+               isl_seq_combine(basis->row[i+1], ctx->one, basis->row[i+1],
                                tmp, basis->row[i], dim);
 
                if (i+1 == n_zero && fixed) {
@@ -209,8 +210,7 @@ struct isl_mat *isl_basic_set_reduced_basis(struct isl_basic_set *bset)
                                --i;
                        } else {
                                GBR_set(F[0], F_new);
-                               if (bset->ctx->gbr_only_first &&
-                                   GBR_lt(F[0], two))
+                               if (ctx->gbr_only_first && GBR_lt(F[0], two))
                                        break;
 
                                if (fixed) {
@@ -267,3 +267,18 @@ error:
 
        return basis;
 }
+
+struct isl_mat *isl_basic_set_reduced_basis(struct isl_basic_set *bset)
+{
+       struct isl_mat *basis;
+       struct isl_tab *tab;
+
+       isl_assert(bset->ctx, bset->n_eq == 0, return NULL);
+
+       tab = isl_tab_from_basic_set(bset);
+       basis = isl_tab_reduced_basis(tab);
+
+       isl_tab_free(tab);
+
+       return basis;
+}
index cc28bae..dffb724 100644 (file)
@@ -3,11 +3,13 @@
 
 #include "isl_set.h"
 #include "isl_mat.h"
+#include "isl_tab.h"
 
 #if defined(__cplusplus)
 extern "C" {
 #endif
 
+struct isl_mat *isl_tab_reduced_basis(struct isl_tab *tab);
 struct isl_mat *isl_basic_set_reduced_basis(struct isl_basic_set *bset);
 
 #if defined(__cplusplus)