Main Page   Compound List   File List   Compound Members   File Members  

Zpolyhedron.c

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

Generated on Mon Mar 15 10:59:51 2004 for polylib by doxygen1.2.18