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
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 }
00030
00031
00032
00033
00034
00035
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 }
00068
00069
00070
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 }
00080
00081
00082
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 }
00093
00094
00095
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 }
00106
00107
00108
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 }
00117
00118
00119
00120
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 }
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
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
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
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 }
00239
00240
00241
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 }
00263
00264
00265
00266
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 }
00280
00281
00282
00283
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 }
00313
00314
00315
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 }
00333
00334
00335
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 }
00347
00348
00349
00350
00351
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 }
00370
00371
00372
00373
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 }
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
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
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 }
00458
00459
00460
00461
00462
00463
00464
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 }
00487
00488
00489
00490
00491
00492
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 }
00521
00522
00523
00524
00525
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 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
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)
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 }
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
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 }
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
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 }
00735
00736
00737
00738
00739
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
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
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
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
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 }
00827
00828
00829
00830
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 }
00859
00860
00861
00862
00863
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 }
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
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