add gen_fun::add(short_rat *r)
[barvinok.git] / reducer.h
blob95a6aa0a06411bf76c3bb6aeec1b2198bd1ad87a
1 #ifndef REDUCER_H
2 #define REDUCER_H
4 #include <NTL/mat_ZZ.h>
5 #include <barvinok/NTL_QQ.h>
6 #include <barvinok/options.h>
7 #include "decomposer.h"
8 #include "dpoly.h"
10 #ifdef NTL_STD_CXX
11 using namespace NTL;
12 #endif
14 struct gen_fun;
16 extern struct OrthogonalException {} Orthogonal;
18 /* base for non-parametric counting */
19 struct np_base : public signed_cone_consumer {
20 unsigned dim;
21 ZZ one;
23 np_base(unsigned dim) {
24 this->dim = dim;
25 one = 1;
28 virtual void handle(const mat_ZZ& rays, Value *vertex, QQ c, int *closed,
29 barvinok_options *options) = 0;
30 virtual void handle(const signed_cone& sc, barvinok_options *options);
31 virtual void start(Polyhedron *P, barvinok_options *options);
32 void do_vertex_cone(const QQ& factor, Polyhedron *Cone,
33 Value *vertex, barvinok_options *options) {
34 current_vertex = vertex;
35 this->factor = factor;
36 barvinok_decompose(Cone, *this, options);
38 virtual void init(Polyhedron *P) {
40 virtual void reset() {
41 assert(0);
43 virtual void get_count(Value *result) {
44 assert(0);
46 virtual ~np_base() {
49 private:
50 QQ factor;
51 Value *current_vertex;
54 struct reducer : public np_base {
55 vec_ZZ vertex;
56 //vec_ZZ den;
57 ZZ num;
58 mpq_t tcount;
59 mpz_t tn;
60 mpz_t td;
61 int lower; // call base when only this many variables is left
63 reducer(unsigned dim) : np_base(dim) {
64 //den.SetLength(dim);
65 mpq_init(tcount);
66 mpz_init(tn);
67 mpz_init(td);
70 ~reducer() {
71 mpq_clear(tcount);
72 mpz_clear(tn);
73 mpz_clear(td);
76 virtual void handle(const mat_ZZ& rays, Value *vertex, QQ c, int *closed,
77 barvinok_options *options);
78 void reduce(QQ c, vec_ZZ& num, const mat_ZZ& den_f);
79 virtual void base(QQ& c, const vec_ZZ& num, const mat_ZZ& den_f) = 0;
80 virtual void split(vec_ZZ& num, ZZ& num_s, vec_ZZ& num_p,
81 const mat_ZZ& den_f, vec_ZZ& den_s, mat_ZZ& den_r) = 0;
82 virtual gen_fun *get_gf() {
83 assert(0);
84 return NULL;
88 struct ireducer : public reducer {
89 ireducer(unsigned dim) : reducer(dim) {}
91 virtual void split(vec_ZZ& num, ZZ& num_s, vec_ZZ& num_p,
92 const mat_ZZ& den_f, vec_ZZ& den_s, mat_ZZ& den_r);
95 void normalize(ZZ& sign, ZZ& num_s, vec_ZZ& num_p, vec_ZZ& den_s, vec_ZZ& den_p,
96 mat_ZZ& f);
98 // incremental counter
99 struct icounter : public ireducer {
100 mpq_t count;
102 icounter(unsigned dim) : ireducer(dim) {
103 mpq_init(count);
104 lower = 1;
106 ~icounter() {
107 mpq_clear(count);
109 virtual void base(QQ& c, const vec_ZZ& num, const mat_ZZ& den_f);
110 virtual void get_count(Value *result) {
111 assert(value_one_p(&count[0]._mp_den));
112 value_assign(*result, &count[0]._mp_num);
116 void normalize(ZZ& sign, ZZ& num, vec_ZZ& den);
118 /* An incremental counter for possibly infinite sets.
119 * Rather than just keeping track of the constant term
120 * of the Laurent expansions, we also keep track of the
121 * coefficients of negative powers.
122 * If any of these is non-zero, then the counted set is infinite.
124 struct infinite_icounter : public ireducer {
125 /* an array of coefficients; count[i] is the coeffient of
126 * the term with power -i.
128 mpq_t *count;
129 unsigned len;
131 infinite_icounter(unsigned dim, unsigned maxlen) : ireducer(dim), len(maxlen+1) {
132 /* Not sure whether it works for dim != 1 */
133 assert(dim == 1);
134 count = new mpq_t[len];
135 for (int i = 0; i < len; ++i)
136 mpq_init(count[i]);
137 lower = 1;
139 ~infinite_icounter() {
140 for (int i = 0; i < len; ++i)
141 mpq_clear(count[i]);
142 delete [] count;
144 virtual void base(QQ& c, const vec_ZZ& num, const mat_ZZ& den_f);
147 #endif