00001
00002 #include <stdlib.h>
00003 #include <polylib/polylib.h>
00004 #define WS 200
00005
00006
00007
00008
00009 typedef struct _Polyhedron_union {
00010 Enumeration *pt;
00011 struct _Polyhedron_union *next;} Polyhedron_union;
00012
00013 static int ppcm1 (int a, int b);
00014 Matrix *CalcBase( Matrix *R);
00015
00016
00017
00018
00019 static void Soustraire_ligne(Matrix *R, int l1, int l2, int piv );
00020 static int existepivot( Matrix *R, int l );
00021 static void swap_line(Matrix *R, int l1, int l2);
00022
00023
00024
00025
00026
00027
00028
00029 Matrix *CalcBase( Matrix *R )
00030 {
00031 Matrix *B;
00032 int i, j;
00033 Value p;
00034 int l;
00035 int lnn;
00036 int dimbase;
00037 int u;
00038 Value som;
00039 int c;
00040
00041
00042 for( l=0 ; l<R->NbRows ; ++l )
00043 {
00044
00045 if( (lnn=existepivot(R,l)) != -1 )
00046 {
00047 swap_line( R, l, lnn );
00048
00049
00050 for( j=l+1 ; j<R->NbRows ; ++j )
00051 if(value_notzero_p( R->p[j][l]) )
00052 Soustraire_ligne( R, l, j, l );
00053
00054
00055 for( j=0 ; j<l ; ++j )
00056 if( value_notzero_p(R->p[j][l]) )
00057 Soustraire_ligne( R, l, j, l );
00058
00059 }
00060
00061
00062 }
00063
00064 dimbase = 0;
00065 for( l=0 ; l<R->NbRows ; ++l )
00066 if( value_zero_p(R->p[l][l]) )
00067 ++dimbase;
00068
00069 B = Matrix_Alloc( dimbase, R->NbRows );
00070
00071 l=0;
00072 for( u=0 ; u<dimbase ; ++u )
00073 {
00074 while(value_notzero_p( R->p[l][l]) )
00075 ++l;
00076
00077
00078 for( i=R->NbRows-1 ; i>l ; --i )
00079 value_set_si(B->p[u][i], 0);
00080 value_set_si(B->p[u][l], 1);
00081 for( i=l-1 ; i>=0 ; --i )
00082 {
00083 if(value_zero_p( R->p[i][i]) )
00084
00085
00086 value_set_si(B->p[u][i],0);
00087 else
00088 {
00089
00090 value_set_si(som,0);
00091 for( c=l ; c>i ; --c )
00092 {
00093 value_addmul(som, R->p[i][c], B->p[u][c]);
00094 value_multiply(B->p[u][c] ,B->p[u][c] , R->p[i][i]);
00095 }
00096 value_oppose(B->p[u][i] , som );
00097 }
00098 }
00099
00100 value_set_si(p,0);
00101 for( i=0 ; i<R->NbRows ; ++i )
00102 value_gcd(p, p, B->p[u][i]);
00103 if( value_zero_p(p))
00104 value_set_si(p,1);
00105 for( i=0 ; i<R->NbRows && value_zero_p(B->p[u][i]); ++i )
00106 ;
00107 if( i<R->NbRows )
00108 if( value_neg_p(B->p[u][i]) )
00109 value_oppose( p,p );
00110
00111 for( i=0 ; i<R->NbRows ; ++i )
00112 value_divexact(B->p[u][i], B->p[u][i], p);
00113
00114
00115 ++l;
00116 }
00117 return B;
00118 }
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 static int existepivot( Matrix *R, int l )
00203 {
00204 int j, c;
00205
00206 for( j=l ; j<R->NbRows ; ++j )
00207 if(value_notzero_p( R->p[j][l]) )
00208 return( j );
00209
00210
00211
00212 for( j=0 ; j<l ; ++j )
00213 {
00214 for( c=0 ; c<l && value_zero_p(R->p[j][c]) ; c++ )
00215 ;
00216 if( c==l && value_notzero_p(R->p[j][l]) )
00217 return( j );
00218 }
00219
00220 return( -1 );
00221 }
00222
00223
00224
00225 static void swap_line(Matrix *R, int l1, int l2)
00226 {
00227 int i;
00228 Value tmp;
00229
00230 if( l1 != l2 )
00231 for(i = 0;i < R->NbColumns;i ++)
00232 {
00233 value_assign(tmp , R->p[l1][i]);
00234 value_assign(R->p[l1][i] , R->p[l2][i]);
00235 value_assign(R->p[l2][i] , tmp);
00236 }
00237 }
00238
00239
00240
00241 int pgcd1( int a, int b)
00242 {
00243 int r;
00244 if( a== 0 )
00245 return( abs(b) );
00246 if(b==0 )
00247 return(abs(a) );
00248 do
00249 {
00250 r= a % b;
00251 a= b;
00252 b = r;
00253 }
00254 while ( r!=0 );
00255 return(abs(a));
00256 }
00257
00258
00259
00260
00261
00262
00263 static void Soustraire_ligne(Matrix *R, int l1, int l2, int piv )
00264 {
00265 int i;
00266 Value a, b, p, t;
00267
00268
00269 if (value_zero_p(R->p[l2][piv] ))
00270 return;
00271
00272 value_init(a);
00273 value_init(b);
00274 value_init(p);
00275 value_init(t);
00276
00277 value_gcd(p, R->p[l1][piv], R->p[l2][piv]);
00278 value_divexact(a, R->p[l1][piv], p);
00279 value_divexact(b, R->p[l2][piv], p);
00280
00281 value_set_si(R->p[l2][piv] , 0);
00282 value_set_si(p,0);
00283 for(i = piv + 1;i < R->NbColumns;i ++)
00284 {
00285 value_multiply(t,b,R->p[l1][i]);
00286 value_multiply(R->p[l2][i],a,R->p[l2][i]);
00287 value_subtract(R->p[l2][i],R->p[l2][i],t);
00288 value_gcd(p, p, R->p[l2][i]);
00289 }
00290
00291 for( i=piv+1 ; i<R->NbColumns && p!=0 ; i++ )
00292 value_divexact(R->p[l2][i], R->p[l2][i], p);
00293
00294 value_clear(a);
00295 value_clear(b);
00296 value_clear(p);
00297 value_clear(t);
00298 }
00299
00300
00301
00302
00303
00304 void new_eadd(evalue *e1,evalue *res) {
00305 int i, p, x, y;
00306
00307 evalue *ne;
00308 Value g,m1,m2;
00309
00310 value_init(g);
00311 value_init(m1);
00312 value_init(m2);
00313 if (value_notzero_p(e1->d) && value_notzero_p(res->d)) {
00314
00315 value_multiply(m1,e1->x.n,res->d);
00316 value_multiply(m2,res->x.n,e1->d);
00317 value_addto(res->x.n,m1,m2);
00318 value_multiply(res->d,e1->d,res->d);
00319 value_gcd(g, res->x.n,res->d);
00320 if (value_notone_p(g)) {
00321 value_divexact(res->d, res->d, g);
00322 value_divexact(res->x.n, res->x.n, g);
00323 }
00324 value_clear(g); value_clear(m1); value_clear(m2);
00325 return ;
00326 }
00327 else if (value_notzero_p(e1->d) && value_zero_p(res->d)) {
00328 if (res->x.p->type==polynomial) {
00329
00330 new_eadd(e1, &res->x.p->arr[0]);
00331 value_clear(g); value_clear(m1); value_clear(m2);
00332 return ;
00333 }
00334 else if (res->x.p->type==periodic) {
00335
00336 for (i=0; i<res->x.p->size; i++) {
00337 new_eadd(e1, &res->x.p->arr[i]);
00338 }
00339 value_clear(g); value_clear(m1); value_clear(m2);
00340
00341 return ;
00342 }
00343 else {
00344 fprintf(stderr, "eadd: cannot add const with vector\n");
00345 value_clear(g); value_clear(m1); value_clear(m2);
00346
00347 return;
00348 }
00349 }
00350
00351
00352
00353 else if (value_zero_p(e1->d) && value_notzero_p(res->d)) {
00354 enode *tmp;
00355 evalue x;
00356 x=*res;
00357 tmp= ecopy(e1->x.p);
00358 value_init(res->d);
00359 value_set_si( res->d, 0 );
00360 res->x.p=tmp;
00361
00362 new_eadd(&x,res);
00363 value_clear(g); value_clear(m1); value_clear(m2);
00364 return ;
00365 }
00366 else {
00367 if ((e1->x.p->type != res->x.p->type) ) {
00368
00369
00370
00371
00372 if ((res->x.p->type == periodic)&&(e1->x.p->type == polynomial)) {
00373
00374 evalue eval;
00375 value_set_si( eval.d, 0 );
00376 eval.x.p=ecopy(res->x.p);
00377 res->x.p= ecopy(e1->x.p);
00378 new_eadd(&eval,&res->x.p->arr[0]);
00379
00380 }
00381 else if ((res->x.p->type == polynomial)&&(e1->x.p->type == periodic)) {
00382
00383
00384
00385 new_eadd(e1,&res->x.p->arr[0]);
00386 }
00387
00388 value_clear(g); value_clear(m1); value_clear(m2);
00389 return;
00390 }
00391 else if (e1->x.p->pos != res->x.p->pos ) {
00392
00393
00394
00395 if (res->x.p->type == polynomial) {
00396
00397
00398 new_eadd(e1,&res->x.p->arr[0]);
00399 value_clear(g); value_clear(m1); value_clear(m2);
00400 return;
00401 }
00402 else {
00403
00404
00405 for (i=0;i<res->x.p->size;i++) {
00406 new_eadd(e1,&res->x.p->arr[i]);
00407 }
00408 value_clear(g); value_clear(m1); value_clear(m2);
00409 return;
00410 }
00411
00412
00413 }
00414
00415
00416
00417 if (e1->x.p->size == res->x.p->size) {
00418
00419 for (i=0; i<res->x.p->size; i++) {
00420 new_eadd(&e1->x.p->arr[i], &res->x.p->arr[i]);
00421 }
00422 value_clear(g); value_clear(m1); value_clear(m2);
00423 return ;
00424 }
00425
00426
00427 if (res->x.p->type==polynomial) {
00428
00429
00430
00431
00432 if(e1->x.p->size > res->x.p->size) {
00433 enode *tmp;
00434 tmp = ecopy(e1->x.p);
00435 for(i=0;i<res->x.p->size;++i) {
00436 new_eadd(&res->x.p->arr[i], &tmp->arr[i]);
00437
00438 }
00439 res->x.p = tmp;
00440
00441 }
00442 else {
00443
00444 for (i=0; i<e1->x.p->size ; i++) {
00445 new_eadd(&e1->x.p->arr[i], &res->x.p->arr[i]);
00446 }
00447 value_clear(g); value_clear(m1); value_clear(m2);
00448
00449 return ;
00450 }
00451 }
00452
00453
00454 else if (res->x.p->type==periodic) {
00455
00456
00457
00458
00459
00460 x=e1->x.p->size;
00461 y= res->x.p->size;
00462 p=ppcm1(x,y);
00463 ne= (evalue *) malloc (sizeof(evalue));
00464 value_init(ne->d);
00465 value_set_si( ne->d,0);
00466
00467 ne->x.p=new_enode(res->x.p->type,p, res->x.p->pos);
00468 for(i=0;i<p;i++) {
00469 value_assign(ne->x.p->arr[i].d, res->x.p->arr[i%y].d);
00470 if (value_notzero_p(ne->x.p->arr[i].d)) {
00471 value_init(ne->x.p->arr[i].x.n);
00472 value_assign(ne->x.p->arr[i].x.n, res->x.p->arr[i%y].x.n);
00473 }
00474 else {
00475 ne->x.p->arr[i].x.p =ecopy(res->x.p->arr[i%y].x.p);
00476 }
00477 }
00478 for(i=0;i<p;i++) {
00479 new_eadd(&e1->x.p->arr[i%x], &ne->x.p->arr[i]);
00480 }
00481
00482 res=ne;
00483
00484 value_clear(g); value_clear(m1); value_clear(m2);
00485 return ;
00486 }
00487 else {
00488 fprintf(stderr, "eadd: ?cannot add vectors of different length\n");
00489 value_clear(g); value_clear(m1); value_clear(m2);
00490 return ;
00491 }
00492 }
00493 value_clear(g); value_clear(m1); value_clear(m2);
00494 return ;
00495 }
00496
00497
00498 Matrix *Reduce_Matrix (Matrix *Mat) {
00499 int i;
00500 Value *p;
00501 p=*(Mat->p+(Mat->NbRows-1));
00502 for (i=0;i<Mat->NbColumns; i++) {
00503 value_clear(*p++);
00504 }
00505 for (i=0; i<Mat->NbRows-1; i++) {
00506 p=*(Mat->p+i);
00507 value_clear(*(p+(Mat->NbColumns-1)));
00508 }
00509 Mat->NbRows--;
00510 Mat->NbColumns--;
00511 return Mat;
00512 }
00513
00514
00515
00516
00517 void Scalar_product(Value *p1,Value *p2,unsigned length, Value *r) {
00518 Value *cp1, *cp2;
00519
00520 int i;
00521 cp1=p1;
00522 cp2=p2;
00523 value_set_si(*r,0);
00524 for (i=0;i<length;i++) {
00525 value_addmul(*r, *cp1, *cp2);
00526 cp1++; cp2++;
00527 }
00528 }
00529
00530
00531
00532 int ppcm1 (int a, int b) {
00533 int t;
00534 t = (a*b)/ pgcd1(a,b);
00535 return t;
00536 }
00537
00538
00539 Matrix *Orthogonal_Base(Matrix *Mat) {
00540 Matrix *OrthMat;
00541 Value a,b,c,d;
00542 Vector *q,*p,*f;
00543 unsigned length;
00544 int i,j,k;
00545 value_init(a);
00546 value_init(b);
00547 value_init(c);
00548 value_init(d);
00549 OrthMat= Matrix_Alloc(Mat->NbRows,Mat->NbColumns);
00550 length=Mat->NbColumns;
00551 for(k=0; k<length; k++) {
00552 value_assign(OrthMat->p[0][k],Mat->p[0][k]);
00553 }
00554 f=Vector_Alloc(length);
00555 p=Vector_Alloc(length);
00556 q=Vector_Alloc(length);
00557 for(i=1; i<Mat->NbRows; i++) {
00558 for(k=0;k<length;k++) {
00559 value_assign(f->p[k],Mat->p[i][k]);
00560 value_assign(q->p[k],Mat->p[i][k]);
00561 }
00562 value_set_si(d,1);
00563 for(j=0; j<i; j++) {
00564 for(k=0;k<length;k++) {
00565 value_assign(p->p[k],OrthMat->p[j][k]);
00566 }
00567
00568 Scalar_product(p->p,f->p,length,&a);
00569 Scalar_product(p->p,p->p,length,&b);
00570 value_gcd(c, a, b);
00571 value_divexact(a, a, c);
00572 value_divexact(b, b, c);
00573 for(k=0;k<length;k++) {
00574 value_multiply(p->p[k],p->p[k],a);
00575 }
00576
00577 if(value_notone_p(d)|value_notone_p(b)) {
00578 value_lcm(c, d, b);
00579 value_divexact(a, c, b);
00580 value_divexact(b, c, d);
00581 value_assign(d,c);
00582 for(k=0;k<length;k++) {
00583 value_multiply(p->p[k],p->p[k],a);
00584 value_multiply(q->p[k],q->p[k],b);
00585 }
00586
00587 }
00588
00589 for(k=0;k<length;k++) {
00590 value_subtract(q->p[k],q->p[k],p->p[k]);
00591 }
00592
00593 }
00594 Vector_Gcd(q->p,length,&c);
00595 Vector_AntiScale(q->p, OrthMat->p[i], c, length);
00596 }
00597 value_clear(a);
00598 value_clear(b);
00599 value_clear(c);
00600 value_clear(d);
00601 return OrthMat;
00602 }
00603
00604
00605
00606 void Remove_Element(Enumeration *en,Enumeration **re, Enumeration *prev) {
00607 if (en== *re) {
00608 *re= (*re)->next;
00609 }
00610 else {
00611 prev->next=en->next;
00612 }
00613 }
00614
00615
00616
00617
00618 void Remove_RedundantDomains (Enumeration **Ures) {
00619 Enumeration *ren1, *ren2, *previous=NULL;
00620 int red;
00621 for (ren1=*Ures; ren1; ren1=ren1->next) {
00622 red=0;
00623 for (ren2=*Ures; ren2; ren2=ren2->next) {
00624 if (ren1!=ren2) {
00625
00626 if (PolyhedronIncludes(ren2->ValidityDomain, ren1->ValidityDomain)) {
00627 red= 1;
00628 break;
00629
00630 }
00631
00632 }
00633 }
00634 if (red) {
00635 Remove_Element(ren1,Ures,previous);
00636 }
00637 previous=ren1;
00638 }
00639 }
00640
00641
00642 int IncludeInRes (Polyhedron *p, Enumeration *e, unsigned MR) {
00643 Enumeration *en;
00644 for (en=e; en; en=en->next) {
00645
00646 if (PolyhedronIncludes(e->ValidityDomain,p))
00647 return 1;
00648 }
00649 return 0;
00650 }
00651
00652 Polyhedron *DMUnion(Enumeration *en, unsigned MR) {
00653 Enumeration *e1;
00654 Polyhedron *d;
00655 e1=en;
00656 d=e1->ValidityDomain;
00657 for (e1=en->next; e1; e1=e1->next) {
00658 d= DomainUnion( d, e1->ValidityDomain, MR);
00659 }
00660 return d;
00661 }
00662
00663
00664 void AffConstraints(Polyhedron *Poldisj)
00665 {
00666 Polyhedron *p;
00667
00668 for(p=Poldisj;p;p=p->next)
00669 {
00670 Polyhedron_PrintConstraints( stdout, P_VALUE_FMT, p);
00671 printf("\n");
00672 }
00673 }
00674 int Degenerate (Enumeration *en) {
00675 if(value_notzero_p(en->EP.d)) {
00676
00677 if(value_mone_p(en->EP.x.n )) {
00678 return 1;
00679 }
00680 }
00681 return 0;
00682 }
00683
00684
00685
00686 Enumeration *Domain_Enumerate(Polyhedron *D, Polyhedron *C, unsigned MAXRAYS,
00687 const char **pn)
00688 { Polyhedron_union *Polun,*pu;
00689 Polyhedron *lp, *lp1, *lp1next;
00690 Polyhedron *d1,*d2,*d;
00691 Enumeration *e,*pr,*en,*en1, *en2,*tmp, *res, *sen;
00692 Polun=NULL;
00693
00694 for (d = D; d; d = d->next) {
00695 POL_ENSURE_FACETS(d);
00696 POL_ENSURE_VERTICES(d);
00697 }
00698 POL_ENSURE_FACETS(C);
00699 POL_ENSURE_VERTICES(C);
00700
00701 lp = Disjoint_Domain( D, 0, MAXRAYS );
00702
00703 #ifdef UE_DEBUG
00704 printf("##############################################################\n");
00705 printf("\n###### DISJOINT UNION ######\n\n");
00706 AffConstraints(lp);
00707 printf("##############################################################\n");
00708 #endif
00709
00710 for (lp1=lp ; lp1; lp1=lp1->next)
00711 {
00712 Enumeration *enext;
00713 lp1next = lp1->next;
00714 lp1->next = NULL;
00715 en= Polyhedron_Enumerate(lp1, C, MAXRAYS,NULL);
00716 lp1->next = lp1next;
00717 sen= NULL;
00718 for (e=en;e;e=enext) {
00719 enext = e->next;
00720 if (!Degenerate(e)) {
00721 e->next = sen;
00722 sen=e;
00723 } else {
00724 free_evalue_refs(&e->EP);
00725 Domain_Free(e->ValidityDomain);
00726 free(e);
00727 }
00728 }
00729
00730 if(sen!= NULL)
00731 {
00732 pu = (Polyhedron_union *)malloc(sizeof(Polyhedron_union));
00733 pu->pt=sen;
00734 pu->next = Polun;
00735 Polun = pu;
00736 }
00737 }
00738 if(!Polun)
00739 {
00740 #ifdef UE_DEBUG
00741 fprintf(stdout,"Empty Polun\n");
00742 #endif
00743 return ((Enumeration *) 0);
00744 }
00745
00746 while(Polun->next != NULL) {
00747 Enumeration *enext;
00748 res=NULL;
00749 en1=Polun->pt;
00750 en2=(Polun->next)->pt;
00751
00752 d1=DMUnion(en1, MAXRAYS);
00753 d2=DMUnion(en2, MAXRAYS);
00754
00755 for (en1=Polun->pt;en1;en1=enext) {
00756 enext = en1->next;
00757 for(en2=(Polun->next)->pt;en2;en2=en2->next)
00758 {
00759 d = DomainIntersection(en1->ValidityDomain,en2->ValidityDomain,MAXRAYS);
00760 if( d && !emptyQ(d)&&!IncludeInRes(d,res,MAXRAYS)) {
00761 tmp = (Enumeration *)malloc(sizeof(Enumeration));
00762 value_init(tmp->EP.d);
00763 value_assign( tmp->EP.d, en2->EP.d );
00764 if(value_zero_p(tmp->EP.d))
00765 tmp->EP.x.p=ecopy(en2->EP.x.p);
00766 else
00767 {
00768 value_init(tmp->EP.x.n);
00769 value_assign( tmp->EP.x.n, en2->EP.x.n );
00770 }
00771
00772 new_eadd(&en1->EP,&tmp->EP);
00773 tmp->ValidityDomain =d;
00774 tmp->next= res;
00775 res=tmp;
00776 }
00777 }
00778 d=DomainDifference(en1->ValidityDomain,d2 ,MAXRAYS);
00779 if (d && !emptyQ(d) && !IncludeInRes(d,res,MAXRAYS)) {
00780 en1->ValidityDomain = d;
00781 en1->next= res;
00782 res=en1;
00783 } else {
00784 free_evalue_refs(&en1->EP);
00785 free(en1);
00786 }
00787 }
00788 for (en2=(Polun->next)->pt; en2; en2 = enext) {
00789 enext = en2->next;
00790 d= DomainDifference(en2->ValidityDomain,d1,MAXRAYS);
00791 if (d && !emptyQ(d)&&!IncludeInRes(d,res,MAXRAYS)) {
00792 en2->ValidityDomain = d;
00793 en2->next = res;
00794 res = en2;
00795 } else {
00796 free_evalue_refs(&en2->EP);
00797 free(en2);
00798 }
00799 }
00800 Domain_Free(d1);
00801 Domain_Free(d2);
00802
00803 Polun->pt=res;
00804
00805 Polun->next= (Polun->next)->next;
00806 }
00807 res=Polun->pt;
00808
00809 Remove_RedundantDomains(&res);
00810 return(res);
00811 }
00812
00813
00814
00815
00816
00817
00818
00819 Enumeration *Polyhedron_Image_Enumerate(Polyhedron *D, Polyhedron *C, Matrix *T, unsigned MAXRAYS, const char **par_name)
00820 { Polyhedron *polun,*pol;
00821 Enumeration *ee;
00822 Matrix *TCopy,*Tred, *d1,*d;
00823 Vector *v1,*v2;
00824 Value h;
00825 int i,j,k;
00826
00827 POL_ENSURE_FACETS(D);
00828 POL_ENSURE_VERTICES(D);
00829 POL_ENSURE_FACETS(C);
00830 POL_ENSURE_VERTICES(C);
00831
00832 value_init(h);
00833 if(!D) {
00834 fprintf(stdout," Error: in reading input domain \n");
00835 value_clear(h);
00836 return ((Enumeration *) 0);
00837 }
00838 else {
00839 printf("\n ################ INPUT POLYHEDRON #######################\n\n");
00840 AffConstraints(D);
00841 }
00842
00843 #ifdef DOMAIN_IMAGE
00844 fpol=DomainImage(D,T,MAXRAYS);
00845 printf("\n $$$$$$$$$$$$$ THE DOMAIN IMAGE $$$$$$$$$$$$$\n\n");
00846 AffConstraints(fpol);
00847 if(emptyQ(fpol)) {
00848 value_clear(h);
00849 return ((Enumeration *) 0);
00850 }
00851 ee = Domain_Enumerate(fpol,C,MAXRAYS,par_name);
00852 value_clear(h);
00853 return (ee);
00854 #endif
00855
00856 TCopy= Matrix_Copy(T);
00857 Tred= Reduce_Matrix(TCopy);
00858 printf("\n ################## INPUT REDUCED TRANSFORMATION MATRIX ##################\n" );
00859 Matrix_Print(stdout,P_VALUE_FMT,Tred);
00860
00861 if (Tred->NbRows <Tred->NbColumns) {
00862 d1=(Matrix *) Matrix_Alloc(Tred->NbColumns,Tred->NbColumns);
00863 for (i=0;i<Tred->NbRows;i++) {
00864 for (j=0; j<Tred->NbColumns;j++) {
00865 value_assign( d1->p[i][j], Tred->p[i][j] );
00866 }
00867 }
00868 for(i=Tred->NbRows;i<Tred->NbColumns;i++) {
00869 for (j=0;j<Tred->NbColumns;j++) {
00870 value_set_si( d1->p[i][j], 0 );
00871 }
00872 }
00873 d= (Matrix *) CalcBase(d1);
00874 Matrix_Free(Tred);
00875 Matrix_Free(d1);
00876
00877 }
00878 else {
00879 d=(Matrix *) CalcBase(Tred);
00880 Matrix_Free(Tred);
00881 }
00882 if(d->NbRows==0) {
00883 if(emptyQ(D)) {
00884 value_clear(h);
00885 return ((Enumeration *) 0);
00886 }
00887 else {
00888 printf( " Ker(A)=0 implys directly Enumeration on input polyhedron\n\n");
00889 ee=Domain_Enumerate(D,C,MAXRAYS,par_name);
00890 value_clear(h);
00891 return ee;
00892 }
00893 }
00894
00895 d1=Transpose(d);
00896 Matrix_Free(d);
00897
00898 if(d1->NbRows!=D->Dimension) {
00899 fprintf(stdout," \n Error: incompatible dimension \n");
00900 value_clear(h);
00901 return ((Enumeration *) 0);
00902 }
00903 if(d1->NbColumns > 1) {
00904 fprintf(stdout," \n Error: Can not compute intégral points : More then vector in ker(A)! \n");
00905 value_clear(h);
00906 return ((Enumeration *) 0);
00907
00908 }
00909 printf( " \n Ker(A)=1 implys adding constraints befor Enumeration\n");
00910 v1=Vector_Alloc(d1->NbRows);
00911 v2=Vector_Alloc(d1->NbRows);
00912
00913 polun=(Polyhedron *) NULL;
00914 for (k=0;k<d1->NbRows;k++) {
00915 value_assign(v1->p[k],d1->p[k][0]) ;
00916 }
00917
00918
00919
00920 for (j=0;j<D->NbConstraints;j++) {
00921 for (k=0;k<=D->Dimension-1;k++) {
00922 value_assign(v2->p[k],D->Constraint[j][k+1]) ;
00923 }
00924 Scalar_product(v1->p,v2->p,D->Dimension,&h);
00925
00926 if(value_pos_p(h)&&!value_zero_p(D->Constraint[j][0])) {
00927 Vector *NCont;
00928 Value val;
00929 value_init( val );
00930
00931
00932 NCont=Vector_Alloc(d1->NbRows+2);
00933 value_set_si( NCont->p[0],1);
00934
00935 for (k=1;k<=D->Dimension;k++) {
00936 value_oppose( NCont->p[k], D->Constraint[j][k]);
00937 }
00938 value_decrement(val,h);
00939 value_subtract(val,val,D->Constraint[j][D->Dimension+1]);
00940 value_assign (NCont->p[D->Dimension+1],val);
00941 value_clear(val);
00942
00943 pol=AddConstraints(NCont->p,1,D,MAXRAYS);
00944 POL_ENSURE_VERTICES(pol);
00945 polun=AddPolyToDomain(Polyhedron_Copy(pol),polun);
00946 Polyhedron_Free(pol);
00947 Vector_Free(NCont);
00948 value_clear( val );
00949 }
00950 }
00951 if(polun==NULL) {
00952 if(emptyQ(D)) {
00953 value_clear(h);
00954 return ((Enumeration *) 0);
00955 }
00956 else {
00957 ee= Domain_Enumerate(D,C,MAXRAYS,par_name);
00958 }
00959 }
00960 else {
00961 if(emptyQ(polun)){
00962 value_clear(h);
00963 return ((Enumeration *) 0);
00964 }
00965 else {
00966 printf("\n ##################################################################");
00967 printf("\n ****** THE RESULT OF ADDING CONSTRAINTS TO THE INPUT POLYHEDRON ****** \n");
00968 AffConstraints(polun);
00969 ee= Domain_Enumerate(polun,C,MAXRAYS,par_name);
00970 value_clear(h);
00971 return (ee );
00972 }
00973 }
00974
00975
00976 return( NULL );
00977 }
00978
00979