polylib 5.22.8
Zpolyhedron.c
Go to the documentation of this file.
1#include <polylib/polylib.h>
2#include <stdlib.h>
3
6static void ZPolyhedron_Free(ZPolyhedron *Zpol);
11static void ZPolyhedronPrint(FILE *fp, const char *format, ZPolyhedron *A);
12
13typedef struct forsimplify {
18
19/*
20 * Returns True if 'Zpol' is empty, otherwise returns False
21 */
23
24 if (Zpol == NULL)
25 return True;
26 if ((isEmptyLattice(Zpol->Lat)) || (emptyQ(Zpol->P)))
27 return True;
28 return False;
29} /* isEmptyZPolyhedron */
30
31/*
32 * Given Lattice 'Lat' and a Polyhderon 'Poly', allocate space, and return
33 * the Z-polyhderon corresponding to the image of the polyhderon 'Poly' by the
34 * lattice 'Lat'. If the input lattice 'Lat' is not integeral, it integralises
35 * it, i.e. the lattice of the Z-polyhderon returned is integeral.
36 */
38
39 ZPolyhedron *A;
40
43
44 if (Lat->NbRows != Poly->Dimension + 1) {
45 fprintf(stderr, "\nInZPolyAlloc - The Lattice and the Polyhedron");
46 fprintf(stderr, " are not compatible to form a ZPolyhedra\n");
47 return NULL;
48 }
49 if ((!(isEmptyLattice(Lat))) && (!isfulldim(Lat))) {
50 fprintf(stderr, "\nZPolAlloc: Lattice not Full Dimensional\n");
51 return NULL;
52 }
53 A = (ZPolyhedron *)malloc(sizeof(ZPolyhedron));
54 if (!A) {
55 fprintf(stderr, "ZPolAlloc : Out of Memory\n");
56 return NULL;
57 }
58 A->next = NULL;
59 A->P = Domain_Copy(Poly);
60 A->Lat = Matrix_Copy(Lat);
61
62 if (IsLattice(Lat) == False) {
63 ZPolyhedron *Res;
64
65 Res = IntegraliseLattice(A);
67 return Res;
68 }
69 return A;
70} /* ZPolyhedron_Alloc */
71
72/*
73 * Free the memory used by the Z-domain 'Head'
74 */
76
77 if (Head == NULL)
78 return;
79 if (Head->next != NULL)
80 ZDomain_Free(Head->next);
81 ZPolyhedron_Free(Head);
82} /* ZDomain_Free */
83
84/*
85 * Free the memory used by the Z-polyhderon 'Zpol'
86 */
87static void ZPolyhedron_Free(ZPolyhedron *Zpol) {
88
89 if (Zpol == NULL)
90 return;
91 Matrix_Free((Matrix *)Zpol->Lat);
92 Domain_Free(Zpol->P);
93 free(Zpol);
94 return;
95} /* ZPolyhderon_Free */
96
97/*
98 * Return a copy of the Z-domain 'Head'
99 */
101
102 ZPolyhedron *Zpol;
103 Zpol = ZPolyhedron_Copy(Head);
104
105 if (Head->next != NULL)
106 Zpol->next = ZDomain_Copy(Head->next);
107 return Zpol;
108} /* ZDomain_Copy */
109
110/*
111 * Return a copy of the Z-polyhderon 'A'
112 */
114
115 ZPolyhedron *Zpol;
116
117 Zpol = ZPolyhedron_Alloc(A->Lat, A->P);
118 return Zpol;
119} /* ZPolyhderon_Copy */
120
121/*
122 * Add the ZPolyhedron 'Zpol' to the Z-domain 'Result' and return a pointer
123 * to the new Z-domain.
124 */
126
127 ZPolyhedron *A;
128
129 if (isEmptyZPolyhedron(Zpol))
130 return Result;
131 A = ZPolyhedron_Copy(Zpol);
132 A->next = NULL;
133
134 if (isEmptyZPolyhedron(Result)) {
135 ZDomain_Free(Result);
136 return A;
137 }
138 A->next = Result;
139 return A;
140} /* AddZPoly2ZDomain */
141
142/*
143 * Given a Z-polyhderon 'A' and a Z-domain 'Head', return a new Z-domain with
144 * 'A' added to it. If the new Z-polyhedron 'A', is already included in the
145 * Z-domain 'Head', it is not added in the list. Othewise, the function checks
146 * if the new Z-polyhedron 'A' to be added to the Z-domain 'Head' has a common
147 * lattice with some other Z-polyhderon already present in the Z-domain. If it
148 * is so, it takes the union of the underlying polyhdera; domains and returns.
149 * The function tries to make sure that the added Z-polyhedron 'A' is in the
150 * canonical form.
151 */
153
154 ZPolyhedron *Zpol, *temp, *temp1;
155 Polyhedron *i;
156 Bool Added;
157
158 if ((A == NULL) || (isEmptyZPolyhedron(A)))
159 return Head;
160
161 /* For each "underlying" Pol, find the Cnf and add Zpol in Cnf*/
162 for (i = A->P; i != NULL; i = i->next) {
163 ZPolyhedron *Z, *Z1;
164 Polyhedron *Image;
165 Matrix *H, *U;
166 Lattice *Lat;
167
168 Added = False;
169 Image = Domain_Copy(i);
170 Domain_Free(Image->next);
171 Image->next = NULL;
172 Z1 = ZPolyhedron_Alloc(A->Lat, Image);
173 Domain_Free(Image);
174 CanonicalForm(Z1, &Z, &H);
175 ZDomain_Free(Z1);
176 Lat = (Lattice *)Matrix_Alloc(H->NbRows, Z->Lat->NbColumns);
177 Matrix_Product(H, Z->Lat, (Matrix *)Lat);
178 Matrix_Free(H);
179 AffineHermite(Lat, (Lattice **)&H, &U);
180 Image = DomainImage(Z->P, U, MAXNOOFRAYS);
181 ZDomain_Free(Z);
182
183 Zpol = ZPolyhedron_Alloc((Lattice *)H, Image);
184 Domain_Free(Image);
185 Matrix_Free((Matrix *)Lat);
186 Matrix_Free(H);
187 Matrix_Free(U);
188
189 if ((Head == NULL) || (isEmptyZPolyhedron(Head))) {
190 Head = Zpol;
191 continue;
192 }
193 temp1 = temp = Head;
194
195 /* Check if the curr pol is included in the zpol or vice versa. */
196 for (; temp != NULL; temp = temp->next) {
197 if (ZPolyhedronIncludes(Zpol, temp) == True) {
198 ZPolyhedron_Free(Zpol);
199 Added = True;
200 break;
201 } else if (ZPolyhedronIncludes(temp, Zpol) == True) {
202 if (temp == Head) {
203 Zpol->next = temp->next;
204 Head = Zpol;
205 ZPolyhedron_Free(temp);
206 Added = True;
207 break;
208 }
209 temp1->next = Zpol;
210 Zpol->next = temp->next;
211 ZPolyhedron_Free(temp);
212 Added = True;
213 break;
214 }
215 temp1 = temp;
216 }
217 if (Added == True)
218 continue;
219 for (temp = Head; temp != NULL; temp = temp->next) {
220 if (sameLattice(temp->Lat, Zpol->Lat) == True) {
221 Polyhedron *Union;
222
223 Union = DomainUnion(temp->P, Zpol->P, MAXNOOFRAYS);
224 if (!Union)
225 fprintf(stderr, "\n In AddZPolytoZDomain: Out of memory\n");
226 else {
227 Domain_Free(temp->P);
228 temp->P = Union;
229 Added = True;
230 ZPolyhedron_Free(Zpol);
231 }
232 break;
233 }
234 temp1 = temp;
235 }
236 if (Added == False)
237 temp1->next = Zpol;
238 }
239 return Head;
240} /* AddZPolytoZDomain */
241
242/*
243 * Return the empty Z-polyhedron of dimension 'dimension'
244 */
246
247 ZPolyhedron *Zpol;
248 Lattice *E;
249 Polyhedron *P;
250
251#ifdef DOMDEBUG
252 FILE *fp;
253 fp = fopen("_debug", "a");
254 fprintf(fp, "\nEntered EMPTYZPOLYHEDRON\n");
255 fclose(fp);
256#endif
257
258 E = EmptyLattice(dimension + 1);
259 P = Empty_Polyhedron(dimension);
260 Zpol = ZPolyhedron_Alloc(E, P);
261 Matrix_Free((Matrix *)E);
262 Domain_Free(P);
263 return Zpol;
264} /* EmptyZPolyhedron */
265
266/*
267 * Given Z-domains 'A' and 'B', return True if A is included in 'B', otherwise
268 * return False.
269 */
271
272 ZPolyhedron *Diff;
273 Bool ret = False;
274
275 Diff = ZDomainDifference(A, B);
276 if (isEmptyZPolyhedron(Diff))
277 ret = True;
278
279 ZDomain_Free(Diff);
280 return ret;
281} /* ZDomainIncludes */
282
283/*
284 * Given Z-polyhedra 'A' and 'B', return True if 'A' is included in 'B',
285 * otherwise return False
286 */
288
289 Polyhedron *Diff = NULL;
290 Bool retval = False;
291
292#ifdef DOMDEBUG
293 FILE *fp;
294 fp = fopen("_debug", "a");
295 fprintf(fp, "\nEntered ZPOLYHEDRONINCLUDES\n");
296 fclose(fp);
297#endif
298
299 if (LatticeIncludes(A->Lat, B->Lat) == True) {
300 Polyhedron *ImageA, *ImageB;
301
302 ImageA = DomainImage(A->P, A->Lat, MAXNOOFRAYS);
303 ImageB = DomainImage(B->P, B->Lat, MAXNOOFRAYS);
304
305 Diff = DomainDifference(ImageA, ImageB, MAXNOOFRAYS);
306 if (emptyQ(Diff))
307 retval = True;
308
309 Domain_Free(ImageA);
310 Domain_Free(ImageB);
311 Domain_Free(Diff);
312 }
313 return retval;
314} /* ZPolyhedronIncludes */
315
316/*
317 * Print the contents of a Z-domain 'A'
318 */
319void ZDomainPrint(FILE *fp, const char *format, ZPolyhedron *A) {
320#ifdef DOMDEBUG
321 FILE *fp1;
322 fp1 = fopen("_debug", "a");
323 fprintf(fp1, "\nEntered ZDOMAINPRINT\n");
324 fclose(fp1);
325#endif
326
327 ZPolyhedronPrint(fp, format, A);
328 if (A->next != NULL) {
329 fprintf(fp, "\nUNIONED with\n");
330 ZDomainPrint(fp, format, A->next);
331 }
332 return;
333} /* ZDomainPrint */
334
335/*
336 * Print the contents of a ZPolyhderon 'A'
337 */
338static void ZPolyhedronPrint(FILE *fp, const char *format, ZPolyhedron *A) {
339 if (A == NULL)
340 return;
341 fprintf(fp, "\nZPOLYHEDRON: Dimension %d \n", A->Lat->NbRows - 1);
342 fprintf(fp, "\nLATTICE: \n");
343 Matrix_Print(fp, format, (Matrix *)A->Lat);
344 Polyhedron_Print(fp, format, A->P);
345 return;
346} /* ZPolyhedronPrint */
347
348/*
349 * Return the Z-domain union of the Z-domain 'A' and 'B'. The dimensions of the
350 * Z-domains 'A' and 'B' must be equal. All the Z-polyhedra of the resulting
351 * union are expected to be in Canonical forms.
352 */
354
355 ZPolyhedron *Result = NULL, *temp;
356
357#ifdef DOMDEBUG
358 FILE *fp;
359 fp = fopen("_debug", "a");
360 fprintf(fp, "\nEntered ZDOMAINUNION\n");
361 fclose(fp);
362#endif
363
364 for (temp = A; temp != NULL; temp = temp->next)
365 Result = AddZPolytoZDomain(temp, Result);
366 for (temp = B; temp != NULL; temp = temp->next)
367 Result = AddZPolytoZDomain(temp, Result);
368 return Result;
369} /* ZDomainUnion */
370
371/*
372 * Return the Z-domain intersection of the Z-domains 'A' and 'B'.The dimensions
373 * of domains 'A' and 'B' must be equal.
374 */
376
377 ZPolyhedron *Result = NULL, *tempA = NULL, *tempB = NULL;
378
379#ifdef DOMDEBUG
380 FILE *fp;
381 fp = fopen("_debug", "a");
382 fprintf(fp, "\nEntered ZDOMAININTERSECTION\n");
383 fclose(fp);
384#endif
385
386 for (tempA = A; tempA != NULL; tempA = tempA->next)
387 for (tempB = B; tempB != NULL; tempB = tempB->next) {
388 ZPolyhedron *Zpol;
389 Zpol = ZPolyhedronIntersection(tempA, tempB);
390 Result = AddZPolytoZDomain(Zpol, Result);
391 ZPolyhedron_Free(Zpol);
392 }
393 if (Result == NULL)
394 return EmptyZPolyhedron(A->Lat->NbRows - 1);
395 return Result;
396} /* ZDomainIntersection */
397
398/*
399 * Return the Z-domain difference of the domains 'A' and 'B'. The dimensions of
400 * the Z-domains 'A' and 'B' must be equal. Note that the difference of two
401 * Z-polyhedra is a Union of Z-polyhedra. The algorithms is as given below :-
402 * Algorithm: (Given Z-domains A and B)
403 * Result <-- NULL
404 * for every Z-polyhderon Zpoly of A {
405 * temp <-- Zpoly;
406 * for every Z-polyhderon Z1 of B
407 * temp = temp - Z1;
408 * }
409 * Add temp to Result;
410 * return;
411 */
413
414 ZPolyhedron *Result = NULL, *tempA = NULL, *tempB = NULL;
415 ZPolyhedron *templist, *res, *i, *j;
416
417#ifdef DOMDEBUG
418 FILE *fp;
419 fp = fopen("_debug", "a");
420 fprintf(fp, "\nEntered ZDOMAINDIFFERENCE\n");
421 fclose(fp);
422#endif
423
424 if (A->Lat->NbRows != B->Lat->NbRows) {
425 fprintf(stderr, "In ZDomainDifference : the input ZDomains ");
426 fprintf(stderr, "do not have compatible dimensions\n");
427 fprintf(stderr, "ZDomainDifference not performed\n");
428 return NULL;
429 }
430
431 for (tempA = A; tempA != NULL; tempA = tempA->next) {
432 ZPolyhedron *temp = NULL;
433 temp = ZPolyhedron_Copy(tempA);
434
435 for (tempB = B; tempB != NULL; tempB = tempB->next) {
436 templist = NULL;
437 res = NULL;
438 for (i = temp; i != NULL; i = i->next) {
439 res = ZPolyhedronDifference(i, tempB);
440 for (j = res; j != NULL; j = j->next)
441 templist = AddZPoly2ZDomain(j, templist);
442 ZDomain_Free(res);
443 }
444 ZDomain_Free(temp);
445 temp = NULL;
446 for (i = templist; i != NULL; i = i->next)
447 temp = AddZPoly2ZDomain(i, temp);
448 ZDomain_Free(templist);
449 }
450 for (i = temp; i != NULL; i = i->next)
451 Result = AddZPolytoZDomain(i, Result);
452 ZDomain_Free(temp);
453 }
454 if (Result == NULL)
455 return (EmptyZPolyhedron(A->Lat->NbRows - 1));
456 return Result;
457} /* ZDomainDifference */
458
459/*
460 * Return the image of the Z-domain 'A' under the invertible, affine, rational
461 * transformation function 'Func'. The matrix representing the function 'Func'
462 * must be non-singular and the number of rows of the function must be equal
463 * to the number of rows in the matrix representing the lattice of 'A'.
464 * Note:: Image((Z1 U Z2),F) = Image(Z1,F) U Image(Z2 U F).
465 */
467
468 ZPolyhedron *Result = NULL, *temp;
469
470#ifdef DOMDEBUG
471 FILE *fp;
472 fp = fopen("_debug", "a");
473 fprintf(fp, "\nEntered ZDOMAINIMAGE\n");
474 fclose(fp);
475#endif
476
477 for (temp = A; temp != NULL; temp = temp->next) {
478 ZPolyhedron *Zpol;
479 Zpol = ZPolyhedronImage(temp, Func);
480 Result = AddZPolytoZDomain(Zpol, Result);
481 ZPolyhedron_Free(Zpol);
482 }
483 if (Result == NULL)
484 return EmptyZPolyhedron(A->Lat->NbRows - 1);
485 return Result;
486} /* ZDomainImage */
487
488/*
489 * Return the preimage of the Z-domain 'A' under the invertible, affine, ratio-
490 * nal transformation 'Func'. The number of rows of the matrix representing
491 * the function 'Func' must be equal to the number of rows of the matrix repr-
492 * senting the lattice of 'A'.
493 */
495
496 ZPolyhedron *Result = NULL, *temp;
497
498#ifdef DOMDEBUG
499 FILE *fp;
500 fp = fopen("_debug", "a");
501 fprintf(fp, "\nEntered ZDOMAINPREIMAGE\n");
502 fclose(fp);
503#endif
504
505 if (A->Lat->NbRows != Func->NbRows) {
506 fprintf(stderr, "\nError : In ZDomainPreimage, ");
507 fprintf(stderr, "Incompatible dimensions of ZPolyhedron ");
508 fprintf(stderr, "and the Function \n");
509 return (EmptyZPolyhedron(Func->NbColumns - 1));
510 }
511 for (temp = A; temp != NULL; temp = temp->next) {
512 ZPolyhedron *Zpol;
513 Zpol = ZPolyhedronPreimage(temp, Func);
514 Result = AddZPolytoZDomain(Zpol, Result);
515 ZPolyhedron_Free(Zpol);
516 }
517 if (Result == NULL)
518 return (EmptyZPolyhedron(Func->NbColumns - 1));
519 return Result;
520} /* ZDomainPreimage */
521
522/*
523 * Return the Z-polyhedron intersection of the Z-polyhedra 'A' and 'B'.
524 * Note: If Z1 = L1 (intersect) P1 and Z2 = L2 (intersect) P2, then
525 * Z1 (intersect) Z2 = (L1 (intersect) L2) (intersect) (P1 (intersect) P2)
526 */
528
529 ZPolyhedron *Result = NULL;
530 Lattice *LInter;
531 Polyhedron *PInter, *ImageA, *ImageB, *PreImage;
532
533#ifdef DOMDEBUG
534 FILE *fp;
535 fp = fopen("_debug", "a");
536 fprintf(fp, "\nEntered ZPOLYHEDRONINTERSECTION\n");
537 fclose(fp);
538#endif
539
540 LInter = LatticeIntersection(A->Lat, B->Lat);
541 if (isEmptyLattice(LInter) == True) {
542 ZPolyhedron_Free(Result);
543 Matrix_Free(LInter);
544 return (EmptyZPolyhedron(A->Lat->NbRows - 1));
545 }
546 ImageA = DomainImage(A->P, A->Lat, MAXNOOFRAYS);
547 ImageB = DomainImage(B->P, B->Lat, MAXNOOFRAYS);
548 PInter = DomainIntersection(ImageA, ImageB, MAXNOOFRAYS);
549 if (emptyQ(PInter))
550 Result = EmptyZPolyhedron(LInter->NbRows - 1);
551 else {
552 PreImage = DomainPreimage(PInter, (Matrix *)LInter, MAXNOOFRAYS);
553 Result = ZPolyhedron_Alloc(LInter, PreImage);
554 Domain_Free(PreImage);
555 }
556 Matrix_Free(LInter);
557 Domain_Free(PInter);
558 Domain_Free(ImageA);
559 Domain_Free(ImageB);
560 return Result;
561} /* ZPolyhedronIntersection */
562
563/*
564 * Return the difference of the two Z-polyhedra 'A' and 'B'. Below is the
565 * procedure to find the difference of 'A' and 'B' :-
566 * Procedure:
567 * Let A = L1 (intersect) P1' and B = L2 (intersect) P2' where
568 * (P1' = DomImage(P1,L1) and P2' = DomImage(P2,L2)). Then
569 * A-B = L1 (intersect) (P1'-P2') Union
570 * (L1-L2) (intersect) (P1' (intersect) P2')
571 */
573
574 ZPolyhedron *Result = NULL;
575 LatticeUnion *LatDiff, *temp;
576 Polyhedron *DomDiff, *DomInter, *PreImage, *ImageA, *ImageB;
577 Bool flag = False;
578
579#ifdef DOMDEBUG
580 FILE *fp;
581 fp = fopen("_debug", "a");
582 fprintf(fp, "\nEntered ZPOLYHEDRONDIFFERENCE\n");
583 fclose(fp);
584#endif
585
586 if (isEmptyZPolyhedron(A))
587 return NULL;
588 if (isEmptyZPolyhedron(B)) {
589 Result = ZDomain_Copy(A);
590 return Result;
591 }
592 ImageA = DomainImage(A->P, (Matrix *)A->Lat, MAXNOOFRAYS);
593 ImageB = DomainImage(B->P, (Matrix *)B->Lat, MAXNOOFRAYS);
594 DomDiff = DomainDifference(ImageA, ImageB, MAXNOOFRAYS);
595 if (emptyQ(DomDiff))
596 flag = True;
597 else {
598 ZPolyhedron *Z;
599 PreImage = DomainPreimage(DomDiff, A->Lat, MAXNOOFRAYS);
600 Z = ZPolyhedron_Alloc(A->Lat, PreImage);
601 Result = AddZPolytoZDomain(Z, Result);
602 }
603 if (flag == True) /* DomDiff = NULL; DomInter = A */
604 DomInter = Domain_Copy(ImageA);
605 else {
606 DomInter = DomainIntersection(ImageA, ImageB, MAXNOOFRAYS);
607 if (emptyQ(DomInter)) {
608 if (flag == True)
609 return (EmptyZPolyhedron(A->Lat->NbRows - 1));
610 else
611 return Result;
612 }
613 }
614 LatDiff = LatticeDifference(A->Lat, B->Lat);
615 if (LatDiff == NULL)
616 if (flag == True)
617 return (EmptyZPolyhedron(A->Lat->NbRows - 1));
618
619 while (LatDiff != NULL) {
620 ZPolyhedron *tempZ = NULL;
621
622 PreImage = DomainPreimage(DomInter, LatDiff->M, MAXNOOFRAYS);
623 tempZ = ZPolyhedron_Alloc(LatDiff->M, PreImage);
624 Domain_Free(PreImage);
625 Result = AddZPoly2ZDomain(tempZ, Result);
626 ZPolyhedron_Free(tempZ);
627 temp = LatDiff;
628 LatDiff = LatDiff->next;
629 Matrix_Free((Matrix *)temp->M);
630 free(temp);
631 }
632 Domain_Free(DomInter);
633 Domain_Free(DomDiff);
634 return Result;
635} /* ZPolyhedronDifference */
636
637/*
638 * Return the image of the Z-polyhedron 'ZPol' under the invertible, affine,
639 * rational transformation function 'Func'. The matrix representing the funct-
640 * ion must be non-singular and the number of rows of the function must be
641 * equal to the number of rows in the matrix representing the lattice of 'ZPol'
642 * Algorithm:
643 * 1) Let ZPol = L (intersect) Q
644 * 2) L1 = LatticeImage(L,F)
645 * 3) Q1 = DomainImage(Q,F)
646 * 4) Z1 = L1(Inverse(L1)*Q1)
647 * 5) Return Z1
648 */
650
651 ZPolyhedron *Result = NULL;
652 Matrix *LatIm;
653 Polyhedron *Pol, *PolImage;
654
655#ifdef DOMDEBUG
656 FILE *fp;
657 fp = fopen("_debug", "a");
658 fprintf(fp, "\nEntered ZPOLYHEDRONIMAGE\n");
659 fclose(fp);
660#endif
661
662 if ((Func->NbRows != ZPol->Lat->NbRows) ||
663 (Func->NbColumns != ZPol->Lat->NbColumns)) {
664 fprintf(stderr, "In ZPolImage - The Function, is not compatible with the "
665 "ZPolyhedron\n");
666 return NULL;
667 }
668 LatIm = LatticeImage(ZPol->Lat, Func);
669 if (isEmptyLattice(LatIm)) {
670 Matrix_Free(LatIm);
671 return NULL;
672 }
673 Pol = DomainImage(ZPol->P, ZPol->Lat, MAXNOOFRAYS);
674 PolImage = DomainImage(Pol, Func, MAXNOOFRAYS);
676 if (emptyQ(PolImage)) {
677 Matrix_Free(LatIm);
678 Domain_Free(PolImage);
679 return NULL;
680 }
681 Pol = DomainPreimage(PolImage, LatIm, MAXNOOFRAYS);
682 Result = ZPolyhedron_Alloc(LatIm, Pol);
684 Domain_Free(PolImage);
685 Matrix_Free(LatIm);
686 return Result;
687} /* ZPolyhedronImage */
688
689/*
690 * Return the preimage of the Z-polyhedron 'Zpol' under an affine transformati-
691 * on function 'G'. The number of rows of matrix representing the function 'G',
692 * must be equal to the number of rows of the matrix representing the lattice
693 * of Z1.
694 * Algorithm:
695 * 1) Let Zpol = L (intersect) Q
696 * 2) L1 =LatticePreimage(L,F);
697 * 3) Q1 = DomainPreimage(Q,F);
698 * 4) Z1 = L1(Inverse(L1)*Q1);
699 * 5) Return Z1
700 */
702
703 Lattice *Latpreim;
704 Polyhedron *Qprime, *Q, *Polpreim;
705 ZPolyhedron *Result;
706
707#ifdef DOMDEBUG
708 FILE *fp;
709 fp = fopen("_debug", "a");
710 fprintf(fp, "\nEntered ZPOLYHEDRONPREIMAGE\n");
711 fclose(fp);
712#endif
713
714 if (G->NbRows != Zpol->Lat->NbRows) {
715 fprintf(stderr, "\nIn ZPolyhedronPreimage: Error, The dimensions of the ");
716 fprintf(stderr, "function are not compatible with that of the Zpolyhedron");
717 return EmptyZPolyhedron(G->NbColumns - 1);
718 }
719 Q = DomainImage(Zpol->P, Zpol->Lat, MAXNOOFRAYS);
720 Polpreim = DomainPreimage(Q, G, MAXNOOFRAYS);
721 if (emptyQ(Polpreim))
722 Result = NULL;
723 else {
724 Latpreim = LatticePreimage(Zpol->Lat, G);
725 if (isEmptyLattice(Latpreim))
726 Result = NULL;
727 else {
728 Qprime = DomainPreimage(Polpreim, Latpreim, MAXNOOFRAYS);
729 Result = ZPolyhedron_Alloc(Latpreim, Qprime);
730 Domain_Free(Qprime);
731 }
732 Matrix_Free(Latpreim);
733 }
734 Domain_Free(Q);
735 return Result;
736} /* ZPolyhedronPreimage */
737
738/*
739 * Return the Z-polyhderon 'Zpol' in canonical form: 'Result' (for the Z-poly-
740 * hedron in canonical form) and Basis 'Basis' (for the basis with respect to
741 * which 'Result' is in canonical form.
742 */
743void CanonicalForm(ZPolyhedron *Zpol, ZPolyhedron **Result, Matrix **Basis) {
744
745 Matrix *B1 = NULL, *B2 = NULL, *T1, *B2inv;
746 int i, l1, l2;
747 Value tmp;
748 Polyhedron *Image, *ImageP;
749 Matrix *H, *U, *temp, *Hprime, *Uprime, *T2;
750
751#ifdef DOMDEBUG
752 FILE *fp;
753 fp = fopen("_debug", "a");
754 fprintf(fp, "\nEntered CANONICALFORM\n");
755 fclose(fp);
756#endif
757
758 if (isEmptyZPolyhedron(Zpol)) {
759 Basis[0] = Identity(Zpol->Lat->NbRows);
760 Result[0] = ZDomain_Copy(Zpol);
761 return;
762 }
763 value_init(tmp);
764 l1 = FindHermiteBasisofDomain(Zpol->P, &B1);
765 Image = DomainImage(Zpol->P, (Matrix *)Zpol->Lat, MAXNOOFRAYS);
766 l2 = FindHermiteBasisofDomain(Image, &B2);
767
768 if (l1 != l2)
769 fprintf(stderr, "In CNF : Something wrong with the Input Zpolyhedra \n");
770
771 B2inv = Matrix_Alloc(B2->NbRows, B2->NbColumns);
772 temp = Matrix_Copy(B2);
773 Matrix_Inverse(temp, B2inv);
774 Matrix_Free(temp);
775
776 temp = Matrix_Alloc(B2inv->NbRows, Zpol->Lat->NbColumns);
777 T1 = Matrix_Alloc(temp->NbRows, B1->NbColumns);
778 Matrix_Product(B2inv, (Matrix *)Zpol->Lat, temp);
779 Matrix_Product(temp, B1, T1);
780 Matrix_Free(temp);
781
782 T2 = ChangeLatticeDimension(T1, l1);
783 temp = ChangeLatticeDimension(T2, T2->NbRows + 1);
784
785 /* Adding the affine part */
786 for (i = 0; i < l1; i++)
787 value_assign(temp->p[i][temp->NbColumns - 1], T1->p[i][T1->NbColumns - 1]);
788
789 AffineHermite(temp, &H, &U);
790 Hprime = ChangeLatticeDimension(H, Zpol->Lat->NbRows);
791
792 /* Exchanging the Affine part */
793 for (i = 0; i < l1; i++) {
794 value_assign(tmp, Hprime->p[i][Hprime->NbColumns - 1]);
795 value_assign(Hprime->p[i][Hprime->NbColumns - 1],
796 Hprime->p[i][H->NbColumns - 1]);
797 value_assign(Hprime->p[i][H->NbColumns - 1], tmp);
798 }
799 Uprime = ChangeLatticeDimension(U, Zpol->Lat->NbRows);
800
801 /* Exchanging the Affine part */
802 for (i = 0; i < l1; i++) {
803 value_assign(tmp, Uprime->p[i][Uprime->NbColumns - 1]);
804 value_assign(Uprime->p[i][Uprime->NbColumns - 1],
805 Uprime->p[i][U->NbColumns - 1]);
806 value_assign(Uprime->p[i][U->NbColumns - 1], tmp);
807 }
808 Polyhedron_Free(Image);
809 Matrix_Free(B2inv);
810 B2inv = Matrix_Alloc(B1->NbRows, B1->NbColumns);
811 Matrix_Inverse(B1, B2inv);
812 ImageP = DomainImage(Zpol->P, B2inv, MAXNOOFRAYS);
813 Matrix_Free(B2inv);
814 Image = DomainImage(ImageP, Uprime, MAXNOOFRAYS);
815 Domain_Free(ImageP);
816 Result[0] = ZPolyhedron_Alloc(Hprime, Image);
817 Basis[0] = Matrix_Copy(B2);
818
819 /* Free the variables */
820 Polyhedron_Free(Image);
821 Matrix_Free(B1);
822 Matrix_Free(B2);
823 Matrix_Free(temp);
824 Matrix_Free(T1);
825 Matrix_Free(T2);
826 Matrix_Free(H);
827 Matrix_Free(U);
828 Matrix_Free(Hprime);
829 Matrix_Free(Uprime);
830 value_clear(tmp);
831 return;
832} /* CanonicalForm */
833
834/*
835 * Given a Z-polyhedron 'A' in which the Lattice is not integral, return the
836 * Z-polyhedron which contains all the integral points in the input lattice.
837 */
839
840 ZPolyhedron *Result;
841 Lattice *M = NULL, *Id;
842 Polyhedron *Im = NULL, *Preim = NULL;
843
844#ifdef DOMDEBUG
845 FILE *fp;
846 fp = fopen("_debug", "a");
847 fprintf(fp, "\nEntered INTEGRALISELATTICE\n");
848 fclose(fp);
849#endif
850
851 Im = DomainImage(A->P, A->Lat, MAXNOOFRAYS);
852 Id = Identity(A->Lat->NbRows);
853 M = LatticeImage(Id, A->Lat);
854 if (isEmptyLattice(M))
855 Result = EmptyZPolyhedron(A->Lat->NbRows - 1);
856 else {
857 Preim = DomainPreimage(Im, M, MAXNOOFRAYS);
858 Result = ZPolyhedron_Alloc(M, Preim);
859 }
860 Matrix_Free(M);
861 Domain_Free(Im);
862 Domain_Free(Preim);
863 return Result;
864} /* IntegraliseLattice */
865
866/*
867 * Return the simplified representation of the Z-domain 'ZDom'. It attempts to
868 * convexize unions of polyhedra when they correspond to the same lattices and
869 * to simplify union of lattices when they correspond to the same polyhdera.
870 */
872
873 ZPolyhedron *Ztmp, *Result;
874 ForSimplify *Head, *Prev, *Curr;
875 ZPolyhedron *ZDomHead, *Emp;
876
877 if (ZDom == NULL) {
878 fprintf(stderr, "\nError in ZDomainSimplify - ZDomHead = NULL\n");
879 return NULL;
880 }
881 if (ZDom->next == NULL)
882 return (ZPolyhedron_Copy(ZDom));
883 Emp = EmptyZPolyhedron(ZDom->Lat->NbRows - 1);
884 ZDomHead = ZDomainUnion(ZDom, Emp);
885 ZPolyhedron_Free(Emp);
886 Head = NULL;
887 Ztmp = ZDomHead;
888 do {
889 Polyhedron *Img;
890 Img = DomainImage(Ztmp->P, Ztmp->Lat, MAXNOOFRAYS);
891 for (Curr = Head; Curr != NULL; Curr = Curr->next) {
892 Polyhedron *Diff1;
893 Bool flag = False;
894
895 Diff1 = DomainDifference(Img, Curr->Pol, MAXNOOFRAYS);
896 if (emptyQ(Diff1)) {
897 Polyhedron *Diff2;
898
899 Diff2 = DomainDifference(Curr->Pol, Img, MAXNOOFRAYS);
900 if (emptyQ(Diff2))
901 flag = True;
902 Domain_Free(Diff2);
903 }
904 Domain_Free(Diff1);
905 if (flag == True) {
906 LatticeUnion *temp;
907
908 temp = (LatticeUnion *)malloc(sizeof(LatticeUnion));
909 temp->M = (Lattice *)Matrix_Copy((Matrix *)Ztmp->Lat);
910 temp->next = Curr->LatUni;
911 Curr->LatUni = temp;
912 break;
913 }
914 }
915 if (Curr == NULL) {
916 Curr = (ForSimplify *)malloc(sizeof(ForSimplify));
917 Curr->Pol = Domain_Copy(Img);
918 Curr->LatUni = (LatticeUnion *)malloc(sizeof(LatticeUnion));
919 Curr->LatUni->M = (Lattice *)Matrix_Copy((Matrix *)Ztmp->Lat);
920 Curr->LatUni->next = NULL;
921 Curr->next = Head;
922 Head = Curr;
923 }
924 Domain_Free(Img);
925 Ztmp = Ztmp->next;
926 } while (Ztmp != NULL);
927
928 for (Curr = Head; Curr != NULL; Curr = Curr->next)
929 Curr->LatUni = LatticeSimplify(Curr->LatUni);
930 Result = NULL;
931 for (Curr = Head; Curr != NULL; Curr = Curr->next) {
932 LatticeUnion *L;
933 for (L = Curr->LatUni; L != NULL; L = L->next) {
934 Polyhedron *Preim;
935 ZPolyhedron *Zpol;
936
937 Preim = DomainPreimage(Curr->Pol, L->M, MAXNOOFRAYS);
938 Zpol = ZPolyhedron_Alloc(L->M, Preim);
939 Zpol->next = Result;
940 Result = Zpol;
941 Domain_Free(Preim);
942 }
943 }
944 Curr = Head;
945 while (Curr != NULL) {
946 Prev = Curr;
947 Curr = Curr->next;
949 Domain_Free(Prev->Pol);
950 free(Prev);
951 }
952 return Result;
953} /* ZDomainSimplify */
954
956
957 Lattice *Intersection = NULL;
958 Lattice *B1 = NULL, *B2 = NULL, *newB1 = NULL, *newB2 = NULL;
959 Matrix *U = NULL, *M1 = NULL, *M2 = NULL, *M1Inverse = NULL,
960 *MtProduct = NULL;
961 Matrix *Vinv, *V, *temp, *DiagMatrix;
962 Matrix *H, *U1, *X, *Y;
963 ZPolyhedron *zpnew, *Result;
964 LatticeUnion *Head = NULL, *tempHead = NULL;
965 int i;
966 Value k;
967
968#ifdef DOMDEBUG
969 FILE *fp;
970 fp = fopen("_debug", "a");
971 fprintf(fp, "\nEntered SplitZpolyhedron \n");
972 fclose(fp);
973#endif
974
975 if (B->NbRows != B->NbColumns) {
976 fprintf(
977 stderr,
978 "\n SplitZpolyhedron : The Input Matrix B is not a proper Lattice \n");
979 return NULL;
980 }
981
982 if (ZPol->Lat->NbRows != B->NbRows) {
983 fprintf(stderr,
984 "\nSplitZpolyhedron : The Lattice in Zpolyhedron and B have ");
985 fprintf(stderr, "incompatible dimensions \n");
986 return NULL;
987 }
988
989 if (isinHnf(ZPol->Lat) != True) {
990 AffineHermite(ZPol->Lat, &H, &U1);
991 X = Matrix_Copy(H);
992 Matrix_Free(U1);
993 Matrix_Free(H);
994 } else
995 X = Matrix_Copy(ZPol->Lat);
996
997 if (isinHnf(B) != True) {
998 AffineHermite(B, &H, &U1);
999 Y = Matrix_Copy(H);
1000 Matrix_Free(H);
1001 Matrix_Free(U1);
1002 } else
1003 Y = Matrix_Copy(B);
1004 if (isEmptyLattice(X)) {
1005 return NULL;
1006 }
1007
1008 Head = Lattice2LatticeUnion(X, Y);
1009
1010 /* If the spliting operation can't be done the result is the original
1011 * Zplyhedron. */
1012
1013 if (Head == NULL) {
1014 Matrix_Free(X);
1015 Matrix_Free(Y);
1016 return ZPol;
1017 }
1018
1019 Result = NULL;
1020
1021 if (Head)
1022 while (Head) {
1023 tempHead = Head;
1024 Head = Head->next;
1025 zpnew = ZPolyhedron_Alloc(tempHead->M, ZPol->P);
1026 Result = AddZPoly2ZDomain(zpnew, Result);
1027 ZPolyhedron_Free(zpnew);
1028 tempHead->next = NULL;
1029 free(tempHead);
1030 }
1031
1032 return Result;
1033}
Lattice * EmptyLattice(int dimension)
Definition: Lattice.c:77
Bool IsLattice(Matrix *m)
Definition: Lattice.c:1234
void AffineHermite(Lattice *A, Lattice **H, Matrix **U)
Definition: Lattice.c:158
LatticeUnion * LatticeDifference(Lattice *A, Lattice *B)
Method :
Definition: Lattice.c:802
Bool isEmptyLattice(Lattice *A)
Definition: Lattice.c:100
Lattice * ChangeLatticeDimension(Lattice *A, int dimension)
Definition: Lattice.c:393
LatticeUnion * Lattice2LatticeUnion(Lattice *X, Lattice *Y)
Definition: Lattice.c:662
Lattice * LatticeIntersection(Lattice *X, Lattice *Y)
Definition: Lattice.c:459
Bool isfulldim(Matrix *m)
Definition: Lattice.c:1262
Bool LatticeIncludes(Lattice *A, Lattice *B)
Definition: Lattice.c:324
LatticeUnion * LatticeSimplify(LatticeUnion *latlist)
Definition: Lattice.c:1654
Lattice * LatticePreimage(Lattice *L, Matrix *G)
Definition: Lattice.c:1158
void LatticeUnion_Free(LatticeUnion *Head)
Definition: Lattice.c:26
Bool sameLattice(Lattice *A, Lattice *B)
Definition: Lattice.c:355
int FindHermiteBasisofDomain(Polyhedron *A, Matrix **B)
Definition: Lattice.c:980
Lattice * LatticeImage(Lattice *A, Matrix *M)
Definition: Lattice.c:1119
Bool isinHnf(Matrix *A)
Definition: Matop.c:139
Matrix * Identity(unsigned size)
Definition: Matop.c:39
Matrix * Matrix_Copy(Matrix const *Src)
Definition: Matop.c:98
static ZPolyhedron * ZPolyhedronDifference(ZPolyhedron *, ZPolyhedron *)
Definition: Zpolyhedron.c:572
static void ZPolyhedron_Free(ZPolyhedron *Zpol)
Definition: Zpolyhedron.c:87
static ZPolyhedron * ZPolyhedronPreimage(ZPolyhedron *, Matrix *)
Definition: Zpolyhedron.c:701
ZPolyhedron * ZDomainIntersection(ZPolyhedron *A, ZPolyhedron *B)
Definition: Zpolyhedron.c:375
static ZPolyhedron * AddZPoly2ZDomain(ZPolyhedron *Zpol, ZPolyhedron *Result)
Definition: Zpolyhedron.c:125
static ZPolyhedron * ZPolyhedronIntersection(ZPolyhedron *, ZPolyhedron *)
Definition: Zpolyhedron.c:527
ZPolyhedron * ZDomainSimplify(ZPolyhedron *ZDom)
Definition: Zpolyhedron.c:871
Bool ZDomainIncludes(ZPolyhedron *A, ZPolyhedron *B)
Definition: Zpolyhedron.c:270
void ZDomain_Free(ZPolyhedron *Head)
Definition: Zpolyhedron.c:75
ZPolyhedron * SplitZpolyhedron(ZPolyhedron *ZPol, Lattice *B)
Definition: Zpolyhedron.c:955
ZPolyhedron * ZDomainDifference(ZPolyhedron *A, ZPolyhedron *B)
Definition: Zpolyhedron.c:412
static ZPolyhedron * ZPolyhedron_Copy(ZPolyhedron *A)
Definition: Zpolyhedron.c:113
void ZDomainPrint(FILE *fp, const char *format, ZPolyhedron *A)
Definition: Zpolyhedron.c:319
ZPolyhedron * ZPolyhedron_Alloc(Lattice *Lat, Polyhedron *Poly)
Definition: Zpolyhedron.c:37
static ZPolyhedron * ZPolyhedronImage(ZPolyhedron *, Matrix *)
Definition: Zpolyhedron.c:649
ZPolyhedron * ZDomain_Copy(ZPolyhedron *Head)
Definition: Zpolyhedron.c:100
Bool isEmptyZPolyhedron(ZPolyhedron *Zpol)
Definition: Zpolyhedron.c:22
ZPolyhedron * IntegraliseLattice(ZPolyhedron *A)
Definition: Zpolyhedron.c:838
static void ZPolyhedronPrint(FILE *fp, const char *format, ZPolyhedron *A)
Definition: Zpolyhedron.c:338
ZPolyhedron * EmptyZPolyhedron(int dimension)
Definition: Zpolyhedron.c:245
ZPolyhedron * ZDomainImage(ZPolyhedron *A, Matrix *Func)
Definition: Zpolyhedron.c:466
struct forsimplify ForSimplify
static ZPolyhedron * AddZPolytoZDomain(ZPolyhedron *A, ZPolyhedron *Head)
Definition: Zpolyhedron.c:152
ZPolyhedron * ZDomainPreimage(ZPolyhedron *A, Matrix *Func)
Definition: Zpolyhedron.c:494
ZPolyhedron * ZDomainUnion(ZPolyhedron *A, ZPolyhedron *B)
Definition: Zpolyhedron.c:353
void CanonicalForm(ZPolyhedron *Zpol, ZPolyhedron **Result, Matrix **Basis)
Definition: Zpolyhedron.c:743
Bool ZPolyhedronIncludes(ZPolyhedron *A, ZPolyhedron *B)
Definition: Zpolyhedron.c:287
#define value_assign(v1, v2)
Definition: arithmetique.h:482
#define value_clear(val)
Definition: arithmetique.h:485
#define value_init(val)
Definition: arithmetique.h:481
void Matrix_Product(Matrix *Mat1, Matrix *Mat2, Matrix *Mat3)
Definition: matrix.c:872
Matrix * Matrix_Alloc(unsigned NbRows, unsigned NbColumns)
Definition: matrix.c:24
int Matrix_Inverse(Matrix *Mat, Matrix *MatInv)
Definition: matrix.c:917
void Matrix_Print(FILE *Dst, const char *Format, Matrix *Mat)
Definition: matrix.c:115
void Matrix_Free(Matrix *Mat)
Definition: matrix.c:71
void Polyhedron_Free(Polyhedron *Pol)
Definition: polyhedron.c:1614
Polyhedron * Empty_Polyhedron(unsigned Dimension)
Definition: polyhedron.c:1721
Polyhedron * DomainDifference(Polyhedron *Pol1, Polyhedron *Pol2, unsigned NbMaxRays)
Definition: polyhedron.c:3694
Polyhedron * DomainIntersection(Polyhedron *Pol1, Polyhedron *Pol2, unsigned NbMaxRays)
Return the intersection of two polyhedral domains 'Pol1' and 'Pol2'.
Definition: polyhedron.c:2637
Polyhedron * Domain_Copy(Polyhedron *Pol)
Definition: polyhedron.c:2867
Polyhedron * DomainPreimage(Polyhedron *Pol, Matrix *Func, unsigned NbMaxRays)
Definition: polyhedron.c:4175
Polyhedron * DomainUnion(Polyhedron *Pol1, Polyhedron *Pol2, unsigned NbMaxRays)
Definition: polyhedron.c:3585
Polyhedron * DomainImage(Polyhedron *Pol, Matrix *Func, unsigned NbMaxConstrs)
Definition: polyhedron.c:4303
void Polyhedron_Print(FILE *Dst, const char *Format, const Polyhedron *Pol)
Definition: polyhedron.c:1639
void Domain_Free(Polyhedron *Pol)
Definition: polyhedron.c:1626
#define POL_ENSURE_VERTICES(P)
Definition: polyhedron.h:17
#define POL_ENSURE_FACETS(P)
Definition: polyhedron.h:13
struct LatticeUnion * next
Definition: types.h:222
Lattice * M
Definition: types.h:221
struct ZPolyhedron * next
Definition: types.h:228
Lattice * Lat
Definition: types.h:226
Polyhedron * P
Definition: types.h:227
Polyhedron * Pol
Definition: Zpolyhedron.c:14
LatticeUnion * LatUni
Definition: Zpolyhedron.c:15
struct forsimplify * next
Definition: Zpolyhedron.c:16
Definition: types.h:75
unsigned NbRows
Definition: types.h:76
Value ** p
Definition: types.h:77
unsigned NbColumns
Definition: types.h:76
unsigned Dimension
Definition: types.h:94
struct polyhedron * next
Definition: types.h:99
#define emptyQ(P)
Definition: types.h:118
Bool
Definition: types.h:218
@ True
Definition: types.h:218
@ False
Definition: types.h:218
#define MAXNOOFRAYS
Definition: types.h:28