polylib 5.22.8
Lattice.c
Go to the documentation of this file.
1#include <polylib/polylib.h>
2#include <stdlib.h>
3
4typedef struct {
5 int count;
6 int *fac;
7} factor;
8
9static factor allfactors(int num);
10
11/*
12 * Print the contents of a list of Lattices 'Head'
13 */
14void PrintLatticeUnion(FILE *fp, char *format, LatticeUnion *Head) {
15
16 LatticeUnion *temp;
17
18 for (temp = Head; temp != NULL; temp = temp->next)
19 Matrix_Print(fp, format, (Matrix *)temp->M);
20 return;
21} /* PrintLatticeUnion */
22
23/*
24 * Free the memory allocated to a list of lattices 'Head'
25 */
27
28 LatticeUnion *temp;
29
30 while (Head != NULL) {
31 temp = Head;
32 Head = temp->next;
33 Matrix_Free(temp->M);
34 free(temp);
35 }
36 return;
37} /* LatticeUnion_Free */
38
39/*
40 * Allocate a heads for a list of Lattices
41 */
43
44 LatticeUnion *temp;
45
46 temp = (LatticeUnion *)malloc(sizeof(LatticeUnion));
47 temp->M = NULL;
48 temp->next = NULL;
49 return temp;
50} /* LatticeUnion_Alloc */
51
52/*
53 * Given two Lattices 'A' and 'B', return True if they have the same affine
54 * part (the last column) otherwise return 'False'.
55 */
57
58 int i;
59
60#ifdef DOMDEBUG
61 FILE *fp;
62 fp = fopen("_debug", "a");
63 fprintf(fp, "\nEntered SAMEAFFINEPART \n");
64 fclose(fp);
65#endif
66
67 for (i = 0; i < A->NbRows; i++)
68 if (value_ne(A->p[i][A->NbColumns - 1], B->p[i][B->NbColumns - 1]))
69 return False;
70 return True;
71} /* sameAffinepart */
72
73/*
74 * Return an empty lattice of dimension 'dimension-1'. An empty lattice is
75 * represented as [[0 0 ... 0] .... [0 ... 0][0 0.....0 1]].
76 */
77Lattice *EmptyLattice(int dimension) {
78
79 Lattice *result;
80 int i, j;
81
82#ifdef DOMDEBUG
83 FILE *fp;
84 fp = fopen("_debug", "a");
85 fprintf(fp, "\nEntered NULLATTICE \n");
86 fclose(fp);
87#endif
88
89 result = (Lattice *)Matrix_Alloc(dimension, dimension);
90 for (i = 0; i < dimension; i++)
91 for (j = 0; j < dimension; j++)
92 value_set_si(result->p[i][j], 0);
93 value_set_si(result->p[i - 1][i - 1], 1);
94 return result;
95} /* EmptyLattice */
96
97/*
98 * Return True if Lattice 'A' is empty, otherwise return False.
99 */
101
102 int i, j;
103
104#ifdef DOMDEBUG
105 FILE *fp;
106 fp = fopen("_debug", "a");
107 fprintf(fp, "\nEntered ISNULLATTICE \n");
108 fclose(fp);
109#endif
110
111 for (i = 0; i < A->NbRows - 1; i++)
112 for (j = 0; j < A->NbColumns - 1; j++)
113 if (value_notzero_p(A->p[i][j])) {
114 return False;
115 }
116 if (value_one_p(A->p[i][A->NbColumns - 1])) {
117 return True;
118 }
119 return False;
120} /* isEmptyLaattice */
121
122/*
123 * Given a Lattice 'A', check whether it is linear or not, i.e. whether the
124 * affine part is NULL or not. If affine part is empty, it returns True other-
125 * wise it returns False.
126 */
128
129 int i;
130
131#ifdef DOMDEBUG
132 FILE *fp;
133 fp = fopen("_debug", "a");
134 fprintf(fp, "\nEntered ISLINEAR \n");
135 fclose(fp);
136#endif
137
138 for (i = 0; i < A->NbRows - 1; i++)
139 if (value_notzero_p(A->p[i][A->NbColumns - 1])) {
140 return False;
141 }
142 return True;
143} /* isLinear */
144
145/*
146 * Return the affine Hermite normal form of the affine lattice 'A'. The unique
147 * affine Hermite form if a lattice is stored in 'H' and the unimodular matrix
148 * corresponding to 'A = H*U' is stored in the matrix 'U'.
149 * Algorithm :
150 * 1) Check if the Lattice is Linear or not.
151 * 2) If it is not Linear, then Homogenise the Lattice.
152 * 3) Call Hermite.
153 * 4) If the Lattice was Homogenised, the HNF H must be
154 * Dehomogenised and also corresponding changes must
155 * be made to the Unimodular Matrix U.
156 * 5) Return.
157 */
159
160 Lattice *temp;
161 Bool flag = True;
162
163#ifdef DOMDEBUG
164 FILE *fp;
165 fp = fopen("_debug", "a");
166 fprintf(fp, "\nEntered AFFINEHERMITE \n");
167 fclose(fp);
168#endif
169
170 if (isLinear(A) == False)
171 temp = Homogenise(A, True);
172 else {
173 flag = False;
174 temp = (Lattice *)Matrix_Copy(A);
175 }
176 Hermite((Matrix *)temp, (Matrix **)H, U);
177 if (flag == True) {
178 Matrix_Free((Matrix *)temp);
179 temp = Homogenise(H[0], False);
180 Matrix_Free((Matrix *)H[0]);
181 H[0] = (Lattice *)Matrix_Copy(temp);
182 Matrix_Free((Matrix *)temp);
183 temp = Homogenise(U[0], False);
184 Matrix_Free((Matrix *)U[0]);
185 U[0] = (Matrix *)Matrix_Copy(temp);
186 }
187 Matrix_Free((Matrix *)temp);
188 return;
189} /* AffineHermite */
190
191/*
192 * Given a Polylib matrix 'A' that rerepresents an affine function, return the
193 * affine Smith normal form 'Delta' of 'A' and unimodular matrices 'U' and 'V'
194 * such that 'A = U*Delta*V'.
195 * Algorithm:
196 * (1) Homogenise the Lattice.
197 * (2) Call Smith
198 * (3) The Smith Normal Form Delta must be Dehomogenised and also
199 * corresponding changes must be made to the Unimodular Matrices
200 * U and V.
201 * 4) Bring Delta into AffineSmith Form.
202 */
203void AffineSmith(Lattice *A, Lattice **U, Lattice **V, Lattice **Diag) {
204
205 Lattice *temp;
206 Lattice *Uinv;
207 int i, j;
208 Value sum, quo, rem;
209
210#ifdef DOMDEBUG
211 FILE *fp;
212 fp = fopen("_debug", "a");
213 fprintf(fp, "\nEntered AFFINESMITH \n");
214 fclose(fp);
215#endif
216
217 value_init(sum);
218 value_init(quo);
219 value_init(rem);
220 temp = Homogenise(A, True);
221 Smith((Matrix *)temp, (Matrix **)U, (Matrix **)V, (Matrix **)Diag);
222 Matrix_Free((Matrix *)temp);
223
224 temp = Homogenise(*U, False);
225 Matrix_Free((Matrix *)*U);
226 *U = (Lattice *)Matrix_Copy((Matrix *)temp);
227 Matrix_Free((Matrix *)temp);
228
229 temp = Homogenise(*V, False);
230 Matrix_Free((Matrix *)*V);
231 *V = (Lattice *)Matrix_Copy((Matrix *)temp);
232 Matrix_Free((Matrix *)temp);
233
234 temp = Homogenise(*Diag, False);
235 Matrix_Free((Matrix *)*Diag);
236 *Diag = (Lattice *)Matrix_Copy((Matrix *)temp);
237 Matrix_Free((Matrix *)temp);
238
239 temp = (Lattice *)Matrix_Copy((Matrix *)*U);
240 Uinv = (Lattice *)Matrix_Alloc(U[0]->NbRows, U[0]->NbColumns);
241 Matrix_Inverse((Matrix *)temp, (Matrix *)Uinv);
242 Matrix_Free((Matrix *)temp);
243
244 for (i = 0; i < U[0]->NbRows - 1; i++) {
245 value_set_si(sum, 0);
246 for (j = 0; j < U[0]->NbColumns - 1; j++) {
247 value_addmul(sum, Uinv->p[i][j], U[0]->p[j][U[0]->NbColumns - 1]);
248 }
249 value_assign(Diag[0]->p[i][j], sum);
250 }
251 Matrix_Free((Matrix *)Uinv);
252 for (i = 0; i < U[0]->NbRows - 1; i++)
253 value_set_si(U[0]->p[i][U[0]->NbColumns - 1], 0);
254 for (i = 0; i < Diag[0]->NbRows - 1; i++) {
255 value_division(quo, Diag[0]->p[i][Diag[0]->NbColumns - 1],
256 Diag[0]->p[i][i]);
257 value_modulus(rem, Diag[0]->p[i][Diag[0]->NbColumns - 1], Diag[0]->p[i][i]);
258
259 fprintf(stdout, " pourcent ");
260 value_print(stdout, VALUE_FMT, rem);
261 fprintf(stdout, " quotient ");
262 value_print(stdout, VALUE_FMT, quo);
263 fprintf(stdout, " \n");
264
265 /* Apparently the % operator is strange when sign are different */
266 if (value_neg_p(rem)) {
267 value_addto(rem, rem, Diag[0]->p[i][i]);
268 value_decrement(quo, quo);
269 };
270 fprintf(stdout, "apres pourcent ");
271 value_print(stdout, VALUE_FMT, rem);
272 fprintf(stdout, " quotient ");
273 value_print(stdout, VALUE_FMT, quo);
274 fprintf(stdout, " \n");
275 value_assign(Diag[0]->p[i][Diag[0]->NbColumns - 1], rem);
276 value_assign(V[0]->p[i][V[0]->NbColumns - 1], quo);
277 }
278 value_clear(sum);
279 value_clear(quo);
280 value_clear(rem);
281 return;
282} /* AffineSmith */
283
284/*
285 * Given a lattice 'A' and a boolean variable 'Forward', homogenise the lattice
286 * if 'Forward' is True, otherwise if 'Forward' is False, dehomogenise the
287 * lattice 'A'.
288 * Algorithm:
289 * (1) If Forward == True
290 * Put the last row first.
291 * Put the last columns first.
292 * (2) Else
293 * Put the first row last.
294 * Put the first column last.
295 * (3) Return the result.
296 */
298
299 Lattice *result;
300
301#ifdef DOMDEBUG
302 FILE *fp;
303 fp = fopen("_debug", "a");
304 fprintf(fp, "\nEntered HOMOGENISE \n");
305 fclose(fp);
306#endif
307
308 result = (Lattice *)Matrix_Copy(A);
309 if (Forward == True) {
310 PutColumnFirst((Matrix *)result, A->NbColumns - 1);
311 PutRowFirst((Matrix *)result, result->NbRows - 1);
312 } else {
313 PutColumnLast((Matrix *)result, 0);
314 PutRowLast((Matrix *)result, 0);
315 }
316 return result;
317} /* Homogenise */
318
319/*
320 * Given two lattices 'A' and 'B', verify if lattice 'A' is included in 'B' or
321 * not. If 'A' is included in 'B' the 'A' intersection 'B', will be 'A'. So,
322 * compute 'A' intersection 'B' and check if it is the same as 'A'.
323 */
325
326 Lattice *temp, *UA, *HA;
327 Bool flag = False;
328
329#ifdef DOMDEBUG
330 FILE *fp;
331 fp = fopen("_debug", "a");
332 fprintf(fp, "\nEntered LATTICE INCLUDES \n");
333 fclose(fp);
334#endif
335
336 AffineHermite(A, &HA, &UA);
337 temp = LatticeIntersection(B, HA);
338 if (sameLattice(temp, HA) == True)
339 flag = True;
340
341 Matrix_Free((Matrix *)temp);
342 Matrix_Free((Matrix *)UA);
343 Matrix_Free((Matrix *)HA);
344 return flag;
345} /* LatticeIncludes */
346
347/*
348 * Given two lattices 'A' and 'B', verify if 'A' and 'B' are the same lattice.
349 * Algorithm:
350 * The Affine Hermite form of two full dimensional matrices are
351 * unique. So, take the Affine Hermite form of both 'A' and 'B' and compare the
352 * matrices. If they are equal, the function returns True, else it returns
353 * False.
354 */
356
357 Lattice *HA, *HB, *UA, *UB;
358 int i, j;
359 Bool result = True;
360
361#ifdef DOMDEBUG
362 FILE *fp;
363 fp = fopen("_debug", "a");
364 fprintf(fp, "\nEntered SAME LATTICE \n");
365 fclose(fp);
366#endif
367
368 AffineHermite(A, &HA, &UA);
369 AffineHermite(B, &HB, &UB);
370
371 for (i = 0; i < A->NbRows; i++)
372 for (j = 0; j < A->NbColumns; j++)
373 if (value_ne(HA->p[i][j], HB->p[i][j])) {
374 result = False;
375 break;
376 }
377
378 Matrix_Free((Matrix *)HA);
379 Matrix_Free((Matrix *)HB);
380 Matrix_Free((Matrix *)UA);
381 Matrix_Free((Matrix *)UB);
382
383 return result;
384} /* sameLattice */
385
386/*
387 * Given a matrix 'A' and an integer 'dimension', do the following:
388 * If dimension < A->dimension), output a (dimension * dimension) submatrix of
389 * A. Otherwise the output matrix is [A 0][0 ID]. The order if the identity
390 * matrix is (dimension - A->dimension). The input matrix is not necessarily
391 * a Polylib matrix but the output is a polylib matrix.
392 */
394
395 int i, j;
396 Lattice *Result;
397
398 Result = Matrix_Alloc(dimension, dimension);
399 if (dimension <= A->NbRows) {
400 for (i = 0; i < dimension; i++)
401 for (j = 0; j < dimension; j++)
402 value_assign(Result->p[i][j], A->p[i][j]);
403 return Result;
404 }
405 for (i = 0; i < A->NbRows; i++)
406 for (j = 0; j < A->NbRows; j++)
407 value_assign(Result->p[i][j], A->p[i][j]);
408
409 for (i = A->NbRows; i < dimension; i++)
410 for (j = 0; j < dimension; j++) {
411 value_set_si(Result->p[i][j], 0);
412 value_set_si(Result->p[j][i], 0);
413 }
414 for (i = A->NbRows; i < dimension; i++)
415 value_set_si(Result->p[i][i], 1);
416 return Result;
417} /* ChangeLatticeDimension */
418
419/*
420 * Given an affine lattice 'A', return a matrix of the linear part of the
421 * lattice.
422 */
424
425 Lattice *Result;
426 int i, j;
427 Result = (Lattice *)Matrix_Alloc(A->NbRows - 1, A->NbColumns - 1);
428 for (i = 0; i < A->NbRows - 1; i++)
429 for (j = 0; j < A->NbColumns - 1; j++)
430 value_assign(Result->p[i][j], A->p[i][j]);
431 return Result;
432} /* ExtractLinearPart */
433
434static Matrix *MakeDioEqforInter(Matrix *A, Matrix *B);
435
436/*
437 * Given two lattices 'A' and 'B', return the intersection of the two lattcies.
438 * The dimension of 'A' and 'B' should be the same.
439 * Algorithm:
440 * (1) Verify if the lattcies 'A' and 'B' have the same affine part.
441 * If they have same affine part, then only their Linear parts
442 * need to be intersected. If they don't have the same affine
443 * part then the affine part has to be taken into consideration.
444 * For this, homogenise the lattices to get their Hermite Forms
445 * and then find their intersection.
446 *
447 * (2) Step(2) involves, solving the Diophantine Equations in order
448 * to extract the intersection of the Lattices. The Diophantine
449 * equations are formed taking into consideration whether the
450 * affine part has to be included or not.
451 *
452 * (3) Solve the Diophantine equations.
453 *
454 * (4) Extract the necessary information from the result.
455 *
456 * (5) If the lattices have different affine parts and they were
457 * homogenised, the result is dehomogenised.
458 */
460
461 int i, j, exist;
462 Lattice *result = NULL, *U = NULL;
463 Lattice *A = NULL, *B = NULL, *H = NULL;
464 Matrix *fordio;
465 Vector *X1 = NULL;
466
467#ifdef DOMDEBUG
468 FILE *fp;
469 fp = fopen("_debug", "a");
470 fprintf(fp, "\nEntered LATTICEINTERSECTION \n");
471 fclose(fp);
472#endif
473
474 if (X->NbRows != X->NbColumns) {
475 fprintf(stderr, "\nIn LatticeIntersection : The Input Matrix X is a not a "
476 "well defined Lattice\n");
477 return EmptyLattice(X->NbRows);
478 }
479
480 if (Y->NbRows != Y->NbColumns) {
481 fprintf(stderr, "\nIn LatticeIntersection : The Input Matrix Y is a not a "
482 "well defined Lattice\n");
483 return EmptyLattice(X->NbRows);
484 }
485
486 if (Y->NbRows != X->NbRows) {
487 fprintf(stderr, "\nIn LatticeIntersection : the input lattices X and Y are "
488 "of incompatible dimensions\n");
489 return EmptyLattice(X->NbRows);
490 }
491
492 if (isinHnf(X))
493 A = (Lattice *)Matrix_Copy(X);
494 else {
495 AffineHermite(X, &H, &U);
496 A = (Lattice *)Matrix_Copy(H);
497 Matrix_Free((Matrix *)H);
498 Matrix_Free((Matrix *)U);
499 }
500
501 if (isinHnf(Y))
502 B = (Lattice *)Matrix_Copy(Y);
503 else {
504 AffineHermite(Y, &H, &U);
505 B = (Lattice *)Matrix_Copy(H);
506 Matrix_Free((Matrix *)H);
507 Matrix_Free((Matrix *)U);
508 }
509
510 if ((isEmptyLattice(A)) || (isEmptyLattice(B))) {
511 result = EmptyLattice(X->NbRows);
512 Matrix_Free((Matrix *)A);
513 Matrix_Free((Matrix *)B);
514 return result;
515 }
516 fordio = MakeDioEqforInter(A, B);
517 Matrix_Free(A);
518 Matrix_Free(B);
519 exist = SolveDiophantine(fordio, (Matrix **)&U, &X1);
520 if (exist < 0) { /* Intersection is NULL */
521 result = (EmptyLattice(X->NbRows));
522 return result;
523 }
524
525 result = (Lattice *)Matrix_Alloc(X->NbRows, X->NbColumns);
526 for (i = 0; i < result->NbRows - 1; i++)
527 for (j = 0; j < result->NbColumns - 1; j++)
528 value_assign(result->p[i][j], U->p[i][j]);
529
530 for (i = 0; i < result->NbRows - 1; i++)
531 value_assign(result->p[i][result->NbColumns - 1], X1->p[i]);
532 for (i = 0; i < result->NbColumns - 1; i++)
533 value_set_si(result->p[result->NbRows - 1][i], 0);
534 value_set_si(result->p[result->NbRows - 1][result->NbColumns - 1], 1);
535
536 Matrix_Free((Matrix *)U);
537 Vector_Free(X1);
538 Matrix_Free(fordio);
539
540 AffineHermite(result, &H, &U);
541 Matrix_Free((Matrix *)result);
542 result = (Lattice *)Matrix_Copy(H);
543
544 Matrix_Free((Matrix *)H);
545 Matrix_Free((Matrix *)U);
546
547 /* Check whether the Lattice is NULL or not */
548
549 if (isEmptyLattice(result)) {
550 Matrix_Free((Matrix *)result);
551 return (EmptyLattice(X->NbRows));
552 }
553 return result;
554} /* LatticeIntersection */
555
557
558 Matrix *Dio;
559 int i, j;
560
561#ifdef DOMDEBUG
562 FILE *fp;
563 fp = fopen("_debug", "a");
564 fprintf(fp, "\nEntered MAKEDIOEQFORINTER \n");
565 fclose(fp);
566#endif
567
568 Dio = Matrix_Alloc(2 * (A->NbRows - 1) + 1, 3 * (A->NbColumns - 1) + 1);
569
570 for (i = 0; i < Dio->NbRows; i++)
571 for (j = 0; j < Dio->NbColumns; j++)
572 value_set_si(Dio->p[i][j], 0);
573
574 for (i = 0; i < A->NbRows - 1; i++) {
575 value_set_si(Dio->p[i][i], 1);
576 value_set_si(Dio->p[i + A->NbRows - 1][i], 1);
577 }
578 for (i = 0; i < A->NbRows - 1; i++)
579 for (j = 0; j < A->NbRows - 1; j++) {
580 value_oppose(Dio->p[i][j + A->NbRows - 1], A->p[i][j]);
581 value_oppose(Dio->p[i + (A->NbRows - 1)][j + 2 * (A->NbRows - 1)],
582 B->p[i][j]);
583 }
584
585 /* Adding the affine part */
586
587 for (i = 0; i < A->NbColumns - 1; i++) {
588 value_oppose(Dio->p[i][Dio->NbColumns - 1], A->p[i][A->NbColumns - 1]);
589 value_oppose(Dio->p[i + A->NbRows - 1][Dio->NbColumns - 1],
590 B->p[i][A->NbColumns - 1]);
591 }
592 value_set_si(Dio->p[Dio->NbRows - 1][Dio->NbColumns - 1], 1);
593 return Dio;
594} /* MakeDioEqforInter */
595
596static void AddLattice(LatticeUnion *, Matrix *, Matrix *, int, int);
598
599/*
600 * The function is transforming a lattice X in a union of lattices based on a
601 starting lattice Y.
602 * Note1: If the intersection of X and Y lattices is empty the result is identic
603 with the first argument (X) because no operation can be made. *Note2: The
604 function is availabe only for simple Lattices and not for a union of Lattices.
605
606 * Step 1: Find Intersection = LatticeIntersection (A, B).
607 * Step 2: Extract the Linear Parts of the Lattices A and Intersection.
608 * (while dealing with Basis we only deal with the Linear Parts)
609 * Step 3: Let M1 = Basis of A and M2 = Basis of B.
610 * Let B1 and B2 be the Basis of A and B respectively,
611 * corresponding to the above Theorem.
612 * Then we Have B1 = M1 * U1 {a unimodular Matrix }
613 * and B2 = M2 * U2. M1 and M2 we know, they are the linear
614 * parts we obtained in Step 2. Our Task is now to find U1 and
615 * U2.
616 * We know that B1 * Delta = B2.
617 * i.e. M1 * U1 * Delta = M2 * U2
618 * or U1*Delta*U2Inverse = M1Inverse * M2.
619 * and Delta is the Diagonal Matrix which satisifies the
620 * above properties (in the Theorem).
621 * So Delta is nothing but the Smith Normal Form of
622 * M1Inverse * M2.
623 * So, first we have to find M1Inverse.
624 *
625 * This Step, involves finding the Inverse of the Matrix M1.
626 * We find the Inverse using the Polylib function
627 * Matrix_Inverse. There is a catch here, the result of this
628 * function is an integral matrix, not necessarily the exact
629 * Inverse (since M1 need not be Unimodular), but a multiple
630 * of the actual inverse. The number by which we have to divide
631 * the matrix, is not obtained here as the input matrix is not
632 * a Polylib matrix { We input only the Linear part }. Later I
633 * give a way for finding that number.
634 *
635 * M1Inverse = Matrix_Inverse ( M1 );
636 *
637 * Step 4 : MtProduct = Matrix_Product (M1Inverse, M2);
638 * Step 5 : SmithNormalFrom (MtProduct, Delta, U, V);
639 * U1 = U and U2Inverse = V.
640 * Step 6 : Find U2 = Matrix_Inverse (U2inverse). Here there is no prob
641 * as U1 and its inverse are unimodular.
642 *
643 * Step 7 : Compute B1 = M1 * U1;
644 * Step 8 : Compute B2 = M2 * U2;
645 * Step 9 : Earlier when we computed M1Inverse, we knew that it was not
646 * the exact inverse but a multiple of it. Now we find the
647 * number, such that ( M1Inverse / number ) would give us the
648 * exact inverse of M1.
649 * We know that B1 * Delta = B2.
650 * Let k = B2[0][0] / B1[0][0].
651 * Let number = Delta[0][0]/k;
652 * This 'number' is the number we want.
653 * We Divide the matrix Delta by this number, to get the actual
654 * Delta such that B1 * Delta = B2.
655 * Step 10 : Call Split Lattice (B1, B2, Delta ).
656 * This function returns the Union of Lattices in such a way
657 * that B2 is at the Head of this List.
658 *
659 *If the intersection between X and Y is empty then the result is NULL.
660 */
661
663 Lattice *B1 = NULL, *B2 = NULL, *newB1 = NULL, *newB2 = NULL,
664 *Intersection = NULL;
665 Matrix *U = NULL, *M1 = NULL, *M2 = NULL, *M1Inverse = NULL,
666 *MtProduct = NULL;
667 Matrix *Vinv, *V, *temp, *DiagMatrix;
668
669 LatticeUnion *Head = NULL, *tempHead = NULL;
670 int i;
671 Value k;
672
673 Intersection = LatticeIntersection(X, Y);
674 if (isEmptyLattice(Intersection) == True) {
675 fprintf(stderr, "\nIn Lattice2LatticeUnion : the input lattices X and Y do "
676 "not have any common part\n");
677 return NULL;
678 }
679
680 value_init(k);
681 M1 = (Matrix *)ExtractLinearPart(X);
682 M2 = (Matrix *)ExtractLinearPart(Intersection);
683
684 M1Inverse = Matrix_Alloc(M1->NbRows, M1->NbColumns);
685 temp = Matrix_Copy(M1);
686 Matrix_Inverse(temp, M1Inverse);
687 Matrix_Free(temp);
688
689 MtProduct = Matrix_Alloc(M1->NbRows, M1->NbColumns);
690 Matrix_Product(M1Inverse, M2, MtProduct);
691 Smith(MtProduct, &U, &Vinv, &DiagMatrix);
692 V = Matrix_Alloc(Vinv->NbRows, Vinv->NbColumns);
693 Matrix_Inverse(Vinv, V);
694 Matrix_Free(Vinv);
695 B1 = Matrix_Alloc(M1->NbRows, U->NbColumns);
696 B2 = Matrix_Alloc(M2->NbRows, V->NbColumns);
697 Matrix_Product(M1, U, B1);
698 Matrix_Product(M2, V, B2);
699 Matrix_Free(M1);
700 Matrix_Free(M2);
701 value_division(k, B2->p[0][0], B1->p[0][0]);
702 value_division(k, DiagMatrix->p[0][0], k);
703 for (i = 0; i < DiagMatrix->NbRows; i++)
704 value_division(DiagMatrix->p[i][i], DiagMatrix->p[i][i], k);
705 newB1 = ChangeLatticeDimension(B1, B1->NbRows + 1);
706 Matrix_Free(B1);
707 newB2 = ChangeLatticeDimension(B2, B2->NbRows + 1);
708 Matrix_Free(B2);
709 for (i = 0; i < newB1->NbRows - 1; i++)
710 value_assign(newB2->p[i][newB1->NbRows - 1],
711 Intersection->p[i][X->NbRows - 1]);
712 Head = SplitLattice(newB1, newB2, DiagMatrix);
713 Matrix_Free(newB1);
714 Matrix_Free(DiagMatrix);
715 value_clear(k);
716 return Head;
717}
718
719/**
720
721*** Method :
722***
723**/
724/*
725 * Return the Union of lattices that constitute the difference the lattices
726 * 'A' and 'B'. The dimensions of 'A' and 'B' should be the same.
727 * Note :
728 * Inorder to Find the Difference of Lattices, we make use of
729 * the following facts.
730 *
731 * Theorem : Given Two Lattices L1 and L2, (L2 subset of L1) there exists a
732 * Basis B = {b1, b2,..bn} of L1 and integers {a1, a2...,an} such
733 * that a1 divides a2, a2 divides a3 and so on and {a1b1, a2b2 ,...,
734 * .., anbn} is a Basis of L2. So given this theorem we can express
735 * the Lattice L1 in terms of Union of Lattices Involving L2, such
736 * that Lattice L1 = B1 = Union of (B2 + i1b1 + i2b2 + .. inbn) such
737 * that 0 <= i1 < a1; 0 <= i2 < a2; ....... 0 <= in < an. We also
738 * know that A/B = A/(A Intersection B) and that (A Intersection B)
739 * is a subset of A. So, Making use of these two facts, we find the
740 * A/B. We Split The Lattice A in terms of Lattice (A Int B). From
741 * this Union of Lattices Delete the Lattice (A Int B).
742 *
743 * Algorithm :
744 *
745 * Step 1: Find Intersection = LatticeIntersection (A, B).
746 * Step 2: Extract the Linear Parts of the Lattices A and Intersection.
747 * (while dealing with Basis we only deal with the Linear Parts)
748 * Step 3: Let M1 = Basis of A and M2 = Basis of B.
749 * Let B1 and B2 be the Basis of A and B respectively,
750 * corresponding to the above Theorem.
751 * Then we Have B1 = M1 * U1 {a unimodular Matrix }
752 * and B2 = M2 * U2. M1 and M2 we know, they are the linear
753 * parts we obtained in Step 2. Our Task is now to find U1 and
754 * U2.
755 * We know that B1 * Delta = B2.
756 * i.e. M1 * U1 * Delta = M2 * U2
757 * or U1*Delta*U2Inverse = M1Inverse * M2.
758 * and Delta is the Diagonal Matrix which satisifies the
759 * above properties (in the Theorem).
760 * So Delta is nothing but the Smith Normal Form of
761 * M1Inverse * M2.
762 * So, first we have to find M1Inverse.
763 *
764 * This Step, involves finding the Inverse of the Matrix M1.
765 * We find the Inverse using the Polylib function
766 * Matrix_Inverse. There is a catch here, the result of this
767 * function is an integral matrix, not necessarily the exact
768 * Inverse (since M1 need not be Unimodular), but a multiple
769 * of the actual inverse. The number by which we have to divide
770 * the matrix, is not obtained here as the input matrix is not
771 * a Polylib matrix { We input only the Linear part }. Later I
772 * give a way for finding that number.
773 *
774 * M1Inverse = Matrix_Inverse ( M1 );
775 *
776 * Step 4 : MtProduct = Matrix_Product (M1Inverse, M2);
777 * Step 5 : SmithNormalFrom (MtProduct, Delta, U, V);
778 * U1 = U and U2Inverse = V.
779 * Step 6 : Find U2 = Matrix_Inverse (U2inverse). Here there is no prob
780 * as U1 and its inverse are unimodular.
781 *
782 * Step 7 : Compute B1 = M1 * U1;
783 * Step 8 : Compute B2 = M2 * U2;
784 * Step 9 : Earlier when we computed M1Inverse, we knew that it was not
785 * the exact inverse but a multiple of it. Now we find the
786 * number, such that ( M1Inverse / number ) would give us the
787 * exact inverse of M1.
788 * We know that B1 * Delta = B2.
789 * Let k = B2[0][0] / B1[0][0].
790 * Let number = Delta[0][0]/k;
791 * This 'number' is the number we want.
792 * We Divide the matrix Delta by this number, to get the actual
793 * Delta such that B1 * Delta = B2.
794 * Step 10 : Call Split Lattice (B1, B2, Delta ).
795 * This function returns the Union of Lattices in such a way
796 * that B2 is at the Head of this List.
797 * Step 11 : To Remove B2 From the list of the Union of Lattices.
798 * Head = Head->next;
799 * Step 12 : Free the Memory that is now not needed and return Head.
800 *
801 */
803
804 Lattice *Intersection = NULL;
805 LatticeUnion *Head = NULL, *tempHead = NULL;
806 Matrix *H, *U1, *X, *Y;
807
808#ifdef DOMDEBUG
809 FILE *fp;
810 fp = fopen("_debug", "a");
811 fprintf(fp, "\nEntered LATTICEDIFFERENCE \n");
812 fclose(fp);
813#endif
814
815 if (A->NbRows != A->NbColumns) {
816 fprintf(stderr, "\nIn LatticeDifference : The Input Matrix A is not a "
817 "proper Lattice \n");
818 return NULL;
819 }
820
821 if (B->NbRows != B->NbColumns) {
822 fprintf(stderr, "\nIn LatticeDifference : The Input Matrix B is not a "
823 "proper Lattice \n");
824 return NULL;
825 }
826
827 if (A->NbRows != B->NbRows) {
828 fprintf(stderr,
829 "\nIn Lattice Difference : The Input Lattices A and B have ");
830 fprintf(stderr, "incompatible dimensions \n");
831 return NULL;
832 }
833
834 if (isinHnf(A) != True) {
835 AffineHermite(A, &H, &U1);
836 X = Matrix_Copy(H);
837 Matrix_Free(U1);
838 Matrix_Free(H);
839 } else
840 X = Matrix_Copy(A);
841
842 if (isinHnf(B) != True) {
843 AffineHermite(B, &H, &U1);
844 Y = Matrix_Copy(H);
845 Matrix_Free(H);
846 Matrix_Free(U1);
847 } else
848 Y = Matrix_Copy(B);
849 if (isEmptyLattice(X)) {
850 return NULL;
851 }
852
853 Head = Lattice2LatticeUnion(X, Y);
854
855 /* If the spliting operation can't be done the result is X. */
856
857 if (Head == NULL) {
858 Head = (LatticeUnion *)malloc(sizeof(LatticeUnion));
859 Head->M = Matrix_Copy(X);
860 Head->next = NULL;
861 Matrix_Free(X);
862 Matrix_Free(Y);
863 return Head;
864 }
865
866 tempHead = Head;
867 Head = Head->next;
868 Matrix_Free(tempHead->M);
869 tempHead->next = NULL;
870 free(tempHead);
871
872 if ((Head != NULL))
873 Head = LatticeSimplify(Head);
874 Matrix_Free(X);
875 Matrix_Free(Y);
876
877 return Head;
878} /* LatticeDifference */
879
880/*
881 * Given a Lattice 'B1' and a Lattice 'B2' and a Diagonal Matrix 'C' such that
882 * 'B2' is a subset of 'B1' and C[0][0] divides C[1][1], C[1][1] divides C[2]
883 * [2] and so on, output the list of matrices whose union is B1. The function
884 * expresses the Lattice B1 in terms of B2 Unions of B1 = Union of {B2 + i0b0 +
885 * i1b1 + .... + inbn} where 0 <= i0 < C[0][0]; 0 <= i1 < C[1][1] and so on and
886 * {b0 ... bn} are the columns of Lattice B1. The list is so formed that the
887 * Lattice B2 is the Head of the list.
888 */
890
891 int i;
892
893 LatticeUnion *Head = NULL;
894 Head = (LatticeUnion *)malloc(sizeof(LatticeUnion));
895 Head->M = (Lattice *)B2;
896 Head->next = NULL;
897 for (i = 0; i < C->NbRows; i++)
898 AddLattice(Head, B1, B2, VALUE_TO_INT(C->p[i][i]), i);
899 return Head;
900} /* SplitLattice */
901
902/*
903 * Given lattices 'B1' and 'B2', an integer 'NumofTimes', a column number
904 * 'Colnumber' and a pointer to a list of lattices, the function does the
905 * following :-
906 * For every lattice in the list, it adds a set of lattices such that the
907 * affine part of the new lattices is greater than the original lattice by 0 to
908 * NumofTimes-1 * {the (ColumnNumber)-th column of B1}.
909 * Note :
910 * Three pointers are defined to point at various points of the list. They are:
911 * Head -> It always points to the head of the list.
912 * tail -> It always points to the last element in the list.
913 * marker -> It points to the element, which is the last element of the Input
914 * list.
915 */
916static void AddLattice(LatticeUnion *Head, Matrix *B1, Matrix *B2,
917 int NumofTimes, int Colnumber) {
918
919 LatticeUnion *temp, *tail, *marker;
920 int i, j;
921 Value tmp;
922
923 value_init(tmp);
924 tail = Head;
925 while (tail->next != NULL)
926 tail = tail->next;
927 marker = tail;
928
929 for (temp = Head; temp != NULL; temp = temp->next) {
930 for (i = 1; i < NumofTimes; i++) {
931 Lattice *tempMatrix, *H, *U;
932
933 tempMatrix = (Lattice *)Matrix_Copy(temp->M);
934 for (j = 0; j < B2->NbRows; j++) {
935 value_set_si(tmp, i);
936 value_addmul(tempMatrix->p[j][B2->NbColumns - 1], tmp,
937 B1->p[j][Colnumber]);
938 }
939 tail->next = (LatticeUnion *)malloc(sizeof(LatticeUnion));
940 AffineHermite(tempMatrix, &H, &U);
941 Matrix_Free((Matrix *)tempMatrix);
942 Matrix_Free(U);
943 tail->next->M = H;
944 tail->next->next = NULL;
945 tail = tail->next;
946 }
947 if (temp == marker)
948 break;
949 }
950 value_clear(tmp);
951 return;
952} /* AddLattice */
953
954/*
955 * Given a polyhedron 'A', store the Hermite basis 'B' and return the true
956 * dimension of the polyhedron 'A'.
957 * Algorithm :
958 *
959 * 1) First we find all the vertices of the Polyhedron A.
960 * Now suppose the vertices are [v1, v2...vn], then
961 * a particular set of vectors governing the space of A are
962 * given by [v1-v2, v1-v3, ... v1-vn] (let us say V).
963 * So we initially calculate these vectors.
964 * 2) Then there are the rays and lines which contribute to the
965 * space in which A is going to lie.
966 * So we append to the rays and lines. So now we get a matrix
967 * {These are the rows} [ V ] [l1] [l2]...[lk]
968 * where l1 to lk are either rays or lines of the Polyhedron A.
969 * 3) The above matrix is the set of vectors which determine
970 * the space in which A is going to lie.
971 * Using this matrix we find a Basis which is such that
972 * the first 'm' columns of it determine the space of A.
973 * 4) But we also have to ensure that in the last 'n-m'
974 * coordinates the Polyhedron is '0', this is done by
975 * taking the image by B(inv) of A and finding the remaining
976 * equalities, and composing it with the matrix B, so as
977 * to get a new matrix which is the actual Hermite Basis of
978 * the Polyhedron.
979 */
981
982 int i, j;
983 Matrix *temp, *temp1, *tempinv, *Newmat;
984 Matrix *vert, *rays, *result;
985 Polyhedron *Image;
986 int rank, equcount;
987 int noofvertices = 0, noofrays = 0;
988 int vercount, raycount;
989 Value lcm, fact;
990
991#ifdef DOMDEBUG
992 FILE *fp;
993 fp = fopen("_debug", "a");
994 fprintf(fp, "\nEntered FINDHERMITEBASISOFDOMAIN \n");
995 fclose(fp);
996#endif
997
1000
1001 /* Checking is empty */
1002 if (emptyQ(A)) {
1003 B[0] = Identity(A->Dimension + 1);
1004 return (-1);
1005 }
1006
1007 value_init(lcm);
1008 value_init(fact);
1009 value_set_si(lcm, 1);
1010
1011 /* Finding the Vertices */
1012 for (i = 0; i < A->NbRays; i++)
1013 if ((value_notzero_p(A->Ray[i][0])) &&
1014 value_notzero_p(A->Ray[i][A->Dimension + 1]))
1015 noofvertices++;
1016 else
1017 noofrays++;
1018
1019 vert = Matrix_Alloc(noofvertices, A->Dimension + 1);
1020 rays = Matrix_Alloc(noofrays, A->Dimension);
1021 vercount = 0;
1022 raycount = 0;
1023
1024 for (i = 0; i < A->NbRays; i++) {
1025 if ((value_notzero_p(A->Ray[i][0])) &&
1026 value_notzero_p(A->Ray[i][A->Dimension + 1])) {
1027 for (j = 1; j < A->Dimension + 2; j++)
1028 value_assign(vert->p[vercount][j - 1], A->Ray[i][j]);
1029 value_lcm(lcm, lcm, A->Ray[i][j - 1]);
1030 vercount++;
1031 } else {
1032 for (j = 1; j < A->Dimension + 1; j++)
1033 value_assign(rays->p[raycount][j - 1], A->Ray[i][j]);
1034 raycount++;
1035 }
1036 }
1037
1038 /* Multiplying the rows by the lcm */
1039 for (i = 0; i < vert->NbRows; i++) {
1040 value_division(fact, lcm, vert->p[i][vert->NbColumns - 1]);
1041 for (j = 0; j < vert->NbColumns - 1; j++)
1042 value_multiply(vert->p[i][j], vert->p[i][j], fact);
1043 }
1044
1045 /* Drop the Last Columns */
1046 temp = RemoveColumn(vert, vert->NbColumns - 1);
1047 Matrix_Free(vert);
1048
1049 /* Getting the Vectors */
1050 vert = Matrix_Alloc(temp->NbRows - 1, temp->NbColumns);
1051 for (i = 1; i < temp->NbRows; i++)
1052 for (j = 0; j < temp->NbColumns; j++)
1053 value_subtract(vert->p[i - 1][j], temp->p[0][j], temp->p[i][j]);
1054
1055 Matrix_Free(temp);
1056
1057 /* Add the Rays and Lines */
1058 /* Combined Matrix */
1059 result = Matrix_Alloc(vert->NbRows + rays->NbRows, vert->NbColumns);
1060 for (i = 0; i < vert->NbRows; i++)
1061 for (j = 0; j < result->NbColumns; j++)
1062 value_assign(result->p[i][j], vert->p[i][j]);
1063
1064 for (; i < result->NbRows; i++)
1065 for (j = 0; j < result->NbColumns; j++)
1066 value_assign(result->p[i][j], rays->p[i - vert->NbRows][j]);
1067
1068 Matrix_Free(vert);
1069 Matrix_Free(rays);
1070
1071 rank = findHermiteBasis(result, &temp);
1072 temp1 = ChangeLatticeDimension(temp, temp->NbRows + 1);
1073
1074 Matrix_Free(result);
1075 Matrix_Free(temp);
1076
1077 /* Adding the Affine Part to take care of the Equalities */
1078 temp = Matrix_Copy(temp1);
1079 tempinv = Matrix_Alloc(temp->NbRows, temp->NbColumns);
1080 Matrix_Inverse(temp, tempinv);
1081 Matrix_Free(temp);
1082 Image = DomainImage(A, tempinv, MAXNOOFRAYS);
1083 Matrix_Free(tempinv);
1084 Newmat = Matrix_Alloc(temp1->NbRows, temp1->NbColumns);
1085 for (i = 0; i < rank; i++)
1086 for (j = 0; j < Newmat->NbColumns; j++)
1087 value_set_si(Newmat->p[i][j], 0);
1088 for (i = 0; i < rank; i++)
1089 value_set_si(Newmat->p[i][i], 1);
1090 equcount = 0;
1091 for (i = 0; i < Image->NbConstraints; i++)
1092 if (value_zero_p(Image->Constraint[i][0])) {
1093 for (j = 1; j < Image->Dimension + 2; j++)
1094 value_assign(Newmat->p[rank + equcount][j - 1],
1095 Image->Constraint[i][j]);
1096 ++equcount;
1097 }
1098 Domain_Free(Image);
1099 for (i = 0; i < Newmat->NbColumns - 1; i++)
1100 value_set_si(Newmat->p[Newmat->NbRows - 1][i], 0);
1101 value_set_si(Newmat->p[Newmat->NbRows - 1][Newmat->NbColumns - 1], 1);
1102 temp = Matrix_Alloc(Newmat->NbRows, Newmat->NbColumns);
1103 Matrix_Inverse(Newmat, temp);
1104 Matrix_Free(Newmat);
1105 B[0] = Matrix_Alloc(temp1->NbRows, temp->NbColumns);
1106
1107 Matrix_Product(temp1, temp, B[0]);
1108 Matrix_Free(temp1);
1109 Matrix_Free(temp);
1110 value_clear(lcm);
1111 value_clear(fact);
1112 return rank;
1113} /* FindHermiteBasisofDomain */
1114
1115/*
1116 * Return the image of a lattice 'A' by the invertible, affine, rational
1117 * function 'M'.
1118 */
1120
1121 Lattice *Img, *temp, *Minv;
1122
1123#ifdef DOMDEBUG
1124 FILE *fp;
1125 fp = fopen("_debug", "a");
1126 fprintf(fp, "\nEntered LATTICEIMAGE \n");
1127 fclose(fp);
1128#endif
1129
1130 if ((A->NbRows != M->NbRows) || (M->NbRows != M->NbColumns))
1131 return (EmptyLattice(A->NbRows));
1132
1133 if (value_one_p(M->p[M->NbRows - 1][M->NbColumns - 1])) {
1134 Img = Matrix_Alloc(M->NbRows, A->NbColumns);
1135 Matrix_Product(M, A, Img);
1136 return Img;
1137 }
1138 temp = Matrix_Copy(M);
1139 Minv = Matrix_Alloc(temp->NbColumns, temp->NbRows);
1140 Matrix_Inverse(temp, Minv);
1141 Matrix_Free(temp);
1142
1143 Img = LatticePreimage(A, Minv);
1144 Matrix_Free(Minv);
1145 return Img;
1146} /* LatticeImage */
1147
1148/*
1149 * Return the preimage of a lattice 'L' by an affine, rational function 'G'.
1150 * Algorithm:
1151 * (1) Prepare Diophantine equation :
1152 * [Gl -Ll][x y] = [Ga -La]{"l-linear, a-affine"}
1153 * (2) Solve the Diophantine equations.
1154 * (3) If there is solution to the Diophantine eq., extract the
1155 * general solution and the particular solution of x and that
1156 * forms the preimage of 'L' by 'G'.
1157 */
1159
1160 Matrix *Dio, *U;
1161 Lattice *Result;
1162 Vector *X;
1163 int i, j;
1164 int rank;
1165 Value divisor, tmp;
1166
1167#ifdef DOMDEBUG
1168 FILE *fp;
1169 fp = fopen("_debug", "a");
1170 fprintf(fp, "\nEntered LATTICEPREIMAGE \n");
1171 fclose(fp);
1172#endif
1173
1174 /* Check for the validity of the function */
1175 if (G->NbRows != L->NbRows) {
1176 fprintf(stderr, "\nIn LatticePreimage: Incompatible types of Lattice and "
1177 "the function\n");
1178 return (EmptyLattice(G->NbColumns));
1179 }
1180
1181 value_init(divisor);
1182 value_init(tmp);
1183
1184 /* Making Diophantine Equations [g -L] */
1185 value_assign(divisor, G->p[G->NbRows - 1][G->NbColumns - 1]);
1186 Dio = Matrix_Alloc(G->NbRows, G->NbColumns + L->NbColumns - 1);
1187 for (i = 0; i < G->NbRows - 1; i++)
1188 for (j = 0; j < G->NbColumns - 1; j++)
1189 value_assign(Dio->p[i][j], G->p[i][j]);
1190
1191 for (i = 0; i < G->NbRows - 1; i++)
1192 for (j = 0; j < L->NbColumns - 1; j++) {
1193 value_multiply(tmp, divisor, L->p[i][j]);
1194 value_oppose(Dio->p[i][j + G->NbColumns - 1], tmp);
1195 }
1196
1197 for (i = 0; i < Dio->NbRows - 1; i++) {
1198 value_multiply(tmp, divisor, L->p[i][L->NbColumns - 1]);
1199 value_subtract(tmp, G->p[i][G->NbColumns - 1], tmp);
1200 value_assign(Dio->p[i][Dio->NbColumns - 1], tmp);
1201 }
1202 for (i = 0; i < Dio->NbColumns - 1; i++)
1203 value_set_si(Dio->p[Dio->NbRows - 1][i], 0);
1204
1205 value_set_si(Dio->p[Dio->NbRows - 1][Dio->NbColumns - 1], 1);
1206 rank = SolveDiophantine(Dio, &U, &X);
1207
1208 if (rank == -1)
1209 Result = EmptyLattice(G->NbColumns);
1210 else {
1211 Result = Matrix_Alloc(G->NbColumns, G->NbColumns);
1212 for (i = 0; i < Result->NbRows - 1; i++)
1213 for (j = 0; j < Result->NbColumns - 1; j++)
1214 value_assign(Result->p[i][j], U->p[i][j]);
1215
1216 for (i = 0; i < Result->NbRows - 1; i++)
1217 value_assign(Result->p[i][Result->NbColumns - 1], X->p[i]);
1218 Matrix_Free(U);
1219 Vector_Free(X);
1220 for (i = 0; i < Result->NbColumns - 1; i++)
1221 value_set_si(Result->p[Result->NbRows - 1][i], 0);
1222 value_set_si(Result->p[i][i], 1);
1223 }
1224 Matrix_Free(Dio);
1225 value_clear(divisor);
1226 value_clear(tmp);
1227 return Result;
1228} /* LatticePreimage */
1229
1230/*
1231 * Return True if the matrix 'm' is a valid lattice, otherwise return False.
1232 * Note: A valid lattice has the last row as [0 0 0 ... 1].
1233 */
1235
1236 int i;
1237
1238#ifdef DOMDEBUG
1239 FILE *fp;
1240 fp = fopen("_debug", "a");
1241 fprintf(fp, "\nEntered ISLATTICE \n");
1242 fclose(fp);
1243#endif
1244
1245 /* Is it necessary to check if the lattice
1246 is fulldimensional or not here only? */
1247
1248 if (m->NbRows != m->NbColumns)
1249 return False;
1250
1251 for (i = 0; i < m->NbColumns - 1; i++)
1252 if (value_notzero_p(m->p[m->NbRows - 1][i]))
1253 return False;
1254 if (value_notone_p(m->p[i][i]))
1255 return False;
1256 return True;
1257} /* IsLattice */
1258
1259/*
1260 * Check whether the matrix 'm' is full row-rank or not.
1261 */
1263
1264 Matrix *h, *u;
1265 int i;
1266
1267 /*
1268 res = Hermite (m, &h, &u);
1269 if (res != m->NbRows)
1270 return False ;
1271 */
1272
1273 Hermite(m, &h, &u);
1274 for (i = 0; i < h->NbRows; i++)
1275 if (value_zero_p(h->p[i][i])) {
1276 Matrix_Free(h);
1277 Matrix_Free(u);
1278 return False;
1279 }
1280 Matrix_Free(h);
1281 Matrix_Free(u);
1282 return True;
1283} /* isfulldim */
1284
1285/*
1286 * This function takes as input a lattice list in which the lattices have the
1287 * same linear part, and almost the same affinepart, i.e. if A and B are two
1288 * of the lattices in the above lattice list and [a1, .. , an] and [b1 .. bn]
1289 * are the affineparts of A and B respectively, then for 0 < i < n ai = bi and
1290 * 'an' may not be equal to 'bn'. These are not the affine parts in the n-th
1291 * dimension, but the lattices have been tranformed such that the value of the
1292 * elment in the dimension on which we are simplifying is in the last row and
1293 * also the lattices are in a sorted order.
1294 * This function also takes as input the dimension along which we
1295 * are simplifying and takes the diagonal element of the lattice along that
1296 * dimension and tries to find out the factors of that element and sees if the
1297 * list of lattices can be simplified using these factors. The output of this
1298 * function is the list of lattices in the simplified form and a flag to indic-
1299 * ate whether any form of simplification was actually done or not.
1300 */
1301static Bool Simplify(LatticeUnion **InputList, LatticeUnion **ResultList,
1302 int dim) {
1303
1304 int i;
1305 LatticeUnion *prev, *temp;
1306 factor allfac;
1307 Bool retval = False;
1308 int width;
1309 Value cnt, aux, k, fac, num, tmp, foobar;
1310
1311 if ((*InputList == NULL) || (InputList[0]->next == NULL))
1312 return False;
1313
1314 value_init(aux);
1315 value_init(cnt);
1316 value_init(k);
1317 value_init(fac);
1318 value_init(num);
1319 value_init(tmp);
1320 value_init(foobar);
1321
1322 width = InputList[0]->M->NbRows - 1;
1323 allfac = allfactors(VALUE_TO_INT(InputList[0]->M->p[dim][dim]));
1324 value_set_si(cnt, 0);
1325 for (temp = InputList[0]; temp != NULL; temp = temp->next)
1326 value_increment(cnt, cnt);
1327 for (i = 0; i < allfac.count; i++) {
1328 value_set_si(foobar, allfac.fac[i]);
1329 value_division(aux, InputList[0]->M->p[dim][dim], foobar);
1330 if (value_ge(cnt, aux))
1331 break;
1332 }
1333 if (i == allfac.count) {
1334 value_clear(cnt);
1335 value_clear(aux);
1336 value_clear(k);
1337 value_clear(fac);
1338 value_clear(num);
1339 value_clear(tmp);
1340 value_clear(foobar);
1341 return False;
1342 }
1343 for (; i < allfac.count; i++) {
1344 Bool Present = False;
1345 value_set_si(k, 0);
1346
1347 if (*InputList == NULL) {
1348 value_clear(cnt);
1349 value_clear(aux);
1350 value_clear(k);
1351 value_clear(fac);
1352 value_clear(num);
1353 value_clear(tmp);
1354 value_clear(foobar);
1355 return retval;
1356 }
1357 value_set_si(foobar, allfac.fac[i]);
1358 value_division(num, InputList[0]->M->p[dim][dim], foobar);
1359 while (value_lt(k, foobar)) {
1360 Present = False;
1361 value_assign(fac, k);
1362 for (temp = *InputList; temp != NULL; temp = temp->next) {
1363 if (value_eq(temp->M->p[temp->M->NbRows - 1][temp->M->NbColumns - 1],
1364 fac)) {
1365 value_set_si(foobar, allfac.fac[i]);
1366 value_addto(fac, fac, foobar);
1367 if (value_ge(fac, (*InputList)->M->p[dim][dim])) {
1368 Present = True;
1369 break;
1370 }
1371 }
1372 if (value_gt(temp->M->p[temp->M->NbRows - 1][temp->M->NbColumns - 1],
1373 fac))
1374 break;
1375 }
1376 if (Present == True) {
1377 retval = True;
1378 if (*ResultList == NULL)
1379 *ResultList = temp = (LatticeUnion *)malloc(sizeof(LatticeUnion));
1380 else {
1381 for (temp = *ResultList; temp->next != NULL; temp = temp->next)
1382 ;
1383 temp->next = (LatticeUnion *)malloc(sizeof(LatticeUnion));
1384 temp = temp->next;
1385 }
1386 temp->M = Matrix_Copy(InputList[0]->M);
1387 temp->next = NULL;
1388 value_set_si(foobar, allfac.fac[i]);
1389 value_assign(temp->M->p[dim][dim], foobar);
1390 value_assign(temp->M->p[dim][width], k);
1391 value_set_si(temp->M->p[width][width], 1);
1392
1393 /* Deleting the Lattices from the curlist */
1394 value_assign(tmp, k);
1395 prev = NULL;
1396 temp = InputList[0];
1397 while (temp != NULL) {
1398 if (value_eq(temp->M->p[width][width], tmp)) {
1399 if (temp == InputList[0]) {
1400 prev = temp;
1401 temp = InputList[0] = temp->next;
1402 Matrix_Free(prev->M);
1403 free(prev);
1404 } else {
1405 prev->next = temp->next;
1406 Matrix_Free(temp->M);
1407 free(temp);
1408 temp = prev->next;
1409 }
1410 value_set_si(foobar, allfac.fac[i]);
1411 value_addto(tmp, tmp, foobar);
1412 } else {
1413 prev = temp;
1414 temp = temp->next;
1415 }
1416 }
1417 }
1418 value_increment(k, k);
1419 }
1420 }
1421 value_clear(cnt);
1422 value_clear(aux);
1423 value_clear(k);
1424 value_clear(fac);
1425 value_clear(num);
1426 value_clear(tmp);
1427 value_clear(foobar);
1428 return retval;
1429} /* Simplify */
1430
1431/*
1432 * This function is used in the qsort function in sorting the lattices. Given
1433 * two lattices 'A' and 'B', both in HNF, where A = [ [a11 0], [a21, a22, 0] .
1434 * .... [an1, .., ann] ] and B = [ [b11 0], [b21, b22, 0] ..[bn1, .., bnn] ],
1435 * then A < B, if there exists a pair <i,j> such that [aij < bij] and for every
1436 * other pair <i1, j1>, 0<=i1<i, 0<=j1<j [ai1j1 = bi1j1].
1437 */
1438static int LinearPartCompare(const void *A, const void *B) {
1439
1440 Lattice **L1, **L2;
1441 int i, j;
1442
1443 L1 = (Lattice **)A;
1444 L2 = (Lattice **)B;
1445
1446 for (i = 0; i < L1[0]->NbRows - 1; i++)
1447 for (j = 0; j <= i; j++) {
1448 if (value_gt(L1[0]->p[i][j], L2[0]->p[i][j]))
1449 return 1;
1450 if (value_lt(L1[0]->p[i][j], L2[0]->p[i][j]))
1451 return -1;
1452 }
1453 return 0;
1454} /* LinearPartCompare */
1455
1456/*
1457 * This function takes as input a List of Lattices and sorts them on the basis
1458 * of their Linear parts. It sorts in place, as a result of which the input
1459 * list is modified to the sorted order.
1460 */
1461static void LinearPartSort(LatticeUnion *Head) {
1462
1463 int cnt;
1464 Lattice **Latlist;
1465 LatticeUnion *temp;
1466
1467 cnt = 0;
1468 for (temp = Head; temp != NULL; temp = temp->next)
1469 cnt++;
1470
1471 Latlist = (Lattice **)malloc(sizeof(Lattice *) * cnt);
1472
1473 cnt = 0;
1474 for (temp = Head; temp != NULL; temp = temp->next)
1475 Latlist[cnt++] = temp->M;
1476
1477 qsort(Latlist, cnt, sizeof(Lattice *), LinearPartCompare);
1478
1479 cnt = 0;
1480 for (temp = Head; temp != NULL; temp = temp->next)
1481 temp->M = Latlist[cnt++];
1482
1483 free(Latlist);
1484 return;
1485} /* LinearPartSort */
1486
1487/*
1488 * This function is used in 'AfiinePartSort' in sorting the lattices with the
1489 * same linear part. GIven two lattices 'A' and 'B' with affineparts [a1 .. an]
1490 * and [b1 ... bn], then A < B if for some 0 < i <= n, ai < bi and for 0 < i1 <
1491 * i, ai1 = bi1.
1492 */
1493static int AffinePartCompare(const void *A, const void *B) {
1494
1495 int i;
1496 Lattice **L1, **L2;
1497
1498 L1 = (Lattice **)A;
1499 L2 = (Lattice **)B;
1500
1501 for (i = 0; i < L1[0]->NbRows; i++) {
1502 if (value_gt(L1[0]->p[i][L1[0]->NbColumns - 1],
1503 L2[0]->p[i][L1[0]->NbColumns - 1]))
1504 return 1;
1505
1506 if (value_lt(L1[0]->p[i][L1[0]->NbColumns - 1],
1507 L2[0]->p[i][L1[0]->NbColumns - 1]))
1508 return -1;
1509 }
1510 return 0;
1511} /* AffinePartCompare */
1512
1513/*
1514 * This function takes a list of lattices with the same linear part and sorts
1515 * them on the basis of their affine part. The sorting is done in place.
1516 */
1517static void AffinePartSort(LatticeUnion *List) {
1518
1519 int cnt;
1520 Lattice **LatList;
1521 LatticeUnion *tmp;
1522
1523 cnt = 0;
1524 for (tmp = List; tmp != NULL; tmp = tmp->next)
1525 cnt++;
1526
1527 LatList = (Lattice **)malloc(sizeof(Lattice *) * cnt);
1528
1529 cnt = 0;
1530 for (tmp = List; tmp != NULL; tmp = tmp->next)
1531 LatList[cnt++] = tmp->M;
1532
1533 qsort(LatList, cnt, sizeof(Lattice *), AffinePartCompare);
1534
1535 cnt = 0;
1536 for (tmp = List; tmp != NULL; tmp = tmp->next)
1537 tmp->M = LatList[cnt++];
1538 return;
1539} /* AffinePartSort */
1540
1542
1543 int i;
1544
1545 if ((A == NULL) || (B == NULL))
1546 return False;
1547
1548 for (i = 0; i < A->M->NbRows - 1; i++)
1549 if (value_ne(A->M->p[i][A->M->NbColumns - 1],
1550 B->M->p[i][A->M->NbColumns - 1]))
1551 return False;
1552 return True;
1553} /* AlmostSameAffinePart */
1554
1555/*
1556 * This function takes a list of lattices having the same linear part and tries
1557 * to simplify these lattices. This may not be the only way of simplifying the
1558 * lattices. The function returns a list of partially simplified lattices and
1559 * also a flag to tell whether any simplification was performed at all.
1560 */
1562
1563 int i;
1564 Value aux;
1565 LatticeUnion *temp, *curr, *next;
1566 LatticeUnion *nextlist;
1567 Bool change = False, chng;
1568
1569 if (curlist == NULL)
1570 return False;
1571
1572 if (curlist->next == NULL) {
1573 curlist->next = newlist[0];
1574 newlist[0] = curlist;
1575 return False;
1576 }
1577
1578 value_init(aux);
1579 for (i = 0; i < curlist->M->NbRows - 1; i++) {
1580
1581 /* Interchanging the elements of the Affine part for easy computation
1582 of the sort (using qsort) */
1583
1584 for (temp = curlist; temp != NULL; temp = temp->next) {
1585 value_assign(aux,
1586 temp->M->p[temp->M->NbRows - 1][temp->M->NbColumns - 1]);
1587 value_assign(temp->M->p[temp->M->NbRows - 1][temp->M->NbColumns - 1],
1588 temp->M->p[i][temp->M->NbColumns - 1]);
1589 value_assign(temp->M->p[i][temp->M->NbColumns - 1], aux);
1590 }
1591 AffinePartSort(curlist);
1592 nextlist = NULL;
1593 curr = curlist;
1594 while (curr != NULL) {
1595 next = curr->next;
1596 if (!AlmostSameAffinePart(curr, next)) {
1597 curr->next = NULL;
1598 chng = Simplify(&curlist, newlist, i);
1599 if (nextlist == NULL)
1600 nextlist = curlist;
1601 else {
1602 LatticeUnion *tmp;
1603 for (tmp = nextlist; tmp->next; tmp = tmp->next)
1604 ;
1605 tmp->next = curlist;
1606 }
1607 change = (Bool)(change | chng);
1608 curlist = next;
1609 }
1610 curr = next;
1611 }
1612 curlist = nextlist;
1613
1614 /* Interchanging the elements of the Affine part for easy computation
1615 of the sort (using qsort) */
1616
1617 for (temp = curlist; temp != NULL; temp = temp->next) {
1618 value_assign(aux,
1619 temp->M->p[temp->M->NbRows - 1][temp->M->NbColumns - 1]);
1620 value_assign(temp->M->p[temp->M->NbRows - 1][temp->M->NbColumns - 1],
1621 temp->M->p[i][temp->M->NbColumns - 1]);
1622 value_assign(temp->M->p[i][temp->M->NbColumns - 1], aux);
1623 }
1624 if (curlist == NULL)
1625 break;
1626 }
1627 if (*newlist == NULL)
1628 *newlist = nextlist;
1629 else {
1630 for (curr = *newlist; curr->next != NULL; curr = curr->next)
1631 ;
1632 curr->next = nextlist;
1633 }
1634 value_clear(aux);
1635 return change;
1636} /* AffinePartSimplify */
1637
1639
1640 int i, j;
1641 if ((A == NULL) || (B == NULL))
1642 return False;
1643 for (i = 0; i < A->M->NbRows - 1; i++)
1644 for (j = 0; j <= i; j++)
1645 if (value_ne(A->M->p[i][j], B->M->p[i][j]))
1646 return False;
1647
1648 return True;
1649} /* SameLinearPart */
1650
1651/*
1652 * Given a union of lattices, return a simplified list of lattices.
1653 */
1655
1656 LatticeUnion *curlist, *nextlist;
1657 LatticeUnion *curr, *next;
1658 Bool change = True, chng;
1659
1660 curlist = latlist;
1661 while (change == True) {
1662 change = False;
1663 LinearPartSort(curlist);
1664 curr = curlist;
1665 nextlist = NULL;
1666 while (curr != NULL) {
1667 next = curr->next;
1668 if (!SameLinearPart(curr, next)) {
1669 curr->next = NULL;
1670 chng = AffinePartSimplify(curlist, &nextlist);
1671 change = (Bool)(change | chng);
1672 curlist = next;
1673 }
1674 curr = next;
1675 }
1676 curlist = nextlist;
1677 }
1678 return curlist;
1679} /* LatticeSimplify */
1680
1681int intcompare(const void *a, const void *b) {
1682
1683 int *i, *j;
1684
1685 i = (int *)a;
1686 j = (int *)b;
1687 if (*i > *j)
1688 return 1;
1689 if (*i < *j)
1690 return -1;
1691 return 0;
1692} /* intcompare */
1693
1694static int polylib_sqrt(int i);
1695static factor allfactors(int num) {
1696
1697 int i, j, tmp;
1698 int noofelmts = 1;
1699 int *list, *newlist;
1700 int count;
1701 factor result;
1702
1703 list = (int *)malloc(sizeof(int));
1704 list[0] = 1;
1705
1706 tmp = num;
1707 for (i = 2; i <= polylib_sqrt(tmp); i++) {
1708 if ((tmp % i) == 0) {
1709 if (noofelmts == 0) {
1710 list = (int *)malloc(sizeof(int));
1711 list[0] = i;
1712 noofelmts = 1;
1713 } else {
1714 newlist = (int *)malloc(sizeof(int) * 2 * noofelmts + 1);
1715 for (j = 0; j < noofelmts; j++)
1716 newlist[j] = list[j];
1717 newlist[j] = i;
1718 for (j = 0; j < noofelmts; j++)
1719 newlist[j + noofelmts + 1] = i * list[j];
1720 free(list);
1721 list = newlist;
1722 noofelmts = 2 * noofelmts + 1;
1723 }
1724 tmp = tmp / i;
1725 i = 1;
1726 }
1727 }
1728
1729 if ((tmp != 0) && (tmp != num)) {
1730 newlist = (int *)malloc(sizeof(int) * 2 * noofelmts + 1);
1731 for (j = 0; j < noofelmts; j++)
1732 newlist[j] = list[j];
1733 newlist[j] = tmp;
1734 for (j = 0; j < noofelmts; j++)
1735 newlist[j + noofelmts + 1] = tmp * list[j];
1736 free(list);
1737 list = newlist;
1738 noofelmts = 2 * noofelmts + 1;
1739 }
1740 qsort(list, noofelmts, sizeof(int), intcompare);
1741 count = 1;
1742 for (i = 1; i < noofelmts; i++)
1743 if (list[i] != list[i - 1])
1744 list[count++] = list[i];
1745 if (list[count - 1] == num)
1746 count--;
1747
1748 result.fac = (int *)malloc(sizeof(int) * count);
1749 result.count = count;
1750 for (i = 0; i < count; i++)
1751 result.fac[i] = list[i];
1752 free(list);
1753 return result;
1754} /* allfactors */
1755
1756static int polylib_sqrt(int i) {
1757
1758 int j;
1759 j = 0;
1760 i = i > 0 ? i : -i;
1761
1762 while (1) {
1763 if ((j * j) > i)
1764 break;
1765 else
1766 j++;
1767 }
1768 return (j - 1);
1769} /* polylib_sqrt */
Lattice * EmptyLattice(int dimension)
Definition: Lattice.c:77
LatticeUnion * LatticeUnion_Alloc(void)
Definition: Lattice.c:42
Lattice * ExtractLinearPart(Lattice *A)
Definition: Lattice.c:423
static void LinearPartSort(LatticeUnion *Head)
Definition: Lattice.c:1461
Bool IsLattice(Matrix *m)
Definition: Lattice.c:1234
static Matrix * MakeDioEqforInter(Matrix *A, Matrix *B)
Definition: Lattice.c:556
static Bool Simplify(LatticeUnion **InputList, LatticeUnion **ResultList, int dim)
Definition: Lattice.c:1301
static void AddLattice(LatticeUnion *, Matrix *, Matrix *, int, int)
Definition: Lattice.c:916
void AffineHermite(Lattice *A, Lattice **H, Matrix **U)
Definition: Lattice.c:158
LatticeUnion * LatticeDifference(Lattice *A, Lattice *B)
Method :
Definition: Lattice.c:802
Bool isLinear(Lattice *A)
Definition: Lattice.c:127
static factor allfactors(int num)
Definition: Lattice.c:1695
Bool sameAffinepart(Lattice *A, Lattice *B)
Definition: Lattice.c:56
static int AffinePartCompare(const void *A, const void *B)
Definition: Lattice.c:1493
Lattice * Homogenise(Lattice *A, Bool Forward)
Definition: Lattice.c:297
Bool isEmptyLattice(Lattice *A)
Definition: Lattice.c:100
static Bool SameLinearPart(LatticeUnion *A, LatticeUnion *B)
Definition: Lattice.c:1638
Lattice * ChangeLatticeDimension(Lattice *A, int dimension)
Definition: Lattice.c:393
LatticeUnion * Lattice2LatticeUnion(Lattice *X, Lattice *Y)
Definition: Lattice.c:662
static Bool AffinePartSimplify(LatticeUnion *curlist, LatticeUnion **newlist)
Definition: Lattice.c:1561
Lattice * LatticeIntersection(Lattice *X, Lattice *Y)
Definition: Lattice.c:459
Bool isfulldim(Matrix *m)
Definition: Lattice.c:1262
static Bool AlmostSameAffinePart(LatticeUnion *A, LatticeUnion *B)
Definition: Lattice.c:1541
static void AffinePartSort(LatticeUnion *List)
Definition: Lattice.c:1517
static int polylib_sqrt(int i)
Definition: Lattice.c:1756
int intcompare(const void *a, const void *b)
Definition: Lattice.c:1681
static int LinearPartCompare(const void *A, const void *B)
Definition: Lattice.c:1438
Bool LatticeIncludes(Lattice *A, Lattice *B)
Definition: Lattice.c:324
LatticeUnion * SplitLattice(Matrix *, Matrix *, Matrix *)
Definition: Lattice.c:889
LatticeUnion * LatticeSimplify(LatticeUnion *latlist)
Definition: Lattice.c:1654
void AffineSmith(Lattice *A, Lattice **U, Lattice **V, Lattice **Diag)
Definition: Lattice.c:203
Lattice * LatticePreimage(Lattice *L, Matrix *G)
Definition: Lattice.c:1158
void LatticeUnion_Free(LatticeUnion *Head)
Definition: Lattice.c:26
void PrintLatticeUnion(FILE *fp, char *format, LatticeUnion *Head)
Definition: Lattice.c:14
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
void PutRowLast(Matrix *X, int Rownumber)
Definition: Matop.c:170
void PutColumnLast(Matrix *X, int Columnnumber)
Definition: Matop.c:231
Matrix * Identity(unsigned size)
Definition: Matop.c:39
void PutRowFirst(Matrix *X, int Rownumber)
Definition: Matop.c:192
void PutColumnFirst(Matrix *X, int Columnnumber)
Definition: Matop.c:212
Matrix * RemoveColumn(Matrix *M, int Columnnumber)
Definition: Matop.c:323
int findHermiteBasis(Matrix *M, Matrix **Result)
Definition: Matop.c:344
Matrix * Matrix_Copy(Matrix const *Src)
Definition: Matop.c:98
void Smith(Matrix *A, Matrix **U, Matrix **V, Matrix **Product)
Smith : This function takes a Matrix A of dim n * l as its input and returns the three matrices U,...
Definition: NormalForms.c:621
void Hermite(Matrix *A, Matrix **H, Matrix **U)
Hermite : This function takes a Matrix as its input and finds its HNF ( Left form )
Definition: NormalForms.c:663
int SolveDiophantine(Matrix *M, Matrix **U, Vector **X)
Definition: SolveDio.c:64
#define value_oppose(ref, val)
Definition: arithmetique.h:552
#define value_gt(v1, v2)
Definition: arithmetique.h:504
#define value_notzero_p(val)
Definition: arithmetique.h:576
#define value_notone_p(val)
Definition: arithmetique.h:578
#define value_one_p(val)
Definition: arithmetique.h:577
#define value_lcm(ref, val1, val2)
Definition: arithmetique.h:557
#define value_decrement(ref, val)
Definition: arithmetique.h:546
#define value_ne(v1, v2)
Definition: arithmetique.h:503
#define value_zero_p(val)
Definition: arithmetique.h:575
#define value_assign(v1, v2)
Definition: arithmetique.h:482
#define value_increment(ref, val)
Definition: arithmetique.h:540
#define value_set_si(val, i)
Definition: arithmetique.h:483
#define value_addmul(ref, val1, val2)
Definition: arithmetique.h:539
#define value_eq(v1, v2)
Definition: arithmetique.h:502
#define value_clear(val)
Definition: arithmetique.h:485
#define value_division(ref, val1, val2)
Definition: arithmetique.h:547
#define value_multiply(ref, val1, val2)
Definition: arithmetique.h:543
#define value_print(Dst, fmt, val)
Definition: arithmetique.h:487
#define value_lt(v1, v2)
Definition: arithmetique.h:506
#define value_modulus(ref, val1, val2)
Definition: arithmetique.h:549
#define value_subtract(ref, val1, val2)
Definition: arithmetique.h:544
#define value_addto(ref, val1, val2)
Definition: arithmetique.h:537
#define value_ge(v1, v2)
Definition: arithmetique.h:505
#define value_neg_p(val)
Definition: arithmetique.h:572
#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
Polyhedron * DomainImage(Polyhedron *Pol, Matrix *Func, unsigned NbMaxConstrs)
Definition: polyhedron.c:4303
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
static int m
Definition: polyparam.c:274
struct LatticeUnion * next
Definition: types.h:222
Lattice * M
Definition: types.h:221
Definition: types.h:70
Value * p
Definition: types.h:72
Definition: Lattice.c:4
int * fac
Definition: Lattice.c:6
int count
Definition: Lattice.c:5
Definition: types.h:75
unsigned NbRows
Definition: types.h:76
Value ** p
Definition: types.h:77
unsigned NbColumns
Definition: types.h:76
Value ** Ray
Definition: types.h:96
unsigned Dimension
Definition: types.h:94
unsigned NbConstraints
Definition: types.h:94
unsigned NbRays
Definition: types.h:94
Value ** Constraint
Definition: types.h:95
#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
void Vector_Free(Vector *vector)
Definition: vector.c:162