Esempio n. 1
0
int isl_set_count_upto(__isl_keep isl_set *set, isl_int max, isl_int *count)
{
	struct isl_counter cnt = { { &increment_counter } };

	if (!set)
		return -1;

	isl_int_init(cnt.count);
	isl_int_init(cnt.max);

	isl_int_set_si(cnt.count, 0);
	isl_int_set(cnt.max, max);
	if (isl_set_scan(isl_set_copy(set), &cnt.callback) < 0 &&
	    isl_int_lt(cnt.count, cnt.max))
		goto error;

	isl_int_set(*count, cnt.count);
	isl_int_clear(cnt.max);
	isl_int_clear(cnt.count);

	return 0;
error:
	isl_int_clear(cnt.count);
	return -1;
}
Esempio n. 2
0
/// Add an isl constraint to an ScopLib matrix.
///
/// @param user The matrix
/// @param c The constraint
int ScopLib::accessToMatrix_constraint(isl_constraint *c, void *user) {
  scoplib_matrix_p m = (scoplib_matrix_p) user;

  int nb_params = isl_constraint_dim(c, isl_dim_param);
  int nb_in = isl_constraint_dim(c, isl_dim_in);
  int nb_div = isl_constraint_dim(c, isl_dim_div);

  assert(!nb_div && "Existentially quantified variables not yet supported");

  scoplib_vector_p vec =
    scoplib_vector_malloc(nb_params + nb_in + 2);

  isl_int v;
  isl_int_init(v);

  // The access dimension has to be one.
  isl_constraint_get_coefficient(c, isl_dim_out, 0, &v);
  assert((isl_int_is_one(v) || isl_int_is_negone(v))
         && "Access relations not supported in scoplib");
  bool inverse = isl_int_is_one(v);

  // Assign variables
  for (int i = 0; i < nb_in; ++i) {
    isl_constraint_get_coefficient(c, isl_dim_in, i, &v);

    if (inverse) isl_int_neg(v,v);

    isl_int_set(vec->p[i + 1], v);
  }

  // Assign parameters
  for (int i = 0; i < nb_params; ++i) {
    isl_constraint_get_coefficient(c, isl_dim_param, i, &v);

    if (inverse) isl_int_neg(v,v);

    isl_int_set(vec->p[nb_in + i + 1], v);
  }

  // Assign constant
  isl_constraint_get_constant(c, &v);

  if (inverse) isl_int_neg(v,v);

  isl_int_set(vec->p[nb_in + nb_params + 1], v);

  scoplib_matrix_insert_vector(m, vec, m->NbRows);

  isl_constraint_free(c);
  isl_int_clear(v);

  return 0;
}
Esempio n. 3
0
/// Add an isl constraint to an ScopLib matrix.
///
/// @param user The matrix
/// @param c The constraint
int ScopLib::scatteringToMatrix_constraint(isl_constraint *c, void *user) {
  scoplib_matrix_p m = (scoplib_matrix_p) user;

  int nb_params = isl_constraint_dim(c, isl_dim_param);
  int nb_in = isl_constraint_dim(c, isl_dim_in);
  int nb_div = isl_constraint_dim(c, isl_dim_div);

  assert(!nb_div && "Existentially quantified variables not yet supported");

  scoplib_vector_p vec =
    scoplib_vector_malloc(nb_params + nb_in + 2);

  // Assign type
  if (isl_constraint_is_equality(c))
    scoplib_vector_tag_equality(vec);
  else
    scoplib_vector_tag_inequality(vec);

  isl_int v;
  isl_int_init(v);

  // Assign variables
  for (int i = 0; i < nb_in; ++i) {
    isl_constraint_get_coefficient(c, isl_dim_in, i, &v);
    isl_int_set(vec->p[i + 1], v);
  }

  // Assign parameters
  for (int i = 0; i < nb_params; ++i) {
    isl_constraint_get_coefficient(c, isl_dim_param, i, &v);
    isl_int_set(vec->p[nb_in + i + 1], v);
  }

  // Assign constant
  isl_constraint_get_constant(c, &v);
  isl_int_set(vec->p[nb_in + nb_params + 1], v);

  scoplib_vector_p null =
    scoplib_vector_malloc(nb_params + nb_in + 2);

  vec = scoplib_vector_sub(null, vec);
  scoplib_matrix_insert_vector(m, vec, 0);

  isl_constraint_free(c);
  isl_int_clear(v);

  return 0;
}
Esempio n. 4
0
static struct isl_vec *interval_sample(struct isl_basic_set *bset)
{
	int i;
	isl_int t;
	struct isl_vec *sample;

