isl_tab: optionally save dual solution
authorSven Verdoolaege <skimo@kotnet.org>
Sat, 11 Jul 2009 13:15:26 +0000 (15:15 +0200)
committerSven Verdoolaege <skimo@kotnet.org>
Mon, 13 Jul 2009 21:40:11 +0000 (23:40 +0200)
isl_convex_hull.c
isl_lp.c
isl_map_simplify.c
isl_tab.c
isl_tab.h

index 3912cbf..caa1c0b 100644 (file)
@@ -2109,7 +2109,7 @@ static int is_bound(struct sh_data *data, struct isl_set *set, int j,
        isl_int_init(opt);
 
        res = isl_tab_min(data->ctx, data->p[j].tab, ineq, data->ctx->one,
-                               &opt, NULL);
+                               &opt, NULL, 0);
        if (res == isl_lp_ok && isl_int_is_neg(opt))
                isl_int_sub(ineq[0], ineq[0], opt);
 
index 559a4b5..9f8c314 100644 (file)
--- a/isl_lp.c
+++ b/isl_lp.c
@@ -17,7 +17,7 @@ enum isl_lp_result isl_tab_solve_lp(struct isl_basic_map *bmap, int maximize,
 
        bmap = isl_basic_map_gauss(bmap, NULL);
        tab = isl_tab_from_basic_map(bmap);
-       res = isl_tab_min(bmap->ctx, tab, f, bmap->ctx->one, opt, opt_denom);
+       res = isl_tab_min(bmap->ctx, tab, f, bmap->ctx->one, opt, opt_denom, 0);
        isl_tab_free(bmap->ctx, tab);
 
        if (maximize)
index abc7695..b797b5e 100644 (file)
@@ -2059,7 +2059,7 @@ static struct isl_basic_map *drop_more_redundant_divs(
                                construct_test_ineq(bmap, i, l, u,
                                                    vec->el, g, fl, fu);
                                res = isl_tab_min(ctx, tab, vec->el,
-                                                 ctx->one, &g, NULL);
+                                                 ctx->one, &g, NULL, 0);
                                if (res == isl_lp_error)
                                        goto error;
                                if (res == isl_lp_empty) {
index 579bac6..ac9310a 100644 (file)
--- a/isl_tab.c
+++ b/isl_tab.c
@@ -115,6 +115,7 @@ void isl_tab_free(struct isl_ctx *ctx, struct isl_tab *tab)
                return;
        free_undo(ctx, tab);
        isl_mat_free(ctx, tab->mat);
+       isl_vec_free(tab->dual);
        free(tab->var);
        free(tab->con);
        free(tab->row_var);
@@ -1547,7 +1548,8 @@ int isl_tab_is_equality(struct isl_ctx *ctx, struct isl_tab *tab, int con)
  * minmimal value returned in *opt).
  */
 enum isl_lp_result isl_tab_min(struct isl_ctx *ctx, struct isl_tab *tab,
-       isl_int *f, isl_int denom, isl_int *opt, isl_int *opt_denom)
+       isl_int *f, isl_int denom, isl_int *opt, isl_int *opt_denom,
+       unsigned flags)
 {
        int r;
        enum isl_lp_result res = isl_lp_ok;
@@ -1575,6 +1577,24 @@ enum isl_lp_result isl_tab_min(struct isl_ctx *ctx, struct isl_tab *tab,
        }
        if (drop_row(ctx, tab, var->index) < 0)
                return isl_lp_error;
+       if (ISL_FL_ISSET(flags, ISL_TAB_SAVE_DUAL)) {
+               int i;
+
+               isl_vec_free(tab->dual);
+               tab->dual = isl_vec_alloc(ctx, 1 + tab->n_con);
+               if (!tab->dual)
+                       return isl_lp_error;
+               isl_int_set(tab->dual->el[0], tab->mat->row[var->index][0]);
+               for (i = 0; i < tab->n_con; ++i) {
+                       if (tab->con[i].is_row)
+                               isl_int_set_si(tab->dual->el[1 + i], 0);
+                       else {
+                               int pos = 2 + tab->con[i].index;
+                               isl_int_set(tab->dual->el[1 + i],
+                                           tab->mat->row[var->index][pos]);
+                       }
+               }
+       }
        if (res == isl_lp_ok) {
                if (opt_denom) {
                        isl_int_set(*opt, tab->mat->row[var->index][1]);
index b9a9810..1df42e1 100644 (file)
--- a/isl_tab.h
+++ b/isl_tab.h
@@ -88,6 +88,8 @@ struct isl_tab {
        struct isl_tab_undo bottom;
        struct isl_tab_undo *top;
 
+       struct isl_vec *dual;
+
        unsigned need_undo : 1;
        unsigned rational : 1;
        unsigned empty : 1;
@@ -109,8 +111,10 @@ struct isl_tab *isl_tab_detect_equalities(struct isl_ctx *ctx,
                                struct isl_tab *tab);
 struct isl_tab *isl_tab_detect_redundant(struct isl_ctx *ctx,
                                struct isl_tab *tab);
+#define ISL_TAB_SAVE_DUAL      (1 << 0)
 enum isl_lp_result isl_tab_min(struct isl_ctx *ctx, struct isl_tab *tab,
-       isl_int *f, isl_int denom, isl_int *opt, isl_int *opt_denom);
+       isl_int *f, isl_int denom, isl_int *opt, isl_int *opt_denom,
+       unsigned flags);
 
 struct isl_tab *isl_tab_extend(struct isl_ctx *ctx, struct isl_tab *tab,
                                unsigned n_new);