00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdlib.h>
00019 #include <polylib/polylib.h>
00020
00021
00022 typedef struct {
00023 int count;
00024 int *fac;
00025 } factor;
00026
00027 static factor allfactors (int num);
00028
00029
00030
00031
00032 void PrintLatticeUnion(FILE *fp, char *format, LatticeUnion *Head) {
00033
00034 LatticeUnion *temp;
00035
00036 for(temp = Head; temp != NULL; temp = temp->next)
00037 Matrix_Print(fp,format,(Matrix *)temp->M);
00038 return;
00039 }
00040
00041
00042
00043
00044 void LatticeUnion_Free(LatticeUnion *Head) {
00045
00046 LatticeUnion *temp;
00047
00048 while (Head != NULL) {
00049 temp = Head;
00050 Head = temp->next;
00051 Matrix_Free(temp->M);
00052 free(temp);
00053 }
00054 return;
00055 }
00056
00057
00058
00059
00060 LatticeUnion *LatticeUnion_Alloc(void) {
00061
00062 LatticeUnion *temp;
00063
00064 temp = (LatticeUnion *)malloc(sizeof(LatticeUnion));
00065 temp->M=NULL;
00066 temp->next=NULL;
00067 return temp;
00068 }
00069
00070
00071
00072
00073
00074 Bool sameAffinepart (Lattice *A, Lattice *B) {
00075
00076 int i;
00077
00078 #ifdef DOMDEBUG
00079 FILE *fp;
00080 fp = fopen("_debug","a");
00081 fprintf(fp,"\nEntered SAMEAFFINEPART \n");
00082 fclose(fp);
00083 #endif
00084
00085 for (i = 0; i < A->NbRows; i ++)
00086 if (value_ne(A->p[i][A->NbColumns-1],B->p[i][B->NbColumns-1]))
00087 return False;
00088 return True;
00089 }
00090
00091
00092
00093
00094
00095 Lattice *EmptyLattice(int dimension) {
00096
00097 Lattice *result;
00098 int i,j;
00099
00100 #ifdef DOMDEBUG
00101 FILE *fp;
00102 fp = fopen ("_debug", "a");
00103 fprintf (fp, "\nEntered NULLATTICE \n");
00104 fclose (fp);
00105 #endif
00106
00107 result = (Lattice *) Matrix_Alloc(dimension, dimension);
00108 for (i = 0; i < dimension; i ++)
00109 for (j = 0; j < dimension; j ++)
00110 value_set_si(result->p[i][j],0);
00111 value_set_si(result->p[i-1][i-1],1);
00112 return result;
00113 }
00114
00115
00116
00117
00118 Bool isEmptyLattice (Lattice *A) {
00119
00120 int i,j;
00121
00122 #ifdef DOMDEBUG
00123 FILE *fp;
00124 fp = fopen("_debug", "a");
00125 fprintf(fp,"\nEntered ISNULLATTICE \n");
00126 fclose(fp);
00127 #endif
00128
00129 for (i = 0; i < A->NbRows-1; i ++)
00130 for (j = 0; j < A->NbColumns-1; j ++)
00131 if(value_notzero_p(A->p[i][j])) {
00132 return False;
00133 }
00134 if (value_one_p(A->p[i][A->NbColumns-1])) {
00135 return True ;
00136 }
00137 return False ;
00138 }
00139
00140
00141
00142
00143
00144
00145 Bool isLinear(Lattice *A) {
00146
00147 int i;
00148
00149 #ifdef DOMDEBUG
00150 FILE *fp;
00151 fp = fopen ("_debug", "a");
00152 fprintf (fp, "\nEntered ISLINEAR \n");
00153 fclose (fp);
00154 #endif
00155
00156 for (i = 0; i < A->NbRows-1; i ++)
00157 if (value_notzero_p(A->p[i][A->NbColumns-1])) {
00158 return False;
00159 }
00160 return True;
00161 }
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 void AffineHermite (Lattice *A, Lattice **H, Matrix **U) {
00177
00178 Lattice *temp;
00179 Bool flag = True;
00180
00181 #ifdef DOMDEBUG
00182 FILE *fp;
00183 fp = fopen ("_debug", "a");
00184 fprintf (fp, "\nEntered AFFINEHERMITE \n");
00185 fclose (fp);
00186 #endif
00187
00188 if (isLinear(A) == False)
00189 temp = Homogenise(A,True);
00190 else {
00191 flag = False ;
00192 temp = (Lattice *)Matrix_Copy(A);
00193 }
00194 Hermite((Matrix *)temp,(Matrix **) H, U);
00195 if (flag == True) {
00196 Matrix_Free ((Matrix *) temp);
00197 temp = Homogenise(H[0],False);
00198 Matrix_Free((Matrix *) H[0]);
00199 H[0] = (Lattice *)Matrix_Copy(temp);
00200 Matrix_Free((Matrix *) temp);
00201 temp = Homogenise(U[0],False);
00202 Matrix_Free ((Matrix *) U[0]);
00203 U[0] = (Matrix *)Matrix_Copy(temp);
00204 }
00205 Matrix_Free((Matrix *) temp);
00206 return;
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 void AffineSmith(Lattice *A, Lattice **U, Lattice **V, Lattice **Diag) {
00222
00223 Lattice *temp;
00224 Lattice *Uinv;
00225 int i,j;
00226 Value sum, quo, rem;
00227
00228 #ifdef DOMDEBUG
00229 FILE *fp;
00230 fp = fopen("_debug", "a");
00231 fprintf(fp,"\nEntered AFFINESMITH \n");
00232 fclose(fp);
00233 #endif
00234
00235 value_init(sum);
00236 value_init(quo); value_init(rem);
00237 temp = Homogenise(A,True);
00238 Smith((Matrix *)temp, (Matrix **)U, (Matrix **)V, (Matrix **)Diag);
00239 Matrix_Free((Matrix *)temp);
00240
00241 temp = Homogenise (*U, False);
00242 Matrix_Free ((Matrix *) *U);
00243 *U = (Lattice *)Matrix_Copy ((Matrix *)temp);
00244 Matrix_Free ((Matrix *)temp);
00245
00246 temp = Homogenise (*V, False);
00247 Matrix_Free ((Matrix *)*V);
00248 *V = (Lattice *) Matrix_Copy ((Matrix *)temp);
00249 Matrix_Free ((Matrix *)temp);
00250
00251 temp = Homogenise (*Diag, False);
00252 Matrix_Free ((Matrix *)*Diag);
00253 *Diag = (Lattice *)Matrix_Copy ((Matrix *)temp);
00254 Matrix_Free ((Matrix *)temp);
00255
00256 temp = (Lattice *) Matrix_Copy ((Matrix *) *U);
00257 Uinv = (Lattice *) Matrix_Alloc (U[0]->NbRows, U[0]->NbColumns);
00258 Matrix_Inverse( (Matrix *) temp, (Matrix *) Uinv);
00259 Matrix_Free ((Matrix *) temp);
00260
00261 for (i = 0; i < U[0]->NbRows-1; i ++) {
00262 value_set_si(sum,0);
00263 for(j = 0; j < U[0]->NbColumns-1; j ++) {
00264 value_addmul(sum, Uinv->p[i][j], U[0]->p[j][U[0]->NbColumns-1]);
00265 }
00266 value_assign(Diag[0]->p[i][j],sum);
00267 }
00268 Matrix_Free((Matrix *) Uinv);
00269 for(i = 0; i < U[0]->NbRows-1; i ++)
00270 value_set_si(U[0]->p[i][U[0]->NbColumns-1],0);
00271 for(i = 0; i < Diag[0]->NbRows-1; i ++) {
00272 value_division(quo,Diag[0]->p[i][Diag[0]->NbColumns-1],Diag[0]->p[i][i]);
00273 value_modulus(rem,Diag[0]->p[i][Diag[0]->NbColumns-1],Diag[0]->p[i][i]);
00274
00275 fprintf(stdout," pourcent ");
00276 value_print(stdout,VALUE_FMT,rem);
00277 fprintf(stdout," quotient ");
00278 value_print(stdout,VALUE_FMT,quo);
00279 fprintf(stdout," \n");
00280
00281
00282 if(value_neg_p(rem)) {
00283 value_addto(rem,rem,Diag[0]->p[i][i]);
00284 value_decrement(quo,quo);
00285 };
00286 fprintf(stdout,"apres pourcent ");
00287 value_print(stdout,VALUE_FMT,rem);
00288 fprintf(stdout," quotient ");
00289 value_print(stdout,VALUE_FMT,quo);
00290 fprintf(stdout," \n");
00291 value_assign( Diag[0]->p[i][Diag[0]->NbColumns-1],rem);
00292 value_assign(V[0]->p[i][V[0]->NbColumns-1],quo);
00293 }
00294 value_clear(sum);
00295 value_clear(quo); value_clear(rem);
00296 return;
00297 }
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 Lattice *Homogenise(Lattice *A, Bool Forward) {
00313
00314 Lattice *result;
00315
00316 #ifdef DOMDEBUG
00317 FILE *fp;
00318 fp = fopen("_debug","a");
00319 fprintf(fp,"\nEntered HOMOGENISE \n");
00320 fclose(fp);
00321 #endif
00322
00323 result = (Lattice *)Matrix_Copy(A);
00324 if (Forward == True ) {
00325 PutColumnFirst((Matrix *)result, A->NbColumns-1);
00326 PutRowFirst((Matrix *)result, result->NbRows-1);
00327 }
00328 else {
00329 PutColumnLast((Matrix *)result,0);
00330 PutRowLast((Matrix *)result,0);
00331 }
00332 return result;
00333 }
00334
00335
00336
00337
00338
00339
00340 Bool LatticeIncludes(Lattice *A, Lattice *B) {
00341
00342 Lattice *temp, *UA, *HA;
00343 Bool flag = False;
00344
00345 #ifdef DOMDEBUG
00346 FILE *fp;
00347 fp = fopen("_debug", "a");
00348 fprintf(fp,"\nEntered LATTICE INCLUDES \n");
00349 fclose(fp);
00350 #endif
00351
00352 AffineHermite(A,&HA,&UA);
00353 temp = LatticeIntersection(B,HA);
00354 if (sameLattice(temp, HA) == True)
00355 flag = True;
00356
00357 Matrix_Free((Matrix *)temp);
00358 Matrix_Free((Matrix *)UA);
00359 Matrix_Free((Matrix *)HA);
00360 return flag;
00361 }
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 Bool sameLattice(Lattice *A, Lattice *B) {
00372
00373 Lattice *HA, *HB, *UA, *UB;
00374 int i,j;
00375 Bool result = True;
00376
00377 #ifdef DOMDEBUG
00378 FILE *fp;
00379 fp = fopen("_debug", "a");
00380 fprintf(fp,"\nEntered SAME LATTICE \n");
00381 fclose(fp);
00382 #endif
00383
00384 AffineHermite(A, &HA, &UA);
00385 AffineHermite(B, &HB, &UB);
00386
00387 for (i = 0 ; i < A->NbRows; i ++)
00388 for (j = 0; j < A->NbColumns; j ++)
00389 if (value_ne(HA->p[i][j],HB->p[i][j])) {
00390 result = False;
00391 break;
00392 }
00393
00394 Matrix_Free ((Matrix *) HA);
00395 Matrix_Free ((Matrix *) HB);
00396 Matrix_Free ((Matrix *) UA);
00397 Matrix_Free ((Matrix *) UB);
00398
00399 return result;
00400 }
00401
00402
00403
00404
00405
00406
00407
00408
00409 Lattice *ChangeLatticeDimension(Lattice *A, int dimension) {
00410
00411 int i, j;
00412 Lattice *Result ;
00413
00414 Result = Matrix_Alloc(dimension, dimension);
00415 if(dimension <= A->NbRows) {
00416 for (i = 0; i < dimension; i ++)
00417 for (j = 0; j < dimension; j ++)
00418 value_assign(Result->p[i][j],A->p[i][j]);
00419 return Result;
00420 }
00421 for (i = 0; i < A->NbRows; i ++)
00422 for (j = 0; j < A->NbRows; j ++)
00423 value_assign(Result->p[i][j],A->p[i][j]);
00424
00425 for (i = A->NbRows; i < dimension; i ++)
00426 for (j = 0; j < dimension; j ++) {
00427 value_set_si(Result->p[i][j],0);
00428 value_set_si(Result->p[j][i],0);
00429 }
00430 for (i = A->NbRows; i < dimension; i ++)
00431 value_set_si(Result->p[i][i],1);
00432 return Result;
00433 }
00434
00435
00436
00437
00438
00439 Lattice *ExtractLinearPart(Lattice *A) {
00440
00441 Lattice *Result;
00442 int i, j;
00443 Result = (Lattice *) Matrix_Alloc(A->NbRows-1, A->NbColumns-1);
00444 for (i = 0; i < A->NbRows-1; i ++)
00445 for (j = 0; j < A->NbColumns-1; j ++)
00446 value_assign(Result->p[i][j],A->p[i][j]);
00447 return Result;
00448 }
00449
00450 static Matrix *MakeDioEqforInter(Matrix *A, Matrix *B);
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 Lattice *LatticeIntersection(Lattice *X, Lattice *Y) {
00476
00477 int i, j, exist;
00478 Lattice *result = NULL, *U = NULL ;
00479 Lattice *A = NULL, *B = NULL, *H = NULL;
00480 Matrix *fordio;
00481 Vector *X1 = NULL;
00482
00483 #ifdef DOMDEBUG
00484 FILE *fp;
00485 fp = fopen("_debug", "a");
00486 fprintf(fp,"\nEntered LATTICEINTERSECTION \n");
00487 fclose(fp);
00488 #endif
00489
00490 if (X->NbRows != X->NbColumns) {
00491 fprintf(stderr, "\nIn LatticeIntersection : The Input Matrix X is a not a well defined Lattice\n");
00492 return EmptyLattice(X->NbRows);
00493 }
00494
00495 if (Y->NbRows != Y->NbColumns) {
00496 fprintf (stderr, "\nIn LatticeIntersection : The Input Matrix Y is a not a well defined Lattice\n");
00497 return EmptyLattice(X->NbRows);
00498 }
00499
00500 if (Y->NbRows != X->NbRows) {
00501 fprintf (stderr, "\nIn LatticeIntersection : the input lattices X and Y are of incompatible dimensions\n");
00502 return EmptyLattice(X->NbRows);
00503 }
00504
00505 if (isinHnf(X))
00506 A = (Lattice *) Matrix_Copy(X);
00507 else {
00508 AffineHermite(X, &H, &U);
00509 A = (Lattice *)Matrix_Copy (H);
00510 Matrix_Free((Matrix *) H);
00511 Matrix_Free((Matrix *) U);
00512 }
00513
00514 if (isinHnf(Y))
00515 B = (Lattice *)Matrix_Copy(Y);
00516 else {
00517 AffineHermite(Y, &H, &U);
00518 B = (Lattice *)Matrix_Copy (H);
00519 Matrix_Free((Matrix *) H);
00520 Matrix_Free((Matrix *) U);
00521 }
00522
00523 if ((isEmptyLattice(A)) || (isEmptyLattice (B))) {
00524 result = EmptyLattice(X->NbRows);
00525 Matrix_Free ((Matrix *) A);
00526 Matrix_Free ((Matrix *) B);
00527 return result;
00528 }
00529 fordio = MakeDioEqforInter (A, B);
00530 Matrix_Free (A);
00531 Matrix_Free (B);
00532 exist = SolveDiophantine(fordio,(Matrix **) &U, &X1);
00533 if (exist < 0) {
00534 result = (EmptyLattice(X->NbRows));
00535 return result;
00536 }
00537
00538 result = (Lattice *)Matrix_Alloc(X->NbRows, X->NbColumns);
00539 for (i = 0; i < result->NbRows-1; i ++)
00540 for (j = 0; j < result->NbColumns-1; j ++)
00541 value_assign(result->p[i][j],U->p[i][j]);
00542
00543 for (i = 0; i < result->NbRows-1; i ++)
00544 value_assign(result->p[i][result->NbColumns-1],X1->p[i]);
00545 for (i = 0; i < result->NbColumns-1; i ++)
00546 value_set_si(result->p[result->NbRows-1][i],0);
00547 value_set_si(result->p[result->NbRows-1][result->NbColumns-1],1);
00548
00549 Matrix_Free((Matrix *) U);
00550 Vector_Free(X1);
00551 Matrix_Free(fordio);
00552
00553 AffineHermite(result,&H,&U);
00554 Matrix_Free((Matrix *)result);
00555 result = (Lattice *)Matrix_Copy(H);
00556
00557 Matrix_Free((Matrix *) H);
00558 Matrix_Free((Matrix *) U);
00559
00560
00561
00562 if (isEmptyLattice (result)) {
00563 Matrix_Free ((Matrix *)result);
00564 return (EmptyLattice (X->NbRows));
00565 }
00566 return result;
00567 }
00568
00569 static Matrix * MakeDioEqforInter (Lattice *A, Lattice *B) {
00570
00571 Matrix *Dio ;
00572 int i,j;
00573
00574 #ifdef DOMDEBUG
00575 FILE *fp;
00576 fp = fopen("_debug", "a");
00577 fprintf(fp,"\nEntered MAKEDIOEQFORINTER \n");
00578 fclose(fp);
00579 #endif
00580
00581 Dio = Matrix_Alloc(2*(A->NbRows-1) + 1, 3 * (A->NbColumns-1)+1);
00582
00583 for (i = 0; i < Dio->NbRows; i ++)
00584 for (j = 0; j < Dio->NbColumns; j ++)
00585 value_set_si(Dio->p[i][j],0);
00586
00587 for (i = 0; i < A->NbRows-1; i++) {
00588 value_set_si(Dio->p[i][i],1);
00589 value_set_si(Dio->p[i+A->NbRows-1][i],1);
00590 }
00591 for (i = 0; i < A->NbRows-1 ; i ++)
00592 for (j = 0; j < A->NbRows-1; j ++) {
00593 value_oppose(Dio->p[i][j+A->NbRows-1],A->p[i][j]);
00594 value_oppose(Dio->p[i+(A->NbRows-1)][j+2*(A->NbRows-1)],B->p[i][j]);
00595 }
00596
00597
00598
00599 for (i = 0; i < A->NbColumns-1; i++) {
00600 value_oppose(Dio->p[i][Dio->NbColumns-1],A->p[i][A->NbColumns-1]);
00601 value_oppose(Dio->p[i+A->NbRows-1][Dio->NbColumns-1],B->p[i][A->NbColumns-1]) ;
00602 }
00603 value_set_si(Dio->p[Dio->NbRows-1][Dio->NbColumns-1],1);
00604 return Dio;
00605 }
00606
00607 static void AddLattice(LatticeUnion *,Matrix *, Matrix *, int , int);
00608 LatticeUnion *SplitLattice(Matrix *, Matrix *, Matrix *);
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674 LatticeUnion *Lattice2LatticeUnion(Lattice *X,Lattice *Y)
00675 {
00676 Lattice *B1 = NULL, *B2 = NULL, *newB1 = NULL, *newB2 = NULL, *Intersection=NULL;
00677 Matrix *U = NULL,*M1 = NULL, *M2 = NULL, *M1Inverse = NULL,*MtProduct = NULL;
00678 Matrix *Vinv, *V , *temp, *DiagMatrix ;
00679
00680 LatticeUnion *Head = NULL, *tempHead = NULL;
00681 int i;
00682 Value k;
00683
00684
00685 Intersection = LatticeIntersection(X,Y);
00686 if (isEmptyLattice(Intersection) == True) {
00687 fprintf(stderr,"\nIn Lattice2LatticeUnion : the input lattices X and Y do not have any common part\n");
00688 return NULL;
00689 }
00690
00691 value_init(k);
00692 M1 = (Matrix *)ExtractLinearPart(X);
00693 M2 = (Matrix *)ExtractLinearPart(Intersection);
00694
00695 M1Inverse = Matrix_Alloc(M1->NbRows,M1->NbColumns);
00696 temp = Matrix_Copy(M1);
00697 Matrix_Inverse(temp,M1Inverse);
00698 Matrix_Free(temp);
00699
00700 MtProduct = Matrix_Alloc(M1->NbRows, M1->NbColumns);
00701 Matrix_Product(M1Inverse,M2,MtProduct) ;
00702 Smith(MtProduct, &U, &Vinv, &DiagMatrix);
00703 V = Matrix_Alloc(Vinv->NbRows,Vinv->NbColumns);
00704 Matrix_Inverse(Vinv, V);
00705 Matrix_Free(Vinv);
00706 B1 = Matrix_Alloc(M1->NbRows, U->NbColumns);
00707 B2 = Matrix_Alloc(M2->NbRows, V->NbColumns);
00708 Matrix_Product(M1, U, B1);
00709 Matrix_Product(M2, V, B2);
00710 Matrix_Free(M1);
00711 Matrix_Free(M2);
00712 value_division(k,B2->p[0][0],B1->p[0][0]);
00713 value_division(k,DiagMatrix->p[0][0],k);
00714 for (i = 0; i < DiagMatrix->NbRows; i++)
00715 value_division(DiagMatrix->p[i][i],DiagMatrix->p[i][i],k);
00716 newB1 = ChangeLatticeDimension(B1, B1->NbRows + 1);
00717 Matrix_Free(B1);
00718 newB2 = ChangeLatticeDimension(B2, B2->NbRows +1);
00719 Matrix_Free(B2);
00720 for(i = 0; i < newB1->NbRows - 1;i ++)
00721 value_assign(newB2->p[i][newB1->NbRows-1],Intersection->p[i][X->NbRows-1]);
00722 Head = SplitLattice(newB1,newB2,DiagMatrix);
00723 Matrix_Free(newB1);
00724 Matrix_Free(DiagMatrix);
00725 value_clear(k);
00726 return Head;
00727 }
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814 LatticeUnion *LatticeDifference(Lattice *A,Lattice *B) {
00815
00816 Lattice *Intersection = NULL;
00817 LatticeUnion *Head = NULL, *tempHead = NULL;
00818 Matrix *H , *U1 , *X, *Y ;
00819
00820 #ifdef DOMDEBUG
00821 FILE *fp;
00822 fp = fopen("_debug", "a");
00823 fprintf(fp,"\nEntered LATTICEDIFFERENCE \n");
00824 fclose(fp);
00825 #endif
00826
00827 if (A->NbRows != A->NbColumns) {
00828 fprintf(stderr,"\nIn LatticeDifference : The Input Matrix A is not a proper Lattice \n");
00829 return NULL;
00830 }
00831
00832 if (B->NbRows != B->NbColumns) {
00833 fprintf(stderr,"\nIn LatticeDifference : The Input Matrix B is not a proper Lattice \n");
00834 return NULL;
00835 }
00836
00837 if (A->NbRows != B->NbRows) {
00838 fprintf(stderr,"\nIn Lattice Difference : The Input Lattices A and B have ");
00839 fprintf(stderr,"incompatible dimensions \n");
00840 return NULL;
00841 }
00842
00843 if (isinHnf (A) != True) {
00844 AffineHermite(A,&H,&U1);
00845 X = Matrix_Copy(H);
00846 Matrix_Free(U1);
00847 Matrix_Free(H);
00848 }
00849 else
00850 X = Matrix_Copy(A);
00851
00852 if (isinHnf(B) != True) {
00853 AffineHermite(B,&H,&U1);
00854 Y = Matrix_Copy(H);
00855 Matrix_Free(H);
00856 Matrix_Free(U1);
00857 }
00858 else
00859 Y = Matrix_Copy(B);
00860 if (isEmptyLattice(X)) {
00861 return NULL;
00862 }
00863
00864 Head=Lattice2LatticeUnion(X,Y);
00865
00866
00867
00868 if (Head == NULL) {
00869 Head = (LatticeUnion *)malloc(sizeof(LatticeUnion));
00870 Head->M = Matrix_Copy(X);
00871 Head->next = NULL;
00872 Matrix_Free(X);
00873 Matrix_Free(Y);
00874 return Head;
00875 }
00876
00877 tempHead = Head;
00878 Head = Head->next;
00879 Matrix_Free (tempHead->M);
00880 tempHead->next = NULL;
00881 free(tempHead);
00882
00883 if ((Head != NULL))
00884 Head = LatticeSimplify (Head);
00885 Matrix_Free (X);
00886 Matrix_Free (Y);
00887
00888 return Head;
00889 }
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901 LatticeUnion *SplitLattice(Lattice *B1, Lattice *B2, Matrix *C) {
00902
00903 int i;
00904
00905 LatticeUnion *Head = NULL;
00906 Head = (LatticeUnion *)malloc(sizeof(LatticeUnion));
00907 Head->M = (Lattice *)B2;
00908 Head->next = NULL;
00909 for (i = 0; i < C->NbRows ; i++)
00910 AddLattice(Head,B1,B2,VALUE_TO_INT(C->p[i][i]),i);
00911 return Head;
00912 }
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928 static void AddLattice (LatticeUnion *Head, Matrix *B1, Matrix *B2, int NumofTimes, int Colnumber) {
00929
00930 LatticeUnion *temp, *tail, *marker;
00931 int i,j;
00932 Value tmp;
00933
00934 value_init(tmp);
00935 tail = Head;
00936 while (tail->next != NULL)
00937 tail = tail->next;
00938 marker = tail;
00939
00940 for(temp = Head; temp != NULL; temp=temp->next) {
00941 for (i = 1; i < NumofTimes; i++) {
00942 Lattice *tempMatrix, *H, *U;
00943
00944 tempMatrix = (Lattice *)Matrix_Copy(temp->M);
00945 for (j = 0; j < B2->NbRows; j++) {
00946 value_set_si(tmp,i);
00947 value_addmul(tempMatrix->p[j][B2->NbColumns-1], tmp, B1->p[j][Colnumber]);
00948 }
00949 tail->next = (LatticeUnion *)malloc(sizeof(LatticeUnion));
00950 AffineHermite(tempMatrix,&H,&U);
00951 Matrix_Free((Matrix *)tempMatrix);
00952 Matrix_Free(U);
00953 tail->next->M = H;
00954 tail->next->next=NULL;
00955 tail = tail->next;
00956 }
00957 if (temp == marker)
00958 break;
00959 }
00960 value_clear(tmp);
00961 return;
00962 }
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990 int FindHermiteBasisofDomain(Polyhedron *A, Matrix **B) {
00991
00992 int i, j;
00993 Matrix *temp,*temp1, *tempinv, *Newmat ;
00994 Matrix *vert, *rays, *result;
00995 Polyhedron *Image;
00996 int rank, equcount ;
00997 int noofvertices = 0, noofrays = 0;
00998 int vercount , raycount;
00999 Value lcm, fact;
01000
01001 #ifdef DOMDEBUG
01002 FILE *fp;
01003 fp = fopen("_debug", "a");
01004 fprintf(fp,"\nEntered FINDHERMITEBASISOFDOMAIN \n");
01005 fclose(fp);
01006 #endif
01007
01008 POL_ENSURE_FACETS(A);
01009 POL_ENSURE_VERTICES(A);
01010
01011
01012 if (emptyQ(A)) {
01013 B[0] = Identity(A->Dimension+1);
01014 return(-1);
01015 }
01016
01017 value_init(lcm); value_init(fact);
01018 value_set_si(lcm,1);
01019
01020
01021 for (i = 0; i < A->NbRays; i++)
01022 if ((value_notzero_p(A->Ray[i][0])) && value_notzero_p(A->Ray[i][A->Dimension+1]))
01023 noofvertices++;
01024 else
01025 noofrays ++;
01026
01027 vert = Matrix_Alloc(noofvertices,A->Dimension+1);
01028 rays = Matrix_Alloc(noofrays,A->Dimension);
01029 vercount = 0;
01030 raycount = 0;
01031
01032 for(i = 0; i < A->NbRays; i++) {
01033 if ((value_notzero_p(A->Ray[i][0])) && value_notzero_p(A->Ray[i][A->Dimension+1])) {
01034 for(j = 1; j < A->Dimension+2; j++)
01035 value_assign(vert->p[vercount][j-1],A->Ray[i][j]);
01036 value_lcm(lcm, lcm, A->Ray[i][j-1]);
01037 vercount++;
01038 }
01039 else {
01040 for (j = 1; j < A->Dimension+1; j++)
01041 value_assign(rays->p[raycount][j-1],A->Ray[i][j]);
01042 raycount++;
01043 }
01044 }
01045
01046
01047 for(i = 0; i < vert->NbRows; i ++) {
01048 value_division(fact,lcm,vert->p[i][vert->NbColumns-1]);
01049 for (j = 0; j < vert->NbColumns-1; j++)
01050 value_multiply(vert->p[i][j],vert->p[i][j],fact);
01051 }
01052
01053
01054 temp = RemoveColumn(vert,vert->NbColumns-1);
01055 Matrix_Free(vert);
01056
01057
01058 vert = Matrix_Alloc(temp->NbRows-1, temp->NbColumns);
01059 for (i = 1; i < temp->NbRows; i++)
01060 for (j = 0; j < temp->NbColumns ; j++)
01061 value_subtract(vert->p[i-1][j],temp->p[0][j],temp->p[i][j]);
01062
01063 Matrix_Free(temp);
01064
01065
01066
01067 result = Matrix_Alloc(vert->NbRows+rays->NbRows, vert->NbColumns);
01068 for (i = 0; i < vert->NbRows; i++)
01069 for (j = 0 ;j < result->NbColumns ; j++)
01070 value_assign(result->p[i][j],vert->p[i][j]);
01071
01072 for (; i<result->NbRows; i++)
01073 for (j = 0; j < result->NbColumns; j++)
01074 value_assign(result->p[i][j],rays->p[i-vert->NbRows][j]);
01075
01076 Matrix_Free(vert);
01077 Matrix_Free(rays);
01078
01079 rank = findHermiteBasis(result, &temp);
01080 temp1 = ChangeLatticeDimension(temp,temp->NbRows+1);
01081
01082 Matrix_Free(result);
01083 Matrix_Free(temp);
01084
01085
01086 temp = Matrix_Copy(temp1);
01087 tempinv = Matrix_Alloc(temp->NbRows,temp->NbColumns);
01088 Matrix_Inverse(temp,tempinv);
01089 Matrix_Free(temp);
01090 Image = DomainImage(A,tempinv,MAXNOOFRAYS);
01091 Matrix_Free(tempinv);
01092 Newmat = Matrix_Alloc(temp1->NbRows,temp1->NbColumns);
01093 for(i = 0; i < rank ; i++)
01094 for(j = 0; j < Newmat->NbColumns ; j++)
01095 value_set_si(Newmat->p[i][j],0);
01096 for(i = 0; i < rank; i++)
01097 value_set_si(Newmat->p[i][i],1);
01098 equcount = 0;
01099 for (i = 0; i < Image->NbConstraints; i ++)
01100 if (value_zero_p(Image->Constraint[i][0])) {
01101 for (j = 1; j<Image->Dimension+2; j ++)
01102 value_assign(Newmat->p[rank+equcount][j-1],Image->Constraint[i][j]);
01103 ++equcount ;
01104 }
01105 Domain_Free(Image);
01106 for (i = 0; i < Newmat->NbColumns-1; i++)
01107 value_set_si(Newmat->p[Newmat->NbRows-1][i],0);
01108 value_set_si(Newmat->p[Newmat->NbRows-1][Newmat->NbColumns-1],1);
01109 temp = Matrix_Alloc(Newmat->NbRows, Newmat->NbColumns);
01110 Matrix_Inverse(Newmat,temp);
01111 Matrix_Free(Newmat);
01112 B[0] = Matrix_Alloc(temp1->NbRows,temp->NbColumns);
01113
01114 Matrix_Product(temp1,temp,B[0]);
01115 Matrix_Free(temp1);
01116 Matrix_Free(temp);
01117 value_clear(lcm);
01118 value_clear(fact);
01119 return rank;
01120 }
01121
01122
01123
01124
01125
01126 Lattice *LatticeImage(Lattice *A, Matrix *M) {
01127
01128 Lattice *Img, *temp, *Minv;
01129
01130 #ifdef DOMDEBUG
01131 FILE *fp;
01132 fp = fopen("_debug", "a");
01133 fprintf(fp, "\nEntered LATTICEIMAGE \n");
01134 fclose(fp);
01135 #endif
01136
01137 if ((A->NbRows != M->NbRows) || (M->NbRows != M->NbColumns))
01138 return (EmptyLattice (A->NbRows));
01139
01140 if (value_one_p(M->p[M->NbRows-1][M->NbColumns-1])) {
01141 Img = Matrix_Alloc ( M->NbRows, A->NbColumns );
01142 Matrix_Product (M,A,Img);
01143 return Img;
01144 }
01145 temp = Matrix_Copy(M);
01146 Minv = Matrix_Alloc(temp->NbColumns, temp->NbRows);
01147 Matrix_Inverse(temp, Minv);
01148 Matrix_Free(temp);
01149
01150 Img = LatticePreimage(A, Minv);
01151 Matrix_Free (Minv);
01152 return Img;
01153 }
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165 Lattice *LatticePreimage(Lattice *L, Matrix *G) {
01166
01167 Matrix *Dio, *U ;
01168 Lattice *Result;
01169 Vector *X;
01170 int i,j;
01171 int rank;
01172 Value divisor, tmp;
01173
01174 #ifdef DOMDEBUG
01175 FILE *fp;
01176 fp = fopen("_debug", "a");
01177 fprintf(fp,"\nEntered LATTICEPREIMAGE \n");
01178 fclose(fp);
01179 #endif
01180
01181
01182 if (G->NbRows != L->NbRows) {
01183 fprintf (stderr, "\nIn LatticePreimage: Incompatible types of Lattice and the function\n");
01184 return (EmptyLattice(G->NbColumns));
01185 }
01186
01187 value_init(divisor); value_init(tmp);
01188
01189
01190 value_assign(divisor,G->p[G->NbRows-1][G->NbColumns-1]);
01191 Dio = Matrix_Alloc(G->NbRows, G->NbColumns+L->NbColumns-1);
01192 for (i = 0; i < G->NbRows-1; i++)
01193 for (j = 0; j < G->NbColumns-1; j++)
01194 value_assign(Dio->p[i][j],G->p[i][j]);
01195
01196 for (i = 0;i < G->NbRows-1; i++)
01197 for (j = 0; j < L->NbColumns-1; j++) {
01198 value_multiply(tmp,divisor,L->p[i][j]);
01199 value_oppose(Dio->p[i][j+G->NbColumns-1],tmp);
01200 }
01201
01202 for (i = 0; i < Dio->NbRows-1; i++) {
01203 value_multiply(tmp,divisor,L->p[i][L->NbColumns-1]);
01204 value_subtract(tmp,G->p[i][G->NbColumns-1],tmp);
01205 value_assign(Dio->p[i][Dio->NbColumns-1],tmp);
01206 }
01207 for (i = 0; i < Dio->NbColumns-1; i++)
01208 value_set_si(Dio->p[Dio->NbRows-1][i],0);
01209
01210 value_set_si(Dio->p[Dio->NbRows-1][Dio->NbColumns-1],1);
01211 rank = SolveDiophantine(Dio, &U, &X);
01212
01213 if (rank == -1)
01214 Result = EmptyLattice(G->NbColumns);
01215 else {
01216 Result = Matrix_Alloc (G->NbColumns, G->NbColumns);
01217 for (i = 0; i < Result->NbRows-1; i++)
01218 for (j = 0; j < Result->NbColumns-1; j++)
01219 value_assign(Result->p[i][j],U->p[i][j]);
01220
01221 for (i = 0; i < Result->NbRows-1; i ++)
01222 value_assign(Result->p[i][Result->NbColumns-1],X->p[i]);
01223 Matrix_Free (U);
01224 Vector_Free (X);
01225 for (i = 0; i < Result->NbColumns-1; i ++)
01226 value_set_si(Result->p[Result->NbRows-1][i],0);
01227 value_set_si(Result->p[i][i],1);
01228 }
01229 Matrix_Free(Dio);
01230 value_clear(divisor);
01231 value_clear(tmp);
01232 return Result;
01233 }
01234
01235
01236
01237
01238
01239 Bool IsLattice(Matrix *m) {
01240
01241 int i;
01242
01243 #ifdef DOMDEBUG
01244 FILE *fp;
01245 fp = fopen ("_debug", "a");
01246 fprintf (fp, "\nEntered ISLATTICE \n");
01247 fclose (fp);
01248 #endif
01249
01250
01251
01252
01253 if (m->NbRows != m->NbColumns)
01254 return False;
01255
01256 for (i = 0; i < m->NbColumns-1; i++)
01257 if (value_notzero_p(m->p[m->NbRows-1][i]))
01258 return False ;
01259 if (value_notone_p(m->p[i][i]))
01260 return False;
01261 return True ;
01262 }
01263
01264
01265
01266
01267 Bool isfulldim(Matrix *m) {
01268
01269 Matrix *h, *u ;
01270 int i ;
01271
01272
01273
01274
01275
01276
01277
01278 Hermite(m, &h, &u);
01279 for (i = 0; i < h->NbRows; i ++)
01280 if (value_zero_p(h->p[i][i])) {
01281 Matrix_Free (h);
01282 Matrix_Free (u);
01283 return False;
01284 }
01285 Matrix_Free (h);
01286 Matrix_Free (u);
01287 return True;
01288 }
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306 static Bool Simplify(LatticeUnion **InputList, LatticeUnion **ResultList, int dim) {
01307
01308 int i;
01309 LatticeUnion *prev, *temp;
01310 factor allfac;
01311 Bool retval = False;
01312 int width;
01313 Value cnt, aux, k, fac, num, tmp, foobar;
01314
01315 if ((*InputList == NULL) || (InputList[0]->next == NULL))
01316 return False ;
01317
01318 value_init(aux); value_init(cnt);
01319 value_init(k); value_init(fac);
01320 value_init(num); value_init(tmp);
01321 value_init(foobar);
01322
01323 width = InputList[0]->M->NbRows-1;
01324 allfac = allfactors(VALUE_TO_INT(InputList[0]->M->p[dim][dim]));
01325 value_set_si(cnt,0);
01326 for (temp = InputList[0]; temp != NULL; temp = temp->next)
01327 value_increment(cnt,cnt);
01328 for(i = 0; i < allfac.count; i++) {
01329 value_set_si(foobar,allfac.fac[i]);
01330 value_division(aux,InputList[0]->M->p[dim][dim],foobar);
01331 if(value_ge(cnt,aux))
01332 break;
01333 }
01334 if (i == allfac.count) {
01335 value_clear(cnt); value_clear(aux);
01336 value_clear(k); value_clear(fac);
01337 value_clear(num); value_clear(tmp);
01338 value_clear(foobar);
01339 return False;
01340 }
01341 for (; i < allfac.count; i++) {
01342 Bool Present = False;
01343 value_set_si(k,0);
01344
01345 if (*InputList == NULL) {
01346 value_clear(cnt); value_clear(aux);
01347 value_clear(k); value_clear(fac);
01348 value_clear(num); value_clear(tmp);
01349 value_clear(foobar);
01350 return retval;
01351 }
01352 value_set_si(foobar,allfac.fac[i]);
01353 value_division(num,InputList[0]->M->p[dim][dim],foobar);
01354 while (value_lt(k,foobar)) {
01355 Present = False;
01356 value_assign(fac,k);
01357 for (temp = *InputList; temp != NULL; temp = temp->next) {
01358 if (value_eq(temp->M->p[temp->M->NbRows-1][temp->M->NbColumns-1],fac)) {
01359 value_set_si(foobar,allfac.fac[i]);
01360 value_addto(fac,fac,foobar);
01361 if (value_ge(fac,(*InputList)->M->p[dim][dim])) {
01362 Present = True;
01363 break;
01364 }
01365 }
01366 if (value_gt(temp->M->p[temp->M->NbRows-1][temp->M->NbColumns-1],fac))
01367 break;
01368 }
01369 if (Present == True) {
01370 retval = True;
01371 if (*ResultList == NULL)
01372 *ResultList = temp = (LatticeUnion *)malloc(sizeof(LatticeUnion));
01373 else {
01374 for (temp = *ResultList; temp->next != NULL; temp = temp->next);
01375 temp->next = (LatticeUnion *) malloc (sizeof (LatticeUnion));
01376 temp = temp->next;
01377 }
01378 temp->M = Matrix_Copy(InputList[0]->M);
01379 temp->next = NULL;
01380 value_set_si(foobar,allfac.fac[i]);
01381 value_assign(temp->M->p[dim][dim],foobar);
01382 value_assign(temp->M->p[dim][width],k);
01383 value_set_si(temp->M->p[width][width],1);
01384
01385
01386 value_assign(tmp,k);
01387 prev = NULL;
01388 temp = InputList[0];
01389 while (temp != NULL) {
01390 if (value_eq(temp->M->p[width][width],tmp)) {
01391 if (temp == InputList[0]) {
01392 prev = temp;
01393 temp = InputList [0] = temp->next;
01394 Matrix_Free(prev->M);
01395 free(prev);
01396 }
01397 else {
01398 prev->next = temp->next;
01399 Matrix_Free(temp->M);
01400 free(temp);
01401 temp = prev->next;
01402 }
01403 value_set_si(foobar,allfac.fac[i]);
01404 value_addto(tmp,tmp,foobar);
01405 }
01406 else {
01407 prev = temp;
01408 temp = temp->next;
01409 }
01410 }
01411 }
01412 value_increment(k,k);
01413 }
01414 }
01415 value_clear(cnt); value_clear(aux);
01416 value_clear(k); value_clear(fac);
01417 value_clear(num); value_clear(tmp);
01418 value_clear(foobar);
01419 return retval;
01420 }
01421
01422
01423
01424
01425
01426
01427
01428
01429 static int LinearPartCompare(const void *A, const void *B) {
01430
01431 Lattice **L1, **L2;
01432 int i, j;
01433
01434 L1 = (Lattice **) A;
01435 L2 = (Lattice **) B;
01436
01437 for (i = 0; i < L1[0]->NbRows-1; i++)
01438 for (j = 0; j <= i ; j++) {
01439 if (value_gt(L1[0]->p[i][j],L2[0]->p[i][j]))
01440 return 1;
01441 if (value_lt(L1[0]->p[i][j],L2[0]->p[i][j]))
01442 return -1;
01443 }
01444 return 0;
01445 }
01446
01447
01448
01449
01450
01451
01452 static void LinearPartSort (LatticeUnion *Head) {
01453
01454 int cnt;
01455 Lattice **Latlist;
01456 LatticeUnion *temp ;
01457
01458 cnt = 0;
01459 for (temp = Head; temp != NULL; temp = temp->next)
01460 cnt ++;
01461
01462 Latlist = (Lattice **) malloc ( sizeof (Lattice *) * cnt);
01463
01464 cnt = 0;
01465 for (temp = Head; temp != NULL; temp = temp->next)
01466 Latlist[cnt++] = temp->M;
01467
01468 qsort(Latlist, cnt, sizeof(Lattice *), LinearPartCompare);
01469
01470 cnt = 0;
01471 for (temp = Head; temp != NULL; temp = temp->next)
01472 temp->M = Latlist[cnt++];
01473
01474 free (Latlist);
01475 return;
01476 }
01477
01478
01479
01480
01481
01482
01483
01484 static int AffinePartCompare(const void *A, const void *B) {
01485
01486 int i;
01487 Lattice **L1, **L2;
01488
01489 L1 = (Lattice **)A;
01490 L2 = (Lattice **)B;
01491
01492 for (i = 0; i < L1[0]->NbRows; i++) {
01493 if (value_gt(L1[0]->p[i][L1[0]->NbColumns-1],L2[0]->p[i][L1[0]->NbColumns-1]))
01494 return 1;
01495
01496 if (value_lt(L1[0]->p[i][L1[0]->NbColumns-1],L2[0]->p[i][L1[0]->NbColumns-1]))
01497 return -1;
01498 }
01499 return 0 ;
01500 }
01501
01502
01503
01504
01505
01506 static void AffinePartSort (LatticeUnion *List) {
01507
01508 int cnt;
01509 Lattice **LatList;
01510 LatticeUnion *tmp;
01511
01512 cnt = 0;
01513 for (tmp = List; tmp != NULL; tmp = tmp->next)
01514 cnt ++;
01515
01516 LatList = (Lattice **) malloc (sizeof(Lattice *) * cnt);
01517
01518 cnt = 0;
01519 for (tmp = List; tmp != NULL; tmp = tmp->next)
01520 LatList[cnt++] = tmp->M;
01521
01522 qsort(LatList,cnt, sizeof (Lattice *), AffinePartCompare);
01523
01524 cnt = 0;
01525 for (tmp = List; tmp != NULL; tmp = tmp->next)
01526 tmp->M = LatList[cnt++];
01527 return;
01528 }
01529
01530 static Bool AlmostSameAffinePart(LatticeUnion *A, LatticeUnion *B) {
01531
01532 int i;
01533
01534 if ((A == NULL) || (B == NULL))
01535 return False;
01536
01537 for (i = 0; i < A->M->NbRows-1; i ++)
01538 if (value_ne(A->M->p[i][A->M->NbColumns-1],B->M->p[i][A->M->NbColumns-1]))
01539 return False;
01540 return True;
01541 }
01542
01543
01544
01545
01546
01547
01548
01549 static Bool AffinePartSimplify(LatticeUnion *curlist, LatticeUnion **newlist) {
01550
01551 int i;
01552 Value aux;
01553 LatticeUnion *temp, *curr, *next;
01554 LatticeUnion *nextlist;
01555 Bool change = False, chng;
01556
01557 if (curlist == NULL)
01558 return False;
01559
01560 if (curlist->next == NULL) {
01561 curlist->next = newlist[0];
01562 newlist[0] = curlist;
01563 return False ;
01564 }
01565
01566 value_init(aux);
01567 for (i = 0; i < curlist->M->NbRows - 1; i ++) {
01568
01569
01570
01571
01572 for (temp = curlist; temp != NULL; temp = temp->next) {
01573 value_assign(aux,temp->M->p[temp->M->NbRows-1][temp->M->NbColumns-1]);
01574 value_assign(temp->M->p[temp->M->NbRows-1][temp->M->NbColumns-1],temp->M->p[i][temp->M->NbColumns-1]);
01575 value_assign(temp->M->p[i][temp->M->NbColumns-1],aux);
01576 }
01577 AffinePartSort(curlist);
01578 nextlist = NULL;
01579 curr = curlist;
01580 while (curr != NULL) {
01581 next = curr->next;
01582 if (!AlmostSameAffinePart(curr, next)) {
01583 curr->next = NULL;
01584 chng = Simplify(&curlist, newlist, i);
01585 if (nextlist == NULL)
01586 nextlist = curlist;
01587 else {
01588 LatticeUnion *tmp;
01589 for (tmp = nextlist; tmp->next; tmp=tmp->next);
01590 tmp->next = curlist;
01591 }
01592 change = (Bool)(change | chng);
01593 curlist = next;
01594 }
01595 curr = next;
01596 }
01597 curlist = nextlist;
01598
01599
01600
01601
01602 for(temp = curlist; temp != NULL; temp = temp->next) {
01603 value_assign(aux,temp->M->p[temp->M->NbRows-1][temp->M->NbColumns-1]);
01604 value_assign(temp->M->p[temp->M->NbRows-1][temp->M->NbColumns-1],temp->M->p[i][temp->M->NbColumns-1]);
01605 value_assign(temp->M->p[i][temp->M->NbColumns-1],aux);
01606 }
01607 if (curlist == NULL)
01608 break;
01609 }
01610 if ( *newlist == NULL)
01611 *newlist = nextlist;
01612 else {
01613 for (curr = *newlist; curr->next != NULL; curr = curr->next);
01614 curr->next = nextlist;
01615 }
01616 value_clear(aux);
01617 return change;
01618 }
01619
01620 static Bool SameLinearPart(LatticeUnion *A, LatticeUnion *B) {
01621
01622 int i, j;
01623 if ((A == NULL) || (B ==NULL))
01624 return False;
01625 for (i = 0; i < A->M->NbRows-1; i++)
01626 for (j = 0; j <= i; j++)
01627 if (value_ne(A->M->p[i][j],B->M->p[i][j]))
01628 return False;
01629
01630 return True;
01631 }
01632
01633
01634
01635
01636 LatticeUnion *LatticeSimplify(LatticeUnion *latlist) {
01637
01638 LatticeUnion *curlist, *nextlist;
01639 LatticeUnion *curr, *next;
01640 Bool change = True, chng;
01641
01642 curlist = latlist;
01643 while (change == True) {
01644 change = False;
01645 LinearPartSort(curlist);
01646 curr = curlist;
01647 nextlist = NULL;
01648 while(curr != NULL) {
01649 next = curr->next;
01650 if (!SameLinearPart(curr, next)) {
01651 curr->next = NULL;
01652 chng = AffinePartSimplify(curlist, &nextlist);
01653 change = (Bool)(change | chng);
01654 curlist = next;
01655 }
01656 curr = next;
01657 }
01658 curlist = nextlist;
01659 }
01660 return curlist;
01661 }
01662
01663 int intcompare (const void *a, const void *b) {
01664
01665 int *i, *j;
01666
01667 i = (int *) a;
01668 j = (int *) b;
01669 if (*i > *j)
01670 return 1;
01671 if (*i < *j)
01672 return -1;
01673 return 0;
01674 }
01675
01676 static int polylib_sqrt(int i);
01677 static factor allfactors (int num) {
01678
01679 int i,j, tmp;
01680 int noofelmts = 1;
01681 int *list, *newlist;
01682 int count;
01683 factor result;
01684
01685 list = (int *)malloc(sizeof (int));
01686 list[0] = 1;
01687
01688 tmp = num;
01689 for (i = 2; i <= polylib_sqrt(tmp); i++) {
01690 if ((tmp % i) == 0) {
01691 if (noofelmts == 0) {
01692 list = (int *) malloc (sizeof (int));
01693 list[0] = i;
01694 noofelmts = 1;
01695 }
01696 else {
01697 newlist = (int *) malloc (sizeof (int) * 2 * noofelmts + 1);
01698 for (j = 0; j < noofelmts; j++)
01699 newlist[j] = list[j] ;
01700 newlist[j] = i;
01701 for (j = 0; j < noofelmts; j++)
01702 newlist[j+noofelmts+1] = i * list[j];
01703 free (list);
01704 list = newlist;
01705 noofelmts= 2*noofelmts+1;
01706 }
01707 tmp = tmp / i;
01708 i = 1;
01709 }
01710 }
01711
01712 if ((tmp != 0) && (tmp != num)) {
01713 newlist = (int *) malloc (sizeof (int) * 2 * noofelmts + 1);
01714 for (j = 0; j < noofelmts; j ++)
01715 newlist[j] = list[j] ;
01716 newlist[j] = tmp;
01717 for (j = 0; j < noofelmts; j ++)
01718 newlist[j+noofelmts+1] = tmp * list[j];
01719 free (list);
01720 list = newlist;
01721 noofelmts= 2*noofelmts+1;
01722 }
01723 qsort (list, noofelmts, sizeof(int), intcompare);
01724 count = 1;
01725 for (i = 1; i < noofelmts; i ++)
01726 if (list[i] != list[i-1])
01727 list[count++] = list[i];
01728 if (list[count-1] == num)
01729 count --;
01730
01731 result.fac = (int *) malloc (sizeof (int) * count);
01732 result.count = count;
01733 for (i = 0; i < count; i ++)
01734 result.fac[i] = list[i];
01735 free (list);
01736 return result;
01737 }
01738
01739 static int polylib_sqrt (int i) {
01740
01741 int j;
01742 j = 0;
01743 i = i > 0 ? i : -i;
01744
01745 while (1) {
01746 if ((j * j) > i)
01747 break;
01748 else
01749 j ++;
01750 }
01751 return (j-1);
01752 }
01753
01754
01755
01756
01757
01758
01759