00001
00002
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
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
00029
00030
00031 void dehomogenize_evalue(evalue *ep, int nb_param){
00032 evalue *w;
00033
00034
00035 if (value_zero_p(ep->d)){
00036
00037
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
00051 dehomogenize_enode(ep->x.p, nb_param);
00052 }
00053
00054 }
00055 }
00056
00057
00058
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
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
00082
00083
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
00098
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
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
00117 value_gcd(gcd, num, den);
00118 value_divexact(num, num, gcd);
00119 value_divexact(den, den, gcd);
00120
00121
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
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
00136
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
00153
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 }