示例#1
0
// Transposoes a matrix 
matrix Matrix_Transpose(matrix A)
{
	matrix out;
	out.rows = A.columns;
	out.columns = A.rows;
	if (A.columns == out.rows && A.rows == out.columns)
	{
		int x;
		int y;
		for(x=0;x < A.rows;x++)
		{
			for(y=0;y<A.columns;y++)
			{
				out.data[y*out.columns+x]=A.data[x*A.columns+y];
			}
		}
	}
	else
	{
		LOG.ERR("Attempted to Transpose this matrix to this out matrix\n");
		Matrix_Print(A);
		Matrix_Print(out);
	}
	return out;
}
int main(int argc, char **argv)
{
    Matrix *M;
    Polyhedron *C;
    struct barvinok_options *options = barvinok_options_new_with_defaults();

    argc = barvinok_options_parse(options, argc, argv, ISL_ARG_ALL);

    M = Matrix_Read();
    C = Constraints2Polyhedron(M, options->MaxRays);
    Matrix_Free(M);

    M = Cone_Integer_Hull(C, NULL, 0, options);

    Polyhedron_Free(C);

    Matrix_Print(stdout, P_VALUE_FMT, M);
    Matrix_Free(M);

    if (options->print_stats)
	barvinok_stats_print(options->stats, stdout);

    barvinok_options_free(options);
    return 0;
}
示例#3
0
/*
 * Print the contents of a ZPolyhderon 'A'
 */
static void ZPolyhedronPrint (FILE *fp, const char *format, ZPolyhedron *A)
{
  if (A == NULL)
    return ;
  fprintf(fp,"\nZPOLYHEDRON: Dimension %d \n",A->Lat->NbRows-1);
  fprintf(fp, "\nLATTICE: \n");
  Matrix_Print(fp,format,(Matrix *)A->Lat);
  Polyhedron_Print(fp,format,A->P);  
  return;
} /* ZPolyhedronPrint */
示例#4
0
/* 
 * Basic hermite engine 
 */
