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