Fix out-of-bounds error in Laurent expansion based summation
[barvinok.git] / reducer.h
blob7e4d082556a5f137aac4c12bec31382fbea66582
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 assert(dim > 0);
26 this->dim = dim;
27 one = 1;
30 virtual void handle(const mat_ZZ& rays, Value *vertex, const QQ& c,
31 unsigned long det,
32 barvinok_options *options) = 0;
33 virtual void handle(const signed_cone& sc, barvinok_options *options);
34 virtual void start(Polyhedron *P, barvinok_options *options);
35 void do_vertex_cone(const QQ& factor, Polyhedron *Cone,
36 Value *vertex, barvinok_options *options) {
37 current_vertex = vertex;
38 this->factor = factor;
39 barvinok_decompose(Cone, *this, options);
41 virtual void init(Polyhedron *P) {
43 virtual void reset() {
44 assert(0);
46 virtual void get_count(Value *result) {
47 assert(0);
49 virtual ~np_base() {
52 private:
53 QQ factor;
54 Value *current_vertex;
57 struct reducer : public np_base {
58 mat_ZZ vertex;
59 //vec_ZZ den;
60 ZZ num;
61 mpq_t tcount;
62 mpz_t tn;
63 mpz_t td;
64 int lower; // call base when only this many variables is left
65 Value tz;
67 reducer(unsigned dim) : np_base(dim) {
68 vertex.SetDims(1, dim);
69 //den.SetLength(dim);
70 mpq_init(tcount);
71 mpz_init(tn);
72 mpz_init(td);
73 value_init(tz);
76 ~reducer() {
77 value_clear(tz);
78 mpq_clear(tcount);
79 mpz_clear(tn);
80 mpz_clear(td);
83 virtual void handle(const mat_ZZ& rays, Value *vertex, const QQ& c,
84 unsigned long det, barvinok_options *options);
85 void reduce(const vec_QQ& c, const mat_ZZ& num, const mat_ZZ& den_f);
86 void reduce_canonical(const vec_QQ& c, const mat_ZZ& num,
87 const mat_ZZ& den_f);
88 virtual void base(const QQ& c, const vec_ZZ& num, const mat_ZZ& den_f) = 0;
89 virtual void base(const vec_QQ& c, const mat_ZZ& num, const mat_ZZ& den_f);
90 virtual void split(const mat_ZZ& num, vec_ZZ& num_s, mat_ZZ& num_p,
91 const mat_ZZ& den_f, vec_ZZ& den_s, mat_ZZ& den_r) = 0;
92 virtual gen_fun *get_gf() {
93 assert(0);
94 return NULL;
98 void split_one(const mat_ZZ& num, vec_ZZ& num_s, mat_ZZ& num_p,
99 const mat_ZZ& den_f, vec_ZZ& den_s, mat_ZZ& den_r);
101 struct ireducer : public reducer {
102 ireducer(unsigned dim) : reducer(dim) {}
104 virtual void split(const mat_ZZ& num, vec_ZZ& num_s, mat_ZZ& num_p,
105 const mat_ZZ& den_f, vec_ZZ& den_s, mat_ZZ& den_r) {
106 split_one(num, num_s, num_p, den_f, den_s, den_r);
110 void normalize(ZZ& sign, vec_ZZ& num_s, mat_ZZ& num_p, vec_ZZ& den_s, vec_ZZ& den_p,
111 mat_ZZ& f);
113 // incremental counter
114 struct icounter : public ireducer {
115 mpq_t count;
117 icounter(unsigned dim) : ireducer(dim) {
118 mpq_init(count);
119 lower = 1;
121 ~icounter() {
122 mpq_clear(count);
124 virtual void base(const QQ& c, const vec_ZZ& num, const mat_ZZ& den_f);
125 virtual void get_count(Value *result) {
126 assert(value_one_p(&count[0]._mp_den));
127 value_assign(*result, &count[0]._mp_num);
131 #endif