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

Generated on Mon Sep 12 15:15:10 2005 for polylib by doxygen 1.3.5