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

Generated on Mon Sep 12 15:15:10 2005 for polylib by doxygen 1.3.5