polylib: ranking.c Source File

- Main Page
- Classes
- Files

- File List
- File Members

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