	bset = isl_basic_set_simplify(bset);
	if (!bset)
		return NULL;
	if (isl_basic_set_plain_is_empty(bset))
		return empty_sample(bset);
	if (bset->n_eq == 0 && bset->n_ineq == 0)
		return zero_sample(bset);

	sample = isl_vec_alloc(bset->ctx, 2);
	if (!sample)
		goto error;
	if (!bset)
		return NULL;
	isl_int_set_si(sample->block.data[0], 1);

	if (bset->n_eq > 0) {
		isl_assert(bset->ctx, bset->n_eq == 1, goto error);
		isl_assert(bset->ctx, bset->n_ineq == 0, goto error);
		if (isl_int_is_one(bset->eq[0][1]))
			isl_int_neg(sample->el[1], bset->eq[0][0]);
		else {
			isl_assert(bset->ctx, isl_int_is_negone(bset->eq[0][1]),
				   goto error);
			isl_int_set(sample->el[1], bset->eq[0][0]);
		}
		isl_basic_set_free(bset);
		return sample;
	}
Esempio n. 5
0
void isl_point_get_coordinate(__isl_keep isl_point *pnt,
	enum isl_dim_type type, int pos, isl_int *v)
{
	if (!pnt || isl_point_is_void(pnt))
		return;
	if (type == isl_dim_set)
		pos += isl_dim_size(pnt->dim, isl_dim_param);
	isl_int_set(*v, pnt->vec->el[1 + pos]);
}
Esempio n. 6
0
/* Compute a common lattice of solutions to the linear modulo
 * constraints specified by B and d.
 * See also the documentation of isl_mat_parameter_compression.
 * We put the matrix
 * 
 *		A = [ L_1^{-T} L_2^{-T} ... L_k^{-T} ]
 *
 * on a common denominator.  This denominator D is the lcm of modulos d.
 * Since L_i = U_i^{-1} diag(d_i, 1, ... 1), we have
 * L_i^{-T} = U_i^T diag(d_i, 1, ... 1)^{-T} = U_i^T diag(1/d_i, 1, ..., 1).
 * Putting this on the common denominator, we have
 * D * L_i^{-T} = U_i^T diag(D/d_i, D, ..., D).
 */
static struct isl_mat *parameter_compression_multi(
			struct isl_mat *B, struct isl_vec *d)
{
	int i, j, k;
	isl_int D;
	struct isl_mat *A = NULL, *U = NULL;
	struct isl_mat *T;
	unsigned size;

	isl_int_init(D);

	isl_vec_lcm(d, &D);

	size = B->n_col - 1;
	A = isl_mat_alloc(B->ctx, size, B->n_row * size);
	U = isl_mat_alloc(B->ctx, size, size);
	if (!U || !A)
		goto error;
	for (i = 0; i < B->n_row; ++i) {
		isl_seq_cpy(U->row[0], B->row[i] + 1, size);
		U = isl_mat_unimodular_complete(U, 1);
		if (!U)
			goto error;
		isl_int_divexact(D, D, d->block.data[i]);
		for (k = 0; k < U->n_col; ++k)
			isl_int_mul(A->row[k][i*size+0], D, U->row[0][k]);
		isl_int_mul(D, D, d->block.data[i]);
		for (j = 1; j < U->n_row; ++j)
			for (k = 0; k < U->n_col; ++k)
				isl_int_mul(A->row[k][i*size+j],
						D, U->row[j][k]);
	}
	A = isl_mat_left_hermite(A, 0, NULL, NULL);
	T = isl_mat_sub_alloc(A, 0, A->n_row, 0, A->n_row);
	T = isl_mat_lin_to_aff(T);
	if (!T)
		goto error;
	isl_int_set(T->row[0][0], D);
	T = isl_mat_right_inverse(T);
	if (!T)
		goto error;
	isl_assert(T->ctx, isl_int_is_one(T->row[0][0]), goto error);
	T = isl_mat_transpose(T);
	isl_mat_free(A);
	isl_mat_free(U);

