polylib: eval_ehrhart.c Source File

- Main Page
- Classes
- Files

- File List
- File Members

# eval_ehrhart.c

Go to the documentation of this file.

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