1 #include <barvinok/options.h>
2 #include "param_util.h"
6 #define ALLOC(type) (type*)malloc(sizeof(type))
7 #define ALLOCN(type,n) (type*)malloc((n) * sizeof(type))
9 void Param_Vertex_Common_Denominator(Param_Vertices
*V
)
15 assert(V
->Vertex
->NbRows
> 0);
16 dim
= V
->Vertex
->NbColumns
-2;
20 value_assign(lcm
, V
->Vertex
->p
[0][dim
+1]);
21 for (i
= 1; i
< V
->Vertex
->NbRows
; ++i
)
22 value_lcm(lcm
, V
->Vertex
->p
[i
][dim
+1], lcm
);
24 for (i
= 0; i
< V
->Vertex
->NbRows
; ++i
) {
25 if (value_eq(V
->Vertex
->p
[i
][dim
+1], lcm
))
27 value_division(V
->Vertex
->p
[i
][dim
+1], lcm
, V
->Vertex
->p
[i
][dim
+1]);
28 Vector_Scale(V
->Vertex
->p
[i
], V
->Vertex
->p
[i
],
29 V
->Vertex
->p
[i
][dim
+1], dim
+1);
30 value_assign(V
->Vertex
->p
[i
][dim
+1], lcm
);
36 /* Plug in the parametric vertex Vertex (nvar x (nparam + 2))
37 * in the constraint constraint (1 + nvar + nparam + 1).
38 * The result is stored in row (1 + nparam + 1),
39 * with the denominator in position 0.
41 void Param_Inner_Product(Value
*constraint
, Matrix
*Vertex
, Value
*row
)
43 unsigned nparam
= Vertex
->NbColumns
- 2;
44 unsigned nvar
= Vertex
->NbRows
;
48 value_set_si(row
[0], 1);
49 Vector_Set(row
+1, 0, nparam
+1);
54 for (j
= 0 ; j
< nvar
; ++j
) {
56 value_assign(tmp2
, constraint
[1+j
]);
57 if (value_ne(row
[0], Vertex
->p
[j
][nparam
+1])) {
58 value_assign(tmp
, row
[0]);
59 value_lcm(row
[0], row
[0], Vertex
->p
[j
][nparam
+1]);
60 value_division(tmp
, row
[0], tmp
);
61 value_multiply(tmp2
, tmp2
, row
[0]);
62 value_division(tmp2
, tmp2
, Vertex
->p
[j
][nparam
+1]);
64 Vector_Combine(row
+1, Vertex
->p
[j
], row
+1, tmp
, tmp2
, nparam
+1);
67 Vector_Combine(row
+1, constraint
+1+nvar
, row
+1, tmp
, row
[0], nparam
+1);
73 static Param_Polyhedron
*PL_P2PP(Polyhedron
*Din
, Polyhedron
*Cin
,
74 struct barvinok_options
*options
)
76 unsigned MaxRays
= options
->MaxRays
;
77 if (MaxRays
& (POL_NO_DUAL
| POL_INTEGER
))
79 return Polyhedron2Param_Domain(Din
, Cin
, MaxRays
);
82 /* Compute a dummy Param_Domain that contains all vertices of Param_Domain D
83 * (which contains the vertices of P) that lie on the facet obtained by
84 * saturating constraint c of P
86 Param_Domain
*Param_Polyhedron_Facet(Param_Polyhedron
*PP
, Param_Domain
*D
,
91 unsigned nparam
= PP
->V
->Vertex
->NbColumns
-2;
92 Vector
*row
= Vector_Alloc(1+nparam
+1);
93 Param_Domain
*FD
= ALLOC(Param_Domain
);
97 nv
= (PP
->nbV
- 1)/(8*sizeof(int)) + 1;
98 FD
->F
= ALLOCN(unsigned, nv
);
99 memset(FD
->F
, 0, nv
* sizeof(unsigned));
101 FORALL_PVertex_in_ParamPolyhedron(V
, D
, PP
) /* _i, _ix, _bx internal counters */
103 Param_Inner_Product(P
->Constraint
[c
], V
->Vertex
, row
->p
);
104 if (First_Non_Zero(row
->p
+1, nparam
+1) == -1)
106 END_FORALL_PVertex_in_ParamPolyhedron
;
113 #ifndef POINTS2TRIANGS_PATH
114 Param_Polyhedron
*TC_P2PP(Polyhedron
*P
, Polyhedron
*C
,
115 struct barvinok_options
*options
)
121 Param_Polyhedron
*Polyhedron2Param_Polyhedron(Polyhedron
*P
, Polyhedron
*C
,
122 struct barvinok_options
*options
)
124 switch(options
->chambers
) {
125 case BV_CHAMBERS_POLYLIB
:
126 return PL_P2PP(P
, C
, options
);
128 case BV_CHAMBERS_TOPCOM
:
129 return TC_P2PP(P
, C
, options
);
136 #define INT_BITS (sizeof(unsigned) * 8)
138 /* Wegner's method for counting the number of ones in a bit vector */
139 int bit_vector_count(unsigned *F
, int F_len
)
144 for (i
= 0; i
< F_len
; ++i
) {
154 Polyhedron
*Param_Vertex_Cone(Param_Polyhedron
*PP
, Param_Vertices
*V
,
155 struct barvinok_options
*options
)
159 int len
= (PP
->Constraints
->NbRows
+INT_BITS
-1)/INT_BITS
;
163 unsigned nvar
= V
->Vertex
->NbRows
;
164 unsigned nparam
= V
->Vertex
->NbColumns
- 2;
169 Vector
*row
= Vector_Alloc(1 + nparam
+ 1);
171 V
->Facets
= (unsigned *)calloc(len
, sizeof(unsigned));
172 for (i
= 0, ix
= 0, bx
= MSB
; i
< PP
->Constraints
->NbRows
; ++i
) {
173 Param_Inner_Product(PP
->Constraints
->p
[i
], V
->Vertex
, row
->p
);
174 if (First_Non_Zero(row
->p
+1, nparam
+1) == -1)
180 n
= bit_vector_count(V
->Facets
, len
);
182 M
= Matrix_Alloc(n
, 1+nvar
+1);
184 for (i
= 0, j
= 0, ix
= 0, bx
= MSB
; i
< PP
->Constraints
->NbRows
; ++i
) {
185 if (V
->Facets
[ix
] & bx
)
186 Vector_Copy(PP
->Constraints
->p
[i
], M
->p
[j
++], 1+nvar
);
189 C
= Constraints2Polyhedron(M
, options
->MaxRays
);
195 /* Compute activity domain of a parametric vertex. */
196 void Param_Vertex_Domain(Param_Vertices
*V
, Polyhedron
*P
)
199 unsigned nparam
= V
->Vertex
->NbColumns
-2;
204 V
->Domain
= Matrix_Alloc(P
->NbConstraints
, 1+nparam
+1);
205 for (i
= 0; i
< P
->NbConstraints
; ++i
) {
206 Param_Inner_Product(P
->Constraint
[i
], V
->Vertex
, V
->Domain
->p
[i
]);
207 value_assign(V
->Domain
->p
[i
][0], P
->Constraint
[i
][0]);