	isl_int_clear(D);
	return T;
error:
	isl_mat_free(A);
	isl_mat_free(U);
	isl_int_clear(D);
	return NULL;
}
Esempio n. 7
0
static void expand_constraint(isl_vec *v, unsigned dim,
	isl_int *c, int *div_map, unsigned n_div)
{
	int i;

	isl_seq_cpy(v->el, c, 1 + dim);
	isl_seq_clr(v->el + 1 + dim, v->size - (1 + dim));

	for (i = 0; i < n_div; ++i)
		isl_int_set(v->el[1 + dim + div_map[i]], c[1 + dim + i]);
}
Esempio n. 8
0
/* Given a set of modulo constraints
 *
 *		c + A y = 0 mod d
 *
 * this function computes a particular solution y_0
 *
 * The input is given as a matrix B = [ c A ] and a vector d.
 *
 * The output is matrix containing the solution y_0 or
 * a zero-column matrix if the constraints admit no integer solution.
 *
 * The given set of constrains is equivalent to
 *
 *		c + A y = -D x
 *
 * with D = diag d and x a fresh set of variables.
 * Reducing both c and A modulo d does not change the
 * value of y in the solution and may lead to smaller coefficients.
 * Let M = [ D A ] and [ H 0 ] = M U, the Hermite normal form of M.
 * Then
 *		  [ x ]
 *		M [ y ] = - c
 * and so
 *		               [ x ]
 *		[ H 0 ] U^{-1} [ y ] = - c
 * Let
 *		[ A ]          [ x ]
 *		[ B ] = U^{-1} [ y ]
 * then
 *		H A + 0 B = -c
 *
 * so B may be chosen arbitrarily, e.g., B = 0, and then
 *
 *		       [ x ] = [ -c ]
 *		U^{-1} [ y ] = [  0 ]
 * or
 *		[ x ]     [ -c ]
 *		[ y ] = U [  0 ]
 * specifically,
 *
 *		y = U_{2,1} (-c)
 *
 * If any of the coordinates of this y are non-integer
 * then the constraints admit no integer solution and
 * a zero-column matrix is returned.
 */
static struct isl_mat *particular_solution(struct isl_mat *B, struct isl_vec *d)
{
	int i, j;
	struct isl_mat *M = NULL;
	struct isl_mat *C = NULL;
	struct isl_mat *U = NULL;
	struct isl_mat *H = NULL;
	struct isl_mat *cst = NULL;
	struct isl_mat *T = NULL;

