00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <string.h>
00029 #include <assert.h>
00030 #ifdef DEBUGPP
00031 #include <time.h>
00032 #endif
00033
00034 #include <polylib/polylib.h>
00035
00036 static void traite_m_face(Polyhedron *, unsigned int *, unsigned int *);
00037 static void scan_m_face(int,int,Polyhedron *,unsigned int *);
00038
00039
00040
00041
00042
00043
00044
00045 Polyhedron *PDomainIntersection(Polyhedron *Pol1,Polyhedron *Pol2,unsigned NbMaxRays) {
00046
00047 Polyhedron *p1, *p2, *p3, *d;
00048
00049 if (!Pol1 || !Pol2) return (Polyhedron*) 0;
00050 if((Pol1->Dimension != Pol2->Dimension) || (Pol1->NbEq != Pol2->NbEq)) {
00051 fprintf(stderr,
00052 "? PDomainIntersection: operation on different dimensions\n");
00053 return (Polyhedron*) 0;
00054 }
00055
00056 POL_ENSURE_FACETS(Pol1);
00057 POL_ENSURE_VERTICES(Pol1);
00058 POL_ENSURE_FACETS(Pol2);
00059 POL_ENSURE_VERTICES(Pol2);
00060
00061 d = (Polyhedron *)0;
00062 for (p1=Pol1; p1; p1=p1->next) {
00063 for (p2=Pol2; p2; p2=p2->next) {
00064 p3 = AddConstraints(p2->Constraint[0],
00065 p2->NbConstraints,p1,NbMaxRays);
00066 if (!p3) continue;
00067
00068
00069 if (p3->NbEq!=Pol1->NbEq)
00070 Polyhedron_Free(p3) ;
00071
00072
00073 else
00074 d = AddPolyToDomain(p3,d);
00075 }
00076 }
00077 return d;
00078 }
00079
00080
00081
00082
00083
00084
00085
00086 Polyhedron *PDomainDifference(Polyhedron *Pol1,Polyhedron *Pol2,unsigned NbMaxRays) {
00087
00088 Polyhedron *p1, *p2, *p3, *d;
00089 int i;
00090
00091 if (!Pol1 || !Pol2)
00092 return (Polyhedron*) 0;
00093 if((Pol1->Dimension != Pol2->Dimension) || (Pol1->NbEq != Pol2->NbEq)) {
00094 fprintf(stderr,
00095 "? PDomainDifference: operation on different dimensions\n");
00096 return (Polyhedron*) 0;
00097 }
00098
00099 POL_ENSURE_FACETS(Pol1);
00100 POL_ENSURE_VERTICES(Pol1);
00101 POL_ENSURE_FACETS(Pol2);
00102 POL_ENSURE_VERTICES(Pol2);
00103
00104 d = (Polyhedron *)0;
00105 for (p2=Pol2; p2; p2=p2->next) {
00106 for (p1=Pol1; p1; p1=p1->next) {
00107 for (i=0; i<p2->NbConstraints; i++) {
00108
00109
00110 p3 = SubConstraint(p2->Constraint[i],p1,NbMaxRays,2);
00111 if (!p3) continue;
00112
00113
00114
00115 if (emptyQ(p3) || p3->NbEq!=Pol1->NbEq)
00116 Polyhedron_Free(p3);
00117
00118
00119 else
00120 d = AddPolyToDomain(p3,d);
00121 }
00122 }
00123 if (p2 != Pol2)
00124 Domain_Free(Pol1);
00125 Pol1 = d;
00126 d = (Polyhedron *)0;
00127 }
00128 return Pol1;
00129 }
00130
00131
00132
00133
00134 static int TestRank(Matrix *Mat) {
00135
00136 int i,j,k;
00137 Value m1,m2,m3,gcd,tmp;
00138
00139
00140 value_init(m1); value_init(m2);
00141 value_init(m3); value_init(gcd); value_init(tmp);
00142
00143 for(k=0;k<Mat->NbColumns;++k) {
00144
00145
00146
00147 if(value_zero_p(Mat->p[k][k])) {
00148 for(j=k+1;j<Mat->NbRows;++j) {
00149
00150
00151 if(value_notzero_p(Mat->p[j][k])) {
00152
00153
00154 for(i=k;i<Mat->NbColumns;++i) {
00155 value_assign(tmp,Mat->p[j][i]);
00156 value_assign(Mat->p[j][i],Mat->p[k][i]);
00157 value_assign(Mat->p[k][i],tmp);
00158 }
00159 break;
00160 }
00161 }
00162
00163
00164
00165 if(j>=Mat->NbRows) {
00166
00167
00168 value_clear(m1); value_clear(m2);
00169 value_clear(m3); value_clear(gcd); value_clear(tmp);
00170 return 0;
00171 }
00172 }
00173
00174
00175 for(j=k+1;j<Mat->NbRows;++j) {
00176
00177
00178 value_gcd(gcd, Mat->p[j][k], Mat->p[k][k]);
00179 for(i=k+1;i<Mat->NbColumns;++i) {
00180
00181
00182 value_multiply(m1,Mat->p[j][i],Mat->p[k][k]);
00183 value_multiply(m2,Mat->p[j][k],Mat->p[k][i]);
00184 value_subtract(m3,m1,m2);
00185 value_division(Mat->p[j][i],m3,gcd);
00186 }
00187 }
00188 }
00189
00190
00191 value_clear(m1); value_clear(m2);
00192 value_clear(m3); value_clear(gcd); value_clear(tmp);
00193
00194
00195 return 1;
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205 typedef struct {
00206 unsigned int NbRows;
00207 unsigned int NbColumns;
00208 unsigned int **p;
00209 unsigned int *p_init;
00210 } SatMatrix;
00211
00212 static SatMatrix *SMAlloc(int rows,int cols) {
00213
00214 unsigned int **q, *p;
00215 int i;
00216
00217 SatMatrix *result = (SatMatrix *)malloc(sizeof(SatMatrix));
00218 assert (result != NULL);
00219
00220 result->NbRows = rows;
00221 result->NbColumns = cols;
00222 result->p = q = (unsigned int **)malloc(rows * sizeof(unsigned int *));
00223 assert (result->p != NULL);
00224 result->p_init = p = (unsigned int *)malloc(rows * cols * sizeof(unsigned int));
00225 assert (result->p_init != NULL);
00226
00227 for (i=0;i<rows;i++) {
00228 *q++ = p;
00229 p += cols;
00230 }
00231
00232 return result;
00233 }
00234
00235 static void SMPrint (SatMatrix *matrix) {
00236
00237 unsigned int *p;
00238 int i, j;
00239 unsigned NbRows, NbColumns;
00240
00241 fprintf(stderr,"%d %d\n",NbRows=matrix->NbRows, NbColumns=matrix->NbColumns);
00242 for (i=0;i<NbRows;i++) {
00243 p = *(matrix->p+i);
00244 for (j=0;j<NbColumns;j++)
00245 fprintf(stderr, " %10X ", *p++);
00246 fprintf(stderr, "\n");
00247 }
00248 }
00249
00250
00251 static void SMFree (SatMatrix *matrix) {
00252
00253 free ((char *) matrix->p_init);
00254 free ((char *) matrix->p);
00255 free ((char *) matrix);
00256 return;
00257 }
00258
00259
00260
00261
00262
00263
00264
00265 static int m;
00266 static int m_dim;
00267 static int n;
00268 static int ws;
00269 static int nr;
00270
00271 static Polyhedron *CEqualities;
00272 static SatMatrix *Sat;
00273 static unsigned int *egalite;
00274 static Matrix *Xi, *Pi;
00275 static Matrix *PiTest;
00276 static Matrix *CTest;
00277 static Matrix *PiInv;
00278
00279 static Matrix *RaysDi;
00280
00281 static int KD;
00282
00283
00284 static int nbPV;
00285 static Param_Vertices *PV_Result;
00286 static Param_Domain *PDomains;
00287
00288 #ifdef DEBUGPP
00289 static int nbfaces;
00290 #endif
00291
00292
00293
00294
00295
00296
00297 static Polyhedron *Add_CEqualities(Polyhedron *D) {
00298
00299 Polyhedron *d,*r,*tmp;
00300
00301 if(!CEqualities)
00302 return D;
00303 else {
00304 if(!D || emptyQ(D)) {
00305 if(D)
00306 Domain_Free(D);
00307 return(Polyhedron_Copy(CEqualities));
00308 }
00309 r = AddConstraints(D->Constraint[0],D->NbConstraints,
00310 CEqualities,ws);
00311 tmp = r;
00312 for(d=D->next;d;d=d->next) {
00313 tmp->next = AddConstraints(d->Constraint[0],d->NbConstraints,
00314 CEqualities,ws);
00315 tmp = tmp->next;
00316 }
00317 Domain_Free(D);
00318 return(r);
00319 }
00320 }
00321
00322 #define INT_BITS (sizeof(unsigned) * 8)
00323
00324 unsigned int *int_array2bit_vector(unsigned int *array, int n)
00325 {
00326 int i, ix;
00327 unsigned bx;
00328 int words = (n+INT_BITS-1)/INT_BITS;
00329 unsigned int *bv = (unsigned int *)calloc(words, sizeof(unsigned));
00330 assert(bv);
00331 for (i = 0, ix = 0, bx = MSB; i < n; ++i) {
00332 if (array[i])
00333 bv[ix] |= bx;
00334 NEXT(ix, bx);
00335 }
00336 return bv;
00337 }
00338
00339
00340
00341
00342
00343
00344
00345
00346 static void traite_m_face(Polyhedron *D, unsigned int *mf,
00347 unsigned int *egalite)
00348 {
00349 Matrix *Si;
00350 Polyhedron *PDi;
00351 Param_Vertices *PV;
00352 int j,k,c,r;
00353 unsigned kx, bx;
00354
00355 #ifdef DEBUGPP
00356 ++nbfaces;
00357 #endif
00358
00359
00360 RaysDi->NbRows = 0;
00361 for(k=0,c=0,kx=0,bx=MSB;k<D->NbRays;++k) {
00362 if(mf[kx]&bx) {
00363 if(c<m+1) {
00364 int i;
00365
00366
00367
00368
00369
00370
00371 for(j=0;j<m+1;++j) {
00372 for(i=0;i<c;++i)
00373
00374
00375 value_assign(PiTest->p[j][i],Pi->p[j][i]);
00376
00377
00378 value_assign(PiTest->p[j][c],D->Ray[k][j+1+n]);
00379 }
00380 PiTest->NbColumns = c+1;
00381 r = TestRank(PiTest);
00382 if(r ) {
00383
00384
00385 for (j=0;j<n;j++)
00386 value_assign(Xi->p[j][c],D->Ray[k][j+1]);
00387 for (j=0;j<m;j++)
00388 value_assign(Pi->p[j][c],D->Ray[k][j+1+n]);
00389 value_assign(Xi->p[n][c],D->Ray[k][n+m+1]);
00390 value_assign(Pi->p[m][c],D->Ray[k][n+m+1]);
00391 c++;
00392 }
00393 }
00394
00395
00396 value_assign(RaysDi->p[RaysDi->NbRows][0],D->Ray[k][0]);
00397 Vector_Copy(&D->Ray[k][n+1],&RaysDi->p[RaysDi->NbRows][1],(m+1));
00398 ++RaysDi->NbRows;
00399 }
00400 NEXT(kx,bx);
00401 }
00402
00403 #ifdef DEBUGPP41
00404 fprintf(stderr, "\nRaysDi=\n");
00405 Matrix_Print(stderr,P_VALUE_FMT,RaysDi);
00406 if(c < m+1)
00407 fprintf(stderr, "Invalid ");
00408 fprintf(stderr, "Pi=\n");
00409 Matrix_Print(stderr,P_VALUE_FMT,Pi);
00410 #endif
00411
00412 #ifdef DEBUGPP4
00413 if(c < m+1)
00414 fprintf(stderr,"Eliminated because of no vertex\n");
00415 #endif
00416
00417 if(c < m+1)
00418 return;
00419
00420
00421
00422
00423
00424
00425
00426
00427 #ifdef DEBUGPP4
00428 fprintf(stderr,"Xi = ");
00429 Matrix_Print(stderr,P_VALUE_FMT,Xi);
00430 fprintf(stderr,"Pi = ");
00431 Matrix_Print(stderr,P_VALUE_FMT,Pi);
00432 #endif
00433
00434
00435
00436 if(!MatInverse(Pi,PiInv)) {
00437
00438 #ifdef DEBUGPP4
00439 fprintf(stderr, "Eliminated because of no inverse Pi\n");
00440 #endif
00441
00442 return;
00443 }
00444
00445 #ifdef DEBUGPP4
00446 fprintf(stderr,"FACE GENERATED!\n");
00447 fprintf(stderr,"PiInv = ");
00448 Matrix_Print(stderr,P_VALUE_FMT,PiInv);
00449 #endif
00450
00451
00452 Si = Matrix_Alloc(Xi->NbRows,PiInv->NbColumns);
00453 rat_prodmat(Si,Xi,PiInv);
00454
00455 #ifdef DEBUGPP4
00456 fprintf(stderr,"Si = ");
00457 Matrix_Print(stderr,P_VALUE_FMT,Si);
00458 #endif
00459
00460 Si->NbRows--;
00461
00462
00463 PV = (Param_Vertices *) malloc(sizeof(Param_Vertices));
00464 PV->next = PV_Result;
00465 PV->Vertex = Si;
00466 PV->Domain = NULL;
00467 PV->Facets = int_array2bit_vector(egalite, D->NbConstraints);
00468 PV_Result = PV;
00469 nbPV++;
00470
00471
00472 PDi = Rays2Polyhedron(RaysDi,ws);
00473
00474 #ifdef DEBUGPP3
00475 fprintf(stderr,"RaysDi = ");
00476 Matrix_Print(stderr,P_VALUE_FMT,RaysDi);
00477 fprintf(stderr,"PDi = ");
00478 Polyhedron_Print(stderr,P_VALUE_FMT,PDi);
00479 #endif
00480
00481 if(KD==0) {
00482
00483
00484 PDi = Add_CEqualities(PDi);
00485 PV->Domain = Polyhedron2Constraints(PDi);
00486 Polyhedron_Free(PDi);
00487 }
00488 else {
00489 Param_Domain *PD;
00490 PD = (Param_Domain *) malloc(sizeof(Param_Domain));
00491 PD->Domain = PDi;
00492 PD->F = NULL;
00493 PD->next = PDomains;
00494 PDomains = PD;
00495 }
00496 return;
00497 }
00498
00499
00500
00501
00502
00503
00504 int cntbit[256] = {
00505 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
00506 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
00507 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
00508 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00509
00510 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
00511 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00512 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00513 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00514
00515 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
00516 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00517 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00518 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00519
00520 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00521 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00522 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00523 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 };
00524
00525 static int count_sat (unsigned int *mf) {
00526
00527 register unsigned int i, tmp, cnt=0;
00528
00529 for (i=0; i<nr; i++) {
00530 tmp = mf[i];
00531 cnt = cnt
00532 + cntbit[ tmp & 0xff ]
00533 + cntbit[ (tmp>>8) & 0xff ]
00534 + cntbit[ (tmp>>16) & 0xff ]
00535 + cntbit[ (tmp>>24) & 0xff ]
00536 ;
00537 }
00538 return cnt;
00539 }
00540
00541
00542 static int bit_vector_includes(unsigned int *bv, int len, unsigned int *part)
00543 {
00544 int j;
00545
00546 for (j = 0; j < len; j++) {
00547 #ifdef DEBUGPP4
00548 fprintf(stderr, "mf=%08X Sat=%08X &=%08X\n",
00549 part[j],bv[j], (part[j] & bv[j]));
00550 #endif
00551 if ((part[j] & bv[j]) != part[j])
00552 return 0;
00553 }
00554 return 1;
00555 }
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598 static void scan_m_face(int pos,int nb_un,Polyhedron *D,unsigned int *mf) {
00599
00600
00601
00602
00603
00604 unsigned int *new_mf;
00605
00606 #ifdef DEBUGPP4
00607 fprintf(stderr,"Start scan_m_face(pos=%d, nb_un=%d, n=%d, m=%d\n",
00608 pos,nb_un,n,m);
00609 fprintf(stderr,"mf = ");
00610 {
00611 int i;
00612 for(i=0;i<nr;i++)
00613 fprintf(stderr,"%08X", mf[i]);
00614 fprintf(stderr,"\nequality = [");
00615 for(i=0;i<D->NbConstraints;i++)
00616 fprintf(stderr," %1d",egalite[i]);
00617 fprintf(stderr,"]\n");
00618 }
00619 #endif
00620
00621 if(nb_un == 0) {
00622 int i;
00623
00624
00625
00626
00627
00628 for(i=0;i<pos-1;i++)
00629 {
00630 if(egalite[i])
00631 continue;
00632
00633
00634 #ifdef DEBUGPP4
00635 fprintf(stderr, "Sat[%d]\n", i);
00636 #endif
00637 if (bit_vector_includes(Sat->p[i], nr, mf)) {
00638 #ifdef DEBUGPP4
00639 fprintf(stderr, "Redundant with constraint %d\n", i);
00640 #endif
00641 return;
00642 }
00643 }
00644
00645
00646 for (i = pos; i < D->NbConstraints; ++i) {
00647 if (bit_vector_includes(Sat->p[i], nr, mf))
00648 egalite[i] = 1;
00649 }
00650
00651
00652 traite_m_face(D, mf, egalite);
00653 for (i = pos; i < D->NbConstraints; ++i)
00654 egalite[i] = 0;
00655 return;
00656 }
00657
00658
00659 if((pos+nb_un)>D->NbConstraints) return;
00660
00661
00662
00663 {
00664 int k;
00665 new_mf = (unsigned int *)malloc(nr*sizeof(unsigned int));
00666 for (k=0; k<nr; k++)
00667 new_mf[k] = mf[k] & Sat->p[pos][k];
00668 }
00669 #ifdef DEBUGPP4
00670 fprintf(stderr,"new_mf = ");
00671 {
00672 int i;
00673 for(i=0;i<nr;i++) {
00674 fprintf(stderr,"%08X", new_mf[i]);
00675 }
00676 fprintf(stderr,"\ncount(new_mf) = %d\n",count_sat(new_mf));
00677 }
00678 #endif
00679
00680 {
00681 int c;
00682 c = count_sat(new_mf);
00683
00684 if (c>m_dim )
00685 {
00686 int redundant = 0;
00687
00688 egalite[pos]=1;
00689
00690
00691
00692
00693
00694
00695
00696 if( c==count_sat(mf) ) {
00697 int i, c, j;
00698
00699 for (i = 0, c = 0; i < D->NbConstraints; ++i) {
00700 if (egalite[i] == 0 || egalite[i] == -1)
00701 continue;
00702 for (j = 0; j < D->Dimension+1; ++j)
00703 value_assign(CTest->p[j][c],
00704 D->Constraint[i][j+1]);
00705 ++c;
00706 }
00707 CTest->NbColumns = c;
00708 #ifdef DEBUGPP41
00709 Matrix_Print(stderr,P_VALUE_FMT,CTest);
00710 #endif
00711 redundant = !TestRank(CTest);
00712 }
00713
00714
00715 if( redundant )
00716 {
00717 egalite[pos]=-1;
00718
00719 scan_m_face(pos+1,nb_un,D,new_mf);
00720 }
00721 else
00722 {
00723 scan_m_face(pos+1,nb_un-1,D,new_mf);
00724 }
00725 }
00726 }
00727 free(new_mf);
00728 egalite[pos]=0;
00729 if ((pos+nb_un)>=D->NbConstraints) return;
00730 scan_m_face(pos+1,nb_un,D,mf);
00731 return;
00732 }
00733
00734
00735
00736
00737
00738
00739 static SatMatrix *Poly2Sat(Polyhedron *Pol,unsigned int **L) {
00740
00741 SatMatrix *Sat;
00742 int i, j, k, kx;
00743 unsigned int *Temp;
00744 Value *p1, *p2, p3,tmp;
00745 unsigned Dimension, NbRay, NbCon, bx;
00746
00747
00748 value_init(p3); value_init(tmp);
00749
00750 NbRay = Pol->NbRays;
00751 NbCon = Pol->NbConstraints;
00752 Dimension = Pol->Dimension+1;
00753
00754
00755 nr = (NbRay - 1)/(sizeof(int)*8) + 1;
00756 Sat = SMAlloc(NbCon,nr);
00757 Temp = (unsigned int *)malloc(nr*sizeof(unsigned int));
00758 memset(Sat->p_init,0,nr*NbCon*sizeof(int));
00759 memset(Temp,0,nr*sizeof(unsigned int));
00760 kx=0; bx=MSB;
00761 for (k=0; k<NbRay; k++) {
00762 for (i=0; i<NbCon; i++) {
00763 p1 = &Pol->Constraint[i][1];
00764 p2 = &Pol->Ray[k][1];
00765 value_set_si(p3,0);
00766 for (j=0;j<Dimension;j++) {
00767 value_multiply(tmp,*p1,*p2);
00768 value_addto(p3,p3,tmp);
00769 p1++; p2++;
00770 }
00771 if (value_zero_p(p3))
00772 Sat->p[i][kx]|=bx;
00773 }
00774 Temp[kx] |= bx;
00775 NEXT(kx, bx);
00776 }
00777
00778
00779
00780 *L = Temp;
00781
00782
00783 value_clear(p3); value_clear(tmp);
00784
00785 return Sat;
00786 }
00787
00788
00789
00790
00791
00792 Param_Polyhedron *GenParamPolyhedron(Polyhedron *Pol, Matrix *Rays)
00793 {
00794 Param_Polyhedron *result;
00795 int nbRows, nbColumns;
00796 int i, size, rays;
00797
00798 nbRows=Pol->NbRays;
00799 nbColumns=Pol->Dimension+2;
00800
00801
00802 for(i=0, rays=0; i<nbRows; i++)
00803 if(value_notone_p(Pol->Ray[i][0]) ||
00804 value_zero_p(Pol->Ray[i][nbColumns-1]))
00805 ++rays;
00806
00807
00808 result=(Param_Polyhedron *)malloc(sizeof(Param_Polyhedron));
00809 result->nbV=nbRows-rays;
00810 result->V=NULL;
00811 result->Constraints = Polyhedron2Constraints(Pol);
00812 result->Rays = Rays;
00813
00814
00815 for(i=0;i<nbRows;i++) {
00816 Matrix *vertex;
00817 Param_Vertices *paramVertex;
00818 int j;
00819
00820 if (value_notone_p(Pol->Ray[i][0]) ||
00821 value_zero_p(Pol->Ray[i][nbColumns-1]))
00822 continue;
00823
00824 vertex=Matrix_Alloc(nbColumns-2,2);
00825 for(j=1;j<nbColumns-1;j++) {
00826 value_assign(vertex->p[j-1][0],Pol->Ray[i][j]);
00827 value_assign(vertex->p[j-1][1],Pol->Ray[i][nbColumns-1]);
00828 }
00829 paramVertex=(Param_Vertices *)malloc(sizeof(Param_Vertices));
00830 paramVertex->Vertex=vertex;
00831
00832
00833 paramVertex->Domain=Matrix_Alloc(1,2);
00834 value_set_si(paramVertex->Domain->p[0][0],1);
00835 value_set_si(paramVertex->Domain->p[0][1],1);
00836 paramVertex->Facets = NULL;
00837 paramVertex->next=result->V;
00838 result->V=paramVertex;
00839 }
00840
00841
00842 if (nbRows > 1)
00843 size=(nbRows-1)/(8*sizeof(int))+1;
00844 else
00845 size = 1;
00846 result->D=(Param_Domain *)malloc(sizeof(Param_Domain));
00847 result->D->next=NULL;
00848 result->D->Domain=Universe_Polyhedron(0);
00849 result->D->F=(unsigned int *)malloc(size*sizeof(int));
00850 memset(&result->D->F[0],0xFF,size*sizeof(int));
00851
00852 return result;
00853 }
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865 Matrix *PreElim_Columns(Polyhedron *E,int *p,int *ref,int m) {
00866
00867 int i,j,l;
00868 Matrix *T;
00869
00870
00871
00872
00873
00874 memset(p,0,sizeof(int)*(E->NbEq));
00875
00876 #ifdef DEBUGPP32
00877 fprintf(stderr,"\n\nPreElim_Columns starting\n");
00878 fprintf(stderr,"E =\n");
00879 Polyhedron_Print(stderr,P_VALUE_FMT,E);
00880 #endif
00881
00882 for(l=0;l<E->NbEq;++l) {
00883 if(value_notzero_p(E->Constraint[l][0])) {
00884 fprintf(stderr,"Internal error: Elim_Columns (polyparam.c), expecting equalities first in E.\n");
00885 free(p);
00886 return(NULL);
00887 }
00888 for(i=1;value_zero_p(E->Constraint[l][i]);++i) {
00889 if(i==E->Dimension+1) {
00890 fprintf(stderr,"Internal error: Elim_Columns (polyparam.c), expecting non-empty constraint in E.\n");
00891 free(p);
00892 return( NULL );
00893 }
00894 }
00895 p[l] = i;
00896
00897 #ifdef DEBUGPP32
00898 fprintf(stderr,"p[%d] = %d,",l,p[l]);
00899 #endif
00900 }
00901
00902
00903 for(i=0;i<E->Dimension+2-E->NbEq;++i) {
00904 ref[i]=i;
00905 for(j=0;j<E->NbEq;++j)
00906 if(p[j]<=ref[i])
00907 ref[i]++;
00908
00909 #ifdef DEBUGPP32
00910 fprintf(stderr,"ref[%d] = %d,",i,ref[i]);
00911 #endif
00912 }
00913
00914
00915 T = Matrix_Alloc(m+1-E->NbEq,m+1);
00916 for(i=0;i<T->NbColumns;i++)
00917 for(j=0;j<T->NbRows;j++)
00918 if(ref[E->Dimension-m+j+1] == E->Dimension-m+i+1)
00919 value_set_si(T->p[j][i],1);
00920 else
00921 value_set_si(T->p[j][i],0);
00922
00923 #ifdef DEBUGPP32
00924 fprintf(stderr,"\nTransMatrix =\n");
00925 Matrix_Print(stderr,P_VALUE_FMT,T);
00926 #endif
00927
00928 return(T);
00929
00930 }
00931
00932
00933
00934
00935
00936
00937
00938 Polyhedron *Elim_Columns(Polyhedron *A,Polyhedron *E,int *p,int *ref) {
00939
00940 int i,l,c;
00941 Matrix *M, *C;
00942 Polyhedron *R;
00943 Value tmp1,tmp2;
00944
00945
00946 value_init(tmp1); value_init(tmp2);
00947
00948 #ifdef DEBUGPP32
00949 fprintf(stderr,"\nElim_Columns starting\n");
00950 fprintf(stderr,"A =\n" );
00951 Polyhedron_Print(stderr,P_VALUE_FMT,A);
00952 #endif
00953
00954
00955 M = Polyhedron2Constraints(A);
00956 for(l=0;l<E->NbEq;++l) {
00957 for(c=0;c<M->NbRows;++c) {
00958 if(value_notzero_p(M->p[c][p[l]])) {
00959
00960
00961 for(i=1;i<M->NbColumns;++i) {
00962 value_multiply(tmp1,M->p[c][i],E->Constraint[l][p[l]]);
00963 value_multiply(tmp2,E->Constraint[l][i],M->p[c][p[l]]);
00964 value_subtract(M->p[c][i],tmp1,tmp2);
00965 }
00966 }
00967 }
00968 }
00969
00970 #ifdef DEBUGPP32
00971 fprintf(stderr,"\nElim_Columns after zeroing columns of A.\n");
00972 fprintf(stderr,"M =\n");
00973 Matrix_Print(stderr,P_VALUE_FMT,M);
00974 #endif
00975
00976
00977 C = Matrix_Alloc(M->NbRows,M->NbColumns - E->NbEq);
00978 for(l=0;l<C->NbRows;++l)
00979 for(c=0;c<C->NbColumns;++c) {
00980 value_assign(C->p[l][c],M->p[l][ref[c]]);
00981 }
00982
00983 #ifdef DEBUGPP32
00984 fprintf(stderr,"\nElim_Columns after eliminating columns of A.\n");
00985 fprintf(stderr,"C =\n");
00986 Matrix_Print(stderr,P_VALUE_FMT,C);
00987 #endif
00988
00989 R = Constraints2Polyhedron(C,ws);
00990 Matrix_Free(C);
00991 Matrix_Free(M);
00992 value_clear(tmp1); value_clear(tmp2);
00993 return(R);
00994 }
00995
00996
00997 static Polyhedron *Recession_Cone(Polyhedron *P, unsigned nvar, unsigned MaxRays)
00998 {
00999 int i;
01000 Matrix *M = Matrix_Alloc(P->NbConstraints, 1 + nvar + 1);
01001 Polyhedron *R;
01002 for (i = 0; i < P->NbConstraints; ++i)
01003 Vector_Copy(P->Constraint[i], M->p[i], 1+nvar);
01004 R = Constraints2Polyhedron(M, MaxRays);
01005 Matrix_Free(M);
01006 return R;
01007 }
01008
01009
01010
01011
01012
01013
01014
01015
01016 static int ComputeNPLinesRays(int n, Polyhedron *D1, Matrix **Rays)
01017 {
01018 int i, j, nbr, dimfaces;
01019 Polyhedron *RC;
01020
01021 RC = Recession_Cone(D1, n, ws);
01022
01023
01024 nbr = 0;
01025 for (i = 0; i < RC->NbRays ;i++)
01026 if (value_zero_p(RC->Ray[i][n+1]))
01027 nbr++;
01028 *Rays=Matrix_Alloc(nbr, n+2);
01029 for (i = 0, j = 0; j < nbr ;i++)
01030 if (value_zero_p(RC->Ray[i][n+1]))
01031 Vector_Copy(RC->Ray[i], (*Rays)->p[j++], n+2);
01032
01033 dimfaces = RC->NbBid;
01034 Polyhedron_Free(RC);
01035
01036 #ifdef DEBUGPP31
01037 fprintf(stderr, "Rays = ");
01038 Matrix_Print(stderr, P_VALUE_FMT, *Rays);
01039 fprintf(stderr, "dimfaces = %d\n", dimfaces);
01040 #endif
01041
01042 return dimfaces;
01043 }
01044
01045
01046
01047
01048
01049
01050
01051 Param_Polyhedron *Find_m_faces(Polyhedron **Di,Polyhedron *C,int keep_dom,int working_space,Polyhedron **CEq,Matrix **CT) {
01052
01053 unsigned int *mf;
01054 int i, j, dimfaces;
01055 Polyhedron *D=*Di,
01056 *C1,
01057 *D1;
01058 Matrix *Rays,
01059 *M;
01060 Param_Polyhedron *res;
01061 int *p, *ref;
01062
01063 CEqualities = NULL;
01064
01065 if(CT) {
01066 *CEq = NULL;
01067 *CT = NULL;
01068 }
01069
01070 if(!D || !C)
01071 return (Param_Polyhedron *) 0;
01072
01073 ws = working_space;
01074 m = C->Dimension;
01075 n = D->Dimension - m;
01076 if(n<0) {
01077 fprintf(stderr,
01078 "Find_m_faces: ?%d parameters of a %d-polyhedron !\n",m,n);
01079 return (Param_Polyhedron *) 0;
01080 }
01081 if (m==0)
01082 return GenParamPolyhedron(D,Matrix_Alloc(0,2));
01083
01084
01085 C1 = align_context(C,D->Dimension,ws);
01086
01087 #ifdef DEBUGPP31
01088 fprintf(stderr,"m = %d\n",m);
01089 fprintf(stderr, "D = ");
01090 Polyhedron_Print(stderr,P_VALUE_FMT,D);
01091 fprintf(stderr,"C1 = ");
01092 Polyhedron_Print(stderr,P_VALUE_FMT,C1);
01093 #endif
01094
01095 D1 = DomainIntersection(D,C1,ws);
01096
01097 #ifdef DEBUGPP31
01098 fprintf(stderr,"D1 = ");
01099 Polyhedron_Print(stderr,P_VALUE_FMT,D1);
01100 #endif
01101
01102 Domain_Free(C1);
01103
01104 if (!D1)
01105 return(NULL);
01106 if (emptyQ(D1)) {
01107 Polyhedron_Free(D1);
01108 return(NULL);
01109 }
01110
01111
01112
01113 M = Matrix_Alloc(n, D1->Dimension+2);
01114 for (i=0; i<n; i++)
01115 value_set_si(M->p[i][i+1],1);
01116 C1 = DomainAddRays(D1,M,ws);
01117 Matrix_Free(M);
01118
01119 #ifdef DEBUGPP31
01120 fprintf(stderr,"True context C1 = ");
01121 Polyhedron_Print(stderr,P_VALUE_FMT,C1);
01122 #endif
01123
01124 dimfaces = ComputeNPLinesRays(n, D1, &Rays);
01125
01126
01127
01128 if(!CT) {
01129 if (C1->NbEq == 0) {
01130 Polyhedron_Free(C1);
01131 C1 = NULL;
01132 } else {
01133 Polyhedron *CEq1,
01134 *D2;
01135
01136
01137
01138
01139 M = Matrix_Alloc(C1->NbEq,m+2);
01140 for(j=0,i=0;i<C1->NbEq;++i,++j) {
01141 while(value_notzero_p(C1->Constraint[j][0]))
01142 ++j;
01143 value_assign(M->p[i][0],C1->Constraint[j][0]);
01144 Vector_Copy(&C1->Constraint[j][D->Dimension-m+1],&M->p[i][1],(m+1));
01145 }
01146 CEqualities = Constraints2Polyhedron(M,ws);
01147 Matrix_Free(M);
01148 CEq1 = align_context(CEqualities,D->Dimension,ws);
01149
01150
01151 D2 = DomainSimplify(D1,CEq1,ws);
01152 Polyhedron_Free(D1);
01153 Polyhedron_Free(C1);
01154 Polyhedron_Free(CEq1);
01155 D1 = D2;
01156 C1 = NULL;
01157 }
01158 }
01159 else {
01160 Polyhedron *CEq1,
01161 *D2;
01162
01163
01164
01165
01166 CEq1 = C1;
01167 M = Matrix_Alloc(C1->NbConstraints,m+2);
01168 for(i=0;i<C1->NbConstraints;++i) {
01169 value_assign(M->p[i][0],C1->Constraint[i][0]);
01170 Vector_Copy(&C1->Constraint[i][D->Dimension-m+1],&M->p[i][1],(m+1));
01171 }
01172 CEqualities = Constraints2Polyhedron( M, ws );
01173 Matrix_Free(M);
01174
01175 D2 = DomainSimplify(D1,CEq1,ws);
01176 Polyhedron_Free(D1);
01177 D1 = D2;
01178 C1 = Universe_Polyhedron(D2->Dimension);
01179
01180
01181
01182
01183 if( CEq1->NbEq )
01184 {
01185 m -= CEq1->NbEq;
01186 p = (int *)malloc(sizeof(int)*(CEq1->NbEq));
01187 }
01188 else
01189 p = NULL;
01190 ref = (int*) malloc(sizeof(int)*
01191 (CEq1->Dimension+2-CEq1->NbEq));
01192 *CT = PreElim_Columns(CEq1,p,ref,CEqualities->Dimension);
01193 D2 = Elim_Columns(D1,CEq1,p,ref);
01194 if (p)
01195 free(p);
01196 free(ref);
01197
01198 #ifdef DEBUGPP3
01199 fprintf(stderr,"D2\t Dim = %3d\tNbEq = %3d\tLines = %3d\n",
01200 D2->Dimension,D2->NbEq,D2->NbBid);
01201 C2 = Elim_Columns(C1,CEq1,p,ref);
01202 fprintf(stderr,"C2\t Dim = %3d\tNbEq = %3d\tLines = %3d\n",
01203 C2->Dimension,C2->NbEq,C2->NbBid);
01204 Polyhedron_Free(C2);
01205 #endif
01206
01207 Polyhedron_Free(D1);
01208 Polyhedron_Free(C1);
01209 D1 = D2;
01210 C1 = NULL;
01211 *CEq = CEqualities;
01212
01213 #ifdef DEBUGPP3
01214 fprintf(stderr,"Polyhedron CEq = ");
01215 Polyhedron_Print(stderr,P_VALUE_FMT,*CEq);
01216 fprintf(stderr,"Matrix CT = ");
01217 Matrix_Print(stderr,P_VALUE_FMT,*CT);
01218 #endif
01219
01220 Polyhedron_Free(CEq1);
01221 CEqualities = NULL;
01222
01223
01224 if(m==0) {
01225
01226 *Di = D1;
01227
01228 return GenParamPolyhedron(D1, Rays);
01229 }
01230 }
01231
01232 #ifdef DEBUGPP3
01233 fprintf(stderr,"Polyhedron D1 (D AND C) = ");
01234 Polyhedron_Print(stderr,P_VALUE_FMT, D1);
01235 fprintf(stderr,"Polyhedron CEqualities = ");
01236 if(CEqualities) Polyhedron_Print(stderr,P_VALUE_FMT, CEqualities);
01237 else fprintf(stderr,"NULL\n");
01238 #endif
01239
01240 KD = keep_dom;
01241 PDomains = NULL;
01242 PV_Result = NULL;
01243 nbPV = 0;
01244
01245 if (emptyQ(D1)) {
01246 Polyhedron_Free(D1);
01247 Matrix_Free(Rays);
01248 return NULL;
01249 }
01250
01251
01252
01253
01254 Sat = Poly2Sat(D1,&mf);
01255
01256 #ifdef DEBUGPP4
01257 fprintf(stderr,"Sat = ");
01258 SMPrint(Sat);
01259
01260 fprintf(stderr,"mf = ");
01261 for (i=0; i<nr; i++)
01262 fprintf(stderr,"%08X", mf[i]);
01263 fprintf(stderr, "\n");
01264 #endif
01265
01266
01267 egalite = (unsigned int *)malloc(sizeof(int)*D1->NbConstraints);
01268 memset(egalite,0, sizeof(int)*D1->NbConstraints);
01269
01270 for (i=0; i<D1->NbEq; i++)
01271 egalite[i] = 1;
01272
01273 Xi = Matrix_Alloc(n+1,m+1);
01274 Pi = Matrix_Alloc(m+1,m+1);
01275 PiTest = Matrix_Alloc(m+1,m+1);
01276 CTest = Matrix_Alloc(D->Dimension+1,D->NbConstraints);
01277 PiInv = Matrix_Alloc(m+1,m+2);
01278 RaysDi = Matrix_Alloc(D1->NbRays,m+2);
01279 m_dim = m;
01280
01281
01282
01283
01284 m_dim += dimfaces;
01285
01286
01287
01288
01289 #ifdef DEBUGPP3
01290 if (m_dim < D1->NbBid)
01291 fprintf(stderr, "m_dim (%d) < D1->NbBid (%d)\n", m_dim, D1->NbBid );
01292 #endif
01293 if (m_dim < D1->NbBid)
01294 m_dim = D1->NbBid;
01295
01296 #ifdef DEBUGPP
01297 nbfaces=0;
01298 #endif
01299 #ifdef DEBUGPP3
01300 fprintf(stderr, "m_dim = %d\n", m_dim);
01301 fprintf(stderr,
01302 "Target: find faces that saturate %d constraints and %d rays/lines\n",
01303 D1->Dimension - m_dim,m_dim+1);
01304 #endif
01305
01306
01307 scan_m_face(D1->NbEq,(D1->Dimension - m_dim - D1->NbEq),D1,mf);
01308
01309
01310
01311 #ifdef DEBUGPP
01312 fprintf( stderr, "Number of m-faces: %d\n", nbfaces );
01313 #endif
01314
01315 Matrix_Free(RaysDi);
01316 Matrix_Free(PiInv);
01317 Matrix_Free(PiTest);
01318 Matrix_Free(CTest);
01319 Matrix_Free(Pi);
01320 Matrix_Free(Xi);
01321 free(egalite);
01322 free(mf);
01323 SMFree(Sat);
01324
01325
01326
01327
01328
01329
01330 res = (Param_Polyhedron *) malloc (sizeof(Param_Polyhedron));
01331 res->nbV = nbPV;
01332 res->V = PV_Result;
01333 res->D = PDomains;
01334 res->Constraints = Polyhedron2Constraints(D1);
01335 res->Rays = Rays;
01336
01337 if(CT)
01338 *Di = D1;
01339 else
01340 Domain_Free(D1);
01341
01342 return(res);
01343 }
01344
01345
01346
01347
01348
01349 void Compute_PDomains(Param_Domain *PD,int nb_domains,int working_space) {
01350
01351 unsigned bx;
01352 int i, ix, nv;
01353 Polyhedron *dx, *d1, *d2;
01354 Param_Domain *p1, *p2, *p2prev, *PDNew;
01355
01356 if (nb_domains==0) {
01357
01358 #ifdef DEBUGPP5
01359 fprintf(stderr,"No domains\n");
01360 #endif
01361
01362 return;
01363 }
01364
01365
01366 if (!PD->next && PD->F)
01367 return;
01368
01369
01370 nv = (nb_domains - 1)/(8*sizeof(int)) + 1;
01371
01372 #ifdef DEBUGPP5
01373 fprintf(stderr,"nv = %d\n",nv);
01374 #endif
01375
01376 for(p1=PD,i=0,ix=0,bx=MSB;p1;p1=p1->next,i++) {
01377
01378
01379 p1->F = (unsigned *) malloc (nv * sizeof(unsigned));
01380
01381
01382 memset(p1->F,0,nv * sizeof(unsigned));
01383 p1->F[ix] |= bx;
01384 NEXT(ix, bx);
01385 }
01386
01387 #ifdef DEBUGPP5
01388 fprintf(stderr,"nb of vertices=%d\n",i);
01389 #endif
01390
01391
01392 ix = 0; bx=MSB;
01393 for (p1=PD;p1;p1=p1->next) {
01394 for (p2prev=p1,p2=p1->next;p2;p2prev=p2,p2=p2->next) {
01395
01396
01397 dx = PDomainIntersection(p1->Domain,p2->Domain,working_space);
01398
01399 if (!dx || emptyQ(dx)) {
01400
01401 #ifdef DEBUGPP5
01402 fprintf( stderr, "Empty dx (p1 inter p2). Continuing\n");
01403 #endif
01404 if(dx)
01405 Domain_Free(dx);
01406 continue;
01407 }
01408
01409 #ifdef DEBUGPP5
01410 fprintf(stderr,"Begin PDomainDifference\n");
01411 fprintf(stderr, "p1=");
01412 Polyhedron_Print(stderr,P_VALUE_FMT,p1->Domain);
01413 fprintf(stderr,"p2=");
01414 Polyhedron_Print(stderr,P_VALUE_FMT,p2->Domain);
01415 #endif
01416 d1 = PDomainDifference(p1->Domain,p2->Domain,working_space);
01417 d2 = PDomainDifference(p2->Domain,p1->Domain,working_space);
01418
01419 #ifdef DEBUGPP5
01420 fprintf(stderr,"p1\\p2=");
01421 Polyhedron_Print(stderr,P_VALUE_FMT,d1);
01422 fprintf(stderr,"p2\\p1=");
01423 Polyhedron_Print(stderr,P_VALUE_FMT,d2);
01424 fprintf(stderr,"END PDomainDifference\n\n");
01425 #endif
01426 if (!d1 || emptyQ(d1) || d1->NbEq!=0) {
01427
01428 #ifdef DEBUGPP5
01429 fprintf(stderr,"Empty d1\n");
01430 #endif
01431 if (d1)
01432 Domain_Free(d1);
01433 Domain_Free(dx);
01434
01435 if (!d2 || emptyQ(d2) || d2->NbEq!=0) {
01436
01437 #ifdef DEBUGPP5
01438 fprintf( stderr, "Empty d2 (deleting)\n");
01439 #endif
01440
01441 if (d2) Domain_Free(d2);
01442
01443
01444 for (i=0;i<nv;i++)
01445 p1->F[i] |= p2->F[i];
01446
01447
01448 p2prev->next = p2->next;
01449 Domain_Free(p2->Domain);
01450 free(p2->F);
01451 free(p2);
01452 p2 = p2prev;
01453 }
01454 else {
01455
01456 #ifdef DEBUGPP5
01457 fprintf( stderr, "p2 replaced by d2\n");
01458 #endif
01459
01460 for(i=0;i<nv;i++)
01461 p1->F[i] |= p2->F[i];
01462
01463
01464 Domain_Free( p2->Domain );
01465 p2->Domain = d2;
01466 }
01467 }
01468 else {
01469 if (!d2 || emptyQ(d2) || d2->NbEq!=0) {
01470
01471 #ifdef DEBUGPP5
01472 fprintf( stderr, "p1 replaced by d1\n");
01473 #endif
01474 if (d2) Domain_Free(d2);
01475
01476
01477 Domain_Free(dx);
01478
01479
01480 for(i=0;i<nv;i++)
01481 p2->F[i] |= p1->F[i];
01482
01483
01484 Domain_Free(p1->Domain);
01485 p1->Domain = d1;
01486 }
01487 else {
01488
01489 #ifdef DEBUGPP5
01490 fprintf(stderr,"Non-empty d1 and d2\nNew node created\n");
01491 #endif
01492
01493 PDNew = (Param_Domain *) malloc( sizeof(Param_Domain) );
01494 PDNew->F = (unsigned int *)malloc( nv*sizeof(int) );
01495 memset(PDNew->F,0,nv*sizeof(int));
01496 PDNew->Domain = dx;
01497
01498 for (i=0;i<nv;i++)
01499 PDNew->F[i] = p1->F[i] | p2->F[i];
01500
01501
01502 Domain_Free( p1->Domain );
01503 p1->Domain = d1;
01504
01505
01506 Domain_Free( p2->Domain );
01507 p2->Domain = d2;
01508
01509
01510 PDNew->next = p1->next;
01511 p1->next = PDNew;
01512 }
01513 }
01514 }
01515 if (p1->Domain->next) {
01516 Polyhedron *C = DomainConvex(p1->Domain, working_space);
01517 Domain_Free(p1->Domain);
01518 p1->Domain = C;
01519 }
01520 }
01521 }
01522
01523
01524
01525
01526
01527
01528
01529 Param_Polyhedron *Polyhedron2Param_Vertices(Polyhedron *Din,Polyhedron *Cin,int working_space) {
01530
01531 Param_Polyhedron *result;
01532
01533 POL_ENSURE_FACETS(Din);
01534 POL_ENSURE_VERTICES(Din);
01535 POL_ENSURE_FACETS(Cin);
01536 POL_ENSURE_VERTICES(Cin);
01537
01538 #ifdef DEBUGPP
01539 fprintf(stderr,"Polyhedron2Param_Vertices algorithm starting at : %.2fs\n",
01540 (float)clock()/CLOCKS_PER_SEC);
01541 #endif
01542
01543
01544 result = Find_m_faces(&Din,Cin,0,working_space,NULL,NULL);
01545
01546 #ifdef DEBUGPP
01547 fprintf(stderr, "nb of points : %d\n",result->nbV);
01548 #endif
01549
01550 #ifdef DEBUGPP
01551 fprintf(stderr, "end main loop : %.2fs\n", (float)clock()/CLOCKS_PER_SEC);
01552 #endif
01553
01554 return(result);
01555 }
01556
01557
01558
01559
01560 void Param_Vertices_Free(Param_Vertices *PV) {
01561
01562 Param_Vertices *next_pv;
01563
01564 while(PV) {
01565 next_pv = PV->next;
01566 if (PV->Vertex) Matrix_Free(PV->Vertex);
01567 if (PV->Domain) Matrix_Free(PV->Domain);
01568 if (PV->Facets) free(PV->Facets);
01569 free(PV);
01570 PV = next_pv;
01571 }
01572 }
01573
01574
01575
01576
01577 void Print_Vertex(FILE *DST, Matrix *V, const char **param_names)
01578 {
01579 int l, v;
01580 int first;
01581 Value gcd,tmp;
01582
01583 value_init(gcd); value_init(tmp);
01584
01585 fprintf(DST, "[" );
01586 for(l=0;l<V->NbRows;++l){
01587
01588
01589 first=1;
01590 fprintf(DST, " " );
01591 for(v=0;v < V->NbColumns-2;++v) {
01592 if(value_notzero_p(V->p[l][v])) {
01593 value_gcd(gcd, V->p[l][v], V->p[l][V->NbColumns-1]);
01594 value_divexact(tmp, V->p[l][v], gcd);
01595 if(value_posz_p(tmp)) {
01596 if(!first)
01597 fprintf(DST, "+");
01598 if(value_notone_p(tmp)) {
01599 value_print(DST,VALUE_FMT,tmp);
01600 }
01601 }
01602 else {
01603 if(value_mone_p(tmp))
01604 fprintf(DST, "-" );
01605 else {
01606 value_print(DST,VALUE_FMT,tmp);
01607 }
01608 }
01609 value_divexact(tmp, V->p[l][V->NbColumns-1], gcd);
01610 if(value_notone_p(tmp)) {
01611 fprintf(DST, "%s/", param_names[v]);
01612 value_print(DST,VALUE_FMT,tmp);
01613 }
01614 else
01615 fprintf(DST, "%s", param_names[v]);
01616 first=0;
01617 }
01618 }
01619
01620
01621 if(value_notzero_p(V->p[l][v]) || first) {
01622 if(value_posz_p(V->p[l][v]) && !first)
01623 fprintf(DST,"+");
01624 value_gcd(gcd, V->p[l][v], V->p[l][V->NbColumns-1]);
01625 value_divexact(tmp, V->p[l][v], gcd);
01626 value_print(DST,VALUE_FMT,tmp);
01627 value_divexact(tmp, V->p[l][V->NbColumns-1], gcd);
01628 if(value_notone_p(tmp)) {
01629 fprintf(DST,"/");
01630 value_print(DST,VALUE_FMT,tmp);
01631 fprintf(DST," ");
01632 }
01633 }
01634 if (l<V->NbRows-1)
01635 fprintf(DST, ", ");
01636 }
01637 fprintf(DST, " ]");
01638 value_clear(gcd); value_clear(tmp);
01639 return;
01640 }
01641
01642
01643
01644
01645
01646 Matrix *VertexCT(Matrix *V,Matrix *CT) {
01647
01648 Matrix *Vt;
01649 int i,j,k;
01650
01651 if(CT) {
01652
01653
01654 Vt = Matrix_Alloc(V->NbRows,CT->NbColumns+1);
01655 for(i=0;i<V->NbRows;++i) {
01656 value_assign(Vt->p[i][CT->NbColumns],V->p[i][V->NbColumns-1]);
01657 for(j=0;j<CT->NbColumns;j++) {
01658 for(k=0;k<CT->NbRows;k++)
01659 if(value_notzero_p(CT->p[k][j]))
01660 break;
01661 if(k<CT->NbRows)
01662 value_assign(Vt->p[i][j],V->p[i][k]);
01663 else
01664 value_set_si(Vt->p[i][j],0);
01665 }
01666 }
01667 return(Vt);
01668 }
01669 else
01670 return(NULL);
01671 }
01672
01673
01674
01675
01676 void Print_Domain(FILE *DST, Polyhedron *D, const char **pname)
01677 {
01678 int l, v;
01679 int first;
01680
01681 POL_ENSURE_FACETS(D);
01682 POL_ENSURE_VERTICES(D);
01683
01684 for(l=0;l<D->NbConstraints;++l) {
01685 fprintf(DST, " ");
01686 first = 1;
01687 for(v=1;v<=D->Dimension;++v) {
01688 if(value_notzero_p(D->Constraint[l][v])) {
01689 if(value_one_p(D->Constraint[l][v])) {
01690 if(first)
01691 fprintf(DST, "%s ", pname[v-1]);
01692 else
01693 fprintf(DST, "+ %s ", pname[v-1] );
01694 }
01695 else if(value_mone_p(D->Constraint[l][v]))
01696 fprintf(DST, "- %s ", pname[v-1] );
01697 else {
01698 if(value_pos_p(D->Constraint[l][v]) && !first )
01699 fprintf(DST, "+ " );
01700 value_print(DST,VALUE_FMT,D->Constraint[l][v]);
01701 fprintf(DST,"%s ",pname[v-1]);
01702 }
01703 first = 0;
01704 }
01705 }
01706 if(value_notzero_p(D->Constraint[l][v])) {
01707 if(value_pos_p(D->Constraint[l][v]) && !first)
01708 fprintf(DST,"+");
01709 fprintf(DST," ");
01710 value_print(DST,VALUE_FMT,D->Constraint[l][v]);
01711 }
01712 fprintf(DST,(value_notzero_p(D->Constraint[l][0])) ?" >= 0":" = 0");
01713 fprintf(DST, "\n" );
01714 }
01715 fprintf(DST, "\n");
01716
01717 if( D->next )
01718 {
01719 fprintf( DST, "UNION\n" );
01720 Print_Domain( DST, D->next, pname );
01721 }
01722 return;
01723 }
01724
01725
01726
01727
01728
01729 void Param_Vertices_Print(FILE *DST, Param_Vertices *PV, const char **param_names)
01730 {
01731 Polyhedron *poly;
01732
01733 while(PV) {
01734 fprintf(DST, "Vertex :\n" );
01735 Print_Vertex(DST,PV->Vertex,param_names);
01736
01737
01738 fprintf(DST, " If :\n" );
01739 poly = Constraints2Polyhedron(PV->Domain,200);
01740 Print_Domain(DST,poly,param_names);
01741 Domain_Free(poly);
01742 PV = PV->next;
01743 }
01744 return;
01745 }
01746
01747
01748
01749
01750
01751
01752
01753
01754 Param_Polyhedron *Polyhedron2Param_Domain(Polyhedron *Din,Polyhedron *Cin,int working_space) {
01755
01756 Param_Polyhedron *result;
01757 Param_Domain *D;
01758
01759 POL_ENSURE_FACETS(Din);
01760 POL_ENSURE_VERTICES(Din);
01761 POL_ENSURE_FACETS(Cin);
01762 POL_ENSURE_VERTICES(Cin);
01763
01764 if (emptyQ(Din) || emptyQ(Cin))
01765 return NULL;
01766
01767 #ifdef DEBUGPP
01768 fprintf(stderr,"Polyhedron2Param_Polyhedron algorithm starting at : %.2fs\n",
01769 (float)clock()/CLOCKS_PER_SEC);
01770 #endif
01771
01772
01773
01774 result = Find_m_faces(&Din,Cin,1,working_space,NULL,NULL);
01775
01776 #ifdef DEBUGPP
01777 if(result) fprintf(stderr, "Number of vertices : %d\n",result->nbV);
01778 fprintf(stderr,"Vertices found at : %.2fs\n",(float)clock()/CLOCKS_PER_SEC);
01779 #endif
01780
01781
01782 if(result && Cin->Dimension>0)
01783 Compute_PDomains(result->D,result->nbV,working_space);
01784 if(result && CEqualities)
01785 for(D=result->D;D;D=D->next)
01786 D->Domain = Add_CEqualities(D->Domain);
01787 Polyhedron_Free(CEqualities);
01788
01789 #ifdef DEBUGPP
01790 fprintf(stderr, "domains found at : %.2fs\n", (float)clock()/CLOCKS_PER_SEC);
01791 #endif
01792
01793 return(result);
01794 }
01795
01796
01797
01798
01799 Param_Polyhedron *Polyhedron2Param_SimplifiedDomain(Polyhedron **Din,Polyhedron *Cin,int working_space,Polyhedron **CEq,Matrix **CT) {
01800
01801 Param_Polyhedron *result;
01802
01803 assert(CEq != NULL);
01804 assert(CT != NULL);
01805
01806 POL_ENSURE_FACETS(*Din);
01807 POL_ENSURE_VERTICES(*Din);
01808 POL_ENSURE_FACETS(Cin);
01809 POL_ENSURE_VERTICES(Cin);
01810
01811 #ifdef DEBUGPP
01812 fprintf(stderr,"Polyhedron2Param_Polyhedron algorithm starting at : %.2fs\n",
01813 (float)clock()/CLOCKS_PER_SEC);
01814 #endif
01815
01816
01817
01818 result = Find_m_faces(Din,Cin,1,working_space,CEq,CT);
01819
01820 #ifdef DEBUGPP
01821 if(result) fprintf(stderr, "Number of vertices : %d\n",result->nbV);
01822 fprintf(stderr,"Vertices found at : %.2fs\n",(float)clock()/CLOCKS_PER_SEC);
01823 #endif
01824
01825
01826 if(result && Cin->Dimension>0)
01827 Compute_PDomains(result->D,result->nbV,working_space);
01828
01829
01830
01831
01832
01833
01834
01835 #ifdef DEBUGPP
01836 fprintf(stderr, "domains found at : %.2fs\n", (float)clock()/CLOCKS_PER_SEC);
01837 #endif
01838
01839 return(result);
01840 }
01841
01842
01843
01844
01845
01846 void Param_Domain_Free(Param_Domain *PD) {
01847
01848 Param_Domain *next_pd;
01849
01850 while(PD) {
01851 free(PD->F);
01852 Domain_Free(PD->Domain);
01853 next_pd = PD->next;
01854 free(PD);
01855 PD = next_pd;
01856 }
01857 return;
01858 }
01859
01860
01861
01862
01863 void Param_Polyhedron_Free(Param_Polyhedron *P) {
01864
01865 if (!P) return;
01866 Param_Vertices_Free(P->V);
01867 Param_Domain_Free(P->D);
01868 if (P->Constraints)
01869 Matrix_Free(P->Constraints);
01870 if (P->Rays)
01871 Matrix_Free(P->Rays);
01872 free(P);
01873 return;
01874 }
01875
01876
01877
01878
01879 void Param_Polyhedron_Scale_Integer(Param_Polyhedron *PP, Polyhedron **P,
01880 Value *det, unsigned MaxRays)
01881 {
01882 int i;
01883 int nb_param, nb_vars;
01884 Vector *denoms;
01885 Param_Vertices *V;
01886 Value global_var_lcm;
01887 Matrix *expansion;
01888
01889 value_set_si(*det, 1);
01890 if (!PP->nbV)
01891 return;
01892
01893 nb_param = PP->D->Domain->Dimension;
01894 nb_vars = PP->V->Vertex->NbRows;
01895
01896
01897
01898
01899 denoms = Vector_Alloc(nb_vars);
01900 value_init(global_var_lcm);
01901
01902
01903 for (V = PP->V; V; V = V->next)
01904 for (i = 0; i < nb_vars; i++)
01905 value_lcm(denoms->p[i], denoms->p[i], V->Vertex->p[i][nb_param+1]);
01906
01907 value_set_si(global_var_lcm, 1);
01908 for (i = 0; i < nb_vars; i++) {
01909 value_multiply(*det, *det, denoms->p[i]);
01910 value_lcm(global_var_lcm, global_var_lcm, denoms->p[i]);
01911 }
01912
01913
01914 for (V = PP->V; V; V = V->next)
01915 for (i = 0; i < nb_vars; i++) {
01916 Vector_Scale(V->Vertex->p[i], V->Vertex->p[i], denoms->p[i], nb_param+1);
01917 Vector_Normalize(V->Vertex->p[i], nb_param+2);
01918 }
01919
01920
01921
01922 for (i = 0; i < nb_vars; i++)
01923 value_division(denoms->p[i], global_var_lcm, denoms->p[i]);
01924
01925
01926
01927 expansion = Matrix_Alloc(nb_vars+nb_param+1, nb_vars+nb_param+1);
01928 for (i = 0; i < nb_vars; i++)
01929 value_assign(expansion->p[i][i], denoms->p[i]);
01930 for (i = nb_vars; i < nb_vars+nb_param+1; i++)
01931 value_assign(expansion->p[i][i], global_var_lcm);
01932
01933
01934 if (P)
01935 *P = Polyhedron_Preimage(*P, expansion, MaxRays);
01936
01937 Matrix_Free(expansion);
01938 value_clear(global_var_lcm);
01939 Vector_Free(denoms);
01940 }