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