polylib: homogenization.c Source File

- Main Page
- Classes
- Files

- File List
- File Members

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