Example #1
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 */
Example #2
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 */
Example #3
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;
}
Example #4
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;
}