00001
00002 #include <stdio.h>
00003 #include <polylib/polylib.h>
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <stdio.h>
00020 #include <stdlib.h>
00021 #include <string.h>
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 static int exist_points(int pos,Polyhedron *Pol,Value *context) {
00033
00034 Value LB, UB, k,tmp;
00035
00036 value_init(LB); value_init(UB);
00037 value_init(k); value_init(tmp);
00038 value_set_si(LB,0);
00039 value_set_si(UB,0);
00040
00041
00042 if (lower_upper_bounds(pos,Pol,context,&LB,&UB) !=0) {
00043 errormsg1("exist_points", "infdom", "infinite domain");
00044 value_clear(LB);
00045 value_clear(UB);
00046 value_clear(k);
00047 value_clear(tmp);
00048 return -1;
00049 }
00050 value_set_si(context[pos],0);
00051 if(value_lt(UB,LB)) {
00052 value_clear(LB);
00053 value_clear(UB);
00054 value_clear(k);
00055 value_clear(tmp);
00056 return 0;
00057 }
00058 if (!Pol->next) {
00059 value_substract(tmp,UB,LB);
00060 value_increment(tmp,tmp);
00061 value_clear(UB);
00062 value_clear(LB);
00063 value_clear(k);
00064 return (value_pos_p(tmp));
00065 }
00066
00067 for (value_assign(k,LB);value_le(k,UB);value_increment(k,k)) {
00068
00069
00070 value_assign(context[pos],k);
00071 if (exist_points(pos+1,Pol->next,context) > 0 ) {
00072 value_clear(LB); value_clear(UB);
00073 value_clear(k); value_clear(tmp);
00074 return 1;
00075 }
00076 }
00077
00078 value_set_si(context[pos],0);
00079 value_clear(UB); value_clear(LB);
00080 value_clear(k); value_clear(tmp);
00081 return 0;
00082 }
00083
00084
00085
00086
00087 int Polyhedron_Not_Empty(Polyhedron *P,Polyhedron *C,int MAXRAYS) {
00088
00089 int res,i;
00090 Value *context;
00091 Polyhedron *L;
00092
00093
00094 context = (Value *) malloc((P->Dimension+2)*sizeof(Value));
00095
00096
00097 for (i=0;i<(P->Dimension+2);i++)
00098 value_init(context[i]);
00099
00100 Vector_Set(context,0,(P->Dimension+2));
00101
00102
00103 value_set_si(context[P->Dimension+1],1);
00104
00105 L = Polyhedron_Scan(P,C,MAXRAYS);
00106 res = exist_points(1,L,context);
00107 Domain_Free(L);
00108
00109
00110 for (i=0;i<(P->Dimension+2);i++)
00111 value_clear(context[i]);
00112 free(context);
00113 return res;
00114 }
00115
00116
00117
00118
00119
00120
00121
00122 int PolyhedronLTQ (Polyhedron *Pol1,Polyhedron *Pol2,int INDEX, int PDIM, int NbMaxConstrs) {
00123
00124 int res, dim, i, j, k;
00125 Polyhedron *Q1, *Q2, *Q3, *Q4, *Q;
00126 Matrix *Mat;
00127
00128 if (Pol1->next || Pol2->next) {
00129 errormsg1("PolyhedronLTQ", "compoly", "Can only compare polyhedra");
00130 return 0;
00131 }
00132 if (Pol1->Dimension != Pol2->Dimension) {
00133 errormsg1("PolyhedronLTQ","diffdim","Polyhedra are not same dimension");
00134 return 0;
00135 }
00136 dim = Pol1->Dimension+2;
00137
00138 #ifdef DEBUG
00139 fprintf(stdout, "P1\n");
00140 Polyhedron_Print(stdout,P_VALUE_FMT,Pol1);
00141 fprintf(stdout, "P2\n");
00142 Polyhedron_Print(stdout,P_VALUE_FMT,Pol2);
00143 #endif
00144
00145
00146 k = Pol1->Dimension-INDEX+1-PDIM;
00147 Mat = Matrix_Alloc(k,dim);
00148 Vector_Set(Mat->p_Init,0,dim*k);
00149 for(j=0,i=INDEX;j<k;i++,j++)
00150 value_set_si(Mat->p[j][i],1);
00151
00152 Q1 = AddRays(Mat->p[0],k,Pol1,NbMaxConstrs);
00153 Q2 = AddRays(Mat->p[0],k,Pol2,NbMaxConstrs);
00154
00155 #ifdef DEBUG
00156 fprintf(stdout, "Q1\n");
00157 Polyhedron_Print(stdout,P_VALUE_FMT,Q1);
00158 fprintf(stdout, "Q2\n");
00159 Polyhedron_Print(stdout,P_VALUE_FMT,Q2);
00160 #endif
00161
00162 Matrix_Free(Mat);
00163 Q = DomainIntersection(Q1,Q2,NbMaxConstrs);
00164
00165 #ifdef DEBUG
00166 fprintf(stdout, "Q\n");
00167 Polyhedron_Print(stdout,P_VALUE_FMT,Q);
00168 #endif
00169
00170 Domain_Free(Q1);
00171 Domain_Free(Q2);
00172
00173 if (emptyQ(Q)) res = 0;
00174 else {
00175 Q1 = DomainIntersection(Pol1,Q,NbMaxConstrs);
00176 Q2 = DomainIntersection(Pol2,Q,NbMaxConstrs);
00177
00178 #ifdef DEBUG
00179 fprintf(stdout, "Q1\n");
00180 Polyhedron_Print(stdout,P_VALUE_FMT,Q1);
00181 fprintf(stdout, "Q2\n");
00182 Polyhedron_Print(stdout,P_VALUE_FMT,Q2);
00183 #endif
00184
00185 k = Q1->NbConstraints + Q2->NbConstraints;
00186 Mat = Matrix_Alloc(k, dim);
00187 Vector_Set(Mat->p_Init,0,k*dim);
00188
00189
00190 j=0;
00191 for (i=0; i<Q1->NbConstraints; i++) {
00192 if ((value_one_p(Q1->Constraint[i][0])) && (value_pos_p(Q1->Constraint[i][INDEX]))) {
00193
00194
00195 for (k=0; k<dim; k++)
00196 value_assign(Mat->p[j][k],Q1->Constraint[i][k]);
00197 j++;
00198 }
00199 }
00200 for (i=0; i<Q2->NbConstraints; i++) {
00201 if ((value_one_p(Q2->Constraint[i][0])) && (value_neg_p(Q2->Constraint[i][INDEX]))) {
00202
00203
00204 for (k=0; k<dim; k++)
00205 value_assign(Mat->p[j][k],Q2->Constraint[i][k]);
00206 j++;
00207 }
00208 }
00209 Q4 = AddConstraints(Mat->p[0], j, Q, NbMaxConstrs);
00210 Matrix_Free(Mat);
00211
00212 #ifdef debug
00213 fprintf(stderr, "Q4 surrounding polyhedron\n");
00214 Polyhderon_Print(stderr,P_VALUE_FMT, Q4);
00215 #endif
00216
00217
00218 if (emptyQ(Q4)) {
00219 res = 1;
00220
00221 #ifdef debug
00222 fprintf(stderr, "Surrounding polyhedron is empty\n");
00223 #endif
00224 goto LTQdone2;
00225 }
00226
00227
00228
00229 Mat = Matrix_Alloc(2,dim);
00230 Vector_Set(Mat->p_Init,0,2*dim);
00231
00232
00233 for (i=0; i<Q1->NbConstraints; i++) {
00234 if (value_zero_p(Q1->Constraint[i][0])) {
00235
00236
00237 if (value_zero_p(Q1->Constraint[i][INDEX])) {
00238
00239
00240 continue;
00241 }
00242 else if (value_neg_p(Q1->Constraint[i][INDEX])) {
00243
00244
00245 value_set_si(Mat->p[0][0],1);
00246 for (k=1; k<dim; k++)
00247 value_oppose(Mat->p[0][k],Q1->Constraint[i][k]);
00248 }
00249 else {
00250
00251
00252
00253 value_set_si(Mat->p[0][0],1);
00254 for (k=1; k<dim; k++)
00255 value_assign(Mat->p[0][k],Q1->Constraint[i][k]);
00256 }
00257 }
00258 else if(value_neg_p(Q1->Constraint[i][INDEX])) {
00259
00260
00261 value_set_si(Mat->p[0][0],1);
00262 for (k=1; k<dim; k++)
00263 value_oppose(Mat->p[0][k],Q1->Constraint[i][k]);
00264 }
00265 else {
00266
00267
00268 continue;
00269 }
00270
00271
00272 for (j=0; j<Q2->NbConstraints; j++) {
00273 if (value_zero_p(Q2->Constraint[j][0])) {
00274 if (value_zero_p(Q2->Constraint[j][INDEX])) {
00275
00276
00277 continue;
00278 }
00279 else if (value_pos_p(Q2->Constraint[j][INDEX])) {
00280
00281
00282 value_set_si(Mat->p[1][0],1);
00283 for (k=1; k<dim; k++)
00284 value_oppose(Mat->p[1][k],Q2->Constraint[j][k]);
00285 }
00286 else {
00287
00288
00289 value_set_si(Mat->p[1][0],1);
00290 for (k=1; k<dim; k++)
00291 value_assign(Mat->p[1][k],Q2->Constraint[j][k]);
00292 };
00293 }
00294 else if (value_pos_p(Q2->Constraint[j][INDEX])) {
00295
00296
00297 value_set_si(Mat->p[1][0],1);
00298 for(k=1;k<dim;k++)
00299 value_oppose(Mat->p[1][k],Q2->Constraint[j][k]);
00300 }
00301 else {
00302
00303
00304 continue;
00305 };
00306
00307 #ifdef DEBUG
00308 fprintf(stdout, "i=%d j=%d M=\n", i+1, j+1);
00309 Matrix_Print(stdout,P_VALUE_FMT,Mat);
00310 #endif
00311
00312
00313 Q3 = AddConstraints(Mat->p[0],2,Q,NbMaxConstrs);
00314
00315 #ifdef DEBUG
00316 fprintf(stdout, "Q3\n");
00317 Polyhedron_Print(stdout,P_VALUE_FMT,Q3);
00318 #endif
00319
00320 if (!emptyQ(Q3)) {
00321 Domain_Free(Q3);
00322
00323 #ifdef DEBUG
00324 fprintf(stdout, "not empty\n");
00325 #endif
00326 res = -1;
00327 goto LTQdone;
00328 }
00329 #ifdef DEBUG
00330 fprintf(stdout,"empty\n");
00331 #endif
00332 Domain_Free(Q3);
00333 }
00334 }
00335 res = 1;
00336 LTQdone:
00337 Matrix_Free(Mat);
00338 LTQdone2:
00339 Domain_Free(Q4);
00340 Domain_Free(Q1);
00341 Domain_Free(Q2);
00342 }
00343 Domain_Free(Q);
00344
00345 #ifdef DEBUG
00346 fprintf(stdout, "res = %d\n", res);
00347 #endif
00348
00349 return res;
00350 }
00351
00352
00353
00354
00355
00356
00357 int GaussSimplify(Matrix *Mat1,Matrix *Mat2) {
00358
00359 int NbRows = Mat1->NbRows;
00360 int NbCols = Mat1->NbColumns;
00361 int *column_index;
00362 int i, j, k, n, t, pivot, Rank;
00363 Value gcd, tmp, *cp;
00364
00365 column_index=(int *)malloc(NbCols * sizeof(int));
00366 if (!column_index) {
00367 errormsg1("GaussSimplify", "outofmem", "out of memory space\n");
00368 Pol_status = 1;
00369 return 0;
00370 }
00371
00372
00373 value_init(gcd); value_init(tmp);
00374
00375 Rank=0;
00376 for (j=0; j<NbCols; j++) {
00377 for (i=Rank; i<NbRows; i++)
00378 if (value_notzero_p(Mat1->p[i][j]))
00379 break;
00380 if (i!=NbRows) {
00381 if (i!=Rank)
00382 Vector_Exchange(Mat1->p[Rank],Mat1->p[i],NbCols);
00383
00384
00385 Vector_Gcd(Mat1->p[Rank],NbCols,&gcd);
00386
00387
00388 value_set_si(tmp,2);
00389 if (value_ge(gcd,tmp)) {
00390 cp = Mat1->p[Rank];
00391 for (k=0; k<NbCols; k++,cp++)
00392 value_division(*cp,*cp,gcd);
00393 }
00394 if (value_neg_p(Mat1->p[Rank][j])) {
00395 cp = Mat1->p[Rank];
00396 for (k=0; k<NbCols; k++,cp++)
00397 value_oppose(*cp,*cp);
00398 }
00399
00400 pivot=i;
00401 for (i=0;i<NbRows;i++)
00402 if (i!=Rank) {
00403 if (value_notzero_p(Mat1->p[i][j])) {
00404 Value a, a1, a2, a1abs, a2abs;
00405 value_init(a); value_init(a1); value_init(a2);
00406 value_init(a1abs); value_init(a2abs);
00407 value_assign(a1,Mat1->p[i][j]);
00408 value_absolute(a1abs,a1);
00409 value_assign(a2,Mat1->p[Rank][j]);
00410 value_absolute(a2abs,a2);
00411 Gcd(a1abs,a2abs,&a);
00412 value_division(a1,a1,a);
00413 value_division(a2,a2,a);
00414 value_oppose(a1,a1);
00415 Vector_Combine(Mat1->p[i],Mat1->p[Rank],Mat1->p[i],a2,
00416 a1,NbCols);
00417 Vector_Normalize(Mat1->p[i],NbCols);
00418 value_clear(a); value_clear(a1); value_clear(a2);
00419 value_clear(a1abs); value_clear(a2abs);
00420 }
00421 }
00422 column_index[Rank]=j;
00423 Rank++;
00424 }
00425 }
00426
00427
00428 if (Mat2) {
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438 for (k=0; k<Rank; k++) {
00439 j = column_index[k];
00440 for (i=0; i<(Mat2->NbRows-1);i++) {
00441 if ((i!=j) && value_notzero_p(Mat2->p[i][j])) {
00442
00443
00444 Value a, a1, a1abs, a2, a2abs;
00445 value_init(a); value_init(a1); value_init(a2);
00446 value_init(a1abs); value_init(a2abs);
00447 value_assign(a1,Mat2->p[i][j]);
00448 value_absolute(a1abs,a1);
00449 value_assign(a2,Mat1->p[k][j]);
00450 value_absolute(a2abs,a2);
00451 Gcd(a1abs,a2abs,&a);
00452 value_division(a1,a1,a);
00453 value_division(a2,a2,a);
00454 value_oppose(a1,a1);
00455 if (value_one_p(a2)) {
00456 Vector_Combine(Mat2->p[i],Mat1->p[k],Mat2->p[i],a2,
00457 a1,NbCols);
00458
00459
00460 }
00461 value_clear(a); value_clear(a1); value_clear(a2);
00462 value_clear(a1abs); value_clear(a2abs);
00463
00464 }
00465 else if ((i==j) && value_zero_p(Mat2->p[i][j])) {
00466
00467
00468 for (n=j+1; n < (NbCols-1); n++) {
00469 if (value_notzero_p(Mat2->p[i][n])) {
00470 value_set_si(tmp,1);
00471 Vector_Combine(Mat2->p[i],Mat1->p[k],Mat2->p[i],tmp,
00472 tmp,NbCols);
00473 break;
00474 }
00475 }
00476 }
00477 }
00478 }
00479
00480
00481 for (j=0; j<(NbCols-1); j++)
00482 if (value_notzero_p(Mat2->p[Mat2->NbRows-1][j])) {
00483 errormsg1("GaussSimplify", "corrtrans", "Corrupted transformation\n");
00484 break;
00485 }
00486
00487 if (value_notone_p(Mat2->p[Mat2->NbRows-1][NbCols-1])) {
00488 errormsg1("GaussSimplify", "corrtrans", "Corrupted transformation\n");
00489 }
00490 }
00491 value_clear(gcd); value_clear(tmp);
00492 free(column_index);
00493 return Rank;
00494 }
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 int PolyhedronTSort (Polyhedron **L,unsigned int n,unsigned int index,unsigned int pdim,int *time,int *pvect,unsigned int MAXRAYS) {
00506
00507 unsigned int const nbcells = ((n*(n-1))>>1);
00508
00509 int *dag;
00510 int **p;
00511 unsigned int i, j, k;
00512 unsigned int t, nb, isroot;
00513
00514 if (n<2) return 0;
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534 dag = (int *) malloc(nbcells*sizeof(int));
00535 if (!dag) return 0;
00536 p = (int **) malloc ((n-1) * sizeof(int *));
00537 if (!p) {
00538 free(dag); return 0;
00539 }
00540
00541
00542 p[0] = dag-1;
00543 for (i=1; i<n-1; i++)
00544 p[i] = p[i-1] + (n-1)-i;
00545 for (i=0; i<nbcells; i++)
00546 dag[i] = -2;
00547 for (i=0; i<n; i++) time[i] = -1;
00548
00549
00550
00551 for (i=0; i<n-1; i++) {
00552 for (j=i+1; j<n; j++) {
00553 if (p[i][j] == -2)
00554 p[i][j] = PolyhedronLTQ(L[i], L[j], index, pdim, MAXRAYS);
00555 if (p[i][j] != 0) {
00556
00557
00558
00559
00560
00561
00562
00563
00564 for (k=0; k<i; k++)
00565 if (p[k][i] == p[i][j]) p[k][j] = p[k][i];
00566
00567
00568 for (k=i+1; k<j; k++)
00569 if (p[i][k] == -p[i][j]) p[k][j] = -p[i][k];
00570
00571
00572 for (k=j+1; k<n; k++)
00573 if (p[i][k] == -p[i][j]) p[j][k] = p[i][k];
00574 }
00575 }
00576 }
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586 t = 0;
00587
00588 nb = 0;
00589 while (nb<n) {
00590 for (i=0; i<n; i++) {
00591
00592
00593
00594
00595 if (time[i]<0) {
00596 isroot = 1;
00597
00598 for (j=0; j<i; j++) {
00599 if (p[j][i]==-1) {
00600 isroot = 0; break;
00601 }
00602 }
00603 if (isroot)
00604 for (j=i+1; j<n; j++) {
00605 if (p[i][j]==1) {
00606 isroot = 0; break;
00607 }
00608 }
00609 if (isroot) {
00610 time[i] = t;
00611 if (pvect)
00612 pvect[nb] = i+1;
00613 nb++;
00614 }
00615 }
00616 }
00617
00618 for (i=0; i<n; i++) {
00619 if (time[i]==t) {
00620 for (j=0; j<i; j++)
00621 p[j][i] = 0;
00622 for (j=i+1; j<n; j++)
00623 p[i][j] = 0;
00624 }
00625 }
00626 t++;
00627 }
00628
00629 free (p);
00630 free (dag);
00631 return 1;
00632 }
00633
00634
00635
00636