2 #include <polylib/polylib.h>
10 static factor
allfactors (int num
);
13 * Print the contents of a list of Lattices 'Head'
15 void PrintLatticeUnion(FILE *fp
, char *format
, LatticeUnion
*Head
) {
19 for(temp
= Head
; temp
!= NULL
; temp
= temp
->next
)
20 Matrix_Print(fp
,format
,(Matrix
*)temp
->M
);
22 } /* PrintLatticeUnion */
25 * Free the memory allocated to a list of lattices 'Head'
27 void LatticeUnion_Free(LatticeUnion
*Head
) {
31 while (Head
!= NULL
) {
38 } /* LatticeUnion_Free */
41 * Allocate a heads for a list of Lattices
43 LatticeUnion
*LatticeUnion_Alloc(void) {
47 temp
= (LatticeUnion
*)malloc(sizeof(LatticeUnion
));
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
) {
63 fp
= fopen("_debug","a");
64 fprintf(fp
,"\nEntered SAMEAFFINEPART \n");
68 for (i
= 0; i
< A
->NbRows
; i
++)
69 if (value_ne(A
->p
[i
][A
->NbColumns
-1],B
->p
[i
][B
->NbColumns
-1]))
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]].
78 Lattice
*EmptyLattice(int dimension
) {
85 fp
= fopen ("_debug", "a");
86 fprintf (fp
, "\nEntered NULLATTICE \n");
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);
99 * Return True if Lattice 'A' is empty, otherwise return False.
101 Bool
isEmptyLattice (Lattice
*A
) {
107 fp
= fopen("_debug", "a");
108 fprintf(fp
,"\nEntered ISNULLATTICE \n");
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
])) {
117 if (value_one_p(A
->p
[i
][A
->NbColumns
-1])) {
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
) {
134 fp
= fopen ("_debug", "a");
135 fprintf (fp
, "\nEntered ISLINEAR \n");
139 for (i
= 0; i
< A
->NbRows
-1; i
++)
140 if (value_notzero_p(A
->p
[i
][A
->NbColumns
-1])) {
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'.
151 * 1) Check if the Lattice is Linear or not.
152 * 2) If it is not Linear, then Homogenise the Lattice.
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.
159 void AffineHermite (Lattice
*A
, Lattice
**H
, Matrix
**U
) {
166 fp
= fopen ("_debug", "a");
167 fprintf (fp
, "\nEntered AFFINEHERMITE \n");
171 if (isLinear(A
) == False
)
172 temp
= Homogenise(A
,True
);
175 temp
= (Lattice
*)Matrix_Copy(A
);
177 Hermite((Matrix
*)temp
,(Matrix
**) H
, U
);
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
);
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'.
197 * (1) Homogenise the Lattice.
199 * (3) The Smith Normal Form Delta must be Dehomogenised and also
200 * corresponding changes must be made to the Unimodular Matrices
202 * 4) Bring Delta into AffineSmith Form.
204 void AffineSmith(Lattice
*A
, Lattice
**U
, Lattice
**V
, Lattice
**Diag
) {
213 fp
= fopen("_debug", "a");
214 fprintf(fp
,"\nEntered AFFINESMITH \n");
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
++) {
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
);
278 value_clear(quo
); value_clear(rem
);
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
287 * (1) If Forward == True
288 * Put the last row first.
289 * Put the last columns first.
291 * Put the first row last.
292 * Put the first column last.
293 * (3) Return the result.
295 Lattice
*Homogenise(Lattice
*A
, Bool Forward
) {
301 fp
= fopen("_debug","a");
302 fprintf(fp
,"\nEntered HOMOGENISE \n");
306 result
= (Lattice
*)Matrix_Copy(A
);
307 if (Forward
== True
) {
308 PutColumnFirst((Matrix
*)result
, A
->NbColumns
-1);
309 PutRowFirst((Matrix
*)result
, result
->NbRows
-1);
312 PutColumnLast((Matrix
*)result
,0);
313 PutRowLast((Matrix
*)result
,0);
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
;
330 fp
= fopen("_debug", "a");
331 fprintf(fp
,"\nEntered LATTICE INCLUDES \n");
335 AffineHermite(A
,&HA
,&UA
);
336 temp
= LatticeIntersection(B
,HA
);
337 if (sameLattice(temp
, HA
) == True
)
340 Matrix_Free((Matrix
*)temp
);
341 Matrix_Free((Matrix
*)UA
);
342 Matrix_Free((Matrix
*)HA
);
344 } /* LatticeIncludes */
347 * Given two lattices 'A' and 'B', verify if 'A' and 'B' are the same lattice.
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
354 Bool
sameLattice(Lattice
*A
, Lattice
*B
) {
356 Lattice
*HA
, *HB
, *UA
, *UB
;
362 fp
= fopen("_debug", "a");
363 fprintf(fp
,"\nEntered SAME LATTICE \n");
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
])) {
377 Matrix_Free ((Matrix
*) HA
);
378 Matrix_Free ((Matrix
*) HB
);
379 Matrix_Free ((Matrix
*) UA
);
380 Matrix_Free ((Matrix
*) UB
);
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
) {
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
]);
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);
416 } /* ChangeLatticeDimension */
419 * Given an affine lattice 'A', return a matrix of the linear part of the
422 Lattice
*ExtractLinearPart(Lattice
*A
) {
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
]);
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.
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
) {
461 Lattice
*result
= NULL
, *U
= NULL
;
462 Lattice
*A
= NULL
, *B
= NULL
, *H
= NULL
;
468 fp
= fopen("_debug", "a");
469 fprintf(fp
,"\nEntered LATTICEINTERSECTION \n");
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
);
489 A
= (Lattice
*) Matrix_Copy(X
);
491 AffineHermite(X
, &H
, &U
);
492 A
= (Lattice
*)Matrix_Copy (H
);
493 Matrix_Free((Matrix
*) H
);
494 Matrix_Free((Matrix
*) U
);
498 B
= (Lattice
*)Matrix_Copy(Y
);
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
);
512 fordio
= MakeDioEqforInter (A
, B
);
515 exist
= SolveDiophantine(fordio
,(Matrix
**) &U
, &X1
);
516 if (exist
< 0) { /* Intersection is NULL */
517 result
= (EmptyLattice(X
->NbRows
));
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
);
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
));
550 } /* LatticeIntersection */
552 static Matrix
* MakeDioEqforInter (Lattice
*A
, Lattice
*B
) {
559 fp
= fopen("_debug", "a");
560 fprintf(fp
,"\nEntered MAKEDIOEQFORINTER \n");
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);
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
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
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
;
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");
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
);
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
);
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
);
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);
701 newB2
= ChangeLatticeDimension(B2
, B2
->NbRows
+1);
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
);
707 Matrix_Free(DiagMatrix
);
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.
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).
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
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
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.
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
;
805 fp
= fopen("_debug", "a");
806 fprintf(fp
,"\nEntered LATTICEDIFFERENCE \n");
810 if (A
->NbRows
!= A
->NbColumns
) {
811 fprintf(stderr
,"\nIn LatticeDifference : The Input Matrix A is not a proper Lattice \n");
815 if (B
->NbRows
!= B
->NbColumns
) {
816 fprintf(stderr
,"\nIn LatticeDifference : The Input Matrix B is not a proper Lattice \n");
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");
826 if (isinHnf (A
) != True
) {
827 AffineHermite(A
,&H
,&U1
);
835 if (isinHnf(B
) != True
) {
836 AffineHermite(B
,&H
,&U1
);
843 if (isEmptyLattice(X
)) {
847 Head
=Lattice2LatticeUnion(X
,Y
);
849 /* If the spliting operation can't be done the result is X. */
852 Head
= (LatticeUnion
*)malloc(sizeof(LatticeUnion
));
853 Head
->M
= Matrix_Copy(X
);
862 Matrix_Free (tempHead
->M
);
863 tempHead
->next
= NULL
;
867 Head
= LatticeSimplify (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
) {
888 LatticeUnion
*Head
= NULL
;
889 Head
= (LatticeUnion
*)malloc(sizeof(LatticeUnion
));
890 Head
->M
= (Lattice
*)B2
;
892 for (i
= 0; i
< C
->NbRows
; i
++)
893 AddLattice(Head
,B1
,B2
,VALUE_TO_INT(C
->p
[i
][i
]),i
);
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
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}.
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
911 static void AddLattice (LatticeUnion
*Head
, Matrix
*B1
, Matrix
*B2
, int NumofTimes
, int Colnumber
) {
913 LatticeUnion
*temp
, *tail
, *marker
;
919 while (tail
->next
!= NULL
)
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
++) {
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
);
937 tail
->next
->next
=NULL
;
948 * Given a polyhedron 'A', store the Hermite basis 'B' and return the true
949 * dimension of the polyhedron 'A'.
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
973 int FindHermiteBasisofDomain(Polyhedron
*A
, Matrix
**B
) {
976 Matrix
*temp
,*temp1
, *tempinv
, *Newmat
;
977 Matrix
*vert
, *rays
, *result
;
980 int noofvertices
= 0, noofrays
= 0;
981 int vercount
, raycount
;
986 fp
= fopen("_debug", "a");
987 fprintf(fp
,"\nEntered FINDHERMITEBASISOFDOMAIN \n");
991 POL_ENSURE_FACETS(A
);
992 POL_ENSURE_VERTICES(A
);
994 /* Checking is empty */
996 B
[0] = Identity(A
->Dimension
+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]))
1010 vert
= Matrix_Alloc(noofvertices
,A
->Dimension
+1);
1011 rays
= Matrix_Alloc(noofrays
,A
->Dimension
);
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]);
1023 for (j
= 1; j
< A
->Dimension
+1; j
++)
1024 value_assign(rays
->p
[raycount
][j
-1],A
->Ray
[i
][j
]);
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);
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
]);
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
]);
1062 rank
= findHermiteBasis(result
, &temp
);
1063 temp1
= ChangeLatticeDimension(temp
,temp
->NbRows
+1);
1065 Matrix_Free(result
);
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
);
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);
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
]);
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]);
1103 } /* FindHermiteBasisofDomain */
1106 * Return the image of a lattice 'A' by the invertible, affine, rational
1109 Lattice
*LatticeImage(Lattice
*A
, Matrix
*M
) {
1111 Lattice
*Img
, *temp
, *Minv
;
1115 fp
= fopen("_debug", "a");
1116 fprintf(fp
, "\nEntered LATTICEIMAGE \n");
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
);
1128 temp
= Matrix_Copy(M
);
1129 Minv
= Matrix_Alloc(temp
->NbColumns
, temp
->NbRows
);
1130 Matrix_Inverse(temp
, Minv
);
1133 Img
= LatticePreimage(A
, Minv
);
1136 } /* LatticeImage */
1139 * Return the preimage of a lattice 'L' by an affine, rational function 'G'.
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
) {
1159 fp
= fopen("_debug", "a");
1160 fprintf(fp
,"\nEntered LATTICEPREIMAGE \n");
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
);
1197 Result
= EmptyLattice(G
->NbColumns
);
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
]);
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);
1213 value_clear(divisor
);
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
) {
1228 fp
= fopen ("_debug", "a");
1229 fprintf (fp
, "\nEntered ISLATTICE \n");
1233 /* Is it necessary to check if the lattice
1234 is fulldimensional or not here only? */
1236 if (m
->NbRows
!= m
->NbColumns
)
1239 for (i
= 0; i
< m
->NbColumns
-1; i
++)
1240 if (value_notzero_p(m
->p
[m
->NbRows
-1][i
]))
1242 if (value_notone_p(m
->p
[i
][i
]))
1248 * Check whether the matrix 'm' is full row-rank or not.
1250 Bool
isfulldim(Matrix
*m
) {
1256 res = Hermite (m, &h, &u);
1257 if (res != m->NbRows)
1262 for (i
= 0; i
< h
->NbRows
; i
++)
1263 if (value_zero_p(h
->p
[i
][i
])) {
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
) {
1292 LatticeUnion
*prev
, *temp
;
1294 Bool retval
= False
;
1296 Value cnt
, aux
, k
, fac
, num
, tmp
, foobar
;
1298 if ((*InputList
== NULL
) || (InputList
[0]->next
== NULL
))
1301 value_init(aux
); value_init(cnt
);
1302 value_init(k
); value_init(fac
);
1303 value_init(num
); value_init(tmp
);
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
))
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
);
1324 for (; i
< allfac
.count
; i
++) {
1325 Bool Present
= False
;
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
);
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
)) {
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
])) {
1349 if (value_gt(temp
->M
->p
[temp
->M
->NbRows
-1][temp
->M
->NbColumns
-1],fac
))
1352 if (Present
== True
) {
1354 if (*ResultList
== NULL
)
1355 *ResultList
= temp
= (LatticeUnion
*)malloc(sizeof(LatticeUnion
));
1357 for (temp
= *ResultList
; temp
->next
!= NULL
; temp
= temp
->next
);
1358 temp
->next
= (LatticeUnion
*) malloc (sizeof (LatticeUnion
));
1361 temp
->M
= Matrix_Copy(InputList
[0]->M
);
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
);
1371 temp
= InputList
[0];
1372 while (temp
!= NULL
) {
1373 if (value_eq(temp
->M
->p
[width
][width
],tmp
)) {
1374 if (temp
== InputList
[0]) {
1376 temp
= InputList
[0] = temp
->next
;
1377 Matrix_Free(prev
->M
);
1381 prev
->next
= temp
->next
;
1382 Matrix_Free(temp
->M
);
1386 value_set_si(foobar
,allfac
.fac
[i
]);
1387 value_addto(tmp
,tmp
,foobar
);
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
);
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
) {
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
]))
1424 if (value_lt(L1
[0]->p
[i
][j
],L2
[0]->p
[i
][j
]))
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
) {
1439 LatticeUnion
*temp
;
1442 for (temp
= Head
; temp
!= NULL
; temp
= temp
->next
)
1445 Latlist
= (Lattice
**) malloc ( sizeof (Lattice
*) * cnt
);
1448 for (temp
= Head
; temp
!= NULL
; temp
= temp
->next
)
1449 Latlist
[cnt
++] = temp
->M
;
1451 qsort(Latlist
, cnt
, sizeof(Lattice
*), LinearPartCompare
);
1454 for (temp
= Head
; temp
!= NULL
; temp
= temp
->next
)
1455 temp
->M
= Latlist
[cnt
++];
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 <
1467 static int AffinePartCompare(const void *A
, const void *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]))
1479 if (value_lt(L1
[0]->p
[i
][L1
[0]->NbColumns
-1],L2
[0]->p
[i
][L1
[0]->NbColumns
-1]))
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
) {
1496 for (tmp
= List
; tmp
!= NULL
; tmp
= tmp
->next
)
1499 LatList
= (Lattice
**) malloc (sizeof(Lattice
*) * cnt
);
1502 for (tmp
= List
; tmp
!= NULL
; tmp
= tmp
->next
)
1503 LatList
[cnt
++] = tmp
->M
;
1505 qsort(LatList
,cnt
, sizeof (Lattice
*), AffinePartCompare
);
1508 for (tmp
= List
; tmp
!= NULL
; tmp
= tmp
->next
)
1509 tmp
->M
= LatList
[cnt
++];
1511 } /* AffinePartSort */
1513 static Bool
AlmostSameAffinePart(LatticeUnion
*A
, LatticeUnion
*B
) {
1517 if ((A
== NULL
) || (B
== NULL
))
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]))
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
) {
1536 LatticeUnion
*temp
, *curr
, *next
;
1537 LatticeUnion
*nextlist
;
1538 Bool change
= False
, chng
;
1540 if (curlist
== NULL
)
1543 if (curlist
->next
== NULL
) {
1544 curlist
->next
= newlist
[0];
1545 newlist
[0] = curlist
;
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
);
1563 while (curr
!= NULL
) {
1565 if (!AlmostSameAffinePart(curr
, next
)) {
1567 chng
= Simplify(&curlist
, newlist
, i
);
1568 if (nextlist
== NULL
)
1572 for (tmp
= nextlist
; tmp
->next
; tmp
=tmp
->next
);
1573 tmp
->next
= curlist
;
1575 change
= (Bool
)(change
| chng
);
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
)
1593 if ( *newlist
== NULL
)
1594 *newlist
= nextlist
;
1596 for (curr
= *newlist
; curr
->next
!= NULL
; curr
= curr
->next
);
1597 curr
->next
= nextlist
;
1601 } /* AffinePartSimplify */
1603 static Bool
SameLinearPart(LatticeUnion
*A
, LatticeUnion
*B
) {
1606 if ((A
== NULL
) || (B
==NULL
))
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
]))
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
;
1626 while (change
== True
) {
1628 LinearPartSort(curlist
);
1631 while(curr
!= NULL
) {
1633 if (!SameLinearPart(curr
, next
)) {
1635 chng
= AffinePartSimplify(curlist
, &nextlist
);
1636 change
= (Bool
)(change
| chng
);
1644 } /* LatticeSimplify */
1646 int intcompare (const void *a
, const void *b
) {
1659 static int polylib_sqrt(int i
);
1660 static factor
allfactors (int num
) {
1664 int *list
, *newlist
;
1668 list
= (int *)malloc(sizeof (int));
1672 for (i
= 2; i
<= polylib_sqrt(tmp
); i
++) {
1673 if ((tmp
% i
) == 0) {
1674 if (noofelmts
== 0) {
1675 list
= (int *) malloc (sizeof (int));
1680 newlist
= (int *) malloc (sizeof (int) * 2 * noofelmts
+ 1);
1681 for (j
= 0; j
< noofelmts
; j
++)
1682 newlist
[j
] = list
[j
] ;
1684 for (j
= 0; j
< noofelmts
; j
++)
1685 newlist
[j
+noofelmts
+1] = i
* list
[j
];
1688 noofelmts
= 2*noofelmts
+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
] ;
1700 for (j
= 0; j
< noofelmts
; j
++)
1701 newlist
[j
+noofelmts
+1] = tmp
* list
[j
];
1704 noofelmts
= 2*noofelmts
+1;
1706 qsort (list
, noofelmts
, sizeof(int), intcompare
);
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
)
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
];
1722 static int polylib_sqrt (int i
) {
1735 } /* polylib_sqrt */