Merge branch 'master' into bernstein
[barvinok.git] / reducer.h
blob055dc74e0bdde6dd5bb72fd7260f8eb2f539103e
1 #ifndef REDUCER_H
2 #define REDUCER_H
4 #include <NTL/mat_ZZ.h>
5 #include <barvinok/NTL_QQ.h>
6 #include "decomposer.h"
7 #include "dpoly.h"
9 #ifdef NTL_STD_CXX
10 using namespace NTL;
11 #endif
13 /* base for non-parametric counting */
14 struct np_base : public polar_decomposer {
15 unsigned dim;
16 ZZ one;
18 np_base(unsigned dim) {
19 this->dim = dim;
20 one = 1;
23 virtual void handle_polar(Polyhedron *C, Value *vertex, QQ c) = 0;
24 virtual void handle_polar(Polyhedron *C, int s);
25 void start(Polyhedron *P, unsigned MaxRays);
26 void do_vertex_cone(const QQ& factor, Polyhedron *Cone,
27 Value *vertex, unsigned MaxRays) {
28 current_vertex = vertex;
29 this->factor = factor;
30 decompose(Cone, MaxRays);
32 virtual void init(Polyhedron *P) {
35 private:
36 QQ factor;
37 Value *current_vertex;
40 struct reducer : public np_base {
41 vec_ZZ vertex;
42 //vec_ZZ den;
43 ZZ num;
44 mpq_t tcount;
45 mpz_t tn;
46 mpz_t td;
47 int lower; // call base when only this many variables is left
49 reducer(unsigned dim) : np_base(dim) {
50 //den.SetLength(dim);
51 mpq_init(tcount);
52 mpz_init(tn);
53 mpz_init(td);
56 ~reducer() {
57 mpq_clear(tcount);
58 mpz_clear(tn);
59 mpz_clear(td);
62 virtual void handle_polar(Polyhedron *C, Value *vertex, QQ c);
63 void reduce(QQ c, vec_ZZ& num, mat_ZZ& den_f);
64 virtual void base(QQ& c, const vec_ZZ& num, const mat_ZZ& den_f) = 0;
65 virtual void split(vec_ZZ& num, ZZ& num_s, vec_ZZ& num_p,
66 mat_ZZ& den_f, vec_ZZ& den_s, mat_ZZ& den_r) = 0;
69 struct ireducer : public reducer {
70 ireducer(unsigned dim) : reducer(dim) {}
72 virtual void split(vec_ZZ& num, ZZ& num_s, vec_ZZ& num_p,
73 mat_ZZ& den_f, vec_ZZ& den_s, mat_ZZ& den_r);
76 void normalize(ZZ& sign, ZZ& num_s, vec_ZZ& num_p, vec_ZZ& den_s, vec_ZZ& den_p,
77 mat_ZZ& f);
79 // incremental counter
80 struct icounter : public ireducer {
81 mpq_t count;
83 icounter(unsigned dim) : ireducer(dim) {
84 mpq_init(count);
85 lower = 1;
87 ~icounter() {
88 mpq_clear(count);
90 virtual void base(QQ& c, const vec_ZZ& num, const mat_ZZ& den_f);
93 void normalize(ZZ& sign, ZZ& num, vec_ZZ& den);
95 /* An incremental counter for possibly infinite sets.
96 * Rather than just keeping track of the constant term
97 * of the Laurent expansions, we also keep track of the
98 * coefficients of negative powers.
99 * If any of these is non-zero, then the counted set is infinite.
101 struct infinite_icounter : public ireducer {
102 /* an array of coefficients; count[i] is the coeffient of
103 * the term wtih power -i.
105 mpq_t *count;
106 unsigned len;
108 infinite_icounter(unsigned dim, unsigned maxlen) : ireducer(dim), len(maxlen+1) {
109 count = new mpq_t[len];
110 for (int i = 0; i < len; ++i)
111 mpq_init(count[i]);
112 lower = 1;
114 ~infinite_icounter() {
115 for (int i = 0; i < len; ++i)
116 mpq_clear(count[i]);
117 delete [] count;
119 virtual void base(QQ& c, const vec_ZZ& num, const mat_ZZ& den_f);
122 #endif