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 Polyhedron 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   Value tmp;
00032 
00033   value_init(v); 
00034   value_init(tmp);
00035   
00036   /*P->Constraint constraint matrice of polyhedron P*/  
00037   for(row=0;row<P->NbConstraints;row++) {
00038     value_assign(v,P->Constraint[row][P->Dimension+1]); /*constant part*/
00039     for(col=1;col<P->Dimension+1;col++) {
00040       value_multiply(tmp,P->Constraint[row][col],list_args[col-1]);
00041       value_addto(v,v,tmp);
00042     }  
00043     if (value_notzero_p(P->Constraint[row][0])) {
00044         
00045       /*if v is not >=0 then this constraint is not respected */
00046       if (value_neg_p(v)) {
00047         value_clear(v);
00048         value_clear(tmp);
00049         return 0;
00050       } 
00051     }
00052     else {
00053       
00054       /*if v is not = 0 then this constraint is not respected */
00055       if (value_notzero_p(v)) {
00056         value_clear(v);
00057         value_clear(tmp);
00058         return 0;
00059       }
00060     }
00061   }
00062   
00063   /*if not return before this point => all 
00064     the constraints are respected */
00065   value_clear(v);
00066   value_clear(tmp);
00067   return 1;
00068 } /* in_domain */
00069 
00070 /****************************************************/
00071 /* function compute enode                           */
00072 /*     compute the value of enode p with parameters */
00073 /*     list "list_args                              */
00074 /*     compute the polynomial or the periodic       */
00075 /****************************************************/
00076 
00077 static double compute_enode(enode *p, Value *list_args) {
00078   
00079   int i;
00080   Value m, param;
00081   double res=0.0;
00082     
00083   if (!p)
00084     return(0.);
00085 
00086   value_init(m);
00087   value_init(param);
00088 
00089   if (p->type == polynomial) {
00090     if (p->size > 1)
00091                 value_assign(param,list_args[p->pos-1]);
00092     
00093     /* Compute the polynomial using Horner's rule */
00094     for (i=p->size-1;i>0;i--) {
00095       res +=compute_evalue(&p->arr[i],list_args);
00096       res *=VALUE_TO_DOUBLE(param);
00097     }
00098     res +=compute_evalue(&p->arr[0],list_args);
00099   }
00100   else if (p->type == periodic) {
00101     value_assign(m,list_args[p->pos-1]);
00102     
00103     /* Choose the right element of the periodic */
00104     value_set_si(param,p->size);
00105     value_pmodulus(m,m,param);
00106     res = compute_evalue(&p->arr[VALUE_TO_INT(m)],list_args);
00107   }
00108   value_clear(m);
00109   value_clear(param);
00110   return res;
00111 } /* compute_enode */
00112 
00113 /*************************************************/
00114 /* return the value of Ehrhart Polynomial        */
00115 /* It returns a double, because since it is      */
00116 /* a recursive function, some intermediate value */
00117 /* might not be integral                         */
00118 /*************************************************/
00119 
00120 double compute_evalue(evalue *e,Value *list_args) {
00121   
00122   double res;
00123   
00124   if (value_notzero_p(e->d)) {
00125     if (value_notone_p(e->d)) 
00126       res = VALUE_TO_DOUBLE(e->x.n) / VALUE_TO_DOUBLE(e->d);
00127     else 
00128       res = VALUE_TO_DOUBLE(e->x.n);
00129   }
00130   else 
00131     res = compute_enode(e->x.p,list_args);
00132   return res;
00133 } /* compute_evalue */
00134 
00135 
00136 /****************************************************/
00137 /* function compute_poly :                          */
00138 /* Check for the good validity domain               */
00139 /* return the number of point in the Polyhedron     */
00140 /* in allocated memory                              */
00141 /* Using the Ehrhart pseudo-polynomial              */
00142 /****************************************************/
00143 Value *compute_poly(Enumeration *en,Value *list_args) {
00144 
00145   Value *tmp;
00146   /*    double d; int i; */
00147 
00148   tmp = (Value *) malloc (sizeof(Value));
00149   assert(tmp != NULL);
00150   value_init(*tmp);
00151   value_set_si(*tmp,0);
00152   
00153   if(!en)
00154     return(tmp);        /* no ehrhart polynomial */
00155   if(en->ValidityDomain) {
00156     if(!en->ValidityDomain->Dimension) { /* no parameters */
00157       value_set_double(*tmp,compute_evalue(&en->EP,list_args)+.25);
00158       return(tmp);
00159     }
00160   }  
00161   else 
00162     return(tmp);  /* no Validity Domain */    
00163   while(en) {
00164     if(in_domain(en->ValidityDomain,list_args)) {
00165       
00166 #ifdef EVAL_EHRHART_DEBUG
00167       Print_Domain(stdout,en->ValidityDomain);
00168       print_evalue(stdout,&en->EP);
00169 #endif
00170       
00171       /*                        d = compute_evalue(&en->EP,list_args);
00172                                 i = d;
00173                                 printf("(double)%lf = %d\n", d, i ); */
00174       value_set_double(*tmp,compute_evalue(&en->EP,list_args)+.25);
00175       return(tmp);
00176     }
00177     else
00178       en=en->next;
00179   }
00180   value_set_si(*tmp,0);
00181   return(tmp); /* no compatible domain with the arguments */
00182 } /* compute_poly */ 
00183 
00184 
00185 
00186 

Generated on Mon Sep 12 14:48:28 2005 for polylib by doxygen 1.3.5