polylib: homogenization.c Source File

- Main Page
- Classes
- Files

# homogenization.c

Go to the documentation of this file.

    00001 /** homogenization.c
    00002     copyright 2004-2005 Bavo Nootaert
    00003 **/
    00004
    00005 #include <assert.h>
    00006 #include <stdlib.h>
    00007 #include <string.h>
    00008 #include <polylib/polylib.h>
    00009 #include <polylib/homogenization.h>
    00010
    00011 static evalue *dehomogenize_periodic(enode *en);
    00012 static evalue *dehomogenize_polynomial(enode *en);
    00013
    00014 Polyhedron *homogenize(Polyhedron *P, unsigned MAXRAYS)
    00015 {
    00016     Matrix M, *M2;
    00017     /* Pretend P is a Matrix for a second */
    00018     M.NbRows = P->NbConstraints;
    00019     M.NbColumns = P->Dimension+2;
    00020     M.p_Init = P->p_Init;
    00021     M.p = P->Constraint;
    00022     M2 = AddANullColumn(&M);
    00023     P = Constraints2Polyhedron(M2, MAXRAYS);
    00024     Matrix_Free(M2);
    00025     return P;
    00026 }
    00027
    00028 /** dehomogenize an evalue. The last parameter (nb_param) is replaced by 1.
    00029     This function is mutually recursive with dehomogenize_enode.
    00030 **/
    00031 void dehomogenize_evalue(evalue *ep, int nb_param){
    00032   evalue *w;
    00033
    00034   /** cannot dehomogenize rationals **/
    00035   if (value_zero_p(ep->d)){
    00036
    00037     /** we need to replace the last parameter **/
    00038     if (ep->x.p->pos == nb_param){
    00039       if (ep->x.p->type == periodic && ep->x.p->size > 1){
    00040         w = dehomogenize_periodic(ep->x.p);
    00041       }
    00042       else{
    00043         w = dehomogenize_polynomial(ep->x.p);
    00044       }
    00045       free_evalue_refs(ep);
    00046       memcpy(ep, w, sizeof(evalue));
    00047       free(w);
    00048     }
    00049     else{
    00050       /** Not the last parameter. Recurse **/
    00051       dehomogenize_enode(ep->x.p, nb_param);
    00052     }
    00053
    00054   }
    00055 }
    00056
    00057 /** dehomogenize all evalues in an enode.
    00058     This function is mutually recursive with dehomogenize_evalue.
    00059 **/
    00060 void dehomogenize_enode(enode *p, int nb_param){
    00061   evalue *temp;
    00062   int i;
    00063   for (i = 0; i < p->size; i++){
    00064     dehomogenize_evalue(&p->arr[i], nb_param);
    00065   }
    00066 }
    00067
    00068
    00069 /** return the 1st element of an enode representing a periodic **/
    00070 static evalue *dehomogenize_periodic(enode *en){
    00071   evalue *w;
    00072   assert(en->type == periodic);
    00073   assert(en->size > 1);
    00074   assert(value_notzero_p(en->arr[1].d));
    00075   w = (evalue*)malloc(sizeof(evalue));
    00076   value_init(w->d); value_init(w->x.n);
    00077   value_assign(w->d, en->arr[1].d); value_assign(w->x.n, en->arr[1].x.n);
    00078   return w;
    00079 }
    00080
    00081 /** dehomogenize a polynomial. Assume the enode contains a polynomial in
    00082     one variable, the homogenous parameter.
    00083     Returns an new evalue, representing a rational.
    00084  **/
    00085 static evalue *dehomogenize_polynomial(enode *en){
    00086   evalue *enn;
    00087   evalue *ev;
    00088   int i;
    00089   double som;
    00090   Value num, den, gcd, f1, f2;
    00091   assert(en->type == polynomial);
    00092   som = 0;
    00093   value_init(num); value_init(den); value_init(gcd);
    00094   value_init(f1); value_init(f2);
    00095   value_set_si(den, 1);
    00096
    00097   /** enumerate over all coefficients (which are either periodic or rational,
    00098       but not polynomial) **/
    00099   for (i = 0; i < en->size; i++){
    00100     if (value_zero_p(en->arr[i].d)){
    00101       if (en->arr[i].x.p->size > 1)
    00102         ev = &en->arr[i].x.p->arr[1];
    00103       else
    00104         ev = &en->arr[i].x.p->arr[0];
    00105     }
    00106     else{
    00107       ev = &en->arr[i];
    00108     }
    00109     /** add ev (fraction) to num/den **/
    00110     value_multiply(f1, den, ev->x.n);
    00111     value_multiply(f2, num, ev->d);
    00112     value_addto(num, f1, f2);
    00113     value_multiply(den, den, ev->d);
    00114   }
    00115
    00116   /** simplify num/den **/
    00117   value_gcd(gcd, num, den);
    00118   value_divexact(num, num, gcd);
    00119   value_divexact(den, den, gcd);
    00120
    00121   /** create new evalue representing num/den**/
    00122   enn = (evalue*)malloc(sizeof(evalue));
    00123   value_init(enn->d); value_init(enn->x.n);
    00124   value_assign(enn->d, den);
    00125   value_assign(enn->x.n, num);
    00126
    00127   /** cleanup **/
    00128   value_clear(gcd);
    00129   value_clear(f1); value_clear(f2);
    00130   value_clear(num); value_clear(den);
    00131
    00132   return enn;
    00133 }
    00134
    00135 /** dehomogenize a polyhedron. Assume the polyhedron p is homogenous.
    00136     Returns a new polyhedron.
    00137 **/
    00138 Polyhedron *dehomogenize_polyhedron(Polyhedron *p, int maxRays){
    00139   Matrix *constr, *constrh;
    00140   Polyhedron *ph;
    00141   int i;
    00142   constr = Polyhedron2Constraints(p);
    00143   constrh = Matrix_Alloc(constr->NbRows, constr->NbColumns - 1);
    00144   for (i = 0; i < constr->NbRows; i++){
    00145     Vector_Copy(constr->p[i], constrh->p[i], constr->NbColumns - 1);
    00146   }
    00147   ph = Constraints2Polyhedron(constrh, maxRays);
    00148   Matrix_Free(constr); Matrix_Free(constrh);
    00149   return ph;
    00150 }
    00151
    00152 /** dehomogenize an enumeration. Replaces each validity domain and
    00153     Ehrhart polynomial in the Enumeration en with the dehomogenized form.
    00154  **/
    00155 void dehomogenize_enumeration(Enumeration* en, int nb_params, int maxRays){
    00156   Enumeration *en2;
    00157   Polyhedron *vd;
    00158   for (en2 = en; en2; en2 = en2->next) {
    00159     vd = dehomogenize_polyhedron(en2->ValidityDomain, maxRays);
    00160     Polyhedron_Free(en2->ValidityDomain);
    00161     en2->ValidityDomain = vd;
    00162     dehomogenize_evalue(&en2->EP, nb_params);
    00163   }
    00164 }