	M = isl_mat_alloc(B->ctx, B->n_row, B->n_row + B->n_col - 1);
	C = isl_mat_alloc(B->ctx, 1 + B->n_row, 1);
	if (!M || !C)
		goto error;
	isl_int_set_si(C->row[0][0], 1);
	for (i = 0; i < B->n_row; ++i) {
		isl_seq_clr(M->row[i], B->n_row);
		isl_int_set(M->row[i][i], d->block.data[i]);
		isl_int_neg(C->row[1 + i][0], B->row[i][0]);
		isl_int_fdiv_r(C->row[1+i][0], C->row[1+i][0], M->row[i][i]);
		for (j = 0; j < B->n_col - 1; ++j)
			isl_int_fdiv_r(M->row[i][B->n_row + j],
					B->row[i][1 + j], M->row[i][i]);
	}
	M = isl_mat_left_hermite(M, 0, &U, NULL);
	if (!M || !U)
		goto error;
	H = isl_mat_sub_alloc(M, 0, B->n_row, 0, B->n_row);
	H = isl_mat_lin_to_aff(H);
	C = isl_mat_inverse_product(H, C);
	if (!C)
		goto error;
	for (i = 0; i < B->n_row; ++i) {
		if (!isl_int_is_divisible_by(C->row[1+i][0], C->row[0][0]))
			break;
		isl_int_divexact(C->row[1+i][0], C->row[1+i][0], C->row[0][0]);
	}
	if (i < B->n_row)
		cst = isl_mat_alloc(B->ctx, B->n_row, 0);
	else
		cst = isl_mat_sub_alloc(C, 1, B->n_row, 0, 1);
	T = isl_mat_sub_alloc(U, B->n_row, B->n_col - 1, 0, B->n_row);
	cst = isl_mat_product(T, cst);
	isl_mat_free(M);
	isl_mat_free(C);
	isl_mat_free(U);
	return cst;
error:
	isl_mat_free(M);
	isl_mat_free(C);
	isl_mat_free(U);
	return NULL;
}
Esempio n. 9
0
static int increment_range(struct isl_scan_callback *cb, isl_int min, isl_int max)
{
	struct isl_counter *cnt = (struct isl_counter *)cb;

	isl_int_add(cnt->count, cnt->count, max);
	isl_int_sub(cnt->count, cnt->count, min);
	isl_int_add_ui(cnt->count, cnt->count, 1);

	if (isl_int_is_zero(cnt->max) || isl_int_lt(cnt->count, cnt->max))
		return 0;
	isl_int_set(cnt->count, cnt->max);
	return -1;
}
Esempio n. 10
0
static int tab_add_divs(struct isl_tab *tab, __isl_keep isl_basic_map *bmap,
	int **div_map)
{
	int i, j;
	struct isl_vec *vec;
	unsigned total;
	unsigned dim;

	if (!bmap)
		return -1;
	if (!bmap->n_div)
		return 0;

	if (!*div_map)
		*div_map = isl_alloc_array(bmap->ctx, int, bmap->n_div);
	if (!*div_map)
		return -1;

	total = isl_basic_map_total_dim(tab->bmap);
	dim = total - tab->bmap->n_div;
	vec = isl_vec_alloc(bmap->ctx, 2 + total + bmap->n_div);
	if (!vec)
		return -1;

	for (i = 0; i < bmap->n_div; ++i) {
		isl_seq_cpy(vec->el, bmap->div[i], 2 + dim);
		isl_seq_clr(vec->el + 2 + dim, tab->bmap->n_div);
		for (j = 0; j < i; ++j)
			isl_int_set(vec->el[2 + dim + (*div_map)[j]],
					bmap->div[i][2 + dim + j]);
		for (j = 0; j < tab->bmap->n_div; ++j)
			if (isl_seq_eq(tab->bmap->div[j],
					vec->el, 2 + dim + tab->bmap->n_div))
				break;
		(*div_map)[i] = j;
		if (j == tab->bmap->n_div) {
			vec->size = 2 + dim + tab->bmap->n_div;
			if (isl_tab_add_div(tab, vec) < 0)
				goto error;
		}
	}

	isl_vec_free(vec);

	return 0;
error:
	isl_vec_free(vec);

	return -1;
}
Esempio n. 11
0
enum isl_lp_result isl_pip_solve_lp(struct isl_basic_map *bmap, int maximize,
				      isl_int *f, isl_int denom, isl_int *opt,
				      isl_int *opt_denom,
				      struct isl_vec **vec)
{
	enum isl_lp_result res = isl_lp_ok;
	PipMatrix	*domain = NULL;
	PipOptions	*options;
	PipQuast   	*sol;
	unsigned	 total;

