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_set_si( res->d, 0 );
00368 res->x.p=tmp;
00369
00370 new_eadd(&x,res);
00371 value_clear(g); value_clear(m1); value_clear(m2);
00372 return ;
00373 }
00374 else {
00375 if ((e1->x.p->type != res->x.p->type) ) {
00376
00377
00378
00379
00380 if ((res->x.p->type == periodic)&&(e1->x.p->type == polynomial)) {
00381
00382 evalue eval;
00383 value_set_si( eval.d, 0 );
00384 eval.x.p=ecopy(res->x.p);
00385 res->x.p= ecopy(e1->x.p);
00386 new_eadd(&eval,&res->x.p->arr[0]);
00387
00388 }
00389 else if ((res->x.p->type == polynomial)&&(e1->x.p->type == periodic)) {
00390
00391
00392
00393 new_eadd(e1,&res->x.p->arr[0]);
00394 }
00395
00396 value_clear(g); value_clear(m1); value_clear(m2);
00397 return;
00398 }
00399 else if (e1->x.p->pos != res->x.p->pos ) {
00400
00401
00402
00403 if (res->x.p->type == polynomial) {
00404
00405
00406 new_eadd(e1,&res->x.p->arr[0]);
00407 value_clear(g); value_clear(m1); value_clear(m2);
00408 return;
00409 }
00410 else {
00411
00412
00413 for (i=0;i<res->x.p->size;i++) {
00414 new_eadd(e1,&res->x.p->arr[i]);
00415 }
00416 value_clear(g); value_clear(m1); value_clear(m2);
00417 return;
00418 }
00419
00420
00421 }
00422
00423
00424
00425 if (e1->x.p->size == res->x.p->size) {
00426
00427 for (i=0; i<res->x.p->size; i++) {
00428 new_eadd(&e1->x.p->arr[i], &res->x.p->arr[i]);
00429 }
00430 value_clear(g); value_clear(m1); value_clear(m2);
00431 return ;
00432 }
00433
00434
00435 if (res->x.p->type==polynomial) {
00436
00437
00438
00439
00440 if(e1->x.p->size > res->x.p->size) {
00441 enode *tmp;
00442 tmp = ecopy(e1->x.p);
00443 for(i=0;i<res->x.p->size;++i) {
00444 new_eadd(&res->x.p->arr[i], &tmp->arr[i]);
00445
00446 }
00447 res->x.p = tmp;
00448
00449 }
00450 else {
00451
00452 for (i=0; i<e1->x.p->size ; i++) {
00453 new_eadd(&e1->x.p->arr[i], &res->x.p->arr[i]);
00454 }
00455 value_clear(g); value_clear(m1); value_clear(m2);
00456
00457 return ;
00458 }
00459 }
00460
00461
00462 else if (res->x.p->type==periodic) {
00463
00464
00465
00466
00467
00468 x=e1->x.p->size;
00469 y= res->x.p->size;
00470 p=ppcm1(x,y);
00471 ne= (evalue *) malloc (sizeof(evalue));
00472 value_init(ne->d);
00473 value_set_si( ne->d,0);
00474
00475 ne->x.p=new_enode(res->x.p->type,p, res->x.p->pos);
00476 for(i=0;i<p;i++) {
00477 value_assign(ne->x.p->arr[i].d, res->x.p->arr[i%y].d);
00478 if (value_notzero_p(ne->x.p->arr[i].d)) {
00479 value_init(ne->x.p->arr[i].x.n);
00480 value_assign(ne->x.p->arr[i].x.n, res->x.p->arr[i%y].x.n);
00481 }
00482 else {
00483 ne->x.p->arr[i].x.p =ecopy(res->x.p->arr[i%y].x.p);
00484 }
00485 }
00486 for(i=0;i<p;i++) {
00487 new_eadd(&e1->x.p->arr[i%x], &ne->x.p->arr[i]);
00488 }
00489
00490 res=ne;
00491
00492 value_clear(g); value_clear(m1); value_clear(m2);
00493 return ;
00494 }
00495 else {
00496 fprintf(stderr, "eadd: ?cannot add vectors of different length\n");
00497 value_clear(g); value_clear(m1); value_clear(m2);
00498 return ;
00499 }
00500 }
00501 value_clear(g); value_clear(m1); value_clear(m2);
00502 return ;
00503 }
00504
00505
00506 Matrix *Reduce_Matrix (Matrix *Mat) {
00507 int i;
00508 Value *p;
00509 p=*(Mat->p+(Mat->NbRows-1));
00510 for (i=0;i<Mat->NbColumns; i++) {
00511 value_clear(*p++);
00512 }
00513 for (i=0; i<Mat->NbRows-1; i++) {
00514 p=*(Mat->p+i);
00515 value_clear(*(p+(Mat->NbColumns-1)));
00516 }
00517 Mat->NbRows--;
00518 Mat->NbColumns--;
00519 return Mat;
00520 }
00521
00522
00523
00524
00525 void Scalar_product(Value *p1,Value *p2,unsigned length, Value *r) {
00526 Value *cp1, *cp2, tmp;
00527
00528 int i;
00529 cp1=p1;
00530 cp2=p2;
00531 value_init(tmp);
00532 value_set_si(*r,0);
00533 for (i=0;i<length;i++) {
00534 value_multiply(tmp,*cp1,*cp2);
00535 value_addto(*r,*r,tmp);
00536 cp1++; cp2++;
00537 }
00538 value_clear(tmp);
00539 }
00540
00541
00542
00543 int ppcm1 (int a, int b) {
00544 int t;
00545 t = (a*b)/ pgcd1(a,b);
00546 return t;
00547 }
00548
00549
00550
00551 void ppcm(Value a, Value b, Value *r) {
00552 Value g;
00553 value_init(g);
00554 Gcd(a,b,&g);
00555 value_multiply(*r,a,b);
00556 value_division(*r,*r,g);
00557 }
00558
00559
00560 Matrix *Orthogonal_Base(Matrix *Mat) {
00561 Matrix *OrthMat;
00562 Value a,b,c,d;
00563 Vector *q,*p,*f;
00564 unsigned length;
00565 int i,j,k;
00566 value_init(a);
00567 value_init(b);
00568 value_init(c);
00569 value_init(d);
00570 OrthMat= Matrix_Alloc(Mat->NbRows,Mat->NbColumns);
00571 length=Mat->NbColumns;
00572 for(k=0; k<length; k++) {
00573 value_assign(OrthMat->p[0][k],Mat->p[0][k]);
00574 }
00575 f=Vector_Alloc(length);
00576 p=Vector_Alloc(length);
00577 q=Vector_Alloc(length);
00578 for(i=1; i<Mat->NbRows; i++) {
00579 for(k=0;k<length;k++) {
00580 value_assign(f->p[k],Mat->p[i][k]);
00581 value_assign(q->p[k],Mat->p[i][k]);
00582 }
00583 value_set_si(d,1);
00584 for(j=0; j<i; j++) {
00585 for(k=0;k<length;k++) {
00586 value_assign(p->p[k],OrthMat->p[j][k]);
00587 }
00588
00589 Scalar_product(p->p,f->p,length,&a);
00590 Scalar_product(p->p,p->p,length,&b);
00591 Gcd(a,b,&c);
00592 value_division(a,a,c);
00593 value_division(b,b,c);
00594 for(k=0;k<length;k++) {
00595 value_multiply(p->p[k],p->p[k],a);
00596 }
00597
00598 if(value_notone_p(d)|value_notone_p(b)) {
00599 ppcm(d,b,&c);
00600 value_division(a,c,b);
00601 value_division(b,c,d);
00602 value_assign(d,c);
00603 for(k=0;k<length;k++) {
00604 value_multiply(p->p[k],p->p[k],a);
00605 value_multiply(q->p[k],q->p[k],b);
00606 }
00607
00608 }
00609
00610 for(k=0;k<length;k++) {
00611 value_substract(q->p[k],q->p[k],p->p[k]);
00612 }
00613
00614 }
00615 Vector_Gcd(q->p,length,&c);
00616 for(k=0;k<length;k++) {
00617 value_division(OrthMat->p[i][k],q->p[k],c);
00618 }
00619
00620 }
00621 value_clear(a);
00622 value_clear(b);
00623 value_clear(c);
00624 value_clear(d);
00625 return OrthMat;
00626 }
00627
00628
00629
00630 void Remove_Element(Enumeration *en,Enumeration **re, Enumeration *prev) {
00631 if (en== *re) {
00632 *re= (*re)->next;
00633 }
00634 else {
00635 prev->next=en->next;
00636 }
00637 }
00638
00639
00640
00641
00642 void Remove_RedundantDomains (Enumeration **Ures) {
00643 Enumeration *ren1, *ren2, *previous=NULL;
00644 int red;
00645 for (ren1=*Ures; ren1; ren1=ren1->next) {
00646 red=0;
00647 for (ren2=*Ures; ren2; ren2=ren2->next) {
00648 if (ren1!=ren2) {
00649
00650 if (PolyhedronIncludes(ren2->ValidityDomain, ren1->ValidityDomain)) {
00651 red= 1;
00652 break;
00653
00654 }
00655
00656 }
00657 }
00658 if (red) {
00659 Remove_Element(ren1,Ures,previous);
00660 }
00661 previous=ren1;
00662 }
00663 }
00664
00665
00666 int IncludeInRes (Polyhedron *p, Enumeration *e, unsigned MR) {
00667 Enumeration *en;
00668 for (en=e; en; en=en->next) {
00669
00670 if (PolyhedronIncludes(e->ValidityDomain,p))
00671 return 1;
00672 }
00673 return 0;
00674 }
00675
00676 Polyhedron *DMUnion(Enumeration *en, unsigned MR) {
00677 Enumeration *e1;
00678 Polyhedron *d;
00679 e1=en;
00680 d=e1->ValidityDomain;
00681 for (e1=en->next; e1; e1=e1->next) {
00682 d= DomainUnion( d, e1->ValidityDomain, MR);
00683 }
00684 return d;
00685 }
00686
00687
00688 void AffConstraints(Polyhedron *Poldisj)
00689 {
00690 Polyhedron *p;
00691
00692 for(p=Poldisj;p;p=p->next)
00693 {
00694 Polyhedron_PrintConstraints( stdout, P_VALUE_FMT, p);
00695 printf("\n");
00696 }
00697 }
00698 int Degenerate (Enumeration *en) {
00699 if(value_notzero_p(en->EP.d)) {
00700
00701 if(value_mone_p(en->EP.x.n )) {
00702 return 1;
00703 }
00704 }
00705 return 0;
00706 }
00707
00708
00709
00710 Enumeration *Domain_Enumerate(Polyhedron *D, Polyhedron *C, unsigned MAXRAYS,char **pn)
00711 { Polyhedron_union *Polun,*pu;
00712 Polyhedron *lp, *lp1, *lp1next;
00713 Polyhedron *d1,*d2,*d;
00714 Enumeration *e,*pr,*en,*en1, *en2,*tmp, *res, *sen;
00715 Polun=NULL;
00716
00717 lp = Disjoint_Domain( D, 0, MAXRAYS );
00718
00719 #ifdef UE_DEBUG
00720 printf("##############################################################\n");
00721 printf("\n###### DISJOINT UNION ######\n\n");
00722 AffConstraints(lp);
00723 printf("##############################################################\n");
00724 #endif
00725
00726 for (lp1=lp ; lp1; lp1=lp1->next)
00727 {
00728 lp1next = lp1->next;
00729 lp1->next = NULL;
00730 en= Polyhedron_Enumerate(lp1, C, MAXRAYS,NULL);
00731 lp1->next = lp1next;
00732 sen= NULL;
00733 for(e=en;e;e=e->next)
00734 if(!Degenerate(e))
00735 {
00736 pr = (Enumeration *)malloc(sizeof(Enumeration));
00737 pr->EP=e->EP;
00738 pr->ValidityDomain=e->ValidityDomain;
00739 pr->next=sen;
00740 sen=pr;
00741 }
00742
00743 if(sen!= NULL)
00744 {
00745 pu = (Polyhedron_union *)malloc(sizeof(Polyhedron_union));
00746 pu->pt=sen;
00747 pu->next = Polun;
00748 Polun = pu;
00749 }
00750 }
00751 if(!Polun)
00752 {
00753 #ifdef UE_DEBUG
00754 fprintf(stdout,"Empty Polun\n");
00755 #endif
00756 return ((Enumeration *) 0);
00757 }
00758
00759 while(Polun->next != NULL) {
00760 res=NULL;
00761 en1=Polun->pt;
00762 en2=(Polun->next)->pt;
00763
00764 d1=DMUnion(en1, MAXRAYS);
00765 d2=DMUnion(en2, MAXRAYS);
00766
00767 for(en1=Polun->pt;en1;en1=en1->next)
00768 {
00769
00770 for(en2=(Polun->next)->pt;en2;en2=en2->next)
00771 {
00772 d = DomainIntersection(en1->ValidityDomain,en2->ValidityDomain,MAXRAYS);
00773 if( d && !emptyQ(d)&&!IncludeInRes(d,res,MAXRAYS)) {
00774 evalue ev;
00775 value_init(ev.d);
00776 value_assign( ev.d, en2->EP.d );
00777 if(value_zero_p(ev.d))
00778 ev.x.p=ecopy(en2->EP.x.p);
00779 else
00780 {
00781 value_init(ev.x.n);
00782 value_assign( ev.x.n, en2->EP.x.n );
00783 }
00784
00785 new_eadd(&en1->EP,&ev);
00786 tmp = (Enumeration *)malloc(sizeof(Enumeration));
00787 tmp->ValidityDomain =d;
00788 tmp->EP=ev;
00789 tmp->next= res;
00790 res=tmp;
00791 }
00792 }
00793 d=DomainDifference(en1->ValidityDomain,d2 ,MAXRAYS);
00794 if( d && !emptyQ(d)&&!IncludeInRes(d,res,MAXRAYS))
00795 {
00796 tmp = (Enumeration *)malloc(sizeof(Enumeration));
00797 tmp->ValidityDomain =d;
00798
00799 tmp->EP=en1->EP;
00800 tmp->next= res;
00801 res=tmp;
00802 }
00803 }
00804 for(en2=(Polun->next)->pt; en2; en2= en2->next)
00805 {
00806 d= DomainDifference(en2->ValidityDomain,d1,MAXRAYS);
00807 if( d && !emptyQ(d)&&!IncludeInRes(d,res,MAXRAYS) )
00808 {
00809 tmp = (Enumeration *)malloc(sizeof(Enumeration));
00810 tmp->ValidityDomain =d;
00811 tmp->EP=en2->EP;
00812 tmp->next= res;
00813 res=tmp;
00814 }
00815 }
00816
00817 Polun->pt=res;
00818
00819 Polun->next= (Polun->next)->next;
00820 }
00821 res=Polun->pt;
00822
00823 Remove_RedundantDomains(&res);
00824 return(res);
00825 }
00826
00827
00828
00829
00830
00831
00832
00833 Enumeration *Polyhedron_Image_Enumerate(Polyhedron *D, Polyhedron *C, Matrix *T, unsigned MAXRAYS, char **par_name)
00834 { Polyhedron *polun,*pol;
00835 Enumeration *ee;
00836 Matrix *TCopy,*Tred, *d1,*d;
00837 Vector *v1,*v2;
00838 Value h;
00839 int i,j,k;
00840 value_init(h);
00841 if(!D) {
00842 fprintf(stdout," Error: in reading input domain \n");
00843 value_clear(h);
00844 return ((Enumeration *) 0);
00845 }
00846 else {
00847 printf("\n ################ INPUT POLYHEDRON #######################\n\n");
00848 AffConstraints(D);
00849 }
00850
00851 #ifdef DOMAIN_IMAGE
00852 fpol=DomainImage(D,T,MAXRAYS);
00853 printf("\n $$$$$$$$$$$$$ THE DOMAIN IMAGE $$$$$$$$$$$$$\n\n");
00854 AffConstraints(fpol);
00855 if(emptyQ(fpol)) {
00856 value_clear(h);
00857 return ((Enumeration *) 0);
00858 }
00859 ee = Domain_Enumerate(fpol,C,MAXRAYS,par_name);
00860 value_clear(h);
00861 return (ee);
00862 #endif
00863
00864 TCopy= Matrix_Copy(T);
00865 Tred= Reduce_Matrix(TCopy);
00866 printf("\n ################## INPUT REDUCED TRANSFORMATION MATRIX ##################\n" );
00867 Matrix_Print(stdout,P_VALUE_FMT,Tred);
00868
00869 if (Tred->NbRows <Tred->NbColumns) {
00870 d1=(Matrix *) Matrix_Alloc(Tred->NbColumns,Tred->NbColumns);
00871 for (i=0;i<Tred->NbRows;i++) {
00872 for (j=0; j<Tred->NbColumns;j++) {
00873 value_assign( d1->p[i][j], Tred->p[i][j] );
00874 }
00875 }
00876 for(i=Tred->NbRows;i<Tred->NbColumns;i++) {
00877 for (j=0;j<Tred->NbColumns;j++) {
00878 value_set_si( d1->p[i][j], 0 );
00879 }
00880 }
00881 d= (Matrix *) CalcBase(d1);
00882 Matrix_Free(Tred);
00883 Matrix_Free(d1);
00884
00885 }
00886 else {
00887 d=(Matrix *) CalcBase(Tred);
00888 Matrix_Free(Tred);
00889 }
00890 if(d->NbRows==0) {
00891 if(emptyQ(D)) {
00892 value_clear(h);
00893 return ((Enumeration *) 0);
00894 }
00895 else {
00896 printf( " Ker(A)=0 implys directly Enumeration on input polyhedron\n\n");
00897 ee=Domain_Enumerate(D,C,MAXRAYS,par_name);
00898 value_clear(h);
00899 return ee;
00900 }
00901 }
00902
00903 d1=Transpose(d);
00904 Matrix_Free(d);
00905
00906 if(d1->NbRows!=D->Dimension) {
00907 fprintf(stdout," \n Error: incompatible dimension \n");
00908 value_clear(h);
00909 return ((Enumeration *) 0);
00910 }
00911 if(d1->NbColumns > 1) {
00912 fprintf(stdout," \n Error: Can not compute intégral points : More then vector in ker(A)! \n");
00913 value_clear(h);
00914 return ((Enumeration *) 0);
00915
00916 }
00917 printf( " \n Ker(A)=1 implys adding constraints befor Enumeration\n");
00918 v1=Vector_Alloc(d1->NbRows);
00919 v2=Vector_Alloc(d1->NbRows);
00920
00921 polun=(Polyhedron *) NULL;
00922 for (k=0;k<d1->NbRows;k++) {
00923 value_assign(v1->p[k],d1->p[k][0]) ;
00924 }
00925
00926
00927
00928 for (j=0;j<D->NbConstraints;j++) {
00929 for (k=0;k<=D->Dimension-1;k++) {
00930 value_assign(v2->p[k],D->Constraint[j][k+1]) ;
00931 }
00932 Scalar_product(v1->p,v2->p,D->Dimension,&h);
00933
00934 if(value_pos_p(h)&&!value_zero_p(D->Constraint[j][0])) {
00935 Vector *NCont;
00936 Value val;
00937 value_init( val );
00938
00939
00940 NCont=Vector_Alloc(d1->NbRows+2);
00941 value_set_si( NCont->p[0],1);
00942
00943 for (k=1;k<=D->Dimension;k++) {
00944 value_oppose( NCont->p[k], D->Constraint[j][k]);
00945 }
00946 value_decrement(val,h);
00947 value_substract(val,val,D->Constraint[j][D->Dimension+1]);
00948 value_assign (NCont->p[D->Dimension+1],val);
00949 value_clear(val);
00950
00951 pol=AddConstraints(NCont->p,1,D,MAXRAYS);
00952 polun=AddPolyToDomain(Polyhedron_Copy(pol),polun);
00953 Polyhedron_Free(pol);
00954 Vector_Free(NCont);
00955 value_clear( val );
00956 }
00957 }
00958 if(polun==NULL) {
00959 if(emptyQ(D)) {
00960 value_clear(h);
00961 return ((Enumeration *) 0);
00962 }
00963 else {
00964 ee= Domain_Enumerate(D,C,MAXRAYS,par_name);
00965 }
00966 }
00967 else {
00968 if(emptyQ(polun)){
00969 value_clear(h);
00970 return ((Enumeration *) 0);
00971 }
00972 else {
00973 printf("\n ##################################################################");
00974 printf("\n ****** THE RESULT OF ADDING CONSTRAINTS TO THE INPUT POLYHEDRON ****** \n");
00975 AffConstraints(polun);
00976 ee= Domain_Enumerate(polun,C,MAXRAYS,par_name);
00977 value_clear(h);
00978 return (ee );
00979 }
00980 }
00981
00982
00983 return( NULL );
00984 }
00985
00986