Main Page | Class List | File List | Class Members | File Members

eval_ehrhart.c

Go to the documentation of this file.
00001 /************************************************/
00002 /*  eval_ehrhart.c                              */
00003 /* functions to evaluate an Ehrhart polynomial. */
00004 /* written by Emmanuel Jeannot (c) 1997.        */
00005 /*  Emmanuel.Jeannot@ens-lyon.fr                */
00006 /*  http://www.ens-lyon.fr/~ejeannot            */
00007 /*                                              */
00008 /* modified 1998, 2000, Vincent Loechner        */
00009 /* (ArithmetiqueLib, Param_Names)               */
00010 /************************************************/
00011 
00012 #include <stdio.h>
00013 #include <math.h>
00014 #include <assert.h>
00015 #include <stdlib.h>
00016 
00017 #include <polylib/polylib.h>
00018 
00019 /* #define EVAL_EHRHART_DEBUG  */
00020 
00021 /********************************************************/
00022 /* function in domain                                   */
00023 /*    check if the parameters in list_args              */
00024 /*    verifies the constraints of Domain P              */
00025 /********************************************************/
00026 int in_domain(Polyhedron *P, Value *list_args) {
00027   
00028   int col,row;
00029   Value v; /* value of the constraint of a row when
00030                parameters are instanciated*/
00031 
00032   if( !P )
00033           return( 0 );
00034   POL_ENSURE_FACETS(P);
00035   POL_ENSURE_VERTICES(P);
00036 
00037   value_init(v); 
00038   
00039   /* P->Constraint constraint matrice of polyhedron P */  
00040   for(row=0;row<P->NbConstraints;row++) {
00041     value_assign(v,P->Constraint[row][P->Dimension+1]); /*constant part*/
00042     for(col=1;col<P->Dimension+1;col++) {
00043       value_addmul(v, P->Constraint[row][col], list_args[col-1]); 
00044     }  
00045     if (value_notzero_p(P->Constraint[row][0])) {
00046         
00047       /*if v is not >=0 then this constraint is not respected */
00048       if (value_neg_p(v)) {
00049         value_clear(v);
00050         return( in_domain(P->next, list_args) );
00051       }        
00052     }
00053     else {
00054       
00055       /*if v is not = 0 then this constraint is not respected */
00056       if (value_notzero_p(v)) {
00057         value_clear(v);
00058         return( in_domain(P->next, list_args) );
00059       }
00060     }
00061   }
00062   
00063   /* if not return before this point => all the constraints are respected */
00064   value_clear(v);
00065   return 1;
00066 } /* in_domain */
00067 
00068 /****************************************************/
00069 /* function compute enode                           */
00070 /*     compute the value of enode p with parameters */
00071 /*     list "list_args                              */
00072 /*     compute the polynomial or the periodic       */
00073 /****************************************************/
00074 
00075 static double compute_enode(enode *p, Value *list_args) {
00076   
00077   int i;
00078   Value m, param;
00079   double res=0.0;
00080     
00081   if (!p)
00082     return(0.);
00083 
00084   value_init(m);
00085   value_init(param);
00086 
00087   if (p->type == polynomial) {
00088     if (p->size > 1)
00089                  value_assign(param,list_args[p->pos-1]);
00090     
00091     /* Compute the polynomial using Horner's rule */
00092     for (i=p->size-1;i>0;i--) {
00093       res +=compute_evalue(&p->arr[i],list_args);
00094       res *=VALUE_TO_DOUBLE(param);
00095     }
00096     res +=compute_evalue(&p->arr[0],list_args);
00097   }
00098   else if (p->type == periodic) {
00099     value_assign(m,list_args[p->pos-1]);
00100     
00101     /* Choose the right element of the periodic */
00102     value_set_si(param,p->size);
00103     value_pmodulus(m,m,param);
00104     res = compute_evalue(&p->arr[VALUE_TO_INT(m)],list_args);
00105   }
00106   value_clear(m);
00107   value_clear(param);
00108   return res;
00109 } /* compute_enode */
00110 
00111 /*************************************************/
00112 /* return the value of Ehrhart Polynomial        */
00113 /* It returns a double, because since it is      */
00114 /* a recursive function, some intermediate value */
00115 /* might not be integral                         */
00116 /*************************************************/
00117 
00118 double compute_evalue(evalue *e,Value *list_args) {
00119   
00120   double res;
00121   
00122   if (value_notzero_p(e->d)) {
00123     if (value_notone_p(e->d)) 
00124       res = VALUE_TO_DOUBLE(e->x.n) / VALUE_TO_DOUBLE(e->d);
00125     else 
00126       res = VALUE_TO_DOUBLE(e->x.n);
00127   }
00128   else 
00129     res = compute_enode(e->x.p,list_args);
00130   return res;
00131 } /* compute_evalue */
00132 
00133 
00134 /****************************************************/
00135 /* function compute_poly :                          */
00136 /* Check for the good validity domain               */
00137 /* return the number of point in the Polyhedron     */
00138 /* in allocated memory                              */
00139 /* Using the Ehrhart pseudo-polynomial              */
00140 /****************************************************/
00141 Value *compute_poly(Enumeration *en,Value *list_args) {
00142 
00143   Value *tmp;
00144   /*        double d; int i; */
00145 
00146   tmp = (Value *) malloc (sizeof(Value));
00147   assert(tmp != NULL);
00148   value_init(*tmp);
00149   value_set_si(*tmp,0);
00150 
00151   if(!en)
00152     return(tmp);        /* no ehrhart polynomial */
00153   if(en->ValidityDomain) {
00154     if(!en->ValidityDomain->Dimension) { /* no parameters */
00155       value_set_double(*tmp,compute_evalue(&en->EP,list_args)+.25);
00156       return(tmp);
00157     }
00158   }  
00159   else 
00160     return(tmp);  /* no Validity Domain */    
00161   while(en) {
00162     if(in_domain(en->ValidityDomain,list_args)) {
00163       
00164 #ifdef EVAL_EHRHART_DEBUG
00165       Print_Domain(stdout,en->ValidityDomain,NULL);
00166       print_evalue(stdout,&en->EP,NULL);
00167 #endif
00168       
00169       /*                        d = compute_evalue(&en->EP,list_args);
00170                                 i = d;
00171                                 printf("(double)%lf = %d\n", d, i ); */
00172       value_set_double(*tmp,compute_evalue(&en->EP,list_args)+.25);
00173       return(tmp);
00174     }
00175     else
00176       en=en->next;
00177   }
00178   value_set_si(*tmp,0);
00179   return(tmp); /* no compatible domain with the arguments */
00180 } /* compute_poly */ 
00181 
00182 
00183 
00184 

Generated on Mon Apr 23 19:23:52 2007 for polylib by doxygen 1.3.5