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

Zpolyhedron.c

Go to the documentation of this file.
00001 #include <polylib/polylib.h> 
00002 #include <stdlib.h>
00003 
00004 static ZPolyhedron * ZPolyhedronIntersection(ZPolyhedron *, ZPolyhedron *);
00005 static ZPolyhedron *ZPolyhedron_Copy(ZPolyhedron *A);
00006 static void ZPolyhedron_Free(ZPolyhedron *Zpol);
00007 static ZPolyhedron * ZPolyhedronDifference(ZPolyhedron *, ZPolyhedron *);
00008 static ZPolyhedron * ZPolyhedronImage(ZPolyhedron *, Matrix *);
00009 static ZPolyhedron * ZPolyhedronPreimage(ZPolyhedron *, Matrix *);
00010 static ZPolyhedron *AddZPolytoZDomain(ZPolyhedron *A, ZPolyhedron *Head);
00011 static void ZPolyhedronPrint(FILE *fp, char *format, ZPolyhedron *A);
00012 
00013 typedef struct forsimplify {
00014   Polyhedron *Pol;
00015   LatticeUnion *LatUni;
00016   struct forsimplify *next;
00017 } ForSimplify;
00018 
00019 
00020 /* 
00021  * Returns True if 'Zpol' is empty, otherwise returns False 
00022  */
00023 Bool isEmptyZPolyhedron (ZPolyhedron *Zpol) {
00024   
00025   if(Zpol == NULL)
00026     return True;
00027   if((isEmptyLattice (Zpol->Lat)) || (emptyQ(Zpol->P)))
00028     return True;
00029   return False;
00030 } /* isEmptyZPolyhedron */
00031 
00032 /*
00033  * Given Lattice 'Lat' and a Polyhderon 'Poly', allocate space, and return
00034  * the Z-polyhderon corresponding to the image of the polyhderon 'Poly' by the 
00035  * lattice 'Lat'. If the input lattice 'Lat' is not integeral, it integralises 
00036  * it, i.e. the lattice of the Z-polyhderon returned is integeral. 
00037  */ 
00038 ZPolyhedron *ZPolyhedron_Alloc(Lattice *Lat, Polyhedron *Poly) {
00039   
00040   ZPolyhedron *A;
00041   
00042   if(Lat->NbRows != Poly->Dimension+1) {
00043     fprintf(stderr,"\nInZPolyAlloc - The Lattice  and the Polyhedron");
00044     fprintf(stderr," are not compatible to form a ZPolyhedra\n");
00045     return NULL;
00046   }  
00047   if((!(isEmptyLattice(Lat))) && (!isfulldim (Lat))) {
00048     fprintf(stderr,"\nZPolAlloc: Lattice not Full Dimensional\n");
00049     return NULL;
00050   }
00051   A = (ZPolyhedron *)malloc(sizeof(ZPolyhedron));
00052   if (!A) {
00053     fprintf(stderr,"ZPolAlloc : Out of Memory\n");
00054     return NULL;
00055   } 
00056   A->next = NULL;
00057   A->P = Domain_Copy(Poly);
00058   A->Lat = Matrix_Copy(Lat);
00059   
00060   if(IsLattice(Lat) == False) {
00061     ZPolyhedron *Res;
00062     
00063     Res = IntegraliseLattice (A);
00064     ZPolyhedron_Free (A);
00065     return Res;
00066   }
00067   return A;
00068 } /* ZPolyhedron_Alloc */
00069 
00070 /*
00071  * Free the memory used by the Z-domain 'Head' 
00072  */
00073 void ZDomain_Free (ZPolyhedron *Head) {
00074   
00075   if (Head == NULL)
00076     return;
00077   if (Head->next != NULL)
00078     ZDomain_Free(Head->next);  
00079   ZPolyhedron_Free(Head);
00080 } /* ZDomain_Free */
00081 
00082 /*
00083  * Free the memory used by the Z-polyhderon 'Zpol' 
00084  */
00085 static void ZPolyhedron_Free (ZPolyhedron *Zpol) {
00086   
00087   if (Zpol == NULL)
00088     return;
00089   Matrix_Free((Matrix *) Zpol->Lat);
00090   Domain_Free(Zpol->P);
00091   free(Zpol);
00092   return;
00093 } /* ZPolyhderon_Free */
00094 
00095 /*
00096  * Return a copy of the Z-domain 'Head' 
00097  */ 
00098 ZPolyhedron *ZDomain_Copy(ZPolyhedron *Head) {
00099   
00100   ZPolyhedron *Zpol;
00101   Zpol = ZPolyhedron_Copy(Head);
00102   
00103   if (Head->next != NULL)
00104     Zpol->next = ZDomain_Copy(Head->next);
00105   return Zpol;
00106 } /* ZDomain_Copy */
00107 
00108 /*
00109  * Return a copy of the Z-polyhderon 'A' 
00110  */
00111 static ZPolyhedron *ZPolyhedron_Copy(ZPolyhedron *A) {
00112 
00113   ZPolyhedron *Zpol;
00114   
00115   Zpol = ZPolyhedron_Alloc(A->Lat, A->P);
00116   return Zpol;
00117 } /* ZPolyhderon_Copy */
00118 
00119 /* 
00120  * Add the ZPolyhedron 'Zpol' to the Z-domain 'Result' and return a pointer 
00121  * to the new Z-domain. 
00122  */
00123 static ZPolyhedron *AddZPoly2ZDomain(ZPolyhedron *Zpol, ZPolyhedron *Result) {
00124  
00125   ZPolyhedron *A;
00126   
00127   if (isEmptyZPolyhedron(Zpol))
00128     return Result;
00129   A = ZPolyhedron_Copy(Zpol);
00130   A->next = NULL;
00131   
00132   if (isEmptyZPolyhedron (Result)) {
00133     ZDomain_Free (Result);
00134     return A;
00135   }
00136   A->next = Result;  
00137   return A;
00138 } /* AddZPoly2ZDomain */
00139   
00140 /*
00141  * Given a Z-polyhderon 'A' and a Z-domain 'Head', return a new Z-domain with 
00142  * 'A' added to it. If the new Z-polyhedron 'A', is already included in the 
00143  * Z-domain 'Head', it is not added in the list. Othewise, the function checks 
00144  * if the new Z-polyhedron 'A' to be added to the Z-domain 'Head' has a common
00145  * lattice with some other Z-polyhderon already present in the Z-domain. If it 
00146  * is so, it takes the union of the underlying polyhdera; domains and returns. 
00147  * The function tries to make sure that the added Z-polyhedron 'A' is in the 
00148  * canonical form.
00149  */
00150 static ZPolyhedron *AddZPolytoZDomain(ZPolyhedron *A, ZPolyhedron *Head) {
00151   
00152   ZPolyhedron *Zpol, *temp, *temp1;
00153   Polyhedron *i;
00154   Bool Added;  
00155   
00156   if ((A == NULL) || (isEmptyZPolyhedron(A)))
00157     return Head;
00158   
00159   /* For each "underlying" Pol, find the Cnf and add Zpol in Cnf*/  
00160   for(i=A->P; i!= NULL; i=i->next) {
00161     ZPolyhedron *Z, *Z1;
00162     Polyhedron *Image;
00163     Matrix *H, *U;
00164     Lattice *Lat ;
00165     
00166     Added = False;    
00167     Image = Domain_Copy(i);
00168     Domain_Free(Image->next);
00169     Image->next = NULL;
00170     Z1 = ZPolyhedron_Alloc(A->Lat,Image);
00171     Domain_Free(Image);
00172     CanonicalForm(Z1,&Z,&H); 
00173     ZDomain_Free(Z1);
00174     Lat = (Lattice *)Matrix_Alloc(H->NbRows,Z->Lat->NbColumns);
00175     Matrix_Product(H,Z->Lat,(Matrix *)Lat);
00176     Matrix_Free(H);    
00177     AffineHermite(Lat,(Lattice **)&H,&U);
00178     Image = DomainImage(Z->P,U,MAXNOOFRAYS);
00179     ZDomain_Free(Z);
00180       
00181     Zpol=ZPolyhedron_Alloc((Lattice *)H,Image);     
00182     Domain_Free(Image);
00183     Matrix_Free((Matrix *)Lat);
00184     Matrix_Free(H);
00185     Matrix_Free(U);
00186     
00187     if ((Head == NULL) || (isEmptyZPolyhedron (Head))) {
00188       Head = Zpol;
00189       continue;
00190     }     
00191     temp1 = temp = Head;
00192     
00193     /* Check if the curr pol is included in the zpol or vice versa. */    
00194     for(; temp != NULL; temp = temp->next) {
00195       if (ZPolyhedronIncludes(Zpol, temp) == True) {
00196         ZPolyhedron_Free (Zpol);
00197         Added = True; 
00198         break;
00199       }
00200       else if (ZPolyhedronIncludes(temp, Zpol) == True) {
00201         if (temp == Head) {
00202           Zpol->next = temp->next;
00203           Head = Zpol;
00204           ZPolyhedron_Free (temp);
00205           Added = True;
00206           break;
00207         }       
00208         temp1->next = Zpol;
00209         Zpol->next = temp->next;
00210         ZPolyhedron_Free (temp);
00211         Added = True;
00212         break ;
00213       }
00214       temp1 = temp ;
00215     }
00216     if(Added == True)
00217       continue ; 
00218     for(temp = Head; temp != NULL; temp = temp->next) {
00219       if(sameLattice(temp->Lat, Zpol->Lat) == True) {
00220         Polyhedron *Union;
00221         
00222         Union = DomainUnion (temp->P,Zpol->P,MAXNOOFRAYS);
00223         if (!Union)
00224           fprintf (stderr,"\n In AddZPolytoZDomain: Out of memory\n");
00225         else {
00226           Domain_Free(temp->P);
00227           temp->P = Union;
00228           Added = True;
00229           ZPolyhedron_Free(Zpol);
00230         }
00231         break ; 
00232       }
00233       temp1 = temp;
00234     }
00235     if (Added == False) 
00236       temp1->next = Zpol;
00237   }
00238   return Head ;  
00239 } /* AddZPolytoZDomain */
00240 
00241 /*
00242  * Return the empty Z-polyhedron of dimension 'dimension' 
00243  */
00244 ZPolyhedron *EmptyZPolyhedron(int dimension) {
00245 
00246   ZPolyhedron *Zpol;
00247   Lattice *E ;
00248   Polyhedron *P; 
00249   
00250 #ifdef DOMDEBUG
00251   FILE *fp;
00252   fp = fopen ("_debug", "a");
00253   fprintf (fp, "\nEntered EMPTYZPOLYHEDRON\n");
00254   fclose (fp);
00255 #endif
00256 
00257   E = EmptyLattice(dimension+1);
00258   P = Empty_Polyhedron(dimension);
00259   Zpol = ZPolyhedron_Alloc(E,P);
00260   Matrix_Free((Matrix *) E);
00261   Domain_Free(P);
00262   return Zpol;
00263 } /* EmptyZPolyhedron */
00264 
00265 /* 
00266  * Given Z-domains 'A' and 'B', return True if A is included in 'B', otherwise
00267  * return False.
00268  */
00269 Bool ZDomainIncludes(ZPolyhedron *A, ZPolyhedron *B) {
00270   
00271   ZPolyhedron *Diff;
00272   Bool ret = False;
00273   
00274   Diff = ZDomainDifference(A,B);
00275   if (isEmptyZPolyhedron(Diff))
00276     ret = True;
00277   
00278   ZDomain_Free(Diff);
00279   return ret;
00280 } /* ZDomainIncludes */
00281 
00282 /* 
00283  * Given Z-polyhedra 'A' and 'B', return True if 'A' is included in 'B', 
00284  * otherwise return False 
00285  */
00286 Bool ZPolyhedronIncludes(ZPolyhedron *A, ZPolyhedron *B) {
00287 
00288   Polyhedron *Diff = NULL ;
00289   Bool retval = False;
00290 
00291 #ifdef DOMDEBUG
00292   FILE *fp;
00293   fp = fopen("_debug","a");
00294   fprintf(fp,"\nEntered ZPOLYHEDRONINCLUDES\n");
00295   fclose(fp);
00296 #endif
00297   
00298   if (LatticeIncludes(A->Lat, B->Lat) == True) {
00299     Polyhedron *ImageA, *ImageB ;
00300     
00301     ImageA = DomainImage(A->P,A->Lat,MAXNOOFRAYS);
00302     ImageB = DomainImage(B->P,B->Lat,MAXNOOFRAYS);
00303       
00304     Diff = DomainDifference(ImageA, ImageB, MAXNOOFRAYS);
00305     if(emptyQ (Diff))
00306       retval = True ;
00307     
00308     Domain_Free (ImageA);
00309     Domain_Free (ImageB);
00310     Domain_Free (Diff);
00311   }  
00312   return retval;
00313 } /* ZPolyhedronIncludes */ 
00314 
00315 /*
00316  * Print the contents of a Z-domain 'A' 
00317  */
00318 void ZDomainPrint(FILE *fp,char *format,ZPolyhedron *A) {
00319   
00320 #ifdef DOMDEBUG
00321   FILE *fp1;
00322   fp1 = fopen("_debug", "a");
00323   fprintf(fp1,"\nEntered ZDOMAINPRINT\n");
00324   fclose(fp1);
00325 #endif
00326   
00327   ZPolyhedronPrint(fp,format,A);
00328   if (A->next != NULL) {
00329     fprintf(fp,"\nUNIONED with\n");
00330     ZDomainPrint(fp,format,A->next);
00331   }
00332   return;
00333 } /* ZDomainPrint */  
00334 
00335 /*
00336  * Print the contents of a ZPolyhderon 'A'
00337  */
00338 static void ZPolyhedronPrint (FILE *fp, char *format, ZPolyhedron *A) {
00339   
00340   if (A == NULL)
00341     return ;
00342   fprintf(fp,"\nZPOLYHEDRON: Dimension %d \n",A->Lat->NbRows-1);
00343   fprintf(fp, "\nLATTICE: \n");
00344   Matrix_Print(fp,format,(Matrix *)A->Lat);
00345   Polyhedron_Print(fp,format,A->P);  
00346   return;
00347 } /* ZPolyhedronPrint */
00348 
00349 /*
00350  * Return the Z-domain union of the Z-domain 'A' and 'B'. The dimensions of the
00351  * Z-domains 'A' and 'B' must be equal. All the Z-polyhedra of the resulting 
00352  * union are expected to be in Canonical forms.
00353  */
00354 ZPolyhedron *ZDomainUnion (ZPolyhedron *A, ZPolyhedron *B) {
00355   
00356   ZPolyhedron *Result = NULL, *temp;
00357   
00358 #ifdef DOMDEBUG
00359   FILE *fp;
00360   fp = fopen("_debug", "a");
00361   fprintf(fp,"\nEntered ZDOMAINUNION\n");
00362   fclose(fp);
00363 #endif
00364 
00365   for(temp = A; temp != NULL; temp = temp->next)
00366     Result = AddZPolytoZDomain(temp, Result); 
00367   for(temp = B; temp != NULL; temp = temp->next )
00368     Result = AddZPolytoZDomain(temp, Result);
00369   return Result;
00370 } /* ZDomainUnion */
00371 
00372 /* 
00373  * Return the Z-domain intersection of the Z-domains 'A' and 'B'.The dimensions
00374  * of domains 'A' and 'B' must be equal. 
00375  */
00376 ZPolyhedron *ZDomainIntersection (ZPolyhedron *A, ZPolyhedron *B) {
00377   
00378   ZPolyhedron *Result = NULL, *tempA = NULL, *tempB = NULL;
00379 
00380 #ifdef DOMDEBUG
00381   FILE *fp;
00382   fp = fopen("_debug", "a");
00383   fprintf(fp,"\nEntered ZDOMAININTERSECTION\n");
00384   fclose(fp);
00385 #endif  
00386   
00387   for(tempA = A; tempA != NULL; tempA = tempA->next)
00388     for(tempB = B; tempB != NULL; tempB = tempB->next) {
00389       ZPolyhedron *Zpol;
00390       Zpol = ZPolyhedronIntersection(tempA, tempB);
00391       Result = AddZPolytoZDomain(Zpol, Result );
00392       ZPolyhedron_Free (Zpol);
00393     }
00394   if (Result == NULL)
00395     return EmptyZPolyhedron (A->Lat->NbRows-1);
00396   return Result;
00397 } /* ZDomainIntersection */
00398 
00399 /*
00400  * Return the Z-domain difference of the domains 'A' and 'B'. The dimensions of
00401  * the Z-domains 'A' and 'B' must be equal. Note that the difference of two 
00402  * Z-polyhedra is a Union of Z-polyhedra. The algorithms is as given below :-
00403  * Algorithm: (Given Z-domains A and B)
00404  *           Result <-- NULL
00405  *           for every Z-polyhderon Zpoly of A {
00406  *               temp <-- Zpoly;
00407  *               for every Z-polyhderon Z1 of B
00408  *                  temp = temp - Z1;
00409  *               }
00410  *           Add temp to Result;
00411  *           return;
00412  */
00413 ZPolyhedron *ZDomainDifference(ZPolyhedron  *A, ZPolyhedron *B) {
00414   
00415   ZPolyhedron *Result = NULL, *tempA = NULL, *tempB = NULL;
00416   ZPolyhedron *templist, *res, *i, *j;
00417 
00418 #ifdef DOMDEBUG
00419   FILE *fp;
00420   fp = fopen("_debug", "a");
00421   fprintf(fp,"\nEntered ZDOMAINDIFFERENCE\n");
00422   fclose(fp);
00423 #endif
00424   
00425   if (A->Lat->NbRows != B->Lat->NbRows) {
00426     fprintf(stderr, "In ZDomainDifference : The Input ZDomains");
00427     fprintf(stderr, "Do not have the compatible dimensions\n");
00428     fprintf(stderr, "ZDomainDiffernce not performed\n");
00429     return NULL;
00430   }
00431   
00432   for(tempA = A; tempA != NULL; tempA = tempA->next) {
00433     ZPolyhedron *temp = NULL;
00434     temp = ZPolyhedron_Copy(tempA);
00435     
00436     for(tempB = B; tempB != NULL; tempB = tempB->next) {
00437       templist = NULL; res = NULL;
00438       //for(i = temp; i != NULL; i = i->next) {
00439         i=temp;
00440         res = ZPolyhedronDifference(i,tempB);
00441         for (j = res; j != NULL; j = j->next )
00442           templist = AddZPoly2ZDomain(j,templist);
00443         ZDomain_Free(res);
00444       //}
00445       ZDomain_Free (temp);
00446       temp = NULL; 
00447       for(i = templist; i != NULL; i = i->next)
00448         temp = AddZPoly2ZDomain(i, temp);
00449       ZDomain_Free (templist);
00450     }
00451     for(i = temp; i != NULL; i = i->next)
00452       Result = AddZPolytoZDomain(i, Result);
00453     ZDomain_Free(temp);    
00454   }
00455   if (Result==NULL)
00456     return (EmptyZPolyhedron(A->Lat->NbRows-1));
00457   return Result;
00458 } /* ZDomainDifference */
00459 
00460 /*
00461  * Return the image of the Z-domain 'A' under the invertible, affine, rational
00462  * transformation function 'Func'. The matrix representing the function 'Func'
00463  * must be non-singular and the number of rows of the function must be equal
00464  * to the number of rows in the matrix representing the lattice of 'A'. 
00465  * Note:: Image((Z1 U Z2),F) = Image(Z1,F) U Image(Z2 U F).
00466  */
00467 ZPolyhedron *ZDomainImage (ZPolyhedron *A, Matrix *Func) {
00468 
00469   ZPolyhedron *Result = NULL, *temp;
00470 
00471 #ifdef DOMDEBUG
00472   FILE *fp;
00473   fp = fopen ("_debug", "a");
00474   fprintf (fp, "\nEntered ZDOMAINIMAGE\n");
00475   fclose (fp);
00476 #endif  
00477   
00478   for(temp = A; temp != NULL; temp = temp->next) {
00479     ZPolyhedron *Zpol;
00480     Zpol =  ZPolyhedronImage (temp, Func);
00481     Result = AddZPolytoZDomain (Zpol, Result);
00482     ZPolyhedron_Free (Zpol);
00483   }  
00484   if(Result == NULL)
00485     return EmptyZPolyhedron(A->Lat->NbRows-1);  
00486   return Result;
00487 } /* ZDomainImage */ 
00488 
00489 /*
00490  * Return the preimage of the Z-domain 'A' under the invertible, affine, ratio-
00491  * nal transformation 'Func'. The number of rows of the matrix representing 
00492  * the function 'Func' must be equal to the number of rows of the matrix repr-
00493  * senting the lattice of 'A'.  
00494  */
00495 ZPolyhedron *ZDomainPreimage (ZPolyhedron *A, Matrix *Func) {
00496 
00497   ZPolyhedron *Result = NULL, *temp ;
00498   
00499 #ifdef DOMDEBUG
00500   FILE *fp;
00501   fp = fopen("_debug", "a");
00502   fprintf(fp,"\nEntered ZDOMAINPREIMAGE\n");
00503   fclose(fp);
00504 #endif
00505   
00506   if (A->Lat->NbRows != Func->NbRows) {
00507     fprintf(stderr,"\nError : In ZDomainPreimage, ");
00508     fprintf(stderr,"Incompatible dimensions of ZPolyhedron ");
00509     fprintf(stderr,"and the Function \n");
00510     return(EmptyZPolyhedron(Func->NbColumns-1)); 
00511   }  
00512   for(temp = A; temp != NULL; temp = temp->next) {       
00513     ZPolyhedron *Zpol;
00514     Zpol = ZPolyhedronPreimage(temp, Func);
00515     Result = AddZPolytoZDomain(Zpol, Result);
00516     ZPolyhedron_Free(Zpol);
00517   }  
00518   if (Result == NULL)
00519     return(EmptyZPolyhedron(Func->NbColumns-1));
00520   return Result;   
00521 } /* ZDomainPreimage */ 
00522 
00523 /*
00524  * Return the Z-polyhedron intersection of the Z-polyhedra 'A' and 'B'. 
00525  * Note: If Z1 = L1 (intersect) P1 and Z2 = L2 (intersect) P2, then 
00526  *     Z1 (intersect) Z2 = (L1 (intersect) L2) (intersect) (P1 (intersect) P2) 
00527  */
00528 static ZPolyhedron *ZPolyhedronIntersection(ZPolyhedron *A, ZPolyhedron *B) {
00529   
00530   ZPolyhedron *Result = NULL;
00531   Lattice *LInter;
00532   Polyhedron *PInter, *ImageA, *ImageB, *PreImage;
00533   
00534 #ifdef DOMDEBUG
00535   FILE *fp;
00536   fp = fopen("_debug","a");
00537   fprintf(fp,"\nEntered ZPOLYHEDRONINTERSECTION\n");
00538   fclose(fp);
00539 #endif  
00540   
00541   LInter = LatticeIntersection(A->Lat,B->Lat);
00542   if(isEmptyLattice(LInter) == True) {
00543     ZPolyhedron_Free (Result);
00544     Matrix_Free(LInter);
00545     return (EmptyZPolyhedron(A->Lat->NbRows-1));
00546   }  
00547   ImageA = DomainImage(A->P,A->Lat,MAXNOOFRAYS);
00548   ImageB = DomainImage(B->P,B->Lat,MAXNOOFRAYS);
00549   PInter = DomainIntersection(ImageA,ImageB,MAXNOOFRAYS); 
00550   if (emptyQ(PInter))
00551     Result = EmptyZPolyhedron(LInter->NbRows-1);
00552   else { 
00553     PreImage = DomainPreimage(PInter,(Matrix *)LInter,MAXNOOFRAYS);
00554     Result = ZPolyhedron_Alloc(LInter, PreImage);    
00555     Domain_Free (PreImage);
00556   }  
00557   Matrix_Free(LInter);
00558   Domain_Free(PInter); 
00559   Domain_Free(ImageA);
00560   Domain_Free(ImageB);  
00561   return Result ;
00562 } /* ZPolyhedronIntersection */ 
00563 
00564 /* 
00565  * Return the difference of the two Z-polyhedra 'A' and 'B'. Below is the 
00566  * procedure to find the difference of 'A' and 'B' :-
00567  * Procedure: 
00568  *     Let A = L1 (intersect) P1' and B = L2 (intersect) P2' where 
00569  *     (P1' = DomImage(P1,L1) and P2' = DomImage(P2,L2)). Then 
00570  *     A-B = L1 (intersect) (P1'-P2') Union 
00571  *           (L1-L2) (intersect) (P1' (intersect) P2')
00572  */ 
00573 static ZPolyhedron *ZPolyhedronDifference(ZPolyhedron *A, ZPolyhedron *B) {
00574   
00575   ZPolyhedron *Result = NULL ;
00576   LatticeUnion *LatDiff, *temp;
00577   Polyhedron *DomDiff, *DomInter, *PreImage, *ImageA, *ImageB;
00578   Bool flag = False;
00579 
00580 #ifdef DOMDEBUG
00581   FILE *fp;
00582   fp = fopen("_debug", "a");
00583   fprintf(fp,"\nEntered ZPOLYHEDRONDIFFERENCE\n");
00584   fclose(fp);
00585 #endif
00586 
00587   if(isEmptyZPolyhedron (A))
00588     return NULL;
00589   if(isEmptyZPolyhedron (B)) {
00590     Result = ZDomain_Copy (A);
00591     return Result;
00592   }  
00593   ImageA = DomainImage(A->P,(Matrix *)A->Lat,MAXNOOFRAYS);
00594   ImageB = DomainImage(B->P,(Matrix *)B->Lat,MAXNOOFRAYS);  
00595   DomDiff = DomainDifference(ImageA,ImageB,MAXNOOFRAYS);
00596   if (emptyQ (DomDiff))
00597     flag = True;
00598   else {
00599     ZPolyhedron *Z;
00600     PreImage = DomainPreimage(DomDiff,A->Lat,MAXNOOFRAYS);
00601     Z = ZPolyhedron_Alloc(A->Lat,PreImage);    
00602     Result = AddZPolytoZDomain(Z,Result);
00603   }  
00604   if (flag == True)  /* DomDiff = NULL; DomInter = A */
00605     DomInter = Domain_Copy(ImageA);
00606   else {
00607     DomInter = DomainIntersection(ImageA,ImageB,MAXNOOFRAYS);
00608     if (emptyQ(DomInter)) {
00609       if (flag == True)
00610         return (EmptyZPolyhedron(A->Lat->NbRows-1));
00611       else
00612         return Result;
00613     }
00614   }  
00615   LatDiff = LatticeDifference(A->Lat, B->Lat);
00616   if(LatDiff == NULL)
00617     if(flag == True )
00618       return(EmptyZPolyhedron (A->Lat->NbRows-1));
00619   
00620   while (LatDiff != NULL) {
00621     ZPolyhedron *tempZ = NULL;
00622     
00623     PreImage = DomainPreimage(DomInter, LatDiff->M, MAXNOOFRAYS);    
00624     tempZ = ZPolyhedron_Alloc(LatDiff->M, PreImage);
00625     Domain_Free(PreImage);
00626     Result = AddZPoly2ZDomain(tempZ,Result);
00627     ZPolyhedron_Free(tempZ);
00628     temp = LatDiff;
00629     LatDiff = LatDiff->next;  
00630     Matrix_Free ((Matrix *) temp->M);
00631     free (temp);
00632   }  
00633   Domain_Free (DomInter);
00634   Domain_Free (DomDiff);
00635   return Result;
00636 } /* ZPolyhedronDifference */ 
00637 
00638 /*
00639  * Return the image of the Z-polyhedron 'ZPol' under the invertible, affine, 
00640  * rational transformation function 'Func'. The matrix representing the funct-
00641  * ion must be non-singular and the number of rows of the function must be 
00642  * equal to the number of rows in the matrix representing the lattice of 'ZPol'
00643  * Algorithm: 
00644  *         1)  Let ZPol = L (intersect) Q
00645  *         2)  L1 = LatticeImage(L,F)
00646  *         3)  Q1 = DomainImage(Q,F)
00647  *         4)  Z1 = L1(Inverse(L1)*Q1)
00648  *         5)  Return Z1
00649  */
00650 static ZPolyhedron *ZPolyhedronImage(ZPolyhedron *ZPol,Matrix *Func) {
00651  
00652   ZPolyhedron *Result = NULL ;
00653   Matrix *LatIm ;
00654   Polyhedron *Pol, *PolImage ; 
00655   
00656 #ifdef DOMDEBUG
00657   FILE *fp;
00658   fp = fopen("_debug", "a");
00659   fprintf(fp,"\nEntered ZPOLYHEDRONIMAGE\n");
00660   fclose(fp);
00661 #endif
00662   
00663   if ((Func->NbRows != ZPol->Lat->NbRows) || (Func->NbColumns != ZPol->Lat->NbColumns)) {
00664     fprintf (stderr, "In ZPolImage - The Function, is not compatible with the ZPolyhedron\n");
00665     return NULL;
00666   }
00667   LatIm = LatticeImage(ZPol->Lat,Func);
00668   if (isEmptyLattice(LatIm)) {
00669     Matrix_Free(LatIm);
00670     return NULL;
00671   }
00672   Pol = DomainImage(ZPol->P,ZPol->Lat,MAXNOOFRAYS);
00673   PolImage = DomainImage(Pol,Func,MAXNOOFRAYS);
00674   Domain_Free(Pol);
00675   if(emptyQ(PolImage)) {
00676     Matrix_Free (LatIm);
00677     Domain_Free (PolImage);
00678     return NULL;
00679   } 
00680   Pol = DomainPreimage(PolImage,LatIm,MAXNOOFRAYS);
00681   Result = ZPolyhedron_Alloc(LatIm,Pol);
00682   Domain_Free(Pol);
00683   Domain_Free(PolImage);
00684   Matrix_Free(LatIm);
00685   return Result;  
00686 } /* ZPolyhedronImage */ 
00687 
00688 /*
00689  * Return the preimage of the Z-polyhedron 'Zpol' under an affine transformati-
00690  * on function 'G'. The number of rows of matrix representing the function 'G',
00691  * must be equal to the number of rows of the matrix representing the lattice 
00692  * of Z1. 
00693  * Algorithm: 
00694  *            1) Let Zpol = L (intersect) Q
00695  *            2) L1 =LatticePreimage(L,F);
00696  *            3) Q1 = DomainPreimage(Q,F);
00697  *            4) Z1 = L1(Inverse(L1)*Q1);
00698  *            5) Return Z1
00699  */
00700 static ZPolyhedron *ZPolyhedronPreimage(ZPolyhedron *Zpol, Matrix *G) {
00701   
00702   Lattice *Latpreim;
00703   Polyhedron *Qprime, *Q, *Polpreim;
00704   ZPolyhedron *Result;
00705   
00706 #ifdef DOMDEBUG
00707   FILE *fp;
00708   fp = fopen("_debug","a");
00709   fprintf(fp,"\nEntered ZPOLYHEDRONPREIMAGE\n");
00710   fclose(fp);
00711 #endif
00712   
00713   if(G->NbRows != Zpol->Lat->NbRows) {
00714     fprintf(stderr,"\nIn ZPolyhedronPreimage: Error, The dimensions of the ");
00715     fprintf(stderr,"function are not compatible with that of the Zpolyhedron");
00716     return EmptyZPolyhedron(G->NbColumns-1);
00717   }
00718   Q = DomainImage(Zpol->P,Zpol->Lat,MAXNOOFRAYS);
00719   Polpreim = DomainPreimage(Q,G,MAXNOOFRAYS);
00720   if (emptyQ(Polpreim))
00721     Result = NULL;
00722   else {
00723     Latpreim = LatticePreimage(Zpol->Lat,G);
00724     if(isEmptyLattice(Latpreim))
00725       Result = NULL;
00726     else {
00727       Qprime = DomainPreimage(Polpreim, Latpreim, MAXNOOFRAYS);
00728       Result = ZPolyhedron_Alloc(Latpreim, Qprime);
00729       Domain_Free(Qprime);
00730     }
00731     Matrix_Free(Latpreim);
00732   }  
00733   Domain_Free(Q);
00734   return Result; 
00735 } /* ZPolyhedronPreimage */ 
00736 
00737 /* 
00738  * Return the Z-polyhderon 'Zpol' in canonical form: 'Result' (for the Z-poly-
00739  * hedron in canonical form) and Basis 'Basis' (for the basis with respect to 
00740  * which 'Result' is in canonical form.   
00741  */
00742 void CanonicalForm(ZPolyhedron *Zpol,ZPolyhedron **Result,Matrix **Basis) {
00743 
00744   Matrix *B1 = NULL, *B2=NULL, *T1 , *B2inv;
00745   int i, l1, l2;
00746   Value tmp;
00747   Polyhedron *Image, *ImageP;
00748   Matrix *H, *U, *temp, *Hprime, *Uprime, *T2;
00749   
00750 #ifdef DOMDEBUG
00751   FILE *fp;
00752   fp = fopen("_debug", "a");
00753   fprintf(fp,"\nEntered CANONICALFORM\n");
00754   fclose(fp);
00755 #endif
00756   
00757   if(isEmptyZPolyhedron (Zpol)) {
00758     Basis[0] = Identity(Zpol->Lat->NbRows);
00759     Result[0] = ZDomain_Copy (Zpol);
00760     return ;
00761   }
00762   value_init(tmp);
00763   l1 = FindHermiteBasisofDomain(Zpol->P,&B1);
00764   Image = DomainImage (Zpol->P,(Matrix *)Zpol->Lat,MAXNOOFRAYS);
00765   l2 = FindHermiteBasisofDomain(Image,&B2);
00766     
00767   if (l1 != l2)
00768     fprintf(stderr,"In CNF : Something wrong with the Input Zpolyhedra \n"); 
00769   
00770   B2inv = Matrix_Alloc(B2->NbRows, B2->NbColumns);
00771   temp = Matrix_Copy(B2);
00772   Matrix_Inverse(temp,B2inv);
00773   Matrix_Free(temp);
00774   
00775   temp = Matrix_Alloc(B2inv->NbRows,Zpol->Lat->NbColumns);
00776   T1 = Matrix_Alloc(temp->NbRows,B1->NbColumns);
00777   Matrix_Product(B2inv,(Matrix *)Zpol->Lat,temp);
00778   Matrix_Product(temp,B1,T1);  
00779   Matrix_Free(temp);
00780   
00781   T2 = ChangeLatticeDimension(T1,l1);
00782   temp = ChangeLatticeDimension(T2,T2->NbRows+1);
00783 
00784   /* Adding the affine part */
00785   for(i = 0; i < l1; i ++)
00786     value_assign(temp->p[i][temp->NbColumns-1],T1->p[i][T1->NbColumns-1]);
00787   
00788   AffineHermite(temp,&H,&U);
00789   Hprime = ChangeLatticeDimension(H,Zpol->Lat->NbRows);
00790   
00791   /* Exchanging the Affine part */
00792   for(i = 0; i < l1; i ++) {
00793     value_assign(tmp,Hprime->p[i][Hprime->NbColumns-1]);
00794     value_assign(Hprime->p[i][Hprime->NbColumns-1],Hprime->p[i][H->NbColumns-1]);
00795     value_assign(Hprime->p[i][H->NbColumns-1],tmp);
00796   }
00797   Uprime = ChangeLatticeDimension(U,Zpol->Lat->NbRows);
00798   
00799   /* Exchanging the Affine part */
00800   for (i = 0;i < l1; i++) {
00801     value_assign(tmp,Uprime->p[i][Uprime->NbColumns-1]);
00802     value_assign(Uprime->p[i][Uprime->NbColumns-1],Uprime->p[i][U->NbColumns-1]);
00803     value_assign(Uprime->p[i][U->NbColumns-1],tmp);
00804   }    
00805   Polyhedron_Free (Image);
00806   Matrix_Free (B2inv);
00807   B2inv = Matrix_Alloc(B1->NbRows, B1->NbColumns);
00808   Matrix_Inverse(B1,B2inv);
00809   ImageP = DomainImage(Zpol->P, B2inv, MAXNOOFRAYS);
00810   Image = DomainImage(ImageP, Uprime, MAXNOOFRAYS);
00811   Result[0] = ZPolyhedron_Alloc(Hprime, Image);
00812   Basis[0] = Matrix_Copy(B2); 
00813   
00814   /* Free the variables */
00815   Polyhedron_Free (Image);
00816   Matrix_Free (B1);
00817   Matrix_Free (B2);
00818   Matrix_Free (temp);
00819   Matrix_Free (T1);
00820   Matrix_Free (T2);
00821   Matrix_Free (H);
00822   Matrix_Free (U);
00823   Matrix_Free (Hprime);
00824   Matrix_Free (Uprime);
00825   value_clear(tmp);
00826   return;
00827 } /* CanonicalForm */ 
00828 
00829 /*
00830  * Given a Z-polyhedron 'A' in which the Lattice is not integral, return the
00831  * Z-polyhedron which contains all the integral points in the input lattice.
00832  */
00833 ZPolyhedron *IntegraliseLattice(ZPolyhedron *A) {
00834  
00835   ZPolyhedron *Result;
00836   Lattice *M = NULL, *Id;
00837   Polyhedron *Im = NULL, *Preim = NULL;
00838 
00839 #ifdef DOMDEBUG
00840   FILE *fp;
00841   fp = fopen("_debug","a");
00842   fprintf(fp,"\nEntered INTEGRALISELATTICE\n");
00843   fclose(fp);
00844 #endif
00845   
00846   Im = DomainImage(A->P,A->Lat,MAXNOOFRAYS);
00847   Id = Identity(A->Lat->NbRows);
00848   M = LatticeImage(Id, A->Lat);
00849   if (isEmptyLattice(M))
00850     Result = EmptyZPolyhedron(A->Lat->NbRows-1);
00851   else {
00852     Preim = DomainPreimage(Im,M,MAXNOOFRAYS);
00853     Result = ZPolyhedron_Alloc(M,Preim);
00854   }  
00855   Matrix_Free(M);
00856   Domain_Free(Im);
00857   Domain_Free(Preim);  
00858   return Result;
00859 } /* IntegraliseLattice */ 
00860 
00861 /* 
00862  * Return the simplified representation of the Z-domain 'ZDom'. It attempts to 
00863  * convexize unions of polyhedra when they correspond to the same lattices and
00864  * to simplify union of lattices when they correspond to the same polyhdera. 
00865  */
00866 ZPolyhedron *ZDomainSimplify(ZPolyhedron *ZDom) {
00867   
00868   ZPolyhedron *Ztmp, *Result;
00869   ForSimplify *Head, *Prev, *Curr;
00870   ZPolyhedron *ZDomHead, *Emp;
00871   
00872   if (ZDom == NULL) {
00873     fprintf(stderr,"\nError in ZDomainSimplify - ZDomHead = NULL\n");
00874     return NULL;
00875   }  
00876   if (ZDom->next == NULL)
00877     return (ZPolyhedron_Copy (ZDom));  
00878   Emp = EmptyZPolyhedron(ZDom->Lat->NbRows-1);
00879   ZDomHead = ZDomainUnion(ZDom, Emp);
00880   ZPolyhedron_Free(Emp);  
00881   Head = NULL;
00882   Ztmp = ZDomHead;
00883   do {
00884     Polyhedron *Img;
00885     Img = DomainImage(Ztmp->P,Ztmp->Lat,MAXNOOFRAYS);
00886     for(Curr = Head; Curr != NULL; Curr = Curr->next) {
00887       Polyhedron *Diff1;
00888       Bool flag = False;
00889       
00890       Diff1 = DomainDifference(Img,Curr->Pol,MAXNOOFRAYS);
00891       if (emptyQ(Diff1)) {
00892         Polyhedron *Diff2;
00893 
00894         Diff2 = DomainDifference(Curr->Pol,Img,MAXNOOFRAYS); 
00895         if (emptyQ(Diff2))
00896           flag = True;  
00897         Domain_Free(Diff2);
00898       }      
00899       Domain_Free (Diff1);
00900       if (flag == True) {
00901         LatticeUnion *temp;     
00902         
00903         temp = (LatticeUnion *)malloc(sizeof(LatticeUnion));
00904         temp->M = (Lattice *)Matrix_Copy((Matrix *)Ztmp->Lat); 
00905         temp->next = Curr->LatUni;
00906         Curr->LatUni = temp;
00907         break;
00908       }
00909     }
00910     if(Curr == NULL) {
00911       Curr = (ForSimplify *)malloc(sizeof(ForSimplify));      
00912       Curr->Pol = Domain_Copy(Img);
00913       Curr->LatUni = (LatticeUnion *)malloc(sizeof(LatticeUnion));
00914       Curr->LatUni->M = (Lattice *)Matrix_Copy((Matrix *)Ztmp->Lat); 
00915       Curr->LatUni->next = NULL;
00916       Curr->next = Head;
00917       Head = Curr;
00918     }   
00919     Domain_Free (Img);
00920     Ztmp = Ztmp->next;
00921   } while(Ztmp != NULL);
00922   
00923   for (Curr = Head; Curr != NULL; Curr = Curr->next)
00924     Curr->LatUni = LatticeSimplify(Curr->LatUni);  
00925   Result = NULL;
00926   for(Curr = Head; Curr != NULL; Curr = Curr->next) {
00927     LatticeUnion *L;    
00928     for(L = Curr->LatUni; L != NULL; L = L->next) {
00929       Polyhedron *Preim;
00930       ZPolyhedron *Zpol;
00931       
00932       Preim = DomainPreimage(Curr->Pol,L->M,MAXNOOFRAYS);
00933       Zpol = ZPolyhedron_Alloc(L->M, Preim);
00934       Zpol->next = Result;
00935       Result = Zpol;
00936       Domain_Free(Preim);
00937     }
00938   }  
00939   Curr = Head;
00940   while (Curr != NULL) {
00941     Prev = Curr;
00942     Curr = Curr->next;     
00943     LatticeUnion_Free(Prev->LatUni);
00944     Domain_Free(Prev->Pol);
00945     free(Prev);
00946   }
00947   return Result;
00948 } /* ZDomainSimplify */ 
00949 
00950 ZPolyhedron *SplitZpolyhedron(ZPolyhedron *ZPol,Lattice *B) {
00951  
00952   Lattice *Intersection = NULL;
00953   Lattice *B1 = NULL, *B2 = NULL, *newB1 = NULL, *newB2 = NULL;
00954   Matrix *U = NULL,*M1 = NULL, *M2 = NULL, *M1Inverse = NULL,*MtProduct = NULL;
00955   Matrix *Vinv, *V , *temp, *DiagMatrix ;
00956   Matrix *H , *U1 , *X, *Y ;
00957   ZPolyhedron *zpnew, *Result;
00958   LatticeUnion *Head = NULL, *tempHead = NULL;
00959   int i;
00960   Value k;
00961   
00962 #ifdef DOMDEBUG
00963   FILE *fp;
00964   fp = fopen("_debug", "a");
00965   fprintf(fp,"\nEntered SplitZpolyhedron \n"); 
00966   fclose(fp);
00967 #endif
00968 
00969   
00970   if (B->NbRows != B->NbColumns) { 
00971     fprintf(stderr,"\n SplitZpolyhedron : The Input Matrix B is not a proper Lattice \n");
00972     return NULL;
00973   }
00974   
00975   if (ZPol->Lat->NbRows != B->NbRows) {
00976     fprintf(stderr,"\nSplitZpolyhedron : The Lattice in Zpolyhedron and B have ");
00977     fprintf(stderr,"incompatible dimensions \n");
00978     return NULL;
00979   }
00980   
00981   if (isinHnf (ZPol->Lat) != True) {
00982     AffineHermite(ZPol->Lat,&H,&U1);
00983     X = Matrix_Copy(H);    
00984     Matrix_Free(U1);
00985     Matrix_Free(H);
00986   }
00987   else
00988     X = Matrix_Copy(ZPol->Lat);
00989   
00990   if (isinHnf(B) != True) {
00991     AffineHermite(B,&H,&U1);
00992     Y = Matrix_Copy(H);   
00993     Matrix_Free(H);
00994     Matrix_Free(U1);
00995   }
00996   else
00997     Y = Matrix_Copy(B);  
00998   if (isEmptyLattice(X)) {
00999     return NULL;  
01000   }
01001 
01002   Head=Lattice2LatticeUnion(X,Y);
01003 
01004 /* If the spliting operation can't be done the result is the original Zplyhedron. */
01005 
01006   if (Head == NULL) {
01007     Matrix_Free(X);
01008     Matrix_Free(Y);
01009     return ZPol;
01010   }  
01011 
01012 
01013   Result=NULL;
01014 
01015   if (Head)
01016    while(Head)
01017     {
01018       tempHead = Head;
01019       Head = Head->next;  
01020       zpnew=ZPolyhedron_Alloc(tempHead->M,ZPol->P);
01021       Result=AddZPoly2ZDomain(zpnew,Result);
01022       ZPolyhedron_Free(zpnew);
01023       tempHead->next = NULL; 
01024       free(tempHead);  
01025     }
01026 
01027   return Result;
01028 }
01029 
01030 
01031 

Generated on Mon Sep 12 14:48:30 2005 for polylib by doxygen 1.3.5