static int hermite(Matrix *H,Matrix *U,Matrix *Q) {
  
  int nc, nr, i, j, k, rank, reduced, pivotrow;
  Value pivot,x,aux;
  Value *temp1, *temp2;
  
  /*                     T                     -1   T */
  /* Computes form: A = Q H  and U A = H  and U  = Q  */
  
  if (!H) { 
    errormsg1("Domlib", "nullH", "hermite: ? Null H");
    return -1;
  }
  nc = H->NbColumns;
  nr = H->NbRows;
  temp1 = (Value *) malloc(nc * sizeof(Value));
  temp2 = (Value *) malloc(nr * sizeof(Value));
  if (!temp1 ||!temp2) {
    errormsg1("Domlib", "outofmem", "out of memory space");
    return -1;
  }
  
  /* Initialize all the 'Value' variables */
  value_init(pivot); value_init(x); 
  value_init(aux);   
  for(i=0;i<nc;i++)
    value_init(temp1[i]);
  for(i=0;i<nr;i++)
    value_init(temp2[i]);
  
#ifdef DEBUG
  fprintf(stderr,"Start  -----------\n");
  Matrix_Print(stderr,0,H);
#endif
  for (k=0, rank=0; k<nc && rank<nr; k=k+1) {
    reduced = 1;	/* go through loop the first time */
#ifdef DEBUG
    fprintf(stderr, "Working on col %d.  Rank=%d ----------\n", k+1, rank+1);
#endif
    while (reduced) {
      reduced=0;
      
      /* 1. find pivot row */
      value_absolute(pivot,H->p[rank][k]);
      
      /* the kth-diagonal element */
      pivotrow = rank;
      
      /* find the row i>rank with smallest nonzero element in col k */
      for (i=rank+1; i<nr; i++) {
	value_absolute(x,H->p[i][k]);
	if (value_notzero_p(x) &&
	    (value_lt(x,pivot) || value_zero_p(pivot))) {
	  value_assign(pivot,x);
	  pivotrow = i;
	}
      }
      
      /* 2. Bring pivot to diagonal (exchange rows pivotrow and rank) */
      if (pivotrow != rank) {
	Vector_Exchange(H->p[pivotrow],H->p[rank],nc);
	if (U)
	  Vector_Exchange(U->p[pivotrow],U->p[rank],nr);
	if (Q)
	  Vector_Exchange(Q->p[pivotrow],Q->p[rank],nr);

#ifdef DEBUG
	fprintf(stderr,"Exchange rows %d and %d  -----------\n", rank+1, pivotrow+1);
	Matrix_Print(stderr,0,H);
#endif
      }
      value_assign(pivot,H->p[rank][k]);	/* actual ( no abs() ) pivot */
      
      /* 3. Invert the row 'rank' if pivot is negative */
      if (value_neg_p(pivot)) {
	value_oppose(pivot,pivot); /* pivot = -pivot */
	for (j=0; j<nc; j++)
	  value_oppose(H->p[rank][j],H->p[rank][j]);
	
	/* H->p[rank][j] = -(H->p[rank][j]); */
	if (U)
	  for (j=0; j<nr; j++)
	    value_oppose(U->p[rank][j],U->p[rank][j]);
	
	/* U->p[rank][j] = -(U->p[rank][j]); */
	if (Q)
	  for (j=0; j<nr; j++)
	    value_oppose(Q->p[rank][j],Q->p[rank][j]);
	
	/* Q->p[rank][j] = -(Q->p[rank][j]); */
#ifdef DEBUG
	fprintf(stderr,"Negate row %d  -----------\n", rank+1);
	Matrix_Print(stderr,0,H);
#endif

      }      
      if (value_notzero_p(pivot)) {
	
	/* 4. Reduce the column modulo the pivot */
	/*    This eventually zeros out everything below the */
	/*    diagonal and produces an upper triangular matrix */
	
	for (i=rank+1;i<nr;i++) {
	  value_assign(x,H->p[i][k]);
	  if (value_notzero_p(x)) {	    
	    value_modulus(aux,x,pivot);
	    
	    /* floor[integer division] (corrected for neg x) */
	    if (value_neg_p(x) && value_notzero_p(aux)) {
	      
	      /* x=(x/pivot)-1; */
	      value_division(x,x,pivot);
	      value_decrement(x,x);
	    }	
	    else 
	      value_division(x,x,pivot);
	    for (j=0; j<nc; j++) {
	      value_multiply(aux,x,H->p[rank][j]);
	      value_subtract(H->p[i][j],H->p[i][j],aux);
	    }
	    
	    /* U->p[i][j] -= (x * U->p[rank][j]); */
	    if (U)
	      for (j=0; j<nr; j++) {
		value_multiply(aux,x,U->p[rank][j]);
		value_subtract(U->p[i][j],U->p[i][j],aux);
	      }
	    
	    /* Q->p[rank][j] += (x * Q->p[i][j]); */
	    if (Q)
	      for(j=0;j<nr;j++) {
		value_addmul(Q->p[rank][j], x, Q->p[i][j]);
	      }
	    reduced = 1;

#ifdef DEBUG
	    fprintf(stderr,
		    "row %d = row %d - %d row %d -----------\n", i+1, i+1, x, rank+1);
	    Matrix_Print(stderr,0,H);
#endif
	
	  } /* if (x) */
	} /* for (i) */
      } /* if (pivot != 0) */
    } /* while (reduced) */
    
    /* Last finish up this column */
    /* 5. Make pivot column positive (above pivot row) */
    /*    x should be zero for i>k */
    
    if (value_notzero_p(pivot)) {
      for (i=0; i<rank; i++) {
	value_assign(x,H->p[i][k]);
	if (value_notzero_p(x)) { 	  
	  value_modulus(aux,x,pivot);
	  
	  /* floor[integer division] (corrected for neg x) */
	  if (value_neg_p(x) && value_notzero_p(aux)) {
	    value_division(x,x,pivot);
	    value_decrement(x,x);
	    
	    /* x=(x/pivot)-1; */
	  }
	  else
	    value_division(x,x,pivot);
	  
	  /* H->p[i][j] -= x * H->p[rank][j]; */
	  for (j=0; j<nc; j++) {
	    value_multiply(aux,x,H->p[rank][j]);
	    value_subtract(H->p[i][j],H->p[i][j],aux);
	  }
	  
	  /* U->p[i][j] -= x * U->p[rank][j]; */
	  if (U)
	    for (j=0; j<nr; j++) {
	      value_multiply(aux,x,U->p[rank][j]);
	      value_subtract(U->p[i][j],U->p[i][j],aux);
	    }
	  
	  /* Q->p[rank][j] += x * Q->p[i][j]; */
	  if (Q)
	    for (j=0; j<nr; j++) {
	      value_addmul(Q->p[rank][j], x, Q->p[i][j]);
	    }  
#ifdef DEBUG
	  fprintf(stderr,
		  "row %d = row %d - %d row %d -----------\n", i+1, i+1, x, rank+1);
	  Matrix_Print(stderr,0,H);
#endif
	} /* if (x) */
      } /* for (i) */
      rank++;
    } /* if (pivot!=0) */
  } /* for (k) */
  
  /* Clear all the 'Value' variables */
  value_clear(pivot); value_clear(x); 
  value_clear(aux); 
  for(i=0;i<nc;i++)
    value_clear(temp1[i]);
  for(i=0;i<nr;i++)
    value_clear(temp2[i]);
  free(temp2);
  free(temp1);
  return rank;
} /* Hermite */ 
示例#5
0
int main() { 
  
  Matrix *a, *b, *t;
  Polyhedron *A, *B, *C, *D;
  
  printf("Polyhedral Library Test\n\n");
  
  /* read in a matrix containing your equations */
  /* for example, run this program and type in these five  lines:
     4 4
     1 0 1 -1
     1 -1 0 6
     1 0 -1 7
     1 1 0 -2
     This is a matrix for the following inequalities
     1 = inequality,  0x +  1y -1 >=0  -->	y >= 1
     1 = inequality, -1x +  0y +6 >=0  -->	x <= 6
     1 = inequality,  0x + -1y +7 >=0  -->	y <= 7
     1 = inequality,  1x +  0y -2 >=0  -->	x >= 2
     If the first number is a 0 instead of a 1, then that constraint
     is an 'equality' instead of an 'inequality'.
  */
  a = Matrix_Read();
  
  /* read in a second matrix containing a second set of constraints:
     for example :
     4 4
     1 1 0 -1
     1 -1 0 3
     1 0 -1 5
     1 0 1 -2
  */
  b = Matrix_Read();

  /* Convert the constraints to a Polyhedron.
     This operation 1. Computes the dual ray/vertice form of the
     system, and 2. Eliminates redundant constraints and reduces
     them to a minimal form.
  */
  A = Constraints2Polyhedron(a, 200);
  B = Constraints2Polyhedron(b, 200);

  /* the 200 is the size of the working space (in terms of number
     of rays) that is allocated temporarily
     -- you can enlarge or reduce it as needed */
  
  /* There is likewise a rays to polyhedron procedure */
  
  /* Since you are done with the matrices a and b, be a good citizen
     and clean up your garbage */
  Matrix_Free(a);
  Matrix_Free(b);
  
  /* If you want the the reduced set of equations back, you can
     either learn to read the polyhedron structure (not hard,
     look in "types.h"...
     or you can get the matrix back in the same format it started
     in... */
  a = Polyhedron2Constraints(A);
  b = Polyhedron2Constraints(B);

  /* Take a look at them if you want */
  printf("\na =");
  Matrix_Print(stdout,P_VALUE_FMT,a);
  printf("\nb =");
  Matrix_Print(stdout,P_VALUE_FMT,b);

  Matrix_Free(a);
  Matrix_Free(b);
  
  /* To intersect the two systems, use the polyhedron formats... */
  C = DomainIntersection(A, B, 200);
  
  /* Again, the 200 is the size of the working space */
  
  /* This time, lets look a the polyhedron itself... */
  printf("\nC = A and B =");
  Polyhedron_Print(stdout,P_VALUE_FMT,C);
  
  /* 
   * The operations DomainUnion, DomainDifference, and DomainConvex
   * are also available 
   */
  
  /* 
   * Read in a third matrix containing a transformation matrix,
   * this one swaps the indices (x,y --> y,x):
   * 3 3
   * 0 1 0
   * 1 0 0
   * 0 0 1
   */
  
  
  t = Matrix_Read();
  
  /* Take the preimage (transform the equations) of the domain C to
     get D.  Are you catching on to this 200 thing yet ??? */
  
  D = Polyhedron_Preimage(C, t, 200);
  
  /* cleanup please */
  Matrix_Free(t);
  
  printf("\nD = transformed C =");
  Polyhedron_Print(stdout,P_VALUE_FMT,D);
  Domain_Free(D);
  
  /* in a similar way, Polyhedron_Image(dom, mat, 200), takes the image
     of dom under matrix mat  (transforms the vertices/rays) */
  
  /* The function PolyhedronIncludes(Pol1, Pol2) returns 1 if Pol1
     includes (covers) Pol2, and a 0 otherwise */
  
  if (PolyhedronIncludes(A,C))
    printf("\nWe expected A to cover C since C = A intersect B\n");
  if (!PolyhedronIncludes(C,B))
    printf("and C does not cover B...\n");
  
  /* Final note:  some functions are defined for Domains, others
   * for Polyhedrons.  A domain is simply a list of polyhedrons.
   * Every polyhedron structure has a "next" pointer used to 
   * make a list of polyhedrons...  For instance, the union of
   * two disjoint polyhedra is a domain consisting of two polyhedra.
   * If you want the convex domain... you have to call 
   * DomainConvex(Pol1, 200) explicity.   
   * Note that includes does not work on domains, only on simple
   * polyhedrons...
   * Thats the end of the demo...  write me if you have questions.
   * And remember to clean up... 
   */
  
  Domain_Free(A);
  Domain_Free(B);
  Domain_Free(C);
  
  return 0;
}
示例#6
0
/* INDEX  = 1 .... Dimension      */
int PolyhedronLTQ (Polyhedron *Pol1,Polyhedron *Pol2,int INDEX, int PDIM, int NbMaxConstrs) { 
  
  int res, dim, i, j, k;
  Polyhedron *Q1, *Q2, *Q3, *Q4, *Q;
  Matrix *Mat;

  if (Pol1->next || Pol2->next) {
    errormsg1("PolyhedronLTQ", "compoly", "Can only compare polyhedra");
    return 0;
  }
  if (Pol1->Dimension != Pol2->Dimension) {
    errormsg1("PolyhedronLTQ","diffdim","Polyhedra are not same dimension");
    return 0;
  }
  dim = Pol1->Dimension+2;

  POL_ENSURE_FACETS(Pol1);
  POL_ENSURE_VERTICES(Pol1);
  POL_ENSURE_FACETS(Pol2);
  POL_ENSURE_VERTICES(Pol2);
  
#ifdef DEBUG
  fprintf(stdout, "P1\n");
  Polyhedron_Print(stdout,P_VALUE_FMT,Pol1);
  fprintf(stdout, "P2\n");
  Polyhedron_Print(stdout,P_VALUE_FMT,Pol2);
#endif
  
  /* Create the Line to add */
  k = Pol1->Dimension-INDEX+1-PDIM;
  Mat = Matrix_Alloc(k,dim);
  Vector_Set(Mat->p_Init,0,dim*k);
  for(j=0,i=INDEX;j<k;i++,j++)
    value_set_si(Mat->p[j][i],1);
  
  Q1 = AddRays(Mat->p[0],k,Pol1,NbMaxConstrs);
  Q2 = AddRays(Mat->p[0],k,Pol2,NbMaxConstrs);

#ifdef DEBUG
  fprintf(stdout, "Q1\n");
  Polyhedron_Print(stdout,P_VALUE_FMT,Q1);
  fprintf(stdout, "Q2\n");
  Polyhedron_Print(stdout,P_VALUE_FMT,Q2);
#endif
  
  Matrix_Free(Mat);
  Q  = DomainIntersection(Q1,Q2,NbMaxConstrs);
  
#ifdef DEBUG
  fprintf(stdout, "Q\n");
  Polyhedron_Print(stdout,P_VALUE_FMT,Q);
#endif
  
  Domain_Free(Q1);
  Domain_Free(Q2);
  
  if (emptyQ(Q)) res = 0;	/* not comparable */
  else {
    Q1 = DomainIntersection(Pol1,Q,NbMaxConstrs);
    Q2 = DomainIntersection(Pol2,Q,NbMaxConstrs);
    
#ifdef DEBUG
    fprintf(stdout, "Q1\n");
    Polyhedron_Print(stdout,P_VALUE_FMT,Q1);
    fprintf(stdout, "Q2\n");
    Polyhedron_Print(stdout,P_VALUE_FMT,Q2);
#endif

    k = Q1->NbConstraints + Q2->NbConstraints;
    Mat = Matrix_Alloc(k, dim);
    Vector_Set(Mat->p_Init,0,k*dim);
    
    /* First compute surrounding polyhedron */    
    j=0;
    for (i=0; i<Q1->NbConstraints; i++) {
      if ((value_one_p(Q1->Constraint[i][0])) && (value_pos_p(Q1->Constraint[i][INDEX]))) {
	
	/* keep Q1's lower bounds */
	for (k=0; k<dim; k++) 
	  value_assign(Mat->p[j][k],Q1->Constraint[i][k]);
	j++;
      }
    }
    for (i=0; i<Q2->NbConstraints; i++) {
      if ((value_one_p(Q2->Constraint[i][0])) && (value_neg_p(Q2->Constraint[i][INDEX]))) {
	
	/* and keep Q2's upper bounds */
	for (k=0; k<dim; k++) 
	  value_assign(Mat->p[j][k],Q2->Constraint[i][k]);
	j++;
      }
    }
    Q4 = AddConstraints(Mat->p[0], j, Q, NbMaxConstrs);
    Matrix_Free(Mat);
    
#ifdef debug
    fprintf(stderr, "Q4 surrounding polyhedron\n");
    Polyhderon_Print(stderr,P_VALUE_FMT, Q4);
#endif

    /* if surrounding polyhedron is empty, D1>D2 */
    if (emptyQ(Q4)) {
      res = 1;
      
#ifdef debug
      fprintf(stderr, "Surrounding polyhedron is empty\n");
#endif
      goto LTQdone2; 
    }
    
    /* Test if Q1 < Q2 */      
    /* Build a constraint array for >= Q1 and <= Q2 */
    Mat = Matrix_Alloc(2,dim);
    Vector_Set(Mat->p_Init,0,2*dim);
    
    /* Choose a contraint from Q1 */
    for (i=0; i<Q1->NbConstraints; i++) {
      if (value_zero_p(Q1->Constraint[i][0])) {
	
	/* Equality */
	if (value_zero_p(Q1->Constraint[i][INDEX])) {
	  
	  /* Ignore side constraint (they are in Q) */
	  continue;
	}
	else if (value_neg_p(Q1->Constraint[i][INDEX])) {
	  
	  /* copy -constraint to Mat */
	  value_set_si(Mat->p[0][0],1);
	  for (k=1; k<dim; k++)
	    value_oppose(Mat->p[0][k],Q1->Constraint[i][k]);
	}
	else {
	  
	  /* Copy constraint to Mat */
	  
	  value_set_si(Mat->p[0][0],1);
	  for (k=1; k<dim; k++)
	    value_assign(Mat->p[0][k],Q1->Constraint[i][k]);
	}
      }
      else if(value_neg_p(Q1->Constraint[i][INDEX])) {
	
	/* Upper bound -- make a lower bound from it */
	value_set_si(Mat->p[0][0],1);
	for (k=1; k<dim; k++)
	  value_oppose(Mat->p[0][k],Q1->Constraint[i][k]);
      }
      else {	
	
	/* Lower or side bound -- ignore it */
	continue;
      }
      
      /* Choose a constraint from Q2 */
      for (j=0; j<Q2->NbConstraints; j++) {
	if (value_zero_p(Q2->Constraint[j][0])) {   /* equality */
	  if (value_zero_p(Q2->Constraint[j][INDEX])) {
	    
	    /* Ignore side constraint (they are in Q) */
	    continue;
	  }
	  else if (value_pos_p(Q2->Constraint[j][INDEX])) {
	    
	    /* Copy -constraint to Mat */
	    value_set_si(Mat->p[1][0],1);
	    for (k=1; k<dim; k++)
	      value_oppose(Mat->p[1][k],Q2->Constraint[j][k]);
	  }
	  else {
	    
	    /* Copy constraint to Mat */
	    value_set_si(Mat->p[1][0],1);
	    for (k=1; k<dim; k++)
	      value_assign(Mat->p[1][k],Q2->Constraint[j][k]);
	  };
	}
	else if (value_pos_p(Q2->Constraint[j][INDEX])) {
	  
	  /* Lower bound -- make an upper bound from it */
	  value_set_si(Mat->p[1][0],1);
	  for(k=1;k<dim;k++)
	    value_oppose(Mat->p[1][k],Q2->Constraint[j][k]);
	}
	else {
	  
	  /* Upper or side bound -- ignore it */
	  continue;
	};
	
#ifdef DEBUG
	fprintf(stdout, "i=%d j=%d M=\n", i+1, j+1);
	Matrix_Print(stdout,P_VALUE_FMT,Mat);
#endif
	
	/* Add Mat to Q and see if anything is made */
	Q3 = AddConstraints(Mat->p[0],2,Q,NbMaxConstrs);

#ifdef DEBUG
	fprintf(stdout, "Q3\n");
	Polyhedron_Print(stdout,P_VALUE_FMT,Q3);
#endif
	
	if (!emptyQ(Q3)) { 
	  Domain_Free(Q3);
	  
#ifdef DEBUG
	  fprintf(stdout, "not empty\n");
#endif
	  res = -1;
	  goto LTQdone;
	}
#ifdef DEBUG
	fprintf(stdout,"empty\n");	
#endif
	Domain_Free(Q3);
      } /* end for j */
    } /* end for i */
    res = 1;
LTQdone:
    Matrix_Free(Mat);
LTQdone2: 
    Domain_Free(Q4);
    Domain_Free(Q1);
    Domain_Free(Q2);
  }
  Domain_Free(Q);
  
#ifdef DEBUG
  fprintf(stdout, "res = %d\n", res);
#endif
  
  return res;
} /* PolyhedronLTQ */
示例#7
0
int main(int argc, char **argv)
{
    isl_ctx *ctx;
    int i, nbPol, nbVec, nbMat, func, j, n;
    Polyhedron *A, *B, *C, *D, *E, *F, *G;
    char s[128];
    struct barvinok_options *options = barvinok_options_new_with_defaults();

    argc = barvinok_options_parse(options, argc, argv, ISL_ARG_ALL);
    ctx = isl_ctx_alloc_with_options(&barvinok_options_args, options);

    nbPol = nbVec = nbMat = 0;
    fgets(s, 128, stdin);
    while ((*s=='#') ||
	    ((sscanf(s, "D %d", &nbPol) < 1) &&
	     (sscanf(s, "V %d", &nbVec) < 1) &&
	     (sscanf(s, "M %d", &nbMat) < 1)))
	fgets(s, 128, stdin);

    for (i = 0; i < nbPol; ++i) {
	Matrix *M = Matrix_Read();
	A = Constraints2Polyhedron(M, options->MaxRays);
	Matrix_Free(M);
	fgets(s, 128, stdin);
	while ((*s=='#') || (sscanf(s, "F %d", &func)<1))
	    fgets(s, 128, stdin);

	switch(func) {
	case 0: {
	    Value cb, ck;
	    value_init(cb);
	    value_init(ck);
	    fgets(s, 128, stdin);
	    /* workaround for apparent bug in older gmps */
	    *strchr(s, '\n') = '\0';
	    while ((*s=='#') || (value_read(ck, s) != 0)) {
		fgets(s, 128, stdin);
		/* workaround for apparent bug in older gmps */
		*strchr(s, '\n') = '\0';
	    }
	    barvinok_count_with_options(A, &cb, options);
	    if (value_ne(cb, ck))
		return -1;
	    value_clear(cb);
	    value_clear(ck);
	    break;
	}
	case 1:
	    Polyhedron_Print(stdout, P_VALUE_FMT, A);
	    B = Polyhedron_Polar(A, options->MaxRays);
	    Polyhedron_Print(stdout, P_VALUE_FMT, B);
	    C = Polyhedron_Polar(B, options->MaxRays);
	    Polyhedron_Print(stdout, P_VALUE_FMT, C);
	    Polyhedron_Free(C);
	    Polyhedron_Free(B);
	    break;
	case 2:
	    Polyhedron_Print(stdout, P_VALUE_FMT, A);
	    for (j = 0; j < A->NbRays; ++j) {
		B = supporting_cone(A, j);
		Polyhedron_Print(stdout, P_VALUE_FMT, B);
		Polyhedron_Free(B);
	    }
	    break;
	case 3:
	    Polyhedron_Print(stdout, P_VALUE_FMT, A);
	    C = B = NULL;
	    barvinok_decompose(A,&B,&C);
	    puts("Pos:");
	    Polyhedron_Print(stdout, P_VALUE_FMT, B);
	    puts("Neg:");
	    Polyhedron_Print(stdout, P_VALUE_FMT, C);
	    Domain_Free(B);
	    Domain_Free(C);
	    break;
	case 4: {
	    Value cm, cb;
	    struct tms tms_before, tms_between, tms_after;
	    value_init(cm);
	    value_init(cb);
	    Polyhedron_Print(stdout, P_VALUE_FMT, A);
	    times(&tms_before);
	    manual_count(A, &cm);
	    times(&tms_between);
	    barvinok_count(A, &cb, 100);
	    times(&tms_after);
	    printf("manual: ");
	    value_print(stdout, P_VALUE_FMT, cm);
	    puts("");
	    time_diff(&tms_before, &tms_between);
	    printf("Barvinok: ");
	    value_print(stdout, P_VALUE_FMT, cb);
	    puts("");
	    time_diff(&tms_between, &tms_after);
	    value_clear(cm);
	    value_clear(cb);
	    break;
	}
	case 5:
	    Polyhedron_Print(stdout, P_VALUE_FMT, A);
	    B = triangulate_cone(A, 100);
	    Polyhedron_Print(stdout, P_VALUE_FMT, B);
	    check_triangulization(A, B);
	    Domain_Free(B);
	    break;
	case 6:
	    Polyhedron_Print(stdout, P_VALUE_FMT, A);
	    B = remove_equalities(A, options->MaxRays);
	    Polyhedron_Print(stdout, P_VALUE_FMT, B);
	    Polyhedron_Free(B);
	    break;
	case 8: {
	    evalue *EP;
	    Matrix *M = Matrix_Read();
	    const char **param_name;
	    C = Constraints2Polyhedron(M, options->MaxRays);
	    Matrix_Free(M);
	    Polyhedron_Print(stdout, P_VALUE_FMT, A);
	    Polyhedron_Print(stdout, P_VALUE_FMT, C);
	    EP = barvinok_enumerate_with_options(A, C, options);
	    param_name = Read_ParamNames(stdin, C->Dimension);
	    print_evalue(stdout, EP, (const char**)param_name);
	    evalue_free(EP);
	    Polyhedron_Free(C);
	}
	case 9:
	    Polyhedron_Print(stdout, P_VALUE_FMT, A);
	    Polyhedron_Polarize(A);
	    C = B = NULL;
	    barvinok_decompose(A,&B,&C);
	    for (D = B; D; D = D->next)
		Polyhedron_Polarize(D);
	    for (D = C; D; D = D->next)
		Polyhedron_Polarize(D);
	    puts("Pos:");
	    Polyhedron_Print(stdout, P_VALUE_FMT, B);
	    puts("Neg:");
	    Polyhedron_Print(stdout, P_VALUE_FMT, C);
	    Domain_Free(B);
	    Domain_Free(C);
	    break;
	case 10: {
	    evalue *EP;
	    Value cb, ck;

	    value_init(cb);
	    value_init(ck);
	    fgets(s, 128, stdin);
	    sscanf(s, "%d", &n);
	    for (j = 0; j < n; ++j) {
		Polyhedron *P;
		M = Matrix_Read();
		P = Constraints2Polyhedron(M, options->MaxRays);
		Matrix_Free(M);
		A = DomainConcat(P, A);
	    }
	    fgets(s, 128, stdin);
	    /* workaround for apparent bug in older gmps */
	    *strchr(s, '\n') = '\0';
	    while ((*s=='#') || (value_read(ck, s) != 0)) {
		fgets(s, 128, stdin);
		/* workaround for apparent bug in older gmps */
		*strchr(s, '\n') = '\0';
	    }
	    C = Universe_Polyhedron(0);
	    EP = barvinok_enumerate_union(A, C, options->MaxRays);
	    value_set_double(cb, compute_evalue(EP, &ck)+.25);
	    if (value_ne(cb, ck))
		return -1;
	    Domain_Free(C);
	    value_clear(cb);
	    value_clear(ck);
	    evalue_free(EP);
	    break;
	}
	case 11: {
	    isl_space *dim;
	    isl_basic_set *bset;
	    isl_pw_qpolynomial *expected, *computed;
	    unsigned nparam;

	    expected = isl_pw_qpolynomial_read_from_file(ctx, stdin);
	    nparam = isl_pw_qpolynomial_dim(expected, isl_dim_param);
	    dim = isl_space_set_alloc(ctx, nparam, A->Dimension - nparam);
	    bset = isl_basic_set_new_from_polylib(A, dim);
	    computed = isl_basic_set_lattice_width(bset);
	    computed = isl_pw_qpolynomial_sub(computed, expected);
	    if (!isl_pw_qpolynomial_is_zero(computed))
		return -1;
	    isl_pw_qpolynomial_free(computed);
	    break;
	}
	case 12: {
	    Vector *sample;
	    int has_sample;
	    fgets(s, 128, stdin);
	    sscanf(s, "%d", &has_sample);

	    sample = Polyhedron_Sample(A, options);
	    if (!sample && has_sample)
		return -1;
	    if (sample && !has_sample)
		return -1;
	    if (sample && !in_domain(A, sample->p))
		return -1;
	    Vector_Free(sample);
	}
	}
	Domain_Free(A);
    }
    for (i = 0; i < nbVec; ++i) {
	int ok;
	Vector *V = Vector_Read();
	Matrix *M = Matrix_Alloc(V->Size, V->Size);
	Vector_Copy(V->p, M->p[0], V->Size);
	ok = unimodular_complete(M, 1);
	assert(ok);
	Matrix_Print(stdout, P_VALUE_FMT, M);
	Matrix_Free(M);
	Vector_Free(V);
    }
    for (i = 0; i < nbMat; ++i) {
	Matrix *U, *V, *S;
	Matrix *M = Matrix_Read();
	Smith(M, &U, &V, &S);
	Matrix_Print(stdout, P_VALUE_FMT, U);
	Matrix_Print(stdout, P_VALUE_FMT, V);
	Matrix_Print(stdout, P_VALUE_FMT, S);
	Matrix_Free(M);
	Matrix_Free(U);
	Matrix_Free(V);
	Matrix_Free(S);
    }

    isl_ctx_free(ctx);
    return 0;
}