	total = isl_basic_map_total_dim(bmap);
	domain = isl_basic_map_to_pip(bmap, 0, 1, 0);
	if (!domain)
		goto error;
	entier_set_si(domain->p[0][1], -1);
	isl_int_set(domain->p[0][domain->NbColumns - 1], f[0]);
	isl_seq_cpy_to_pip(domain->p[0]+2, f+1, total);

	options = pip_options_init();
	if (!options)
		goto error;
	options->Urs_unknowns = -1;
	options->Maximize = maximize;
	options->Nq = 0;
	sol = pip_solve(domain, NULL, -1, options);
	pip_options_free(options);
	if (!sol)
		goto error;

	if (vec) {
		isl_ctx *ctx = isl_basic_map_get_ctx(bmap);
		*vec = isl_vec_alloc(ctx, 1 + total);
	}
	if (vec && !*vec)
		res = isl_lp_error;
	else if (!sol->list)
		res = isl_lp_empty;
	else if (entier_zero_p(sol->list->vector->the_deno[0]))
		res = isl_lp_unbounded;
	else
		copy_solution(*vec, maximize, opt, opt_denom, sol);
	pip_matrix_free(domain);
	pip_quast_free(sol);
	return res;
error:
	if (domain)
		pip_matrix_free(domain);
	return isl_lp_error;
}
Esempio n. 12
0
/* Given a matrix that maps a (possibly) parametric domain to
 * a parametric domain, add in rows that map the "nparam" parameters onto
 * themselves.
 */
static __isl_give isl_mat *insert_parameter_rows(__isl_take isl_mat *mat,
	unsigned nparam)
{
	int i;

	if (nparam == 0)
		return mat;
	if (!mat)
		return NULL;

	mat = isl_mat_insert_rows(mat, 1, nparam);
	if (!mat)
		return NULL;

	for (i = 0; i < nparam; ++i) {
		isl_seq_clr(mat->row[1 + i], mat->n_col);
		isl_int_set(mat->row[1 + i][1 + i], mat->row[0][0]);
	}

	return mat;
}
Esempio n. 13
0
__isl_give isl_point *isl_point_set_coordinate(__isl_take isl_point *pnt,
	enum isl_dim_type type, int pos, isl_int v)
{
	if (!pnt || isl_point_is_void(pnt))
		return pnt;

	pnt = isl_point_cow(pnt);
	if (!pnt)
		return NULL;
	pnt->vec = isl_vec_cow(pnt->vec);
	if (!pnt->vec)
		goto error;

	if (type == isl_dim_set)
		pos += isl_dim_size(pnt->dim, isl_dim_param);

	isl_int_set(pnt->vec->el[1 + pos], v);

