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
, unsigned MaxRays
)
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, MaxRays
);
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 vector
< dpoly_r_term
* >& final
= rc
->c
[rc
->len
-1];
180 for (int j
= 0; j
< final
.size(); ++j
) {
181 if (final
[j
]->coeff
== 0)
184 pden
.SetDims(rows
, pden
.NumCols());
185 for (int k
= 0; k
< rc
->dim
; ++k
) {
186 int n
= final
[j
]->powers
[k
];
189 pden
.SetDims(rows
+n
, pden
.NumCols());
190 for (int l
= 0; l
< n
; ++l
)
191 pden
[rows
+l
] = den_r
[k
];
194 factor
.n
= final
[j
]->coeff
*= c
.n
;
195 reduce(factor
, num_p
, pden
);
204 void reducer::handle_polar(Polyhedron
*C
, Value
*V
, QQ c
)
206 lattice_point(V
, C
, vertex
);
209 den
.SetDims(dim
, dim
);
212 for (r
= 0; r
< dim
; ++r
)
213 values2zz(C
->Ray
[r
]+1, den
[r
], dim
);
215 reduce(c
, vertex
, den
);
218 void ireducer::split(vec_ZZ
& num
, ZZ
& num_s
, vec_ZZ
& num_p
,
219 mat_ZZ
& den_f
, vec_ZZ
& den_s
, mat_ZZ
& den_r
)
221 unsigned len
= den_f
.NumRows(); // number of factors in den
222 unsigned d
= num
.length() - 1;
224 den_s
.SetLength(len
);
225 den_r
.SetDims(len
, d
);
227 for (int r
= 0; r
< len
; ++r
) {
228 den_s
[r
] = den_f
[r
][0];
229 for (int k
= 1; k
<= d
; ++k
)
230 den_r
[r
][k
-1] = den_f
[r
][k
];
235 for (int k
= 1 ; k
<= d
; ++k
)
239 void normalize(ZZ
& sign
, ZZ
& num
, vec_ZZ
& den
)
241 unsigned dim
= den
.length();
245 for (int j
= 0; j
< den
.length(); ++j
) {
249 den
[j
] = abs(den
[j
]);
257 void icounter::base(QQ
& c
, const vec_ZZ
& num
, const mat_ZZ
& den_f
)
260 unsigned len
= den_f
.NumRows(); // number of factors in den
262 den_s
.SetLength(len
);
264 for (r
= 0; r
< len
; ++r
)
265 den_s
[r
] = den_f
[r
][0];
266 normalize(c
.n
, num_s
, den_s
);
269 dpoly
D(len
, den_s
[0], 1);
270 for (int k
= 1; k
< len
; ++k
) {
271 dpoly
fact(len
, den_s
[k
], 1);
274 mpq_set_si(tcount
, 0, 1);
275 n
.div(D
, tcount
, one
);
278 mpz_mul(mpq_numref(tcount
), mpq_numref(tcount
), tn
);
279 mpz_mul(mpq_denref(tcount
), mpq_denref(tcount
), td
);
280 mpq_canonicalize(tcount
);
281 mpq_add(count
, count
, tcount
);
284 void infinite_icounter::base(QQ
& c
, const vec_ZZ
& num
, const mat_ZZ
& den_f
)
287 unsigned len
= den_f
.NumRows(); // number of factors in den
289 den_s
.SetLength(len
);
292 for (r
= 0; r
< len
; ++r
)
293 den_s
[r
] = den_f
[r
][0];
294 normalize(c
.n
, num_s
, den_s
);
297 dpoly
D(len
, den_s
[0], 1);
298 for (int k
= 1; k
< len
; ++k
) {
299 dpoly
fact(len
, den_s
[k
], 1);
308 value_assign(mpq_numref(factor
), tmp
);
310 value_assign(mpq_denref(factor
), tmp
);
312 n
.div(D
, count
, factor
);