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