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