Main Page   Compound List   File List   Compound Members   File Members  

ext_ehrhart.c

Go to the documentation of this file.
00001 
00002 #include <stdlib.h>
00003 #include <polylib/polylib.h>
00004 #define WS 200 
00005 
00006 /* #define UE_DEBUG */
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 /**** ker.c ****/
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 /* Caclule une base du noyau de l'application definie
00025 par la matrice _carree_ R (completee par des 0..0) */
00026 
00027 /* /!\ R est alteree par cette fonction. */
00028 
00029 Matrix *CalcBase( Matrix *R )
00030 {
00031         Matrix *B/*,*BTran*/;   /* matrice des vect. de la base */
00032         int i, j;
00033         Value p;
00034         int l;          /* ligne en cours de `pivotage' */
00035         int lnn;
00036         int dimbase;
00037         int u;          /* vecteur util en cours de calcul */
00038         Value  som, t;
00039         int c;
00040         /* diagonalisation de R : algo du pivot */
00041         /* avec conservation des pivots nuls */
00042         for( l=0 ; l<R->NbRows ; ++l )
00043         {
00044                 /* cherche le prochain pivot non nul */
00045                 if( (lnn=existepivot(R,l)) != -1 )
00046                 {
00047                         swap_line( R, l, lnn );
00048 
00049                         /* met la colonne dessous a 0 */
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                         /* et celle dessus aussi */
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                 /* s'ils sont tous nuls on passe au suivant */
00061                 /* en laissant cette ligne inchangee. */
00062         }
00063 
00064         dimbase = 0;
00065         for( l=0 ; l<R->NbRows ; ++l )
00066                 if( value_zero_p(R->p[l][l]) )
00067                         ++dimbase;                      /* = nb de 0 dans la diagonale */
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         /* calcul effectif de ce vecteur : chaque coord en commencant par le bas */
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 )       /* i=chaque coord du vecteur */
00082                 {
00083                         if(value_zero_p( R->p[i][i]) )
00084                                 value_set_si(B->p[u][i],0);             /* on a deux 0... un seul dans */
00085                                                                         /* ce vect util suffit */
00086                         else
00087                         {
00088                                 /* somme des coef deja calcules * coef dans la matrice */
00089                                 value_set_si(som,0);
00090                                 value_init( t );
00091                                 for( c=l ; c>i ; --c )
00092                                 {
00093                                //som += R->p[i][c] * B->p[u][c];
00094                                         value_multiply( t, R->p[i][c] , B->p[u][c]);
00095                                         value_addto(som, som, t );
00096                                         //B->p[u][c] *= R->p[i][i];
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                 /* reste a faire le pgcd du vecteur et a l'orienter */
00104                 value_set_si(p,0);
00105                 for( i=0 ; i<R->NbRows ; ++i )
00106                         //p = pgcd( p, B->p[u][i] );
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                                 //p = -p;
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                 /* incrementer le compteur de lignes */
00121                 ++l;
00122         }
00123        // BTran=Transpose(B);
00124         //Matrix_Free(B);
00125         return B;
00126 }
00127 
00128 
00129 /* fonction qui calcule les vect generateurs de l'espace vectoriel
00130         contenant le polyhedre P */
00131 /*
00132 Matrix *CalcPolyhedronBase( Polyhedron *P )
00133 {
00134         Matrix *R;
00135         Matrix *B;
00136         int n, lines;
00137 
00138         if( emptyQ(P) )
00139                 return( Matrix_Alloc( 0, P->Dimension ) ); // pas de vect. gen 
00140 
00141         R = Matrix_Alloc( P->Dimension, P->Dimension );
00142 
00143          // recopie le 'lineality space' du polyedre dans la matrice R 
00144         for( lines=0,n=0 ; n<P->NbConstraints ; ++n )
00145         {
00146                 if( P->Constraint[n][0]==0 )
00147                 // c'est une direction definissant un ss-espace 
00148                 {
00149                         memcpy( &R->p[lines][0], &P->Constraint[n][1],
00150                                         sizeof(int)*P->Dimension );
00151                         ++lines;
00152                 }
00153         }
00154         // remplit le reste de 0..0 
00155         for( ; lines<R->NbRows ; ++lines )
00156                 memset( &R->p[lines][0], 0, sizeof(int)*P->Dimension );
00157 
00158         B = CalcBase( R );
00159         Matrix_Free( R );
00160 
00161         return( B );
00162 }*/
00163 
00164 
00165 /* fonction qui calcule l'espace vectoriel non parametre de dimension dim
00166         contenant le polyhedre parametre P */
00167 /* les _egalites_ sont stockees par la polylib sous forme triangulaire
00168 superieure donc il suffit de prendre les premieres. */
00169 
00170 /*Matrix *CalcEVPolyhedronNP( Polyhedron *P, int dim )
00171 {
00172         Matrix *R;
00173         Matrix *B;
00174         int n, lines;
00175 
00176         if( emptyQ(P) ) // pas de vect. gen 
00177         {
00178                 B = Matrix_Alloc( 1, dim );     //on ne peut pas allouer 0 lignes ! 
00179                 B->NbRows = 0;
00180                 return( B );
00181         }
00182 
00183         R = Matrix_Alloc( dim, dim );
00184 
00185         // recopie le 'lineality space' du polyedre dans la matrice R 
00186         for( lines=0,n=0 ; n<P->NbConstraints && lines<dim ; ++n )
00187         {
00188                 if( P->Constraint[n][0]==0 )
00189                 // c'est une direction definissant un ss-espace 
00190                 {
00191                         memcpy( &R->p[lines][0], &P->Constraint[n][1],
00192                                         sizeof(int)*P->Dimension );
00193                         ++lines;
00194                 }
00195         }
00196         // remplit le reste de 0..0 
00197         for( ; lines<R->NbRows ; ++lines )
00198                 memset( &R->p[lines][0], 0, sizeof(int)*dim );
00199 
00200         B = CalcBase( R );
00201         Matrix_Free( R );
00202 
00203         return( B );
00204 }*/
00205 
00206 /* renvoie la ligne sur laquelle on a trouve un coef non nul */
00207 /* pareil mais cherche dans toutes les lignes */
00208 /* et -1 s'il n'y en a pas. */
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         /* on ne l'a pas trouve pour l'instant... on cherche au dessus */
00218         /* les lignes ayant que des 0 jusqu'a la position l */
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 /* echange les lignes l1 et l2 dans la matrice R */
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 /* Soustraire la ligne l1 de l2 */
00269 /* On effectue l2 = (l1[piv]/pgcd)*l2 - l1 * (l2[piv]/pgcd) */
00270 static void Soustraire_ligne(Matrix *R, int l1, int l2, int piv )
00271 {
00272         int i;
00273         Value  a, b, p, t;
00274         /* l2 = a*l2 - b*l1 */
00275 
00276         if (value_zero_p(R->p[l2][piv] ))               /* c'est deja fait ! */
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                 //R->p[l2][i] = a*R->p[l2][i] - b*R->p[l1][i];
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                 //p = pgcd( p, R->p[l2][i] );
00297                 Gcd(p, R->p[l2][i], &p );
00298         }
00299         /* Simplification par le pgcd de toute la ligne */
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 /*** ext_ehrhart.c ****/
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          /* Add two rational numbers*/
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                   /* Add the constant to the constant term of a polynomial*/
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                           /* Add the constant to all elements of a periodic number */
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      // ######### add polynomial or periodic to constant #############
00360      //you have to exchange e1 and res, before doing addition 
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 {   // ((e1->d==0) && (res->d==0)) 
00375                  if ((e1->x.p->type != res->x.p->type) ) {
00376                       // ##### adding to evalues of different type. two cases are possible  #### 
00377                       
00378                       //  #### res is periodic and e1 is polynomial, you have to exchange
00379                       //e1 and res then to add e1 to the constant term of res  ####
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                           // #### res is polynomial and e1 is periodic,
00391                           //  add e1 to the constant term of res  ####
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                  // ### adding evalues of different position (i.e function of different unknowns
00401                  // to case are possible  ###
00402                            
00403                          if (res->x.p->type == polynomial) {//  ### res and e1 are polynomials
00404                                //  add e1 to the constant term of res
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 {  // ### res and e1 are pointers to periodic numbers
00411                                    //add e1 to all elements of res 
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                  //same type , same pos  and same size
00425                  if (e1->x.p->size == res->x.p->size) {
00426                       // add any element in e1 to the corresponding element in res 
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                 /* Sizes are different */
00435                 if (res->x.p->type==polynomial) {
00436                     /* VIN100: if e1-size > res-size you have to copy e1 in a   */
00437                     /* new enode and add res to that new node. If you do not do */
00438                     /* that, you lose the the upper weight part of e1 !         */
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                               //  free_evalue_refs(&res->x.p->arr[i]);
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     // ### add two periodics of the same pos (unknown) but whith different sizes (periods) ###
00462                 else if (res->x.p->type==periodic) {
00463                       /* you have to create a new evalue 'ne' in whitch size equals to the scm
00464                        of the sizes of e1 and res, then to copy res periodicaly in ne, after
00465                        to add periodicaly elements of e1 to elements of ne, and finaly to 
00466                        return ne. */
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 { /* evector */
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  } /* new_eadd */
00504    
00505 // remove the last row and the last column of a matrix Mat
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    } /* Reduce_Matrix */
00521     
00522   
00523   /* Computes the scalar product (in euclidien space) of two vectors */ 
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   } /* Scalar_product */
00540 
00541     /* computes the scm of two integrals  */
00542      
00543       int ppcm1 (int a, int b) {
00544            int t;
00545            t = (a*b)/ pgcd1(a,b);
00546           return t;
00547        } /* ppcm1 */
00548   
00549 /* computes the scm of two values */
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 } /* ppcm  */
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   }  /* Orthogaunal_Base  */
00627      
00628 
00629   // Remove an element of à list  
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   } /* Remove_Element */
00638   
00639  /* Remove validite domains and correspending ehrhart polynomials whitch are redundant after 
00640   the enumeration of a polyhedron */
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  }/*Remove_RedendentDomains */
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 /* Enumeration of a domain D */
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  DO NOT USE THE FOLLOWING FUNCTION IT'S NOT WORKING PROPERLY YET.
00830  **********/
00831 
00832 /* Enumeration of the image by T of domain D */
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           /* adding a new constraint for all constraints of D in which the scalar product of the*/
00926           /* normal whith vector v1 is greter then zero*/
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                        /* Create a new contraint whitch is added to the polyhedron*/
00939                        
00940                        NCont=Vector_Alloc(d1->NbRows+2);
00941                        value_set_si( NCont->p[0],1); // the constraint is an inequalite
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                         //add the new constraint to polyhedron D
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) { //  No constraint is added to input polyhedron
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 { // some constraintes are added to input polyhedron 
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 

Generated on Mon Mar 15 10:59:50 2004 for polylib by doxygen1.2.18