4 #include <NTL/mat_ZZ.h>
5 #include <barvinok/NTL_QQ.h>
6 #include <barvinok/options.h>
7 #include "decomposer.h"
16 extern struct OrthogonalException
{} Orthogonal
;
18 /* base for non-parametric counting */
19 struct np_base
: public signed_cone_consumer
{
23 np_base(unsigned dim
) {
28 virtual void handle(const mat_ZZ
& rays
, Value
*vertex
, const QQ
& c
,
29 unsigned long det
, int *closed
,
30 barvinok_options
*options
) = 0;
31 virtual void handle(const signed_cone
& sc
, barvinok_options
*options
);
32 virtual void start(Polyhedron
*P
, barvinok_options
*options
);
33 void do_vertex_cone(const QQ
& factor
, Polyhedron
*Cone
,
34 Value
*vertex
, barvinok_options
*options
) {
35 current_vertex
= vertex
;
36 this->factor
= factor
;
37 barvinok_decompose(Cone
, *this, options
);
39 virtual void init(Polyhedron
*P
) {
41 virtual void reset() {
44 virtual void get_count(Value
*result
) {
52 Value
*current_vertex
;
55 struct reducer
: public np_base
{
62 int lower
; // call base when only this many variables is left
65 reducer(unsigned dim
) : np_base(dim
) {
66 vertex
.SetDims(1, dim
);
81 virtual void handle(const mat_ZZ
& rays
, Value
*vertex
, const QQ
& c
,
82 unsigned long det
, int *closed
, barvinok_options
*options
);
83 void reduce(const vec_QQ
& c
, const mat_ZZ
& num
, const mat_ZZ
& den_f
);
84 virtual void base(const QQ
& c
, const vec_ZZ
& num
, const mat_ZZ
& den_f
) = 0;
85 virtual void base(const vec_QQ
& c
, const mat_ZZ
& num
, const mat_ZZ
& den_f
);
86 virtual void split(const mat_ZZ
& num
, vec_ZZ
& num_s
, mat_ZZ
& num_p
,
87 const mat_ZZ
& den_f
, vec_ZZ
& den_s
, mat_ZZ
& den_r
) = 0;
88 virtual gen_fun
*get_gf() {
94 void split_one(const mat_ZZ
& num
, vec_ZZ
& num_s
, mat_ZZ
& num_p
,
95 const mat_ZZ
& den_f
, vec_ZZ
& den_s
, mat_ZZ
& den_r
);
97 struct ireducer
: public reducer
{
98 ireducer(unsigned dim
) : reducer(dim
) {}
100 virtual void split(const mat_ZZ
& num
, vec_ZZ
& num_s
, mat_ZZ
& num_p
,
101 const mat_ZZ
& den_f
, vec_ZZ
& den_s
, mat_ZZ
& den_r
) {
102 split_one(num
, num_s
, num_p
, den_f
, den_s
, den_r
);
106 void normalize(ZZ
& sign
, vec_ZZ
& num_s
, mat_ZZ
& num_p
, vec_ZZ
& den_s
, vec_ZZ
& den_p
,
109 // incremental counter
110 struct icounter
: public ireducer
{
113 icounter(unsigned dim
) : ireducer(dim
) {
120 virtual void base(const QQ
& c
, const vec_ZZ
& num
, const mat_ZZ
& den_f
);
121 virtual void get_count(Value
*result
) {
122 assert(value_one_p(&count
[0]._mp_den
));
123 value_assign(*result
, &count
[0]._mp_num
);
127 void normalize(ZZ
& sign
, ZZ
& num
, vec_ZZ
& den
);
129 /* An incremental counter for possibly infinite sets.
130 * Rather than just keeping track of the constant term
131 * of the Laurent expansions, we also keep track of the
132 * coefficients of negative powers.
133 * If any of these is non-zero, then the counted set is infinite.
135 struct infinite_icounter
: public ireducer
{
136 /* an array of coefficients; count[i] is the coeffient of
137 * the term with power -i.
143 infinite_icounter(unsigned dim
, unsigned maxlen
) : ireducer(dim
), len(maxlen
+1) {
144 /* Not sure whether it works for dim != 1 */
146 count
= new mpq_t
[len
];
147 for (int i
= 0; i
< len
; ++i
)
152 ~infinite_icounter() {
153 for (int i
= 0; i
< len
; ++i
)
158 virtual void base(const QQ
& c
, const vec_ZZ
& num
, const mat_ZZ
& den_f
);