Main Page | Class List | File List | Class Members | File Members

testCompressParms.c

Go to the documentation of this file.
00001 /** 
00002  * $Id: testCompressParms.c,v 1.4 2006/09/18 03:09:03 meister Exp $
00003  * 
00004  * Test routines for kernel/compress_parms.c functions
00005  * @author B. Meister, 3/2006
00006  * 
00007  */
00008 
00009 #include <polylib/polylib.h>
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 #include <string.h>
00013 
00014 #ifdef dbg
00015 #undef dbg
00016 #endif
00017 #define dbg 1
00018 
00019 #define TEST(a) if (isOk = a) { \
00020                   printf(#a" tested ok.\n"); \
00021                 } \
00022                 else { \
00023                   printf(#a" NOT OK\n"); \
00024                 } 
00025 
00026 #define maxRays 200
00027 
00028 char * origNames[] = {"n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"};
00029 
00030 int main(int argc, char ** argv) {
00031   int isOk = 0;
00032   Matrix * A, * B;
00033   if (argc>1) {
00034     printf("Warning: No arguments taken into account: testing"
00035            "remove_parm_eqs().\n");
00036   }
00037 
00038   A = Matrix_Read();
00039   B = Matrix_Read();
00040   TEST( test_Constraints_Remove_parm_eqs(A, B) )
00041   TEST( test_Polyhedron_Remove_parm_eqs(A, B) )
00042   TEST( test_Constraints_fullDimensionize(A, B, 4) )
00043   Matrix_Free(A);
00044   Matrix_Free(B);
00045   return (1-isOk);
00046 }
00047 
00048 
00049 /** extracts the equalities involving the parameters only, try to introduce
00050     them back and compare the two polyhedra.
00051     Reads a polyhedron and a context.
00052  */
00053 int test_Constraints_Remove_parm_eqs(Matrix * A, Matrix * B) {
00054   int isOk = 1;
00055   Matrix * M, *C, *Cp, * Eqs, *M1, *C1;
00056   Polyhedron *Pm, *Pc, *Pcp, *Peqs, *Pint;
00057   unsigned int * elimParms;
00058   printf("----- test_Constraints_Remove_parm_eqs() -----\n");
00059   M1 = Matrix_Copy(A);
00060   C1 = Matrix_Copy(B);
00061 
00062   M = Matrix_Copy(M1);
00063   C = Matrix_Copy(C1);
00064 
00065    /* compute the combined polyhedron */
00066   Pm = Constraints2Polyhedron(M, maxRays);
00067   Pc = Constraints2Polyhedron(C, maxRays);
00068   Pcp = align_context(Pc, Pm->Dimension, maxRays);
00069   Polyhedron_Free(Pc);
00070   Pc = DomainIntersection(Pm, Pcp, maxRays);
00071   Polyhedron_Free(Pm);
00072   Polyhedron_Free(Pcp);
00073   Matrix_Free(M);
00074   Matrix_Free(C);
00075 
00076   /* extract the parm-equalities, expressed in the combined space */
00077   Eqs = Constraints_Remove_parm_eqs(&M1, &C1, 1, &elimParms);
00078 
00079   printf("Removed equalities: \n");
00080   show_matrix(Eqs); 
00081   printf("Polyhedron without equalities involving only parameters: \n");
00082   show_matrix(M1);  
00083   printf("Context without equalities: \n");
00084   show_matrix(C1);  
00085   
00086   /* compute the supposedly-same polyhedron, using the extracted equalities */
00087   Pm = Constraints2Polyhedron(M1, maxRays);
00088   Pcp = Constraints2Polyhedron(C1, maxRays);
00089   Peqs = align_context(Pcp, Pm->Dimension, maxRays);
00090   Polyhedron_Free(Pcp);
00091   Pcp = DomainIntersection(Pm, Peqs, maxRays);
00092   Polyhedron_Free(Peqs);
00093   Polyhedron_Free(Pm);
00094   Peqs = Constraints2Polyhedron(Eqs, maxRays);
00095   Matrix_Free(Eqs);
00096   Matrix_Free(M1);
00097   Matrix_Free(C1);
00098   Pint = DomainIntersection(Pcp, Peqs, maxRays);
00099   Polyhedron_Free(Pcp);
00100   Polyhedron_Free(Peqs);
00101 
00102   /* test their equality */
00103   if (!PolyhedronIncludes(Pint, Pc)) {
00104     isOk = 0;
00105   }
00106   else {
00107     if (!PolyhedronIncludes(Pc, Pint)) {
00108       isOk = 0;
00109     }
00110   }
00111   Polyhedron_Free(Pc);
00112   Polyhedron_Free(Pint);
00113   return isOk;
00114 } /* test_Constraints_Remove_parm_eqs() */
00115 
00116 
00117 /** extracts the equalities holding on the parameters only, try to introduce
00118     them back and compare the two polyhedra.
00119     Reads a polyhedron and a context.
00120  */
00121 int test_Polyhedron_Remove_parm_eqs(Matrix * A, Matrix * B) {
00122   int isOk = 1;
00123   Matrix * M, *C;
00124   Polyhedron *Pm, *Pc, *Pcp, *Peqs, *Pint, *Pint1;
00125   unsigned int * elimParms;
00126   printf("----- test_Polyhedron_Remove_parm_eqs() -----\n");
00127 
00128   M = Matrix_Copy(A);
00129   C = Matrix_Copy(B);
00130 
00131    /* compute the combined polyhedron */
00132   Pm = Constraints2Polyhedron(M, maxRays);
00133   Pc = Constraints2Polyhedron(C, maxRays);
00134   Pcp = align_context(Pc, Pm->Dimension, maxRays);
00135   Polyhedron_Free(Pc);
00136   Pint1 = DomainIntersection(Pm, Pcp, maxRays);
00137   Polyhedron_Free(Pm);
00138   Polyhedron_Free(Pcp);
00139   Matrix_Free(M);
00140   Matrix_Free(C);
00141 
00142   M = Matrix_Copy(A);
00143   C = Matrix_Copy(B);
00144   /* extract the parm-equalities, expressed in the combined space */
00145   Pm = Constraints2Polyhedron(M, maxRays);
00146   Pc = Constraints2Polyhedron(C, maxRays);
00147   Matrix_Free(M);
00148   Matrix_Free(C);
00149   Peqs = Polyhedron_Remove_parm_eqs(&Pm, &Pc, 1, &elimParms, 200);
00150   
00151   /* compute the supposedly-same polyhedron, using the extracted equalities */
00152   Pcp = align_context(Pc, Pm->Dimension, maxRays);
00153   Polyhedron_Free(Pc);
00154   Pc = DomainIntersection(Pm, Pcp, maxRays);
00155   Polyhedron_Free(Pm);
00156   Polyhedron_Free(Pcp);
00157  
00158   Pint = DomainIntersection(Pc, Peqs, maxRays);
00159   Polyhedron_Free(Pc);
00160   Polyhedron_Free(Peqs);
00161 
00162   /* test their equality */
00163   if (!PolyhedronIncludes(Pint, Pint1)) {
00164     isOk = 0;
00165   }
00166   else {
00167     if (!PolyhedronIncludes(Pint1, Pint)) {
00168       isOk = 0;
00169     }
00170   }
00171   Polyhedron_Free(Pint1);
00172   Polyhedron_Free(Pint);
00173   return isOk;
00174 } /* test_Polyhedron_remove_parm_eqs() */
00175 
00176 
00177 /** 
00178  * Eliminates certain parameters from a vector of values for parameters
00179  * @param origParms the initial vector of values of parameters
00180  * @param elimParms the list of parameters to be eliminated in the vector
00181  * @param newParms the vector of values without the eliminated ones.
00182  */
00183 void valuesWithoutElim(Matrix * origParms, unsigned int * elimParms, 
00184                        Matrix ** newParms) {
00185   unsigned int i, j=0;
00186   if (*newParms==NULL) {
00187     *newParms = Matrix_Alloc(1, origParms->NbColumns-elimParms[0]);
00188   } /* else assume enough space is allocated */
00189   if (elimParms[0] ==0) {
00190     for (i=0; i< origParms->NbColumns; i++) {
00191       value_assign((*newParms)->p[0][i], origParms->p[0][i]);
00192     }
00193   }
00194   for (i=0; i< origParms->NbColumns; i++) {
00195     if (i!=elimParms[j+1]) {
00196       value_assign((*newParms)->p[0][i-j], origParms->p[0][i]);
00197     }
00198     else {
00199       j++;
00200     }
00201   }
00202 }/* valuesWithoutElim */
00203 
00204 
00205 /**
00206  * takes a list of parameter names, a list ofparameters to eliminate, and
00207  * returns the list of parameters without the eliminated ones.
00208  * @param parms the original parameter names
00209  * @param nbParms the number of original parmaeters
00210  * @param elimParms the array-list of indices of parameters to eliminate (first
00211  * element set to the number of its elements)
00212  * @param newParms the returned list of parm names. Allocated if set to NULL,
00213  * reused if not.
00214  * @return the number of names in the returned list.
00215  */
00216 unsigned int namesWithoutElim(char ** parms, unsigned nbParms,
00217                               unsigned int * elimParms,
00218                               char *** newParms) {
00219   unsigned int i, j=0;
00220   unsigned int newSize = nbParms -elimParms[0];
00221   if (dbg) {
00222     printf("Size of the new parm vector: %d\n", newSize);
00223   }
00224   if (*newParms==NULL) {
00225     *newParms = malloc(newSize*sizeof(char *));
00226   }
00227   if (elimParms[0]==0) {
00228     for (i=0; i< nbParms; i++) {
00229       (*newParms)[i] = strdup(parms[i]);
00230     }
00231     return newSize;
00232   }
00233   for (i=0; i< nbParms; i++) {
00234     if (i!=elimParms[j+1]) {
00235       (*newParms)[i-j] = strdup(parms[i]);
00236     }
00237     else {
00238       j++;
00239     }
00240   }
00241   return newSize;
00242 }
00243 
00244 
00245 /**
00246  * Tests Constraints_fullDimensionize by comparing the Ehrhart polynomials 
00247  * @param A the input set of constraints
00248  * @param B the corresponding context
00249  * @param the number of samples to generate for the test
00250  * @return 1 if the Ehrhart polynomial had the same value for the
00251  * full-dimensional and non-full-dimensional sets of constraints, for their
00252  * corresponding sample parameters values.
00253  */
00254 int test_Constraints_fullDimensionize(Matrix * A, Matrix * B, 
00255                                       unsigned int nbSamples) {
00256   Matrix * Eqs= NULL, *ParmEqs=NULL, *VL=NULL;
00257   unsigned int * elimVars=NULL, * elimParms=NULL;
00258   Matrix * sample, * smallerSample=NULL;
00259   Matrix * transfSample=NULL;
00260   Matrix * parmVL=NULL;
00261   unsigned int i, j, r, nbOrigParms, nbParms;
00262   Value div, mod, *origVal=NULL, *fullVal=NULL;
00263   Matrix * VLInv;
00264   Polyhedron * P, *PC;
00265   Matrix * M, *C;
00266   Enumeration * origEP, * fullEP=NULL;
00267   char ** fullNames = NULL;
00268   int isOk = 1; /* holds the result */
00269 
00270   /* compute the origial Ehrhart polynomial */
00271   M = Matrix_Copy(A);
00272   C = Matrix_Copy(B);
00273   P = Constraints2Polyhedron(M, maxRays);
00274   PC = Constraints2Polyhedron(C, maxRays);
00275   origEP = Polyhedron_Enumerate(P, PC, maxRays, origNames);
00276   Matrix_Free(M);
00277   Matrix_Free(C);
00278   Polyhedron_Free(P);
00279   Polyhedron_Free(PC);
00280 
00281   /* compute the full-dimensional polyhedron corresponding to A and its Ehrhart
00282      polynomial */
00283   M = Matrix_Copy(A);
00284   C = Matrix_Copy(B);
00285   nbOrigParms = B->NbColumns-2;
00286   Constraints_fullDimensionize(&M, &C, &VL, &Eqs, &ParmEqs, 
00287                                &elimVars, &elimParms, maxRays);
00288   if ((Eqs->NbRows==0) && (ParmEqs->NbRows==0)) {
00289     Matrix_Free(M);
00290     Matrix_Free(C);
00291     Matrix_Free(Eqs);
00292     Matrix_Free(ParmEqs);
00293     free(elimVars);
00294     free(elimParms);
00295     return 1;
00296   }
00297   nbParms = C->NbColumns-2;
00298   P = Constraints2Polyhedron(M, maxRays);
00299   PC = Constraints2Polyhedron(C, maxRays);
00300   namesWithoutElim(origNames, nbOrigParms, elimParms, &fullNames);
00301   fullEP = Polyhedron_Enumerate(P, PC, maxRays, fullNames);
00302   Matrix_Free(M);
00303   Matrix_Free(C);
00304   Polyhedron_Free(P);
00305   Polyhedron_Free(PC);
00306   
00307   /* make a set of sample parameter values and compare the corresponding
00308      Ehrhart polnomials */
00309   sample = Matrix_Alloc(1,nbOrigParms);
00310   transfSample = Matrix_Alloc(1, nbParms);
00311   Lattice_extractSubLattice(VL, nbParms, &parmVL);
00312   VLInv = Matrix_Alloc(parmVL->NbRows, parmVL->NbRows+1);
00313   MatInverse(parmVL, VLInv);
00314   if (dbg) {
00315     show_matrix(parmVL);
00316     show_matrix(VLInv);
00317   }
00318   srandom(nbSamples);
00319   value_init(mod);
00320   value_init(div);
00321   for (i = 0; i< nbSamples; i++) {
00322     /* create a random sample */
00323     for (j=0; j< nbOrigParms; j++) {
00324       value_set_si(sample->p[0][j], random()%100);
00325     }
00326     /* compute the corresponding value for the full-dimensional
00327        constraints */
00328     valuesWithoutElim(sample, elimParms, &smallerSample); 
00329     /* (N' i' 1)^T = VLinv.(N i 1)^T*/
00330     for (r = 0; r < nbParms; r++) {
00331       Inner_Product(&(VLInv->p[r][0]), smallerSample->p[0], nbParms,
00332                     &(transfSample->p[0][r]));
00333       /* add the constant part */
00334       value_addto(transfSample->p[0][r], transfSample->p[0][r], 
00335                                          VLInv->p[r][VLInv->NbColumns-2]);
00336       value_pdivision(div, transfSample->p[0][r], 
00337                          VLInv->p[r][VLInv->NbColumns-1]);
00338       value_subtract(mod, transfSample->p[0][r], div);
00339       /* if the parameters value does not belong to the validity lattice, the
00340          Ehrhart polynomial is zero. */
00341       if (!value_zero_p(mod)) {
00342         fullEP = Enumeration_zero(nbParms, maxRays);
00343         break;
00344       }
00345     }
00346     /* compare the two forms of the Ehrhart polynomial.*/
00347     if (origEP ==NULL) break; /* NULL has loose semantics for EPs */
00348     origVal = compute_poly(origEP, sample->p[0]);
00349     fullVal = compute_poly(fullEP, transfSample->p[0]);
00350     if (!value_eq(*origVal, *fullVal)) {
00351       isOk = 0;
00352       printf("EPs don't match. \n Original value = ");
00353       value_print(stdout, VALUE_FMT, *origVal);
00354       printf("\n Original sample = [");
00355       for (j=0; j<sample->NbColumns; j++) {
00356         value_print(stdout, VALUE_FMT, sample->p[0][j]);
00357         printf(" ");
00358       }
00359       printf("] \n EP = ");
00360       if(origEP!=NULL) {
00361         print_evalue(stdout, &(origEP->EP), origNames);
00362       }
00363       else {
00364         printf("NULL");
00365       }
00366       printf(" \n Full-dimensional value = ");
00367       value_print(stdout, P_VALUE_FMT, *fullVal);
00368       printf("\n full-dimensional sample = [");
00369       for (j=0; j<sample->NbColumns; j++) {
00370         value_print(stdout, VALUE_FMT, transfSample->p[0][j]);
00371         printf(" ");
00372       }
00373       printf("] \n EP = ");
00374       if(origEP!=NULL) {
00375         print_evalue(stdout, &(origEP->EP), fullNames);
00376       }
00377       else {
00378         printf("NULL");
00379       }
00380     }
00381     if (dbg) {
00382       printf("\nOriginal value = ");
00383       value_print(stdout, VALUE_FMT, *origVal);
00384       printf("\nFull-dimensional value = ");
00385       value_print(stdout, P_VALUE_FMT, *fullVal);
00386       printf("\n");
00387     }
00388     value_clear(*origVal);
00389     value_clear(*fullVal);
00390   }
00391   value_clear(mod);
00392   value_clear(div);
00393   Matrix_Free(sample);
00394   Matrix_Free(smallerSample);
00395   Matrix_Free(transfSample);
00396   Enumeration_Free(origEP);
00397   Enumeration_Free(fullEP);
00398   return isOk;
00399 } /* test_Constraints_fullDimensionize */

Generated on Mon Apr 23 19:23:53 2007 for polylib by doxygen 1.3.5