1 #include <barvinok/options.h>
2 #include <barvinok/util.h>
3 #include "reduce_domain.h"
5 Polyhedron
*true_context(Polyhedron
*P
, Matrix
*CT
,
6 Polyhedron
*C
, unsigned MaxRays
)
8 unsigned nparam
= CT
? CT
->NbRows
- 1 : C
->Dimension
;
9 Polyhedron
*tmp
= Polyhedron_Project(P
, nparam
);
10 Polyhedron
*D
= CT
? DomainPreimage(tmp
, CT
, MaxRays
) : tmp
;
11 C
= DomainIntersection(D
, C
, MaxRays
);
18 Vector
*inner_point(Polyhedron
*P
)
23 unsigned dim
= P
->Dimension
;
26 average
= Vector_Alloc(1+dim
+1);
28 POL_ENSURE_VERTICES(P
);
29 for (i
= 0; i
< P
->NbRays
; ++i
) {
30 if (value_zero_p(P
->Ray
[i
][1+dim
]))
34 Vector_Copy(P
->Ray
[i
]+1, average
->p
+1, dim
+1);
41 value_assign(fc
, average
->p
[1+dim
]);
42 value_lcm(fc
, P
->Ray
[i
][1+dim
], &average
->p
[1+dim
]);
43 value_division(fc
, average
->p
[1+dim
], fc
);
44 value_division(fv
, average
->p
[1+dim
], P
->Ray
[i
][1+dim
]);
45 Vector_Combine(average
->p
+1, P
->Ray
[i
]+1, average
->p
+1, fc
, fv
, dim
);
49 value_multiply(average
->p
[1+dim
], average
->p
[1+dim
], fc
);
50 Vector_Normalize(average
->p
+1, dim
+1);
54 for (i
= 0; i
< P
->NbRays
; ++i
) {
55 if (value_notzero_p(P
->Ray
[i
][1+dim
]))
57 Vector_Add(average
->p
+1, P
->Ray
[i
]+1, average
->p
+1, dim
);
62 int is_internal(Vector
*point
, Value
*constraint
)
65 unsigned dim
= point
->Size
-2;
67 Inner_Product(constraint
+1, point
->p
+1, dim
+1, &point
->p
[0]);
68 if (value_notzero_p(point
->p
[0]))
69 return value_pos_p(point
->p
[0]);
71 p
= First_Non_Zero(constraint
+1, dim
);
72 return value_pos_p(constraint
[1+p
]);
75 Polyhedron
*reduce_domain(Polyhedron
*D
, Matrix
*CT
, Polyhedron
*CEq
, int nd
,
76 Vector
*inner
, struct barvinok_options
*options
)
85 C
= D
->next
? DomainConvex(D
, options
->MaxRays
) : D
;
86 Dt
= CT
? DomainPreimage(C
, CT
, options
->MaxRays
) : C
;
87 rVD
= CEq
? DomainIntersection(Dt
, CEq
, options
->MaxRays
) : Domain_Copy(Dt
);
89 /* If there is only one chamber, then we don't need to take care
90 * of possible overlaps.
91 * Plus, this decomposition may be the result of a recursive call
92 * and then some of the assumptions used in determining whether
93 * the domain is too small in geometric dimension no longer apply.
98 /* if rVD is empty or too small in geometric dimension */
99 if(!rVD
|| emptyQ(rVD
) ||
100 (CEq
&& rVD
->Dimension
-rVD
->NbEq
< Dt
->Dimension
-Dt
->NbEq
-CEq
->NbEq
)) {
103 rVD
= NULL
; /* empty validity domain */
115 assert(rVD
->Dimension
== inner
->Size
-2);
116 constraints
= Polyhedron2Constraints(rVD
);
118 for (i
= 0; i
< constraints
->NbRows
; ++i
) {
119 if (!is_internal(inner
, constraints
->p
[i
])) {
120 value_decrement(constraints
->p
[i
][1+rVD
->Dimension
],
121 constraints
->p
[i
][1+rVD
->Dimension
]);
126 Polyhedron_Free(rVD
);
127 rVD
= Constraints2Polyhedron(constraints
, options
->MaxRays
);
129 Matrix_Free(constraints
);
134 rVD
= DomainConstraintSimplify(rVD
, options
->MaxRays
);
135 POL_ENSURE_FACETS(rVD
);
142 barvinok_count_with_options(rVD
, &c
, options
);
143 if (value_zero_p(c
)) {