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