polylib: ranking.c Source File

- Main Page
- Classes
- Files

# 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 }