polylib: verif_ehrhart.c Source File

- Main Page
- Classes
- Files

- File List
- File Members

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