2 #include <barvinok/options.h>
3 #include "param_util.h"
5 #include "isl_param_util.h"
8 #define ALLOC(type) (type*)malloc(sizeof(type))
9 #define ALLOCN(type,n) (type*)malloc((n) * sizeof(type))
11 void Param_Vertex_Common_Denominator(Param_Vertices
*V
)
17 assert(V
->Vertex
->NbRows
> 0);
18 dim
= V
->Vertex
->NbColumns
-2;
22 value_assign(lcm
, V
->Vertex
->p
[0][dim
+1]);
23 for (i
= 1; i
< V
->Vertex
->NbRows
; ++i
)
24 value_lcm(lcm
, V
->Vertex
->p
[i
][dim
+1], lcm
);
26 for (i
= 0; i
< V
->Vertex
->NbRows
; ++i
) {
27 if (value_eq(V
->Vertex
->p
[i
][dim
+1], lcm
))
29 value_division(V
->Vertex
->p
[i
][dim
+1], lcm
, V
->Vertex
->p
[i
][dim
+1]);
30 Vector_Scale(V
->Vertex
->p
[i
], V
->Vertex
->p
[i
],
31 V
->Vertex
->p
[i
][dim
+1], dim
+1);
32 value_assign(V
->Vertex
->p
[i
][dim
+1], lcm
);
38 /* Plug in the parametric vertex Vertex (nvar x (nparam + 2))
39 * in the constraint constraint (1 + nvar + nparam + 1).
40 * The result is stored in row (1 + nparam + 1),
41 * with the denominator in position 0.
43 void Param_Inner_Product(Value
*constraint
, Matrix
*Vertex
, Value
*row
)
45 unsigned nparam
= Vertex
->NbColumns
- 2;
46 unsigned nvar
= Vertex
->NbRows
;
50 value_set_si(row
[0], 1);
51 Vector_Set(row
+1, 0, nparam
+1);
56 for (j
= 0 ; j
< nvar
; ++j
) {
58 value_assign(tmp2
, constraint
[1+j
]);
59 if (value_ne(row
[0], Vertex
->p
[j
][nparam
+1])) {
60 value_assign(tmp
, row
[0]);
61 value_lcm(row
[0], row
[0], Vertex
->p
[j
][nparam
+1]);
62 value_division(tmp
, row
[0], tmp
);
63 value_multiply(tmp2
, tmp2
, row
[0]);
64 value_division(tmp2
, tmp2
, Vertex
->p
[j
][nparam
+1]);
66 Vector_Combine(row
+1, Vertex
->p
[j
], row
+1, tmp
, tmp2
, nparam
+1);
69 Vector_Combine(row
+1, constraint
+1+nvar
, row
+1, tmp
, row
[0], nparam
+1);
75 static Param_Polyhedron
*PL_P2PP(Polyhedron
*Din
, Polyhedron
*Cin
,
76 struct barvinok_options
*options
)
78 unsigned MaxRays
= options
->MaxRays
;
79 if (MaxRays
& (POL_NO_DUAL
| POL_INTEGER
))
81 return Polyhedron2Param_Domain(Din
, Cin
, MaxRays
);
84 /* Compute a dummy Param_Domain that contains all vertices of Param_Domain D
85 * (which contains the vertices of P) that lie on the facet obtained by
86 * saturating constraint c of P
88 Param_Domain
*Param_Polyhedron_Facet(Param_Polyhedron
*PP
, Param_Domain
*D
,
93 unsigned nparam
= PP
->V
->Vertex
->NbColumns
-2;
94 Vector
*row
= Vector_Alloc(1+nparam
+1);
95 Param_Domain
*FD
= ALLOC(Param_Domain
);
99 nv
= (PP
->nbV
- 1)/(8*sizeof(int)) + 1;
100 FD
->F
= ALLOCN(unsigned, nv
);
101 memset(FD
->F
, 0, nv
* sizeof(unsigned));
103 FORALL_PVertex_in_ParamPolyhedron(V
, D
, PP
) /* _i, _ix, _bx internal counters */
105 Param_Inner_Product(constraint
, V
->Vertex
, row
->p
);
106 if (First_Non_Zero(row
->p
+1, nparam
+1) == -1)
108 END_FORALL_PVertex_in_ParamPolyhedron
;
115 #ifndef POINTS2TRIANGS_PATH
116 Param_Polyhedron
*TC_P2PP(Polyhedron
*P
, Polyhedron
*C
,
117 struct barvinok_options
*options
)
123 Param_Polyhedron
*Polyhedron2Param_Polyhedron(Polyhedron
*P
, Polyhedron
*C
,
124 struct barvinok_options
*options
)
126 switch(options
->chambers
) {
127 case BV_CHAMBERS_POLYLIB
:
128 return PL_P2PP(P
, C
, options
);
130 case BV_CHAMBERS_TOPCOM
:
131 return TC_P2PP(P
, C
, options
);
133 case BV_CHAMBERS_ISL
:
134 return ISL_P2PP(P
, C
, options
);
141 #define INT_BITS (sizeof(unsigned) * 8)
143 /* Wegner's method for counting the number of ones in a bit vector */
144 int bit_vector_count(unsigned *F
, int F_len
)
149 for (i
= 0; i
< F_len
; ++i
) {
159 void Param_Vertex_Set_Facets(Param_Polyhedron
*PP
, Param_Vertices
*V
)
162 unsigned nparam
= V
->Vertex
->NbColumns
- 2;
163 int len
= (PP
->Constraints
->NbRows
+INT_BITS
-1)/INT_BITS
;
166 Vector
*row
= Vector_Alloc(1 + nparam
+ 1);
168 V
->Facets
= (unsigned *)calloc(len
, sizeof(unsigned));
169 for (i
= 0, ix
= 0, bx
= MSB
; i
< PP
->Constraints
->NbRows
; ++i
) {
170 Param_Inner_Product(PP
->Constraints
->p
[i
], V
->Vertex
, row
->p
);
171 if (First_Non_Zero(row
->p
+1, nparam
+1) == -1)
179 Polyhedron
*Param_Vertex_Cone(Param_Polyhedron
*PP
, Param_Vertices
*V
,
180 struct barvinok_options
*options
)
184 int len
= (PP
->Constraints
->NbRows
+INT_BITS
-1)/INT_BITS
;
188 unsigned nvar
= V
->Vertex
->NbRows
;
189 unsigned nparam
= V
->Vertex
->NbColumns
- 2;
192 Param_Vertex_Set_Facets(PP
, V
);
193 n
= bit_vector_count(V
->Facets
, len
);
195 M
= Matrix_Alloc(n
, 1+nvar
+1);
197 for (i
= 0, j
= 0, ix
= 0, bx
= MSB
; i
< PP
->Constraints
->NbRows
; ++i
) {
198 if (V
->Facets
[ix
] & bx
)
199 Vector_Copy(PP
->Constraints
->p
[i
], M
->p
[j
++], 1+nvar
);
202 C
= Constraints2Polyhedron(M
, options
->MaxRays
);
208 /* Compute activity domain of a parametric vertex. */
209 void Param_Vertex_Domain(Param_Vertices
*V
, Polyhedron
*P
)
212 unsigned nparam
= V
->Vertex
->NbColumns
-2;
217 V
->Domain
= Matrix_Alloc(P
->NbConstraints
, 1+nparam
+1);
218 for (i
= 0; i
< P
->NbConstraints
; ++i
) {
219 Param_Inner_Product(P
->Constraint
[i
], V
->Vertex
, V
->Domain
->p
[i
]);
220 value_assign(V
->Domain
->p
[i
][0], P
->Constraint
[i
][0]);