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