X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=isl_lp.c;h=28e317cca1b8d3bf42f41082b92d5c026b2ba7c7;hb=63fb8a7f484648c3caa25351c8c94ac2395ec563;hp=533f20fc267eb9c1e5141060e794d60b6001f653;hpb=2b5b1c229c88bc61da4163431711d762eac2cc81;p=platform%2Fupstream%2Fisl.git diff --git a/isl_lp.c b/isl_lp.c index 533f20f..28e317c 100644 --- a/isl_lp.c +++ b/isl_lp.c @@ -1,9 +1,19 @@ -#include "isl_ctx.h" -#include "isl_lp.h" +/* + * Copyright 2008-2009 Katholieke Universiteit Leuven + * + * Use of this software is governed by the MIT license + * + * Written by Sven Verdoolaege, K.U.Leuven, Departement + * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium + */ + +#include +#include +#include #include "isl_lp_piplib.h" -#include "isl_seq.h" +#include #include "isl_tab.h" -#include "isl_map_private.h" +#include enum isl_lp_result isl_tab_solve_lp(struct isl_basic_map *bmap, int maximize, isl_int *f, isl_int denom, isl_int *opt, @@ -18,8 +28,8 @@ enum isl_lp_result isl_tab_solve_lp(struct isl_basic_map *bmap, int maximize, isl_seq_neg(f, f, 1 + dim); bmap = isl_basic_map_gauss(bmap, NULL); - tab = isl_tab_from_basic_map(bmap); - res = isl_tab_min(tab, f, bmap->ctx->one, opt, opt_denom, 0); + tab = isl_tab_from_basic_map(bmap, 0); + res = isl_tab_min(tab, f, denom, opt, opt_denom, 0); if (res == isl_lp_ok && sol) { *sol = isl_tab_get_sample_value(tab); if (!*sol) @@ -29,12 +39,14 @@ enum isl_lp_result isl_tab_solve_lp(struct isl_basic_map *bmap, int maximize, if (maximize) isl_seq_neg(f, f, 1 + dim); + if (maximize && opt) + isl_int_neg(*opt, *opt); return res; } /* Given a basic map "bmap" and an affine combination of the variables "f" - * with denominator "denom", set *opt/*opt_denom to the minimal + * with denominator "denom", set *opt / *opt_denom to the minimal * (or maximal if "maximize" is true) value attained by f/d over "bmap", * assuming the basic map is not empty and the expression cannot attain * arbitrarily small (or large) values. @@ -72,3 +84,121 @@ enum isl_lp_result isl_basic_set_solve_lp(struct isl_basic_set *bset, int max, return isl_basic_map_solve_lp((struct isl_basic_map *)bset, max, f, d, opt, opt_denom, sol); } + +enum isl_lp_result isl_map_solve_lp(__isl_keep isl_map *map, int max, + isl_int *f, isl_int d, isl_int *opt, + isl_int *opt_denom, + struct isl_vec **sol) +{ + int i; + isl_int o; + isl_int t; + isl_int opt_i; + isl_int opt_denom_i; + enum isl_lp_result res; + int max_div; + isl_vec *v = NULL; + + if (!map) + return isl_lp_error; + if (map->n == 0) + return isl_lp_empty; + + max_div = 0; + for (i = 0; i < map->n; ++i) + if (map->p[i]->n_div > max_div) + max_div = map->p[i]->n_div; + if (max_div > 0) { + unsigned total = isl_space_dim(map->dim, isl_dim_all); + v = isl_vec_alloc(map->ctx, 1 + total + max_div); + if (!v) + return isl_lp_error; + isl_seq_cpy(v->el, f, 1 + total); + isl_seq_clr(v->el + 1 + total, max_div); + f = v->el; + } + + if (!opt && map->n > 1 && sol) { + isl_int_init(o); + opt = &o; + } + if (map->n > 0) + isl_int_init(opt_i); + if (map->n > 0 && opt_denom) { + isl_int_init(opt_denom_i); + isl_int_init(t); + } + + res = isl_basic_map_solve_lp(map->p[0], max, f, d, + opt, opt_denom, sol); + if (res == isl_lp_error || res == isl_lp_unbounded) + goto done; + + if (sol) + *sol = NULL; + + for (i = 1; i < map->n; ++i) { + isl_vec *sol_i = NULL; + enum isl_lp_result res_i; + int better; + + res_i = isl_basic_map_solve_lp(map->p[i], max, f, d, + &opt_i, + opt_denom ? &opt_denom_i : NULL, + sol ? &sol_i : NULL); + if (res_i == isl_lp_error || res_i == isl_lp_unbounded) { + res = res_i; + goto done; + } + if (res_i == isl_lp_empty) + continue; + if (res == isl_lp_empty) { + better = 1; + } else if (!opt_denom) { + if (max) + better = isl_int_gt(opt_i, *opt); + else + better = isl_int_lt(opt_i, *opt); + } else { + isl_int_mul(t, opt_i, *opt_denom); + isl_int_submul(t, *opt, opt_denom_i); + if (max) + better = isl_int_is_pos(t); + else + better = isl_int_is_neg(t); + } + if (better) { + res = res_i; + if (opt) + isl_int_set(*opt, opt_i); + if (opt_denom) + isl_int_set(*opt_denom, opt_denom_i); + if (sol) { + isl_vec_free(*sol); + *sol = sol_i; + } + } else + isl_vec_free(sol_i); + } + +done: + isl_vec_free(v); + if (map->n > 0 && opt_denom) { + isl_int_clear(opt_denom_i); + isl_int_clear(t); + } + if (map->n > 0) + isl_int_clear(opt_i); + if (opt == &o) + isl_int_clear(o); + return res; +} + +enum isl_lp_result isl_set_solve_lp(__isl_keep isl_set *set, int max, + isl_int *f, isl_int d, isl_int *opt, + isl_int *opt_denom, + struct isl_vec **sol) +{ + return isl_map_solve_lp((struct isl_map *)set, max, + f, d, opt, opt_denom, sol); +}