polylib: verif_ehrhart.c Source File

- Main Page
- Classes
- Files

# verif_ehrhart.c

Go to the documentation of this file.

    00001 /*************************************************/
    00002 /*     verif_ehrhart.c                           */
    00003 /* program to compare effective number of points */
    00004 /* in a polytope with the corresponding          */
    00005 /* evaluation of the Ehrhart polynomial.         */
    00006 /* Parameters vary in range -RANGE to RANGE      */
    00007 /* (define below) by default.                    */
    00008 /* Can be overridden by specifying               */
    00009 /* -r<RANGE>, or -m<min> and -M<max>             */
    00010 /*                                               */
    00011 /* written by Vincent Loechner (c) 2000.         */
    00012 /*  loechner@icps.u-strasbg.fr                   */
    00013 /*************************************************/
    00014
    00015 #include <stdio.h>
    00016 #include <string.h>
    00017 #include <stdlib.h>
    00018
    00019 #include <polylib/polylib.h>
    00020 #define MAXRAYS 1024
    00021
    00022 /* define this to print all the results */
    00023 /* else, only a progress bar is printed */
    00024 /* #define PRINT_ALL_RESULTS     */
    00025 /* define this to continue the test after first error found */
    00026 /* #define DONT_BREAK_ON_ERROR */
    00027
    00028 /* RANGE : normal range for evalutations (-RANGE -> RANGE) */
    00029 #define RANGE 50
    00030
    00031 /* SRANGE : small range for evalutations */
    00032 #define SRANGE 15
    00033
    00034 /* if dimension >= BIDDIM, use SRANGE */
    00035 #define BIGDIM 5
    00036
    00037 /* VSRANGE : very small range for evalutations */
    00038 #define VSRANGE 5
    00039
    00040 /* if dimension >= VBIDDIM, use VSRANGE */
    00041 #define VBIGDIM 8
    00042
    00043 Value min, max;
    00044
    00045 #ifdef DONT_BREAK_ON_ERROR
    00046 #define PRINT_ALL_RESULTS
    00047 #endif
    00048
    00049 #ifndef PRINT_ALL_RESULTS
    00050 int st;
    00051 #endif
    00052
    00053 /****************************************************/
    00054 /* function check_poly :                            */
    00055 /* scans the parameter space from min to max (all   */
    00056 /* directions). Computes the number of points in    */
    00057 /* the polytope using both methods, and compare them*/
    00058 /* returns 1 on success                             */
    00059 /****************************************************/
    00060
    00061 int check_poly(Polyhedron *S,Polyhedron *C,Enumeration *en,
    00062                int nparam,int pos,Value *z) {
    00063
    00064   int cc,k;
    00065   Value c,tmp,*ctmp;
    00066
    00067   value_init(c); value_init(tmp);
    00068
    00069   if(pos == nparam) {
    00070
    00071     /* Computes the ehrhart polynomial */
    00072     value_assign(c,*(ctmp=compute_poly(en,&z[S->Dimension-nparam+1])));
    00073     free(ctmp);
    00074     /* if c=0 we may be out of context. */
    00075     /* scanning is useless in this case*/
    00076     if(!in_domain(C,&z[S->Dimension-nparam+1])) {
    00077
    00078       /* ok */ ;
    00079     }
    00080     else {
    00081
    00082 #ifdef PRINT_ALL_RESULTS
    00083       printf("EP( ");
    00084       value_print(stdout,VALUE_FMT,z[S->Dimension-nparam+1]);
    00085       for(k=S->Dimension-nparam+2;k<=S->Dimension;++k) {
    00086         printf(", ");
    00087         value_print(stdout,VALUE_FMT,z[k]);
    00088       }
    00089       printf(" ) = ");
    00090       value_print(stdout,VALUE_FMT,c);
    00091       printf(" ");
    00092 #endif
    00093
    00094       /* Count manually the number of points */
    00095       count_points(1,S,z,&tmp);
    00096 #ifdef PRINT_ALL_RESULTS
    00097         printf(", count = ");
    00098         value_print(stdout, P_VALUE_FMT, tmp);
    00099         printf(". ");
    00100 #endif
    00101
    00102       if(value_ne(tmp,c)) {
    00103         printf("\n");
    00104         fflush(stdout);
    00105         fprintf(stderr,"Error !\n");
    00106         fprintf(stderr,"EP( ");
    00107         value_print(stderr,VALUE_FMT,z[S->Dimension-nparam+1]);
    00108         for(k=S->Dimension-nparam+2;k<=S->Dimension;++k) {
    00109           fprintf(stderr,", ");
    00110           value_print(stderr,VALUE_FMT,z[k]);
    00111         }
    00112         fprintf(stderr," ) should be ");
    00113         value_print(stderr,VALUE_FMT,tmp);
    00114         fprintf(stderr,", while EP eval gives ");
    00115         value_print(stderr,VALUE_FMT,c);
    00116         fprintf(stderr,".\n");
    00117 #ifndef DONT_BREAK_ON_ERROR
    00118         value_clear(c); value_clear(tmp);
    00119         return(0);
    00120 #endif
    00121       }
    00122
    00123 #ifdef PRINT_ALL_RESULTS
    00124       else
    00125         printf("OK.\n");
    00126 #endif
    00127     }
    00128   }
    00129   else
    00130     for(value_assign(tmp,min); value_le(tmp,max); value_increment(tmp,tmp)) {
    00131
    00132 #ifndef PRINT_ALL_RESULTS
    00133       k = VALUE_TO_INT(tmp);
    00134       if(!pos && !(k%st)) {
    00135         printf("o");
    00136         fflush(stdout);
    00137       }
    00138 #endif
    00139
    00140       value_assign(z[pos+S->Dimension-nparam+1],tmp);
    00141       if(!check_poly(S,C,en,nparam,pos+1,z)) {
    00142         value_clear(c); value_clear(tmp);
    00143         return(0);
    00144       }
    00145     }
    00146   value_clear(c); value_clear(tmp);
    00147   return(1);
    00148 } /* check_poly */
    00149
    00150 int main(int argc,char *argv[]) {
    00151
    00152   Matrix *C1, *P1;
    00153   Polyhedron *C, *P, *S;
    00154   Polyhedron *CC, *PP;
    00155   Enumeration *en;
    00156   Value *p, tmp;
    00157   int i,j;
    00158   int m,M;
    00159
    00160 /******* Read the input *********/
    00161   P1 = Matrix_Read();
    00162   C1 = Matrix_Read();
    00163
    00164   if(C1->NbColumns < 2) {
    00165     fprintf(stderr,"Not enough parameters !\n");
    00166     exit(0);
    00167   }
    00168
    00169   P = Constraints2Polyhedron(P1,MAXRAYS);
    00170   C = Constraints2Polyhedron(C1,MAXRAYS);
    00171   Matrix_Free(C1);
    00172   Matrix_Free(P1);
    00173
    00174   /******* Read the options: initialize min and max ********/
    00175   if(P->Dimension >= VBIGDIM)
    00176     M = VSRANGE;
    00177   else if(P->Dimension >= BIGDIM)
    00178     M = SRANGE;
    00179   else
    00180     M = RANGE;
    00181   m = -M;
    00182   if(argc != 1 ) {
    00183     for(i=1;i<argc;i++) {
    00184       if(!strncmp(argv[i],"-m",2)) {
    00185
    00186         /* min specified */
    00187         m = atoi(&argv[i][2]);
    00188       }
    00189       else if(!strncmp(argv[i],"-M",2)) {
    00190
    00191         /* max specified */
    00192         M = atoi(&argv[i][2]);
    00193       }
    00194       else if(!strncmp(argv[i], "-r", 2)) {
    00195
    00196         /* range specified */
    00197         M = atoi(&argv[i][2]);
    00198         m = -M;
    00199       }
    00200       else {
    00201         fprintf(stderr,"Unknown option: %s\n",argv[i]);
    00202         fprintf(stderr,"Usage: %s [-m<>][-M<>][-r<>]\n",argv[0]);
    00203         return(-1);
    00204       }
    00205     }
    00206   }
    00207   if(m > M) {
    00208     fprintf(stderr,"Nothing to do: min > max !\n");
    00209     return(0);
    00210   }
    00211   value_init(min);
    00212   value_init(max);
    00213   value_set_si(min,m);
    00214   value_set_si(max,M);
    00215   value_init(tmp);
    00216
    00217   /******* Compute true context *******/
    00218   CC = align_context(C,P->Dimension,MAXRAYS);
    00219   PP = DomainIntersection(P,CC,MAXRAYS);
    00220   Domain_Free(CC);
    00221   C1 = Matrix_Alloc(C->Dimension+1,P->Dimension+1);
    00222
    00223   for(i=0;i<C1->NbRows;i++)
    00224     for(j=0;j<C1->NbColumns;j++)
    00225       if(i==j-P->Dimension+C->Dimension)
    00226         value_set_si(C1->p[i][j],1);
    00227       else
    00228         value_set_si(C1->p[i][j],0);
    00229   CC = Polyhedron_Image(PP,C1,MAXRAYS);
    00230   Domain_Free(C);
    00231   C = CC;
    00232
    00233   /******* Compute EP *********/
    00234   en = Polyhedron_Enumerate(P,C,MAXRAYS,NULL);
    00235
    00236   /******* Initializations for check *********/
    00237   p = (Value *)malloc(sizeof(Value) * (P->Dimension+2));
    00238   for(i=0;i<=P->Dimension;i++) {
    00239     value_init(p[i]);
    00240     value_set_si(p[i],0);
    00241   }
    00242   value_init(p[i]);
    00243   value_set_si(p[i],1);
    00244
    00245   /* S = scanning list of polyhedra */
    00246   S = Polyhedron_Scan(P,C,MAXRAYS);
    00247
    00248 #ifndef PRINT_ALL_RESULTS
    00249   if(C->Dimension > 0) {
    00250     value_subtract(tmp,max,min);
    00251     if (VALUE_TO_INT(tmp) > 80)
    00252       st = 1+(VALUE_TO_INT(tmp))/80;
    00253     else
    00254       st=1;
    00255     for(i=VALUE_TO_INT(min);i<=VALUE_TO_INT(max);i+=st)
    00256       printf(".");
    00257     printf( "\r" );
    00258     fflush(stdout);
    00259   }
    00260 #endif
    00261
    00262   /******* CHECK NOW *********/
    00263   if(S && !check_poly(S,C,en,C->Dimension,0,p)) {
    00264     fprintf(stderr,"Check failed !\n");
    00265     for(i=0;i<=(P->Dimension+1);i++)
    00266       value_clear(p[i]);
    00267     value_clear(tmp);
    00268     return(-1);
    00269   }
    00270
    00271 #ifndef PRINT_ALL_RESULTS
    00272   printf( "\n" );
    00273 #endif
    00274
    00275   for(i=0;i<=(P->Dimension+1);i++)
    00276     value_clear(p[i]);
    00277   value_clear(tmp);
    00278   return(0);
    00279 } /* main */
    00280
    00281
    00282
    00283