	return pnt;
error:
	isl_point_free(pnt);
	return NULL;
}
Esempio n. 14
0
/* Add stride constraints to "bset" based on the inverse mapping
 * that was plugged in.  In particular, if morph maps x' to x,
 * the the constraints of the original input
 *
 *	A x' + b >= 0
 *
 * have been rewritten to
 *
 *	A inv x + b >= 0
 *
 * However, this substitution may loose information on the integrality of x',
 * so we need to impose that
 *
 *	inv x
 *
 * is integral.  If inv = B/d, this means that we need to impose that
 *
 *	B x = 0		mod d
 *
 * or
 *
 *	exists alpha in Z^m: B x = d alpha
 *
 */
static __isl_give isl_basic_set *add_strides(__isl_take isl_basic_set *bset,
	__isl_keep isl_morph *morph)
{
	int i, div, k;
	isl_int gcd;

	if (isl_int_is_one(morph->inv->row[0][0]))
		return bset;

	isl_int_init(gcd);

	for (i = 0; 1 + i < morph->inv->n_row; ++i) {
		isl_seq_gcd(morph->inv->row[1 + i], morph->inv->n_col, &gcd);
		if (isl_int_is_divisible_by(gcd, morph->inv->row[0][0]))
			continue;
		div = isl_basic_set_alloc_div(bset);
		if (div < 0)
			goto error;
		k = isl_basic_set_alloc_equality(bset);
		if (k < 0)
			goto error;
		isl_seq_cpy(bset->eq[k], morph->inv->row[1 + i],
			    morph->inv->n_col);
		isl_seq_clr(bset->eq[k] + morph->inv->n_col, bset->n_div);
		isl_int_set(bset->eq[k][morph->inv->n_col + div],
			    morph->inv->row[0][0]);
	}

	isl_int_clear(gcd);

	return bset;
error:
	isl_int_clear(gcd);
	isl_basic_set_free(bset);
	return NULL;
}
Esempio n. 15
0
/* Compute a reduced basis for the set represented by the tableau "tab".
 * tab->basis, which must be initialized by the calling function to an affine
 * unimodular basis, is updated to reflect the reduced basis.
 * The first tab->n_zero rows of the basis (ignoring the constant row)
 * are assumed to correspond to equalities and are left untouched.
 * tab->n_zero is updated to reflect any additional equalities that
 * have been detected in the first rows of the new basis.
 * The final tab->n_unbounded rows of the basis are assumed to correspond
 * to unbounded directions and are also left untouched.
 * In particular this means that the remaining rows are assumed to
 * correspond to bounded directions.
 *
 * This function implements the algorithm described in
 * "An Implementation of the Generalized Basis Reduction Algorithm
 *  for Integer Programming" of Cook el al. to compute a reduced basis.
 * We use \epsilon = 1/4.
 *
 * If ctx->opt->gbr_only_first is set, the user is only interested
 * 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_tab *isl_tab_compute_reduced_basis(struct isl_tab *tab)
{
    unsigned dim;
    struct isl_ctx *ctx;
    struct isl_mat *B;
    int unbounded;
    int i;
    GBR_LP *lp = NULL;
    GBR_type F_old, alpha, F_new;
    int row;
    isl_int tmp;
    struct isl_vec *b_tmp;
    GBR_type *F = NULL;
    GBR_type *alpha_buffer[2] = { NULL, NULL };
    GBR_type *alpha_saved;
    GBR_type F_saved;
    int use_saved = 0;
    isl_int mu[2];
    GBR_type mu_F[2];
    GBR_type two;
    GBR_type one;
    int empty = 0;
    int fixed = 0;
    int fixed_saved = 0;
    int mu_fixed[2];
    int n_bounded;
    int gbr_only_first;

    if (!tab)
        return NULL;

    if (tab->empty)
        return tab;

    ctx = tab->mat->ctx;
    gbr_only_first = ctx->opt->gbr_only_first;
    dim = tab->n_var;
    B = tab->basis;
    if (!B)
        return tab;

    n_bounded = dim - tab->n_unbounded;
    if (n_bounded <= tab->n_zero + 1)
        return tab;

    isl_int_init(tmp);
    isl_int_init(mu[0]);
    isl_int_init(mu[1]);

    GBR_init(alpha);
    GBR_init(F_old);
    GBR_init(F_new);
    GBR_init(F_saved);
    GBR_init(mu_F[0]);
    GBR_init(mu_F[1]);
    GBR_init(two);
    GBR_init(one);

    b_tmp = isl_vec_alloc(ctx, dim);
    if (!b_tmp)
        goto error;

    F = isl_alloc_array(ctx, GBR_type, n_bounded);
    alpha_buffer[0] = isl_alloc_array(ctx, GBR_type, n_bounded);
    alpha_buffer[1] = isl_alloc_array(ctx, GBR_type, n_bounded);
    alpha_saved = alpha_buffer[0];

    if (!F || !alpha_buffer[0] || !alpha_buffer[1])
        goto error;

    for (i = 0; i < n_bounded; ++i) {
        GBR_init(F[i]);
        GBR_init(alpha_buffer[0][i]);
        GBR_init(alpha_buffer[1][i]);
    }

    GBR_set_ui(two, 2);
    GBR_set_ui(one, 1);

    lp = GBR_lp_init(tab);
    if (!lp)
        goto error;

    i = tab->n_zero;

    GBR_lp_set_obj(lp, B->row[1+i]+1, dim);
    ctx->stats->gbr_solved_lps++;
    unbounded = GBR_lp_solve(lp);
    isl_assert(ctx, !unbounded, goto error);
    GBR_lp_get_obj_val(lp, &F[i]);

    if (GBR_lt(F[i], one)) {
        if (!GBR_is_zero(F[i])) {
            empty = GBR_lp_cut(lp, B->row[1+i]+1);
            if (empty)
                goto done;
            GBR_set_ui(F[i], 0);
        }
        tab->n_zero++;
    }

    do {
        if (i+1 == tab->n_zero) {
            GBR_lp_set_obj(lp, B->row[1+i+1]+1, dim);
            ctx->stats->gbr_solved_lps++;
            unbounded = GBR_lp_solve(lp);
            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);
        } else if (use_saved) {
            row = GBR_lp_next_row(lp);
            GBR_set(F_new, F_saved);
            fixed = fixed_saved;
            GBR_set(alpha, alpha_saved[i]);
        } else {
            row = GBR_lp_add_row(lp, B->row[1+i]+1, dim);
            GBR_lp_set_obj(lp, B->row[1+i+1]+1, dim);
            ctx->stats->gbr_solved_lps++;
            unbounded = GBR_lp_solve(lp);
            isl_assert(ctx, !unbounded, goto error);
            GBR_lp_get_obj_val(lp, &F_new);
            fixed = GBR_lp_is_fixed(lp);

            GBR_lp_get_alpha(lp, row, &alpha);

            if (i > 0)
                save_alpha(lp, row-i, i, alpha_saved);

            if (GBR_lp_del_row(lp) < 0)
                goto error;
        }
        GBR_set(F[i+1], F_new);

        GBR_floor(mu[0], alpha);
        GBR_ceil(mu[1], alpha);

        if (isl_int_eq(mu[0], mu[1]))
            isl_int_set(tmp, mu[0]);
        else {
            int j;

            for (j = 0; j <= 1; ++j) {
                isl_int_set(tmp, mu[j]);
                isl_seq_combine(b_tmp->el,
                                ctx->one, B->row[1+i+1]+1,
                                tmp, B->row[1+i]+1, dim);
                GBR_lp_set_obj(lp, b_tmp->el, dim);
                ctx->stats->gbr_solved_lps++;
                unbounded = GBR_lp_solve(lp);
                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)
                    save_alpha(lp, row-i, i, alpha_buffer[j]);
            }

            if (GBR_lt(mu_F[0], mu_F[1]))
                j = 0;
            else
                j = 1;

            isl_int_set(tmp, mu[j]);
            GBR_set(F_new, mu_F[j]);
            fixed = mu_fixed[j];
            alpha_saved = alpha_buffer[j];
        }
        isl_seq_combine(B->row[1+i+1]+1, ctx->one, B->row[1+i+1]+1,
                        tmp, B->row[1+i]+1, dim);

        if (i+1 == tab->n_zero && fixed) {
            if (!GBR_is_zero(F[i+1])) {
                empty = GBR_lp_cut(lp, B->row[1+i+1]+1);
                if (empty)
                    goto done;
                GBR_set_ui(F[i+1], 0);
            }
            tab->n_zero++;
        }

        GBR_set(F_old, F[i]);

        use_saved = 0;
        /* mu_F[0] = 4 * F_new; mu_F[1] = 3 * F_old */
        GBR_set_ui(mu_F[0], 4);
        GBR_mul(mu_F[0], mu_F[0], F_new);
        GBR_set_ui(mu_F[1], 3);
        GBR_mul(mu_F[1], mu_F[1], F_old);
        if (GBR_lt(mu_F[0], mu_F[1])) {
            B = isl_mat_swap_rows(B, 1 + i, 1 + i + 1);
            if (i > tab->n_zero) {
                use_saved = 1;
                GBR_set(F_saved, F_new);
                fixed_saved = fixed;
                if (GBR_lp_del_row(lp) < 0)
                    goto error;
                --i;
            } else {
                GBR_set(F[tab->n_zero], F_new);
                if (gbr_only_first && GBR_lt(F[tab->n_zero], two))
                    break;

                if (fixed) {
                    if (!GBR_is_zero(F[tab->n_zero])) {
                        empty = GBR_lp_cut(lp, B->row[1+tab->n_zero]+1);
                        if (empty)
                            goto done;
                        GBR_set_ui(F[tab->n_zero], 0);
                    }
                    tab->n_zero++;
                }
            }
        } else {
            GBR_lp_add_row(lp, B->row[1+i]+1, dim);
            ++i;
        }
    } while (i < n_bounded - 1);
