Move GiNaC-independent part of library to barvinok-core
[barvinok.git] / reducer.h
blobfc7226a1a27e72c7c5ba53bcc3d24f082bc30840
1 #ifndef REDUCER_H
2 #define REDUCER_H
4 #include <assert.h>
5 #include <NTL/mat_ZZ.h>
6 #include <barvinok/NTL_QQ.h>
7 #include <barvinok/options.h>
8 #include "decomposer.h"
9 #include "dpoly.h"
11 #ifdef NTL_STD_CXX
12 using namespace NTL;
13 #endif
15 struct gen_fun;
17 extern struct OrthogonalException {} Orthogonal;
19 /* base for non-parametric counting */
20 struct np_base : public signed_cone_consumer {
21 unsigned dim;
22 ZZ one;
24 np_base(unsigned dim) {
25 this->dim = dim;
26 one = 1;
29 virtual void handle(const mat_ZZ& rays, Value *vertex, const QQ& c,
30 unsigned long det,
31 barvinok_options *options) = 0;
32 virtual void handle(const signed_cone& sc, barvinok_options *options);
33 virtual void start(Polyhedron *P, barvinok_options *options);
34 void do_vertex_cone(const QQ& factor, Polyhedron *Cone,
35 Value *vertex, barvinok_options *options) {
36 current_vertex = vertex;
37 this->factor = factor;
38 barvinok_decompose(Cone, *this, options);
40 virtual void init(Polyhedron *P) {
42 virtual void reset() {
43 assert(0);
45 virtual void get_count(Value *result) {
46 assert(0);
48 virtual ~np_base() {
51 private:
52 QQ factor;
53 Value *current_vertex;
56 struct reducer : public np_base {
57 mat_ZZ vertex;
58 //vec_ZZ den;
59 ZZ num;
60 mpq_t tcount;
61 mpz_t tn;
62 mpz_t td;
63 int lower; // call base when only this many variables is left
64 Value tz;
66 reducer(unsigned dim) : np_base(dim) {
67 vertex.SetDims(1, dim);
68 //den.SetLength(dim);
69 mpq_init(tcount);
70 mpz_init(tn);
71 mpz_init(td);
72 value_init(tz);
75 ~reducer() {
76 value_clear(tz);
77 mpq_clear(tcount);
78 mpz_clear(tn);
79 mpz_clear(td);
82 virtual void handle(const mat_ZZ& rays, Value *vertex, const QQ& c,
83 unsigned long det, barvinok_options *options);
84 void reduce(const vec_QQ& c, const mat_ZZ& num, const mat_ZZ& den_f);
85 void reduce_canonical(const vec_QQ& c, const mat_ZZ& num,
86 const mat_ZZ& den_f);
87 virtual void base(const QQ& c, const vec_ZZ& num, const mat_ZZ& den_f) = 0;
88 virtual void base(const vec_QQ& c, const mat_ZZ& num, const mat_ZZ& den_f);
89 virtual void split(const mat_ZZ& num, vec_ZZ& num_s, mat_ZZ& num_p,
90 const mat_ZZ& den_f, vec_ZZ& den_s, mat_ZZ& den_r) = 0;
91 virtual gen_fun *get_gf() {
92 assert(0);
93 return NULL;
97 void split_one(const mat_ZZ& num, vec_ZZ& num_s, mat_ZZ& num_p,
98 const mat_ZZ& den_f, vec_ZZ& den_s, mat_ZZ& den_r);
100 struct ireducer : public reducer {
101 ireducer(unsigned dim) : reducer(dim) {}
103 virtual void split(const mat_ZZ& num, vec_ZZ& num_s, mat_ZZ& num_p,
104 const mat_ZZ& den_f, vec_ZZ& den_s, mat_ZZ& den_r) {
105 split_one(num, num_s, num_p, den_f, den_s, den_r);
109 void normalize(ZZ& sign, vec_ZZ& num_s, mat_ZZ& num_p, vec_ZZ& den_s, vec_ZZ& den_p,
110 mat_ZZ& f);
112 // incremental counter
113 struct icounter : public ireducer {
114 mpq_t count;
116 icounter(unsigned dim) : ireducer(dim) {
117 mpq_init(count);
118 lower = 1;
120 ~icounter() {
121 mpq_clear(count);
123 virtual void base(const QQ& c, const vec_ZZ& num, const mat_ZZ& den_f);
124 virtual void get_count(Value *result) {
125 assert(value_one_p(&count[0]._mp_den));
126 value_assign(*result, &count[0]._mp_num);
130 #endif