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

ranking.c

Go to the documentation of this file.
00001 /**
00002  * Tools to compute the ranking function of an iteration J: the number of
00003  * integer points in P that are lexicographically inferior to J 
00004  * B. Meister
00005  * 6/2005
00006  * LSIIT-ICPS, UMR 7005 CNRS Université Louis Pasteur
00007  * HiPEAC Network
00008  */
00009 
00010 #include <polylib/polylib.h>
00011 #include <polylib/ranking.h>
00012 
00013 /**
00014  * Returns a list of polytopes needed to compute
00015  * the number of points in P that are lexicographically
00016  * smaller than a given point in D.
00017  * Only the first dim dimensions are taken into account
00018  * for computing the lexsmaller relation.
00019  * The remaining variables are assumed to be extra
00020  * existential/control variables.
00021  * When P == D, this is the conventional ranking function.
00022  * P and D are assumed to have the same parameter domain C.
00023  *
00024  * The first polyhedron in the list returned is the
00025  * updated context: a combination of D and C or an extended C.
00026  *
00027  * The order of the variables in the remaining polyhedra is
00028  * - first dim variables of P
00029  * - existential variables of P
00030  * - existential variables of D
00031  * - first dim variables of D
00032  * - the parameters
00033  */
00034 Polyhedron *LexSmaller(Polyhedron *P, Polyhedron *D, unsigned dim,
00035                         Polyhedron *C, unsigned MAXRAYS)
00036 {
00037   unsigned i, j, k, r;
00038   unsigned nb_parms = C->Dimension;
00039   unsigned nb_vars = dim;
00040   unsigned P_extra = P->Dimension - nb_vars - nb_parms;
00041   unsigned D_extra = D->Dimension - nb_vars - nb_parms;
00042   unsigned nb_new_parms;
00043   unsigned ncons;
00044   Matrix * cur_element, * C_times_J, * Klon;
00045   Polyhedron * P1, *C1;
00046   Polyhedron * lexico_lesser_union = NULL;
00047 
00048   POL_ENSURE_INEQUALITIES(C);
00049   POL_ENSURE_INEQUALITIES(D);
00050   POL_ENSURE_INEQUALITIES(P);
00051 
00052   assert(P->Dimension >= C->Dimension + dim);
00053   assert(D->Dimension >= C->Dimension + dim);
00054   nb_new_parms = nb_vars;
00055 
00056   /* the number of variables must be positive */
00057   if (nb_vars<=0) {
00058     printf("\nRanking > No variables, returning NULL.\n"); 
00059     return NULL;
00060   }
00061   /*
00062    * if D has extra variables, then we can't squeeze the contraints
00063    * of D in the new context, so we simply add them to each element.
00064    */
00065   if (D_extra)
00066     cur_element = Matrix_Alloc(P->NbConstraints+D->NbConstraints+nb_new_parms, 
00067                                P->Dimension+D_extra+nb_new_parms+2);
00068   else
00069     cur_element = Matrix_Alloc(P->NbConstraints+nb_new_parms, 
00070                                P->Dimension+D_extra+nb_new_parms+2);
00071 
00072 
00073   /* 0- Put P in the first rows of cur_element */
00074   for (i=0; i < P->NbConstraints; i++) {
00075     Vector_Copy(P->Constraint[i], cur_element->p[i], nb_vars+P_extra+1);
00076     Vector_Copy(P->Constraint[i]+1+nb_vars+P_extra, 
00077                 cur_element->p[i]+1+nb_vars+P_extra+D_extra+nb_new_parms, 
00078                 nb_parms+1);
00079   }
00080   ncons = P->NbConstraints;
00081   if (D_extra) {
00082     for (i=0; i < D->NbConstraints; i++) {
00083       r = P->NbConstraints + i;
00084       Vector_Copy(D->Constraint[i], cur_element->p[r], 1);
00085       Vector_Copy(D->Constraint[i]+1, 
00086                   cur_element->p[r]+1+nb_vars+P_extra+D_extra, nb_new_parms);
00087       Vector_Copy(D->Constraint[i]+1+nb_new_parms, 
00088                   cur_element->p[r]+1+nb_vars+P_extra, D_extra);
00089       Vector_Copy(D->Constraint[i]+1+nb_new_parms+D_extra, 
00090                   cur_element->p[r]+1+nb_vars+P_extra+D_extra+nb_new_parms, 
00091                   nb_parms+1);
00092     }
00093     ncons += D->NbConstraints;
00094   }
00095 
00096   /* 1- compute the Ehrhart polynomial of each disjoint polyhedron defining the
00097      lexicographic order */
00098   for (k=0, r = ncons; k < nb_vars; k++, r++) {
00099 
00100     /* a- build the corresponding matrix
00101      *  the nb of rows of cur_element is fake, so that we do not have to
00102      *  re-allocate it. */
00103     cur_element->NbRows = r+1;
00104 
00105     /* convert the previous (strict) inequality into an equality */
00106     if (k>=1) {
00107       value_set_si(cur_element->p[r-1][0], 0);
00108       value_set_si(cur_element->p[r-1][cur_element->NbColumns-1], 0);
00109     }
00110     /* build the k-th inequality from P */
00111     value_set_si(cur_element->p[r][0], 1);
00112     value_set_si(cur_element->p[r][k+1], -1);
00113     value_set_si(cur_element->p[r][nb_vars+P_extra+D_extra+k+1], 1);
00114     /* we want a strict inequality */
00115     value_set_si(cur_element->p[r][cur_element->NbColumns-1], -1);
00116 #ifdef ERDEBUG
00117     show_matrix(cur_element);
00118 #endif
00119 
00120     /* b- add it to the current union
00121        as Constraints2Polyhedron modifies its input, we must clone cur_element */
00122     Klon = Matrix_Copy(cur_element);
00123     P1 = Constraints2Polyhedron(Klon, MAXRAYS);
00124     Matrix_Free(Klon);
00125     P1->next = lexico_lesser_union;
00126     lexico_lesser_union = P1;
00127   }
00128   
00129   /* 2- as we introduce n parameters, we must introduce them into the context
00130    * as well. 
00131    * The added constraints are P.M.(J N 1 )^T >=0 */
00132   if (D_extra)
00133     C_times_J = Matrix_Alloc(C->NbConstraints, nb_new_parms+nb_parms+2);
00134   else
00135     C_times_J = Matrix_Alloc(C->NbConstraints + D->NbConstraints, D->Dimension+2);
00136   /* copy the initial context while adding the new parameters */
00137   for (i = 0; i < C->NbConstraints; i++) {
00138     value_assign(C_times_J->p[i][0], C->Constraint[i][0]);
00139     Vector_Copy(C->Constraint[i]+1, C_times_J->p[i]+1+nb_new_parms, nb_parms+1);
00140   }
00141 
00142   /* copy constraints from evaluation domain */
00143   if (!D_extra)
00144     for (i = 0; i < D->NbConstraints; i++)
00145       Vector_Copy(D->Constraint[i], C_times_J->p[C->NbConstraints+i], 
00146                   D->Dimension+2);
00147 
00148 #ifdef ERDEBUG
00149   show_matrix(C_times_J);
00150 #endif
00151   C1 = Constraints2Polyhedron(C_times_J, POL_NO_DUAL);
00152 
00153   /* 4- clean up */
00154   Matrix_Free(cur_element);
00155   Matrix_Free(C_times_J);
00156 
00157   C1->next = P1;
00158 
00159   return C1;
00160 } /* LexSmaller */
00161 
00162 
00163 /**
00164  * Returns the number of points in P that are lexicographically
00165  * smaller than a given point in D.
00166  * Only the first dim dimensions are taken into account
00167  * for computing the lexsmaller relation.
00168  * The remaining variables are assumed to be extra
00169  * existential/control variables.
00170  * When P == D, this is the conventional ranking function.
00171  * P and D are assumed to have the same parameter domain C.
00172  * The variables in the Enumeration correspond to the first dim variables
00173  * in D followed by the parameters of D (the variables of C).
00174  */
00175 Enumeration *Polyhedron_LexSmallerEnumerate(Polyhedron *P, Polyhedron *D, 
00176                                             unsigned dim,
00177                                             Polyhedron *C, unsigned MAXRAYS)
00178 {
00179   Enumeration * ranking;
00180   Polyhedron *RC, *RD;
00181 
00182   RC = LexSmaller(P, D, dim, C, MAXRAYS);
00183   RD = RC->next;
00184   RC->next = NULL;
00185 
00186   /* Compute the ranking, which is the sum of the Ehrhart polynomials of the n
00187      disjoint polyhedra we just put in P1. */
00188   /* OPT : our polyhdera are (already) disjoint, so Domain_Enumerate does
00189      probably too much work uselessly */
00190   ranking = Domain_Enumerate(RD, RC, MAXRAYS, NULL);
00191 
00192   Domain_Free(RD);
00193   Polyhedron_Free(RC);
00194 
00195   return ranking;
00196 }
00197 
00198 
00199 /*
00200  * Returns a function that assigns a unique number to each point in the
00201  * polytope P ranging from zero to (number of points in P)-1.
00202  * The order of the numbers corresponds to the lexicographical order.
00203  *
00204  * C is the parameter context of the polytope
00205  */
00206 Enumeration *Polyhedron_Ranking(Polyhedron *P, Polyhedron *C, unsigned MAXRAYS)
00207 {
00208     return Polyhedron_LexSmallerEnumerate(P, P, P->Dimension-C->Dimension, 
00209                                           C, MAXRAYS);
00210 }

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