Esempio n. 16
0
__isl_give isl_basic_set *isl_basic_set_box_from_points(
	__isl_take isl_point *pnt1, __isl_take isl_point *pnt2)
{
	isl_basic_set *bset;
	unsigned total;
	int i;
	int k;
	isl_int t;

	isl_int_init(t);

	if (!pnt1 || !pnt2)
		goto error;

	isl_assert(pnt1->dim->ctx,
			isl_dim_equal(pnt1->dim, pnt2->dim), goto error);

	if (isl_point_is_void(pnt1) && isl_point_is_void(pnt2)) {
		isl_dim *dim = isl_dim_copy(pnt1->dim);
		isl_point_free(pnt1);
		isl_point_free(pnt2);
		isl_int_clear(t);
		return isl_basic_set_empty(dim);
	}
	if (isl_point_is_void(pnt1)) {
		isl_point_free(pnt1);
		isl_int_clear(t);
		return isl_basic_set_from_point(pnt2);
	}
	if (isl_point_is_void(pnt2)) {
		isl_point_free(pnt2);
		isl_int_clear(t);
		return isl_basic_set_from_point(pnt1);
	}

	total = isl_dim_total(pnt1->dim);
	bset = isl_basic_set_alloc_dim(isl_dim_copy(pnt1->dim), 0, 0, 2 * total);

	for (i = 0; i < total; ++i) {
		isl_int_mul(t, pnt1->vec->el[1 + i], pnt2->vec->el[0]);
		isl_int_submul(t, pnt2->vec->el[1 + i], pnt1->vec->el[0]);

		k = isl_basic_set_alloc_inequality(bset);
		if (k < 0)
			goto error;
		isl_seq_clr(bset->ineq[k] + 1, total);
		if (isl_int_is_pos(t)) {
			isl_int_set_si(bset->ineq[k][1 + i], -1);
			isl_int_set(bset->ineq[k][0], pnt1->vec->el[1 + i]);
		} else {
			isl_int_set_si(bset->ineq[k][1 + i], 1);
			isl_int_neg(bset->ineq[k][0], pnt1->vec->el[1 + i]);
		}
		isl_int_fdiv_q(bset->ineq[k][0], bset->ineq[k][0], pnt1->vec->el[0]);

		k = isl_basic_set_alloc_inequality(bset);
		if (k < 0)
			goto error;
		isl_seq_clr(bset->ineq[k] + 1, total);
		if (isl_int_is_pos(t)) {
			isl_int_set_si(bset->ineq[k][1 + i], 1);
			isl_int_neg(bset->ineq[k][0], pnt2->vec->el[1 + i]);
		} else {
			isl_int_set_si(bset->ineq[k][1 + i], -1);
			isl_int_set(bset->ineq[k][0], pnt2->vec->el[1 + i]);
		}
		isl_int_fdiv_q(bset->ineq[k][0], bset->ineq[k][0], pnt2->vec->el[0]);
	}

	bset = isl_basic_set_finalize(bset);

	isl_point_free(pnt1);
	isl_point_free(pnt2);

	isl_int_clear(t);

	return bset;
error:
	isl_point_free(pnt1);
	isl_point_free(pnt2);
	isl_int_clear(t);
	return NULL;
}