polylib: eval_ehrhart.c Source File

- Main Page
- Classes
- Files

# 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
    00035   POL_ENSURE_INEQUALITIES(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