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, const 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, const 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, const 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 compatible dimensions\n");
00431 fprintf(stderr, "ZDomainDifference 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 res = ZPolyhedronDifference(i,tempB);
00443 for (j = res; j != NULL; j = j->next )
00444 templist = AddZPoly2ZDomain(j,templist);
00445 ZDomain_Free(res);
00446 }
00447 ZDomain_Free (temp);
00448 temp = NULL;
00449 for(i = templist; i != NULL; i = i->next)
00450 temp = AddZPoly2ZDomain(i, temp);
00451 ZDomain_Free (templist);
00452 }
00453 for(i = temp; i != NULL; i = i->next)
00454 Result = AddZPolytoZDomain(i, Result);
00455 ZDomain_Free(temp);
00456 }
00457 if (Result==NULL)
00458 return (EmptyZPolyhedron(A->Lat->NbRows-1));
00459 return Result;
00460 }
00461
00462
00463
00464
00465
00466
00467
00468
00469 ZPolyhedron *ZDomainImage (ZPolyhedron *A, Matrix *Func) {
00470
00471 ZPolyhedron *Result = NULL, *temp;
00472
00473 #ifdef DOMDEBUG
00474 FILE *fp;
00475 fp = fopen ("_debug", "a");
00476 fprintf (fp, "\nEntered ZDOMAINIMAGE\n");
00477 fclose (fp);
00478 #endif
00479
00480 for(temp = A; temp != NULL; temp = temp->next) {
00481 ZPolyhedron *Zpol;
00482 Zpol = ZPolyhedronImage (temp, Func);
00483 Result = AddZPolytoZDomain (Zpol, Result);
00484 ZPolyhedron_Free (Zpol);
00485 }
00486 if(Result == NULL)
00487 return EmptyZPolyhedron(A->Lat->NbRows-1);
00488 return Result;
00489 }
00490
00491
00492
00493
00494
00495
00496
00497 ZPolyhedron *ZDomainPreimage (ZPolyhedron *A, Matrix *Func) {
00498
00499 ZPolyhedron *Result = NULL, *temp ;
00500
00501 #ifdef DOMDEBUG
00502 FILE *fp;
00503 fp = fopen("_debug", "a");
00504 fprintf(fp,"\nEntered ZDOMAINPREIMAGE\n");
00505 fclose(fp);
00506 #endif
00507
00508 if (A->Lat->NbRows != Func->NbRows) {
00509 fprintf(stderr,"\nError : In ZDomainPreimage, ");
00510 fprintf(stderr,"Incompatible dimensions of ZPolyhedron ");
00511 fprintf(stderr,"and the Function \n");
00512 return(EmptyZPolyhedron(Func->NbColumns-1));
00513 }
00514 for(temp = A; temp != NULL; temp = temp->next) {
00515 ZPolyhedron *Zpol;
00516 Zpol = ZPolyhedronPreimage(temp, Func);
00517 Result = AddZPolytoZDomain(Zpol, Result);
00518 ZPolyhedron_Free(Zpol);
00519 }
00520 if (Result == NULL)
00521 return(EmptyZPolyhedron(Func->NbColumns-1));
00522 return Result;
00523 }
00524
00525
00526
00527
00528
00529
00530 static ZPolyhedron *ZPolyhedronIntersection(ZPolyhedron *A, ZPolyhedron *B) {
00531
00532 ZPolyhedron *Result = NULL;
00533 Lattice *LInter;
00534 Polyhedron *PInter, *ImageA, *ImageB, *PreImage;
00535
00536 #ifdef DOMDEBUG
00537 FILE *fp;
00538 fp = fopen("_debug","a");
00539 fprintf(fp,"\nEntered ZPOLYHEDRONINTERSECTION\n");
00540 fclose(fp);
00541 #endif
00542
00543 LInter = LatticeIntersection(A->Lat,B->Lat);
00544 if(isEmptyLattice(LInter) == True) {
00545 ZPolyhedron_Free (Result);
00546 Matrix_Free(LInter);
00547 return (EmptyZPolyhedron(A->Lat->NbRows-1));
00548 }
00549 ImageA = DomainImage(A->P,A->Lat,MAXNOOFRAYS);
00550 ImageB = DomainImage(B->P,B->Lat,MAXNOOFRAYS);
00551 PInter = DomainIntersection(ImageA,ImageB,MAXNOOFRAYS);
00552 if (emptyQ(PInter))
00553 Result = EmptyZPolyhedron(LInter->NbRows-1);
00554 else {
00555 PreImage = DomainPreimage(PInter,(Matrix *)LInter,MAXNOOFRAYS);
00556 Result = ZPolyhedron_Alloc(LInter, PreImage);
00557 Domain_Free (PreImage);
00558 }
00559 Matrix_Free(LInter);
00560 Domain_Free(PInter);
00561 Domain_Free(ImageA);
00562 Domain_Free(ImageB);
00563 return Result ;
00564 }
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575 static ZPolyhedron *ZPolyhedronDifference(ZPolyhedron *A, ZPolyhedron *B) {
00576
00577 ZPolyhedron *Result = NULL ;
00578 LatticeUnion *LatDiff, *temp;
00579 Polyhedron *DomDiff, *DomInter, *PreImage, *ImageA, *ImageB;
00580 Bool flag = False;
00581
00582 #ifdef DOMDEBUG
00583 FILE *fp;
00584 fp = fopen("_debug", "a");
00585 fprintf(fp,"\nEntered ZPOLYHEDRONDIFFERENCE\n");
00586 fclose(fp);
00587 #endif
00588
00589 if(isEmptyZPolyhedron (A))
00590 return NULL;
00591 if(isEmptyZPolyhedron (B)) {
00592 Result = ZDomain_Copy (A);
00593 return Result;
00594 }
00595 ImageA = DomainImage(A->P,(Matrix *)A->Lat,MAXNOOFRAYS);
00596 ImageB = DomainImage(B->P,(Matrix *)B->Lat,MAXNOOFRAYS);
00597 DomDiff = DomainDifference(ImageA,ImageB,MAXNOOFRAYS);
00598 if (emptyQ (DomDiff))
00599 flag = True;
00600 else {
00601 ZPolyhedron *Z;
00602 PreImage = DomainPreimage(DomDiff,A->Lat,MAXNOOFRAYS);
00603 Z = ZPolyhedron_Alloc(A->Lat,PreImage);
00604 Result = AddZPolytoZDomain(Z,Result);
00605 }
00606 if (flag == True)
00607 DomInter = Domain_Copy(ImageA);
00608 else {
00609 DomInter = DomainIntersection(ImageA,ImageB,MAXNOOFRAYS);
00610 if (emptyQ(DomInter)) {
00611 if (flag == True)
00612 return (EmptyZPolyhedron(A->Lat->NbRows-1));
00613 else
00614 return Result;
00615 }
00616 }
00617 LatDiff = LatticeDifference(A->Lat, B->Lat);
00618 if(LatDiff == NULL)
00619 if(flag == True )
00620 return(EmptyZPolyhedron (A->Lat->NbRows-1));
00621
00622 while (LatDiff != NULL) {
00623 ZPolyhedron *tempZ = NULL;
00624
00625 PreImage = DomainPreimage(DomInter, LatDiff->M, MAXNOOFRAYS);
00626 tempZ = ZPolyhedron_Alloc(LatDiff->M, PreImage);
00627 Domain_Free(PreImage);
00628 Result = AddZPoly2ZDomain(tempZ,Result);
00629 ZPolyhedron_Free(tempZ);
00630 temp = LatDiff;
00631 LatDiff = LatDiff->next;
00632 Matrix_Free ((Matrix *) temp->M);
00633 free (temp);
00634 }
00635 Domain_Free (DomInter);
00636 Domain_Free (DomDiff);
00637 return Result;
00638 }
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652 static ZPolyhedron *ZPolyhedronImage(ZPolyhedron *ZPol,Matrix *Func) {
00653
00654 ZPolyhedron *Result = NULL ;
00655 Matrix *LatIm ;
00656 Polyhedron *Pol, *PolImage ;
00657
00658 #ifdef DOMDEBUG
00659 FILE *fp;
00660 fp = fopen("_debug", "a");
00661 fprintf(fp,"\nEntered ZPOLYHEDRONIMAGE\n");
00662 fclose(fp);
00663 #endif
00664
00665 if ((Func->NbRows != ZPol->Lat->NbRows) || (Func->NbColumns != ZPol->Lat->NbColumns)) {
00666 fprintf (stderr, "In ZPolImage - The Function, is not compatible with the ZPolyhedron\n");
00667 return NULL;
00668 }
00669 LatIm = LatticeImage(ZPol->Lat,Func);
00670 if (isEmptyLattice(LatIm)) {
00671 Matrix_Free(LatIm);
00672 return NULL;
00673 }
00674 Pol = DomainImage(ZPol->P,ZPol->Lat,MAXNOOFRAYS);
00675 PolImage = DomainImage(Pol,Func,MAXNOOFRAYS);
00676 Domain_Free(Pol);
00677 if(emptyQ(PolImage)) {
00678 Matrix_Free (LatIm);
00679 Domain_Free (PolImage);
00680 return NULL;
00681 }
00682 Pol = DomainPreimage(PolImage,LatIm,MAXNOOFRAYS);
00683 Result = ZPolyhedron_Alloc(LatIm,Pol);
00684 Domain_Free(Pol);
00685 Domain_Free(PolImage);
00686 Matrix_Free(LatIm);
00687 return Result;
00688 }
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702 static ZPolyhedron *ZPolyhedronPreimage(ZPolyhedron *Zpol, Matrix *G) {
00703
00704 Lattice *Latpreim;
00705 Polyhedron *Qprime, *Q, *Polpreim;
00706 ZPolyhedron *Result;
00707
00708 #ifdef DOMDEBUG
00709 FILE *fp;
00710 fp = fopen("_debug","a");
00711 fprintf(fp,"\nEntered ZPOLYHEDRONPREIMAGE\n");
00712 fclose(fp);
00713 #endif
00714
00715 if(G->NbRows != Zpol->Lat->NbRows) {
00716 fprintf(stderr,"\nIn ZPolyhedronPreimage: Error, The dimensions of the ");
00717 fprintf(stderr,"function are not compatible with that of the Zpolyhedron");
00718 return EmptyZPolyhedron(G->NbColumns-1);
00719 }
00720 Q = DomainImage(Zpol->P,Zpol->Lat,MAXNOOFRAYS);
00721 Polpreim = DomainPreimage(Q,G,MAXNOOFRAYS);
00722 if (emptyQ(Polpreim))
00723 Result = NULL;
00724 else {
00725 Latpreim = LatticePreimage(Zpol->Lat,G);
00726 if(isEmptyLattice(Latpreim))
00727 Result = NULL;
00728 else {
00729 Qprime = DomainPreimage(Polpreim, Latpreim, MAXNOOFRAYS);
00730 Result = ZPolyhedron_Alloc(Latpreim, Qprime);
00731 Domain_Free(Qprime);
00732 }
00733 Matrix_Free(Latpreim);
00734 }
00735 Domain_Free(Q);
00736 return Result;
00737 }
00738
00739
00740
00741
00742
00743
00744 void CanonicalForm(ZPolyhedron *Zpol,ZPolyhedron **Result,Matrix **Basis) {
00745
00746 Matrix *B1 = NULL, *B2=NULL, *T1 , *B2inv;
00747 int i, l1, l2;
00748 Value tmp;
00749 Polyhedron *Image, *ImageP;
00750 Matrix *H, *U, *temp, *Hprime, *Uprime, *T2;
00751
00752 #ifdef DOMDEBUG
00753 FILE *fp;
00754 fp = fopen("_debug", "a");
00755 fprintf(fp,"\nEntered CANONICALFORM\n");
00756 fclose(fp);
00757 #endif
00758
00759 if(isEmptyZPolyhedron (Zpol)) {
00760 Basis[0] = Identity(Zpol->Lat->NbRows);
00761 Result[0] = ZDomain_Copy (Zpol);
00762 return ;
00763 }
00764 value_init(tmp);
00765 l1 = FindHermiteBasisofDomain(Zpol->P,&B1);
00766 Image = DomainImage (Zpol->P,(Matrix *)Zpol->Lat,MAXNOOFRAYS);
00767 l2 = FindHermiteBasisofDomain(Image,&B2);
00768
00769 if (l1 != l2)
00770 fprintf(stderr,"In CNF : Something wrong with the Input Zpolyhedra \n");
00771
00772 B2inv = Matrix_Alloc(B2->NbRows, B2->NbColumns);
00773 temp = Matrix_Copy(B2);
00774 Matrix_Inverse(temp,B2inv);
00775 Matrix_Free(temp);
00776
00777 temp = Matrix_Alloc(B2inv->NbRows,Zpol->Lat->NbColumns);
00778 T1 = Matrix_Alloc(temp->NbRows,B1->NbColumns);
00779 Matrix_Product(B2inv,(Matrix *)Zpol->Lat,temp);
00780 Matrix_Product(temp,B1,T1);
00781 Matrix_Free(temp);
00782
00783 T2 = ChangeLatticeDimension(T1,l1);
00784 temp = ChangeLatticeDimension(T2,T2->NbRows+1);
00785
00786
00787 for(i = 0; i < l1; i ++)
00788 value_assign(temp->p[i][temp->NbColumns-1],T1->p[i][T1->NbColumns-1]);
00789
00790 AffineHermite(temp,&H,&U);
00791 Hprime = ChangeLatticeDimension(H,Zpol->Lat->NbRows);
00792
00793
00794 for(i = 0; i < l1; i ++) {
00795 value_assign(tmp,Hprime->p[i][Hprime->NbColumns-1]);
00796 value_assign(Hprime->p[i][Hprime->NbColumns-1],Hprime->p[i][H->NbColumns-1]);
00797 value_assign(Hprime->p[i][H->NbColumns-1],tmp);
00798 }
00799 Uprime = ChangeLatticeDimension(U,Zpol->Lat->NbRows);
00800
00801
00802 for (i = 0;i < l1; i++) {
00803 value_assign(tmp,Uprime->p[i][Uprime->NbColumns-1]);
00804 value_assign(Uprime->p[i][Uprime->NbColumns-1],Uprime->p[i][U->NbColumns-1]);
00805 value_assign(Uprime->p[i][U->NbColumns-1],tmp);
00806 }
00807 Polyhedron_Free (Image);
00808 Matrix_Free (B2inv);
00809 B2inv = Matrix_Alloc(B1->NbRows, B1->NbColumns);
00810 Matrix_Inverse(B1,B2inv);
00811 ImageP = DomainImage(Zpol->P, B2inv, MAXNOOFRAYS);
00812 Matrix_Free(B2inv);
00813 Image = DomainImage(ImageP, Uprime, MAXNOOFRAYS);
00814 Domain_Free(ImageP);
00815 Result[0] = ZPolyhedron_Alloc(Hprime, Image);
00816 Basis[0] = Matrix_Copy(B2);
00817
00818
00819 Polyhedron_Free (Image);
00820 Matrix_Free (B1);
00821 Matrix_Free (B2);
00822 Matrix_Free (temp);
00823 Matrix_Free (T1);
00824 Matrix_Free (T2);
00825 Matrix_Free (H);
00826 Matrix_Free (U);
00827 Matrix_Free (Hprime);
00828 Matrix_Free (Uprime);
00829 value_clear(tmp);
00830 return;
00831 }
00832
00833
00834
00835
00836
00837 ZPolyhedron *IntegraliseLattice(ZPolyhedron *A) {
00838
00839 ZPolyhedron *Result;
00840 Lattice *M = NULL, *Id;
00841 Polyhedron *Im = NULL, *Preim = NULL;
00842
00843 #ifdef DOMDEBUG
00844 FILE *fp;
00845 fp = fopen("_debug","a");
00846 fprintf(fp,"\nEntered INTEGRALISELATTICE\n");
00847 fclose(fp);
00848 #endif
00849
00850 Im = DomainImage(A->P,A->Lat,MAXNOOFRAYS);
00851 Id = Identity(A->Lat->NbRows);
00852 M = LatticeImage(Id, A->Lat);
00853 if (isEmptyLattice(M))
00854 Result = EmptyZPolyhedron(A->Lat->NbRows-1);
00855 else {
00856 Preim = DomainPreimage(Im,M,MAXNOOFRAYS);
00857 Result = ZPolyhedron_Alloc(M,Preim);
00858 }
00859 Matrix_Free(M);
00860 Domain_Free(Im);
00861 Domain_Free(Preim);
00862 return Result;
00863 }
00864
00865
00866
00867
00868
00869
00870 ZPolyhedron *ZDomainSimplify(ZPolyhedron *ZDom) {
00871
00872 ZPolyhedron *Ztmp, *Result;
00873 ForSimplify *Head, *Prev, *Curr;
00874 ZPolyhedron *ZDomHead, *Emp;
00875
00876 if (ZDom == NULL) {
00877 fprintf(stderr,"\nError in ZDomainSimplify - ZDomHead = NULL\n");
00878 return NULL;
00879 }
00880 if (ZDom->next == NULL)
00881 return (ZPolyhedron_Copy (ZDom));
00882 Emp = EmptyZPolyhedron(ZDom->Lat->NbRows-1);
00883 ZDomHead = ZDomainUnion(ZDom, Emp);
00884 ZPolyhedron_Free(Emp);
00885 Head = NULL;
00886 Ztmp = ZDomHead;
00887 do {
00888 Polyhedron *Img;
00889 Img = DomainImage(Ztmp->P,Ztmp->Lat,MAXNOOFRAYS);
00890 for(Curr = Head; Curr != NULL; Curr = Curr->next) {
00891 Polyhedron *Diff1;
00892 Bool flag = False;
00893
00894 Diff1 = DomainDifference(Img,Curr->Pol,MAXNOOFRAYS);
00895 if (emptyQ(Diff1)) {
00896 Polyhedron *Diff2;
00897
00898 Diff2 = DomainDifference(Curr->Pol,Img,MAXNOOFRAYS);
00899 if (emptyQ(Diff2))
00900 flag = True;
00901 Domain_Free(Diff2);
00902 }
00903 Domain_Free (Diff1);
00904 if (flag == True) {
00905 LatticeUnion *temp;
00906
00907 temp = (LatticeUnion *)malloc(sizeof(LatticeUnion));
00908 temp->M = (Lattice *)Matrix_Copy((Matrix *)Ztmp->Lat);
00909 temp->next = Curr->LatUni;
00910 Curr->LatUni = temp;
00911 break;
00912 }
00913 }
00914 if(Curr == NULL) {
00915 Curr = (ForSimplify *)malloc(sizeof(ForSimplify));
00916 Curr->Pol = Domain_Copy(Img);
00917 Curr->LatUni = (LatticeUnion *)malloc(sizeof(LatticeUnion));
00918 Curr->LatUni->M = (Lattice *)Matrix_Copy((Matrix *)Ztmp->Lat);
00919 Curr->LatUni->next = NULL;
00920 Curr->next = Head;
00921 Head = Curr;
00922 }
00923 Domain_Free (Img);
00924 Ztmp = Ztmp->next;
00925 } while(Ztmp != NULL);
00926
00927 for (Curr = Head; Curr != NULL; Curr = Curr->next)
00928 Curr->LatUni = LatticeSimplify(Curr->LatUni);
00929 Result = NULL;
00930 for(Curr = Head; Curr != NULL; Curr = Curr->next) {
00931 LatticeUnion *L;
00932 for(L = Curr->LatUni; L != NULL; L = L->next) {
00933 Polyhedron *Preim;
00934 ZPolyhedron *Zpol;
00935
00936 Preim = DomainPreimage(Curr->Pol,L->M,MAXNOOFRAYS);
00937 Zpol = ZPolyhedron_Alloc(L->M, Preim);
00938 Zpol->next = Result;
00939 Result = Zpol;
00940 Domain_Free(Preim);
00941 }
00942 }
00943 Curr = Head;
00944 while (Curr != NULL) {
00945 Prev = Curr;
00946 Curr = Curr->next;
00947 LatticeUnion_Free(Prev->LatUni);
00948 Domain_Free(Prev->Pol);
00949 free(Prev);
00950 }
00951 return Result;
00952 }
00953
00954 ZPolyhedron *SplitZpolyhedron(ZPolyhedron *ZPol,Lattice *B) {
00955
00956 Lattice *Intersection = NULL;
00957 Lattice *B1 = NULL, *B2 = NULL, *newB1 = NULL, *newB2 = NULL;
00958 Matrix *U = NULL,*M1 = NULL, *M2 = NULL, *M1Inverse = NULL,*MtProduct = NULL;
00959 Matrix *Vinv, *V , *temp, *DiagMatrix ;
00960 Matrix *H , *U1 , *X, *Y ;
00961 ZPolyhedron *zpnew, *Result;
00962 LatticeUnion *Head = NULL, *tempHead = NULL;
00963 int i;
00964 Value k;
00965
00966 #ifdef DOMDEBUG
00967 FILE *fp;
00968 fp = fopen("_debug", "a");
00969 fprintf(fp,"\nEntered SplitZpolyhedron \n");
00970 fclose(fp);
00971 #endif
00972
00973
00974 if (B->NbRows != B->NbColumns) {
00975 fprintf(stderr,"\n SplitZpolyhedron : The Input Matrix B is not a proper Lattice \n");
00976 return NULL;
00977 }
00978
00979 if (ZPol->Lat->NbRows != B->NbRows) {
00980 fprintf(stderr,"\nSplitZpolyhedron : The Lattice in Zpolyhedron and B have ");
00981 fprintf(stderr,"incompatible dimensions \n");
00982 return NULL;
00983 }
00984
00985 if (isinHnf (ZPol->Lat) != True) {
00986 AffineHermite(ZPol->Lat,&H,&U1);
00987 X = Matrix_Copy(H);
00988 Matrix_Free(U1);
00989 Matrix_Free(H);
00990 }
00991 else
00992 X = Matrix_Copy(ZPol->Lat);
00993
00994 if (isinHnf(B) != True) {
00995 AffineHermite(B,&H,&U1);
00996 Y = Matrix_Copy(H);
00997 Matrix_Free(H);
00998 Matrix_Free(U1);
00999 }
01000 else
01001 Y = Matrix_Copy(B);
01002 if (isEmptyLattice(X)) {
01003 return NULL;
01004 }
01005
01006 Head=Lattice2LatticeUnion(X,Y);
01007
01008
01009
01010 if (Head == NULL) {
01011 Matrix_Free(X);
01012 Matrix_Free(Y);
01013 return ZPol;
01014 }
01015
01016
01017 Result=NULL;
01018
01019 if (Head)
01020 while(Head)
01021 {
01022 tempHead = Head;
01023 Head = Head->next;
01024 zpnew=ZPolyhedron_Alloc(tempHead->M,ZPol->P);
01025 Result=AddZPoly2ZDomain(zpnew,Result);
01026 ZPolyhedron_Free(zpnew);
01027 tempHead->next = NULL;
01028 free(tempHead);
01029 }
01030
01031 return Result;
01032 }
01033
01034
01035