2 #include <barvinok/util.h>
4 #include "lattice_point.h"
8 static void rays(mat_ZZ
& rays
, Polyhedron
*C
)
10 unsigned dim
= C
->NbRays
- 1; /* don't count zero vertex */
11 assert(C
->NbRays
- 1 == C
->Dimension
);
12 rays
.SetDims(dim
, dim
);
15 for (i
= 0, j
= 0; i
< C
->NbRays
; ++i
) {
16 if (value_notzero_p(C
->Ray
[i
][dim
+1]))
18 values2zz(C
->Ray
[i
]+1, rays
[j
], dim
);
23 void np_base::handle(const signed_cone
& sc
)
25 assert(sc
.C
->NbRays
-1 == dim
);
29 handle(r
, current_vertex
, factor
, sc
.closed
);
33 void np_base::start(Polyhedron
*P
, barvinok_options
*options
)
37 for (int i
= 0; i
< P
->NbRays
; ++i
) {
38 if (!value_pos_p(P
->Ray
[i
][dim
+1]))
41 Polyhedron
*C
= supporting_cone(P
, i
);
42 do_vertex_cone(factor
, C
, P
->Ray
[i
]+1, options
);
47 * f: the powers in the denominator for the remaining vars
48 * each row refers to a factor
49 * den_s: for each factor, the power of (s+1)
51 * num_s: powers in the numerator corresponding to the summed vars
52 * num_p: powers in the numerator corresponding to the remaining vars
53 * number of rays in cone: "dim" = "k"
54 * length of each ray: "dim" = "d"
55 * for now, it is assumed: k == d
57 * den_p: for each factor
58 * 0: independent of remaining vars
59 * 1: power corresponds to corresponding row in f
61 * all inputs are subject to change
63 void normalize(ZZ
& sign
, ZZ
& num_s
, vec_ZZ
& num_p
, vec_ZZ
& den_s
, vec_ZZ
& den_p
,
66 unsigned dim
= f
.NumRows();
67 unsigned nparam
= num_p
.length();
68 unsigned nvar
= dim
- nparam
;
72 for (int j
= 0; j
< den_s
.length(); ++j
) {
78 for (k
= 0; k
< nparam
; ++k
)
92 den_s
[j
] = abs(den_s
[j
]);
101 void reducer::reduce(QQ c
, vec_ZZ
& num
, const mat_ZZ
& den_f
)
103 unsigned len
= den_f
.NumRows(); // number of factors in den
105 if (num
.length() == lower
) {
109 assert(num
.length() > 1);
116 split(num
, num_s
, num_p
, den_f
, den_s
, den_r
);
119 den_p
.SetLength(len
);
121 normalize(c
.n
, num_s
, num_p
, den_s
, den_p
, den_r
);
123 int only_param
= 0; // k-r-s from text
124 int no_param
= 0; // r from text
125 for (int k
= 0; k
< len
; ++k
) {
128 else if (den_s
[k
] == 0)
132 reduce(c
, num_p
, den_r
);
136 pden
.SetDims(only_param
, den_r
.NumCols());
138 for (k
= 0, l
= 0; k
< len
; ++k
)
140 pden
[l
++] = den_r
[k
];
142 for (k
= 0; k
< len
; ++k
)
146 dpoly
n(no_param
, num_s
);
147 dpoly
D(no_param
, den_s
[k
], 1);
150 dpoly
fact(no_param
, den_s
[k
], 1);
154 if (no_param
+ only_param
== len
) {
155 mpq_set_si(tcount
, 0, 1);
156 n
.div(D
, tcount
, one
);
159 value2zz(mpq_numref(tcount
), q
.n
);
160 value2zz(mpq_denref(tcount
), q
.d
);
165 reduce(q
, num_p
, pden
);
169 for (k
= 0; k
< len
; ++k
) {
170 if (den_s
[k
] == 0 || den_p
[k
] == 0)
173 dpoly
pd(no_param
-1, den_s
[k
], 1);
176 for (l
= 0; l
< k
; ++l
)
177 if (den_r
[l
] == den_r
[k
])
181 r
= new dpoly_r(n
, pd
, l
, len
);
183 dpoly_r
*nr
= new dpoly_r(r
, pd
, l
, len
);
189 dpoly_r
*rc
= r
->div(D
);
192 factor
.d
= rc
->denom
* c
.d
;
194 int common
= pden
.NumRows();
195 dpoly_r_term_list
& final
= rc
->c
[rc
->len
-1];
197 dpoly_r_term_list::iterator j
;
198 for (j
= final
.begin(); j
!= final
.end(); ++j
) {
199 if ((*j
)->coeff
== 0)
202 pden
.SetDims(rows
, pden
.NumCols());
203 for (int k
= 0; k
< rc
->dim
; ++k
) {
204 int n
= (*j
)->powers
[k
];
207 pden
.SetDims(rows
+n
, pden
.NumCols());
208 for (int l
= 0; l
< n
; ++l
)
209 pden
[rows
+l
] = den_r
[k
];
212 factor
.n
= (*j
)->coeff
*= c
.n
;
213 reduce(factor
, num_p
, pden
);
222 void reducer::handle(const mat_ZZ
& den
, Value
*V
, QQ c
, int *closed
)
224 lattice_point(V
, den
, vertex
, closed
);
226 reduce(c
, vertex
, den
);
229 void ireducer::split(vec_ZZ
& num
, ZZ
& num_s
, vec_ZZ
& num_p
,
230 const mat_ZZ
& den_f
, vec_ZZ
& den_s
, mat_ZZ
& den_r
)
232 unsigned len
= den_f
.NumRows(); // number of factors in den
233 unsigned d
= num
.length() - 1;
235 den_s
.SetLength(len
);
236 den_r
.SetDims(len
, d
);
238 for (int r
= 0; r
< len
; ++r
) {
239 den_s
[r
] = den_f
[r
][0];
240 for (int k
= 1; k
<= d
; ++k
)
241 den_r
[r
][k
-1] = den_f
[r
][k
];
246 for (int k
= 1 ; k
<= d
; ++k
)
250 void normalize(ZZ
& sign
, ZZ
& num
, vec_ZZ
& den
)
252 unsigned dim
= den
.length();
256 for (int j
= 0; j
< den
.length(); ++j
) {
260 den
[j
] = abs(den
[j
]);
268 void icounter::base(QQ
& c
, const vec_ZZ
& num
, const mat_ZZ
& den_f
)
271 unsigned len
= den_f
.NumRows(); // number of factors in den
273 den_s
.SetLength(len
);
275 for (r
= 0; r
< len
; ++r
)
276 den_s
[r
] = den_f
[r
][0];
277 normalize(c
.n
, num_s
, den_s
);
280 dpoly
D(len
, den_s
[0], 1);
281 for (int k
= 1; k
< len
; ++k
) {
282 dpoly
fact(len
, den_s
[k
], 1);
285 mpq_set_si(tcount
, 0, 1);
286 n
.div(D
, tcount
, one
);
289 mpz_mul(mpq_numref(tcount
), mpq_numref(tcount
), tn
);
290 mpz_mul(mpq_denref(tcount
), mpq_denref(tcount
), td
);
291 mpq_canonicalize(tcount
);
292 mpq_add(count
, count
, tcount
);
295 void infinite_icounter::base(QQ
& c
, const vec_ZZ
& num
, const mat_ZZ
& den_f
)
298 unsigned len
= den_f
.NumRows(); // number of factors in den
300 den_s
.SetLength(len
);
303 for (r
= 0; r
< len
; ++r
)
304 den_s
[r
] = den_f
[r
][0];
305 normalize(c
.n
, num_s
, den_s
);
308 dpoly
D(len
, den_s
[0], 1);
309 for (int k
= 1; k
< len
; ++k
) {
310 dpoly
fact(len
, den_s
[k
], 1);
319 value_assign(mpq_numref(factor
), tmp
);
321 value_assign(mpq_denref(factor
), tmp
);
323 n
.div(D
, count
, factor
);