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
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 }
00031
00032
00033
00034
00035
00036
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 }
00072
00073
00074
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 }
00084
00085
00086
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 }
00097
00098
00099
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 }
00110
00111
00112
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 }
00121
00122
00123
00124
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 }
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
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
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
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 }
00243
00244
00245
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 }
00267
00268
00269
00270
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 }
00284
00285
00286
00287
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 }
00317
00318
00319
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 }
00337
00338
00339
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 }
00351
00352
00353
00354
00355
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 }
00374
00375
00376
00377
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 }
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
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 }
00462
00463
00464
00465
00466
00467
00468
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 }
00491
00492
00493
00494
00495
00496
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 }
00525
00526
00527
00528
00529
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 }
00566
00567
00568
00569
00570
00571
00572
00573
00574
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)
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 }
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
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 }
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
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 }
00739
00740
00741
00742
00743
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
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
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
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
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 }
00833
00834
00835
00836
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 }
00865
00866
00867
00868
00869
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 }
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
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