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