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