2 #include <barvinok/util.h>
4 #include "lattice_point.h"
8 void np_base::handle_polar(Polyhedron
*C
, int s
)
10 assert(C
->NbRays
-1 == dim
);
12 handle_polar(C
, current_vertex
, factor
);
16 void np_base::start(Polyhedron
*P
, barvinok_options
*options
)
20 for (int i
= 0; i
< P
->NbRays
; ++i
) {
21 if (!value_pos_p(P
->Ray
[i
][dim
+1]))
24 Polyhedron
*C
= supporting_cone(P
, i
);
25 do_vertex_cone(factor
, C
, P
->Ray
[i
]+1, options
);
30 * f: the powers in the denominator for the remaining vars
31 * each row refers to a factor
32 * den_s: for each factor, the power of (s+1)
34 * num_s: powers in the numerator corresponding to the summed vars
35 * num_p: powers in the numerator corresponding to the remaining vars
36 * number of rays in cone: "dim" = "k"
37 * length of each ray: "dim" = "d"
38 * for now, it is assumed: k == d
40 * den_p: for each factor
41 * 0: independent of remaining vars
42 * 1: power corresponds to corresponding row in f
44 * all inputs are subject to change
46 void normalize(ZZ
& sign
, ZZ
& num_s
, vec_ZZ
& num_p
, vec_ZZ
& den_s
, vec_ZZ
& den_p
,
49 unsigned dim
= f
.NumRows();
50 unsigned nparam
= num_p
.length();
51 unsigned nvar
= dim
- nparam
;
55 for (int j
= 0; j
< den_s
.length(); ++j
) {
61 for (k
= 0; k
< nparam
; ++k
)
75 den_s
[j
] = abs(den_s
[j
]);
84 void reducer::reduce(QQ c
, vec_ZZ
& num
, mat_ZZ
& den_f
)
86 unsigned len
= den_f
.NumRows(); // number of factors in den
88 if (num
.length() == lower
) {
92 assert(num
.length() > 1);
99 split(num
, num_s
, num_p
, den_f
, den_s
, den_r
);
102 den_p
.SetLength(len
);
104 normalize(c
.n
, num_s
, num_p
, den_s
, den_p
, den_r
);
106 int only_param
= 0; // k-r-s from text
107 int no_param
= 0; // r from text
108 for (int k
= 0; k
< len
; ++k
) {
111 else if (den_s
[k
] == 0)
115 reduce(c
, num_p
, den_r
);
119 pden
.SetDims(only_param
, den_r
.NumCols());
121 for (k
= 0, l
= 0; k
< len
; ++k
)
123 pden
[l
++] = den_r
[k
];
125 for (k
= 0; k
< len
; ++k
)
129 dpoly
n(no_param
, num_s
);
130 dpoly
D(no_param
, den_s
[k
], 1);
133 dpoly
fact(no_param
, den_s
[k
], 1);
137 if (no_param
+ only_param
== len
) {
138 mpq_set_si(tcount
, 0, 1);
139 n
.div(D
, tcount
, one
);
142 value2zz(mpq_numref(tcount
), q
.n
);
143 value2zz(mpq_denref(tcount
), q
.d
);
148 reduce(q
, num_p
, pden
);
152 for (k
= 0; k
< len
; ++k
) {
153 if (den_s
[k
] == 0 || den_p
[k
] == 0)
156 dpoly
pd(no_param
-1, den_s
[k
], 1);
159 for (l
= 0; l
< k
; ++l
)
160 if (den_r
[l
] == den_r
[k
])
164 r
= new dpoly_r(n
, pd
, l
, len
);
166 dpoly_r
*nr
= new dpoly_r(r
, pd
, l
, len
);
172 dpoly_r
*rc
= r
->div(D
);
175 factor
.d
= rc
->denom
* c
.d
;
177 int common
= pden
.NumRows();
178 dpoly_r_term_list
& final
= rc
->c
[rc
->len
-1];
180 dpoly_r_term_list::iterator j
;
181 for (j
= final
.begin(); j
!= final
.end(); ++j
) {
182 if ((*j
)->coeff
== 0)
185 pden
.SetDims(rows
, pden
.NumCols());
186 for (int k
= 0; k
< rc
->dim
; ++k
) {
187 int n
= (*j
)->powers
[k
];
190 pden
.SetDims(rows
+n
, pden
.NumCols());
191 for (int l
= 0; l
< n
; ++l
)
192 pden
[rows
+l
] = den_r
[k
];
195 factor
.n
= (*j
)->coeff
*= c
.n
;
196 reduce(factor
, num_p
, pden
);
205 void reducer::handle_polar(Polyhedron
*C
, Value
*V
, QQ c
)
207 lattice_point(V
, C
, vertex
);
210 den
.SetDims(dim
, dim
);
213 for (r
= 0; r
< dim
; ++r
)
214 values2zz(C
->Ray
[r
]+1, den
[r
], dim
);
216 reduce(c
, vertex
, den
);
219 void ireducer::split(vec_ZZ
& num
, ZZ
& num_s
, vec_ZZ
& num_p
,
220 mat_ZZ
& den_f
, vec_ZZ
& den_s
, mat_ZZ
& den_r
)
222 unsigned len
= den_f
.NumRows(); // number of factors in den
223 unsigned d
= num
.length() - 1;
225 den_s
.SetLength(len
);
226 den_r
.SetDims(len
, d
);
228 for (int r
= 0; r
< len
; ++r
) {
229 den_s
[r
] = den_f
[r
][0];
230 for (int k
= 1; k
<= d
; ++k
)
231 den_r
[r
][k
-1] = den_f
[r
][k
];
236 for (int k
= 1 ; k
<= d
; ++k
)
240 void normalize(ZZ
& sign
, ZZ
& num
, vec_ZZ
& den
)
242 unsigned dim
= den
.length();
246 for (int j
= 0; j
< den
.length(); ++j
) {
250 den
[j
] = abs(den
[j
]);
258 void icounter::base(QQ
& c
, const vec_ZZ
& num
, const mat_ZZ
& den_f
)
261 unsigned len
= den_f
.NumRows(); // number of factors in den
263 den_s
.SetLength(len
);
265 for (r
= 0; r
< len
; ++r
)
266 den_s
[r
] = den_f
[r
][0];
267 normalize(c
.n
, num_s
, den_s
);
270 dpoly
D(len
, den_s
[0], 1);
271 for (int k
= 1; k
< len
; ++k
) {
272 dpoly
fact(len
, den_s
[k
], 1);
275 mpq_set_si(tcount
, 0, 1);
276 n
.div(D
, tcount
, one
);
279 mpz_mul(mpq_numref(tcount
), mpq_numref(tcount
), tn
);
280 mpz_mul(mpq_denref(tcount
), mpq_denref(tcount
), td
);
281 mpq_canonicalize(tcount
);
282 mpq_add(count
, count
, tcount
);
285 void infinite_icounter::base(QQ
& c
, const vec_ZZ
& num
, const mat_ZZ
& den_f
)
288 unsigned len
= den_f
.NumRows(); // number of factors in den
290 den_s
.SetLength(len
);
293 for (r
= 0; r
< len
; ++r
)
294 den_s
[r
] = den_f
[r
][0];
295 normalize(c
.n
, num_s
, den_s
);
298 dpoly
D(len
, den_s
[0], 1);
299 for (int k
= 1; k
< len
; ++k
) {
300 dpoly
fact(len
, den_s
[k
], 1);
309 value_assign(mpq_numref(factor
), tmp
);
311 value_assign(mpq_denref(factor
), tmp
);
313 n
.div(D
, count
, factor
);