2 #include <barvinok/options.h>
3 #include "param_util.h"
7 #define ALLOC(type) (type*)malloc(sizeof(type))
8 #define ALLOCN(type,n) (type*)malloc((n) * sizeof(type))
10 void Param_Vertex_Common_Denominator(Param_Vertices
*V
)
16 assert(V
->Vertex
->NbRows
> 0);
17 dim
= V
->Vertex
->NbColumns
-2;
21 value_assign(lcm
, V
->Vertex
->p
[0][dim
+1]);
22 for (i
= 1; i
< V
->Vertex
->NbRows
; ++i
)
23 value_lcm(lcm
, V
->Vertex
->p
[i
][dim
+1], lcm
);
25 for (i
= 0; i
< V
->Vertex
->NbRows
; ++i
) {
26 if (value_eq(V
->Vertex
->p
[i
][dim
+1], lcm
))
28 value_division(V
->Vertex
->p
[i
][dim
+1], lcm
, V
->Vertex
->p
[i
][dim
+1]);
29 Vector_Scale(V
->Vertex
->p
[i
], V
->Vertex
->p
[i
],
30 V
->Vertex
->p
[i
][dim
+1], dim
+1);
31 value_assign(V
->Vertex
->p
[i
][dim
+1], lcm
);
37 /* Plug in the parametric vertex Vertex (nvar x (nparam + 2))
38 * in the constraint constraint (1 + nvar + nparam + 1).
39 * The result is stored in row (1 + nparam + 1),
40 * with the denominator in position 0.
42 void Param_Inner_Product(Value
*constraint
, Matrix
*Vertex
, Value
*row
)
44 unsigned nparam
= Vertex
->NbColumns
- 2;
45 unsigned nvar
= Vertex
->NbRows
;
49 value_set_si(row
[0], 1);
50 Vector_Set(row
+1, 0, nparam
+1);
55 for (j
= 0 ; j
< nvar
; ++j
) {
57 value_assign(tmp2
, constraint
[1+j
]);
58 if (value_ne(row
[0], Vertex
->p
[j
][nparam
+1])) {
59 value_assign(tmp
, row
[0]);
60 value_lcm(row
[0], row
[0], Vertex
->p
[j
][nparam
+1]);
61 value_division(tmp
, row
[0], tmp
);
62 value_multiply(tmp2
, tmp2
, row
[0]);
63 value_division(tmp2
, tmp2
, Vertex
->p
[j
][nparam
+1]);
65 Vector_Combine(row
+1, Vertex
->p
[j
], row
+1, tmp
, tmp2
, nparam
+1);
68 Vector_Combine(row
+1, constraint
+1+nvar
, row
+1, tmp
, row
[0], nparam
+1);
74 static Param_Polyhedron
*PL_P2PP(Polyhedron
*Din
, Polyhedron
*Cin
,
75 struct barvinok_options
*options
)
77 unsigned MaxRays
= options
->MaxRays
;
78 if (MaxRays
& (POL_NO_DUAL
| POL_INTEGER
))
80 return Polyhedron2Param_Domain(Din
, Cin
, MaxRays
);
83 /* Compute a dummy Param_Domain that contains all vertices of Param_Domain D
84 * (which contains the vertices of P) that lie on the facet obtained by
85 * saturating constraint c of P
87 Param_Domain
*Param_Polyhedron_Facet(Param_Polyhedron
*PP
, Param_Domain
*D
,
92 unsigned nparam
= PP
->V
->Vertex
->NbColumns
-2;
93 Vector
*row
= Vector_Alloc(1+nparam
+1);
94 Param_Domain
*FD
= ALLOC(Param_Domain
);
98 nv
= (PP
->nbV
- 1)/(8*sizeof(int)) + 1;
99 FD
->F
= ALLOCN(unsigned, nv
);
100 memset(FD
->F
, 0, nv
* sizeof(unsigned));
102 FORALL_PVertex_in_ParamPolyhedron(V
, D
, PP
) /* _i, _ix, _bx internal counters */
104 Param_Inner_Product(constraint
, V
->Vertex
, row
->p
);
105 if (First_Non_Zero(row
->p
+1, nparam
+1) == -1)
107 END_FORALL_PVertex_in_ParamPolyhedron
;
114 #ifndef POINTS2TRIANGS_PATH
115 Param_Polyhedron
*TC_P2PP(Polyhedron
*P
, Polyhedron
*C
,
116 struct barvinok_options
*options
)
122 Param_Polyhedron
*Polyhedron2Param_Polyhedron(Polyhedron
*P
, Polyhedron
*C
,
123 struct barvinok_options
*options
)
125 switch(options
->chambers
) {
126 case BV_CHAMBERS_POLYLIB
:
127 return PL_P2PP(P
, C
, options
);
129 case BV_CHAMBERS_TOPCOM
:
130 return TC_P2PP(P
, C
, options
);
137 #define INT_BITS (sizeof(unsigned) * 8)
139 /* Wegner's method for counting the number of ones in a bit vector */
140 int bit_vector_count(unsigned *F
, int F_len
)
145 for (i
= 0; i
< F_len
; ++i
) {
155 void Param_Vertex_Set_Facets(Param_Polyhedron
*PP
, Param_Vertices
*V
)
158 unsigned nparam
= V
->Vertex
->NbColumns
- 2;
159 int len
= (PP
->Constraints
->NbRows
+INT_BITS
-1)/INT_BITS
;
162 Vector
*row
= Vector_Alloc(1 + nparam
+ 1);
164 V
->Facets
= (unsigned *)calloc(len
, sizeof(unsigned));
165 for (i
= 0, ix
= 0, bx
= MSB
; i
< PP
->Constraints
->NbRows
; ++i
) {
166 Param_Inner_Product(PP
->Constraints
->p
[i
], V
->Vertex
, row
->p
);
167 if (First_Non_Zero(row
->p
+1, nparam
+1) == -1)
175 Polyhedron
*Param_Vertex_Cone(Param_Polyhedron
*PP
, Param_Vertices
*V
,
176 struct barvinok_options
*options
)
180 int len
= (PP
->Constraints
->NbRows
+INT_BITS
-1)/INT_BITS
;
184 unsigned nvar
= V
->Vertex
->NbRows
;
185 unsigned nparam
= V
->Vertex
->NbColumns
- 2;
188 Param_Vertex_Set_Facets(PP
, V
);
189 n
= bit_vector_count(V
->Facets
, len
);
191 M
= Matrix_Alloc(n
, 1+nvar
+1);
193 for (i
= 0, j
= 0, ix
= 0, bx
= MSB
; i
< PP
->Constraints
->NbRows
; ++i
) {
194 if (V
->Facets
[ix
] & bx
)
195 Vector_Copy(PP
->Constraints
->p
[i
], M
->p
[j
++], 1+nvar
);
198 C
= Constraints2Polyhedron(M
, options
->MaxRays
);
204 /* Compute activity domain of a parametric vertex. */
205 void Param_Vertex_Domain(Param_Vertices
*V
, Polyhedron
*P
)
208 unsigned nparam
= V
->Vertex
->NbColumns
-2;
213 V
->Domain
= Matrix_Alloc(P
->NbConstraints
, 1+nparam
+1);
214 for (i
= 0; i
< P
->NbConstraints
; ++i
) {
215 Param_Inner_Product(P
->Constraint
[i
], V
->Vertex
, V
->Domain
->p
[i
]);
216 value_assign(V
->Domain
->p
[i
][0], P
->Constraint
[i
][0]);