barvinok 0.41.7
[barvinok.git] / reducer.h
blobc91322b55cd877404240fcef09015fd63cfc5950
1 #ifndef REDUCER_H
2 #define REDUCER_H
4 #include <assert.h>
5 #include <NTL/ZZ.h>
6 #include <NTL/vec_ZZ.h>
7 #include <NTL/mat_ZZ.h>
8 #include <barvinok/NTL_QQ.h>
9 #include <barvinok/polylib.h>
10 #include <barvinok/options.h>
11 #include "decomposer.h"
12 #include "dpoly.h"
14 using namespace NTL;
16 struct gen_fun;
18 extern struct OrthogonalException {} Orthogonal;
20 /* base for non-parametric counting */
21 struct np_base : public signed_cone_consumer {
22 unsigned dim;
24 np_base(unsigned dim) {
25 assert(dim > 0);
26 this->dim = dim;
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, int n_try) {
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 mpq_t tcount;
59 mpz_t tn;
60 mpz_t td;
61 int lower; // call base when only this many variables is left
62 Value tz;
64 reducer(unsigned dim) : np_base(dim) {
65 vertex.SetDims(1, dim);
66 mpq_init(tcount);
67 mpz_init(tn);
68 mpz_init(td);
69 value_init(tz);
72 ~reducer() {
73 value_clear(tz);
74 mpq_clear(tcount);
75 mpz_clear(tn);
76 mpz_clear(td);
79 virtual void handle(const mat_ZZ& rays, Value *vertex, const QQ& c,
80 unsigned long det, barvinok_options *options);
81 void reduce(const vec_QQ& c, const mat_ZZ& num, const mat_ZZ& den_f);
82 void reduce_canonical(const vec_QQ& c, const mat_ZZ& num,
83 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() {
89 assert(0);
90 return NULL;
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,
107 mat_ZZ& f);
109 // incremental counter
110 struct icounter : public ireducer {
111 mpq_t count;
113 icounter(unsigned dim) : ireducer(dim) {
114 mpq_init(count);
115 lower = 1;
117 ~icounter() {
118 mpq_clear(count);
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 #endif