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

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 }

Generated on Thu Sep 4 15:28:57 2008 for polylib by doxygen 1.3.5