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

Generated on Mon Sep 12 15:15:12 2005 for polylib by doxygen 1.3.5