1 /*++
2 Copyright (c) 2011 Microsoft Corporation
3
4 Module Name:
5
6 upolynomial.cpp
7
8 Abstract:
9
10 Goodies for creating and handling univariate polynomials.
11
12 Author:
13
14 Leonardo (leonardo) 2011-12-01
15
16 Notes:
17
18 --*/
19 #include "math/polynomial/upolynomial.h"
20 #include "util/timeit.h"
21 #include "util/rlimit.h"
22
tst1()23 static void tst1() {
24 reslimit rl;
25 polynomial::numeral_manager nm;
26 polynomial::manager m(rl, nm);
27 upolynomial::manager um(rl, nm);
28 polynomial_ref x(m);
29 x = m.mk_polynomial(m.mk_var());
30 // create univariate polynomial using multivariate polynomial package
31 polynomial_ref p(m);
32 p = (x - 1)*(x + 1)*(x + 2)*(x + 3)*(x - 3);
33 std::cout << "p: " << p << "\n";
34 // convert p into an univariate polynomial
35 upolynomial::scoped_numeral_vector q(um);
36 um.to_numeral_vector(p, q);
37 std::cout << "q: "; um.display(std::cout, q); std::cout << "\n";
38
39 std::cout << "degree(q): " << um.degree(q) << "\n";
40
41 // display coefficients of q
42 std::cout << "expanded q: ";
43 for (unsigned i = 0; i < q.size(); i++)
44 std::cout << nm.to_string(q[i]) << " ";
45 std::cout << "\n";
46
47 // traverse coefficients of q adding 1
48 for (unsigned i = 0; i < q.size(); i++) {
49 nm.add(q[i], mpz(1), q[i]);
50 }
51 // All operations in upolynomial::manager assume the leading coefficient of q is not zero.
52 // So, if we perform destructive operations on these coefficients, we must execute the "trim" operation
53 // before invoking another operation of upolynomial::manager
54 um.trim(q);
55
56 // q after adding 1 to all coefficients
57 std::cout << "new q: "; um.display(std::cout, q); std::cout << "\n";
58
59 // q^2
60 um.mul(q.size(), q.data(), q.size(), q.data(), q);
61 std::cout << "new q^2: "; um.display(std::cout, q); std::cout << "\n";
62
63 // using pw for (q^2)^3
64 um.pw(q.size(), q.data(), 3, q);
65 std::cout << "new (q^2)^3: "; um.display(std::cout, q); std::cout << "\n";
66 }
67
tst_isolate_roots(polynomial_ref const & p,unsigned prec,mpbq_manager & bqm,mpbq_vector & roots,mpbq_vector & lowers,mpbq_vector & uppers)68 static void tst_isolate_roots(polynomial_ref const & p, unsigned prec, mpbq_manager & bqm, mpbq_vector & roots, mpbq_vector & lowers, mpbq_vector & uppers) {
69 reslimit rl;
70 upolynomial::manager um(rl, p.m().m());
71 upolynomial::scoped_numeral_vector q(um);
72 um.to_numeral_vector(p, q);
73 std::cout << "isolating roots of: "; um.display(std::cout, q); std::cout << "\n";
74 {
75 timeit timer(true, "isolate time");
76 um.isolate_roots(q.size(), q.data(), bqm, roots, lowers, uppers);
77 }
78
79 upolynomial::scoped_upolynomial_sequence sseq(um), fseq(um);
80 {
81 timeit timer(true, "sturm time");
82 um.sturm_seq(q.size(), q.data(), sseq);
83 // um.display(std::cout, sseq); std::cout << "\n";
84 }
85
86 // Fourier sequence is sensitive to repeated roots... we remove them by taking the square free component.
87 upolynomial::scoped_numeral_vector q_sqf(um);
88 {
89 timeit timer(true, "sqf time");
90 um.square_free(q.size(), q.data(), q_sqf);
91 std::cout << "square free part: "; um.display(std::cout, q_sqf); std::cout << "\n";
92 }
93
94 {
95 timeit timer(true, "fourier time");
96 um.fourier_seq(q_sqf.size(), q_sqf.data(), fseq);
97 }
98
99 // um.display(std::cout, fseq);
100
101 std::cout << "num. roots: " << roots.size() + lowers.size() << "\n";
102 std::cout << "sign var(-oo): " << um.sign_variations_at_minus_inf(sseq) << "\n";
103 std::cout << "sign var(+oo): " << um.sign_variations_at_plus_inf(sseq) << "\n";
104 ENSURE(roots.size() + lowers.size() == um.sign_variations_at_minus_inf(sseq) - um.sign_variations_at_plus_inf(sseq));
105 std::cout << "roots:";
106 for (unsigned i = 0; i < roots.size(); i++) {
107 ENSURE(um.eval_sign_at(q.size(), q.data(), roots[i]) == 0);
108 std::cout << " "; bqm.display_decimal(std::cout, roots[i], prec);
109 }
110 {
111 timeit timer(true, "interval check");
112 std::cout << "\n";
113 std::cout << "intervals:";
114 for (unsigned i = 0; i < lowers.size(); i++) {
115 std::cout << " (";
116 bqm.display_decimal(std::cout, lowers[i], prec);
117 std::cout << ", ";
118 bqm.display_decimal(std::cout, uppers[i], prec);
119 std::cout << ")";
120 // Check interval with Sturm sequence. Small detail: Sturm sequence is for close intervals.
121 ENSURE(um.eval_sign_at(q.size(), q.data(), lowers[i]) == 0 ||
122 um.eval_sign_at(q.size(), q.data(), uppers[i]) == 0 ||
123 um.sign_variations_at(sseq, lowers[i]) - um.sign_variations_at(sseq, uppers[i]) == 1);
124 // Fourier sequence may also be used to check if the interval is isolating
125 TRACE("upolynomial",
126 tout << "lowers[i]: " << bqm.to_string(lowers[i]) << "\n";
127 tout << "uppers[i]: " << bqm.to_string(uppers[i]) << "\n";
128 tout << "fourier lower: " << um.sign_variations_at(fseq, lowers[i]) << "\n";
129 tout << "fourier upper: " << um.sign_variations_at(fseq, uppers[i]) << "\n";);
130 unsigned fsv_lower = um.sign_variations_at(fseq, lowers[i]);
131 unsigned fsv_upper = um.sign_variations_at(fseq, uppers[i]);
132 VERIFY(um.eval_sign_at(q.size(), q.data(), lowers[i]) == 0 ||
133 um.eval_sign_at(q.size(), q.data(), uppers[i]) == 0 ||
134 // fsv_lower - fsv_upper is an upper bound for the number of roots in the interval
135 // fsv_upper - fsv_upper - num_roots is even
136 // Recall that num_roots == 1 in the interval.
137 (fsv_lower - fsv_upper >= 1 && (fsv_lower - fsv_upper - 1) % 2 == 0));
138
139 // Double checking using Descartes bounds for the interval
140 // Must use square free component.
141 unsigned dab = um.descartes_bound_a_b(q_sqf.size(), q_sqf.data(), bqm, lowers[i], uppers[i]);
142 TRACE("upolynomial", tout << "Descartes bound: " << dab << "\n";);
143 VERIFY(dab == 1);
144 }
145 }
146 std::cout << "\n";
147 }
148
tst_isolate_roots(polynomial_ref const & p,unsigned prec=5)149 static void tst_isolate_roots(polynomial_ref const & p, unsigned prec = 5) {
150 mpbq_manager bqm(p.m().m());
151 scoped_mpbq_vector roots(bqm);
152 scoped_mpbq_vector lowers(bqm);
153 scoped_mpbq_vector uppers(bqm);
154 tst_isolate_roots(p, prec, bqm, roots, lowers, uppers);
155 }
156
check_roots(mpbq_vector const & roots,mpbq_vector const & lowers,mpbq_vector const & uppers,unsigned expected_sz,rational const * expected_roots)157 static void check_roots(mpbq_vector const & roots, mpbq_vector const & lowers, mpbq_vector const & uppers, unsigned expected_sz, rational const * expected_roots) {
158 ENSURE(expected_sz == roots.size() + lowers.size());
159 bool_vector visited;
160 visited.resize(expected_sz, false);
161 for (unsigned i = 0; i < expected_sz; i++) {
162 rational const & r = expected_roots[i];
163 bool found = false;
164 for (unsigned j = 0; j < roots.size(); j++) {
165 if (to_rational(roots[j]) == r) {
166 ENSURE(!visited[j]);
167 VERIFY(!found);
168 found = true;
169 visited[j] = true;
170 }
171 }
172 for (unsigned j = 0; j < lowers.size(); j++) {
173 unsigned j_prime = j + roots.size();
174 if (to_rational(lowers[j]) < r && r < to_rational(uppers[j])) {
175 VERIFY(!found);
176 ENSURE(!visited[j_prime]);
177 found = true;
178 visited[j_prime] = true;
179 }
180 }
181 ENSURE(found);
182 }
183 }
184
tst_isolate_roots(polynomial_ref const & p,unsigned expected_sz,rational const * expected_roots,unsigned prec=5)185 static void tst_isolate_roots(polynomial_ref const & p, unsigned expected_sz, rational const * expected_roots, unsigned prec = 5) {
186 mpbq_manager bqm(p.m().m());
187 scoped_mpbq_vector roots(bqm);
188 scoped_mpbq_vector lowers(bqm);
189 scoped_mpbq_vector uppers(bqm);
190 tst_isolate_roots(p, prec, bqm, roots, lowers, uppers);
191 check_roots(roots, lowers, uppers, expected_sz, expected_roots);
192 }
193
tst_isolate_roots()194 static void tst_isolate_roots() {
195 reslimit rl;
196 polynomial::numeral_manager nm;
197 polynomial::manager m(rl, nm);
198 polynomial_ref x(m);
199 x = m.mk_polynomial(m.mk_var());
200 // create univariate polynomial using multivariate polynomial package
201 polynomial_ref p(m);
202 p = (x-1)*(x-2);
203 {
204 rational ex[2] = { rational(1), rational(2) };
205 tst_isolate_roots(p, 2, ex);
206 }
207 p = (x-1)*(x-1)*x*x*x;
208 {
209 rational ex[2] = { rational(1), rational(0) };
210 tst_isolate_roots(p, 2, ex);
211 }
212 p = (x^5) - x - 1;
213 {
214 rational ex[1] = { rational(11673039, 10000000) }; // approximated root
215 tst_isolate_roots(p, 1, ex);
216 }
217 p = (x - 1)*(x + 1)*(x + 2)*(x + 3)*((x - 3)^2);
218 {
219 rational ex[5] = { rational(1), rational(-1), rational(-2), rational(-3), rational(3) };
220 tst_isolate_roots(p, 5, ex);
221 }
222 p = (10000*x - 31)*(10000*x - 32);
223 {
224 rational ex[2] = { rational(31, 10000), rational(32, 10000) };
225 tst_isolate_roots(p, 2, ex, 10);
226 }
227 p = (10000*x - 31)*(10000*x - 32)*(10000*x - 33);
228 {
229 rational ex[3] = { rational(31, 10000), rational(32, 10000), rational(33, 10000) };
230 tst_isolate_roots(p, 3, ex, 10);
231 }
232 p = ((x^5) - x - 1)*((x^5) + x - 1)*(1000*x - 1167);
233 {
234 rational ex[3] = { rational(11673039, 10000000), // approximated
235 rational(75487766, 100000000), // approximated
236 rational(1167, 1000) };
237 tst_isolate_roots(p, 3, ex, 10);
238 }
239 p = (x - 2)*(x - 4)*(x - 8)*(x - 16)*(x - 32)*(x - 64)*(2*x - 1)*(4*x - 1)*(8*x - 1)*(16*x - 1)*(32*x - 1);
240 {
241 rational ex[11] = { rational(2), rational(4), rational(8), rational(16), rational(32), rational(64),
242 rational(1, 2), rational(1, 4), rational(1, 8), rational(1, 16), rational(1, 32) };
243 tst_isolate_roots(p, 11, ex, 10);
244 }
245 p = ((x^5) - x - 1)*((x^5) + x - 1)*(1000*x - 1167)*((x^5) - x - 1)*((x^5) + x - 1)*(1000*x - 1167);
246 {
247 rational ex[3] = { rational(11673039, 10000000), // approximated
248 rational(75487766, 100000000), // approximated
249 rational(1167, 1000) };
250 tst_isolate_roots(p, 3, ex, 10);
251 }
252 p = (x^17) + 5*(x^16) + 3*(x^15) + 10*(x^13) + 13*(x^10) + (x^9) + 8*(x^5) + 3*(x^2) + 7;
253 {
254 rational ex[3] = { rational(-413582, 100000), // approximated
255 rational(-170309, 100000), // approximated
256 rational(-109968, 100000), // approximated
257 };
258 tst_isolate_roots(p, 3, ex, 10);
259 }
260 p = ((x^17) + 5*(x^16) + 3*(x^15) + 10*(x^13) + 13*(x^10) + (x^9) + 8*(x^5) + 3*(x^2) + 7)*(((x^5) - x - 1)^2)*(((x^3) - 2)^2);
261 {
262 rational ex[5] = { rational(-413582, 100000), // approximated
263 rational(-170309, 100000), // approximated
264 rational(-109968, 100000), // approximated
265 rational(11673039, 10000000), // approximated
266 rational(125992, 100000) // approximated
267 };
268 tst_isolate_roots(p, 5, ex, 10);
269 }
270 p = (((x^5) - 1000000000)^3)*((3*x - 10000000)^2)*((10*x - 632)^2);
271 {
272 rational ex[3] = { rational(630957, 10000), // approximated
273 rational(10000000, 3),
274 rational(632, 10)
275 };
276 tst_isolate_roots(p, 3, ex, 10);
277 }
278
279 }
280
tst_remove_one_half()281 static void tst_remove_one_half() {
282 reslimit rl;
283 polynomial::numeral_manager nm;
284 polynomial::manager m(rl, nm);
285 polynomial_ref x(m);
286 x = m.mk_polynomial(m.mk_var());
287 // create univariate polynomial using multivariate polynomial package
288 polynomial_ref p(m), r(m);
289 p = 4*(x^3) - 12*(x^2) - x + 3;
290 r = 16*(x^2) - 40*x - 24;
291 upolynomial::manager um(rl, nm);
292 upolynomial::scoped_numeral_vector _p(um), _q(um), _r(um);
293 um.to_numeral_vector(p, _p);
294 um.to_numeral_vector(r, _r);
295 ENSURE(um.has_one_half_root(_p.size(), _p.data()));
296 um.remove_one_half_root(_p.size(), _p.data(), _q);
297 ENSURE(!um.has_one_half_root(_q.size(), _q.data()));
298 std::cout << "_p: "; um.display(std::cout, _p); std::cout << "\n";
299 std::cout << "_r: "; um.display(std::cout, _r); std::cout << "\n";
300 std::cout << "_q: "; um.display(std::cout, _q); std::cout << "\n";
301 ENSURE(um.eq(_q, _r));
302
303 p = (((x^5) - 1000000000)^3)*((3*x - 10000000)^2)*((10*x - 632)^2);
304 um.to_numeral_vector(p, _p);
305 ENSURE(!um.has_one_half_root(_p.size(), _p.data()));
306
307 p = (x - 2)*(x - 4)*(x - 8)*(x - 16)*(x - 32)*(x - 64)*(2*x - 1)*(4*x - 1)*(8*x - 1)*(16*x - 1)*(32*x - 1);
308 um.to_numeral_vector(p, _p);
309 ENSURE(um.has_one_half_root(_p.size(), _p.data()));
310 }
311
312 template<typename pmanager>
tst_gcd(polynomial_ref const & p,polynomial_ref const & q,pmanager & um)313 static void tst_gcd(polynomial_ref const & p, polynomial_ref const & q, pmanager & um) {
314 typename pmanager::scoped_numeral_vector _p(um.m()), _q(um.m()), _r(um.m());
315 um.to_numeral_vector(p, _p);
316 um.to_numeral_vector(q, _q);
317 std::cout << "_p: "; um.display(std::cout, _p); std::cout << "\n";
318 std::cout << "_q: "; um.display(std::cout, _q); std::cout << std::endl;
319 um.gcd(_p.size(), _p.data(), _q.size(), _q.data(), _r);
320 std::cout << "gcd: "; um.display(std::cout, _r); std::cout << "\n";
321 um.subresultant_gcd(_p.size(), _p.data(), _q.size(), _q.data(), _r);
322 std::cout << "_p: "; um.display(std::cout, _p); std::cout << "\n";
323 std::cout << "_q: "; um.display(std::cout, _q); std::cout << "\n";
324 std::cout << "subresultant_gcd: "; um.display(std::cout, _r); std::cout << "\n";
325 }
326
tst_gcd()327 static void tst_gcd() {
328 std::cout << "\n\nTesting GCD\n";
329 reslimit rl;
330 polynomial::numeral_manager nm;
331 polynomial::manager m(rl, nm);
332 polynomial_ref x(m);
333 x = m.mk_polynomial(m.mk_var());
334 // create univariate polynomial using multivariate polynomial package
335 polynomial_ref p(m);
336 polynomial_ref q(m);
337
338 upolynomial::manager um(rl, nm);
339
340 p = 13*((x - 3)^6)*((x - 5)^5)*((x - 11)^7);
341 q = derivative(p, 0);
342 tst_gcd(p, q, um);
343
344 return;
345
346 p = (x^8) + (x^6) - 3*(x^4) - 3*(x^3) + 8*(x^2) + 2*x - 5;
347 q = 3*(x^6) + 5*(x^4) - 4*(x^2) - 9*x + 21;
348
349 tst_gcd(p, q, um);
350
351 p = ((x - 1)^2)*(x - 3)*(x + 2)*((x - 5)^3);
352 q = (x + 1)*(x-1)*((x-3)^2)*(x + 3)*(x - 5);
353 tst_gcd(p, q, um);
354 std::cout << "expected: " << ((x - 1)*(x-3)*(x-5)) << "\n";
355
356 }
357
tst_zp()358 static void tst_zp() {
359 std::cout << "\n\nTesting Z_p\n";
360 reslimit rl;
361 polynomial::numeral_manager nm;
362 polynomial::manager m(rl, nm);
363 polynomial_ref x(m);
364 x = m.mk_polynomial(m.mk_var());
365 // create univariate polynomial using multivariate polynomial package
366 polynomial_ref p(m);
367 polynomial_ref q(m);
368 p = (x^4) + 2*(x^3) + 2*(x^2) + x;
369 q = (x^3) + x + 1;
370
371 // Computing GCD of p an q in Z[x]
372 std::cout << "GCD in Z[x]\n";
373 upolynomial::manager um(rl, nm);
374 tst_gcd(p, q, um);
375
376 // Computing GCD of p an q in Z_3[x]
377 std::cout << "GCD in Z_3[x]\n";
378 upolynomial::zp_manager um3(rl, nm);
379 um3.set_zp(3);
380 tst_gcd(p, q, um3);
381 }
382
tst_zp2()383 static void tst_zp2() {
384 std::cout << "\n\nTesting Z_p\n";
385 reslimit rl;
386 polynomial::numeral_manager nm;
387 polynomial::manager m(rl, nm);
388 polynomial_ref x(m);
389 x = m.mk_polynomial(m.mk_var());
390 // create univariate polynomial using multivariate polynomial package
391 polynomial_ref u(m);
392 polynomial_ref v(m);
393 v = (x^6) + 5*(x^5) + 9*(x^4) + 5*(x^2) + 5*x;
394 u = (x^8) + (x^6) + 10*(x^4) + 10*(x^3) + 8*(x^2) + 2*x + 8;
395
396 // Computing GCD of p an q in Z[x]
397 std::cout << "GCD in Z[x]\n";
398 upolynomial::manager um(rl, nm);
399 tst_gcd(u, v, um);
400
401 // Computing GCD of p an q in Z_3[x]
402 std::cout << "GCD in Z_13[x]\n";
403 upolynomial::zp_manager um13(rl, nm);
404 um13.set_zp(13);
405 tst_gcd(u, v, um13);
406 }
407
tst_ext_gcd()408 static void tst_ext_gcd() {
409 std::cout << "\nExtended GCD\n";
410 reslimit rl;
411 polynomial::numeral_manager nm;
412 polynomial::manager m(rl, nm);
413 polynomial_ref x(m);
414 x = m.mk_polynomial(m.mk_var());
415 // create univariate polynomial using multivariate polynomial package
416 polynomial_ref a(m);
417 polynomial_ref b(m);
418 a = (x^6) + 5*(x^5) + 9*(x^4) + 5*(x^2) + 5*x;
419 b = (x^8) + (x^6) + 10*(x^4) + 10*(x^3) + 8*(x^2) + 2*x + 8;
420
421 // Computing GCD of p an q in Z_3[x]
422 std::cout << "GCD in Z_13[x]\n";
423 upolynomial::zp_manager um(rl, nm);
424 um.set_zp(13);
425 mpzzp_manager & z13 = um.m();
426 upolynomial::zp_manager::scoped_numeral_vector A(z13), B(z13), U(z13), V(z13), D(z13);
427 um.to_numeral_vector(a, A);
428 um.to_numeral_vector(b, B);
429 um.ext_gcd(A.size(), A.data(), B.size(), B.data(), U, V, D);
430 std::cout << "A: "; um.display(std::cout, A); std::cout << "\n";
431 std::cout << "B: "; um.display(std::cout, B); std::cout << "\n";
432 std::cout << "U: "; um.display(std::cout, U); std::cout << "\n";
433 std::cout << "V: "; um.display(std::cout, V); std::cout << "\n";
434 std::cout << "D: "; um.display(std::cout, D); std::cout << "\n";
435 }
436
tst_ext_gcd_z7()437 static void tst_ext_gcd_z7() {
438 std::cout << "\nExtended GCD in Z_7\n";
439 reslimit rl;
440 polynomial::numeral_manager nm;
441 polynomial::manager m(rl, nm);
442 polynomial_ref x(m);
443 x = m.mk_polynomial(m.mk_var());
444 // create univariate polynomial using multivariate polynomial package
445 polynomial_ref a(m);
446 polynomial_ref b(m);
447
448 a = (x^3) + 2;
449 b = 6*(x^2) + 6;
450
451 // Computing GCD of a and b in Z_3[x]
452 // expecting: D = 1, U = 3*x + 6, V = 3*x^2 + 6*x + 4
453 std::cout << "GCD in Z_7[x]\n";
454 upolynomial::zp_manager um(rl, nm);
455 um.set_zp(7);
456 mpzzp_manager & z7 = um.m();
457 upolynomial::zp_manager::scoped_numeral_vector A(z7), B(z7), U(z7), V(z7), D(z7);
458 um.to_numeral_vector(a, A);
459 um.to_numeral_vector(b, B);
460 um.ext_gcd(A.size(), A.data(), B.size(), B.data(), U, V, D);
461 std::cout << "A: "; um.display(std::cout, A); std::cout << "\n";
462 std::cout << "B: "; um.display(std::cout, B); std::cout << "\n";
463 std::cout << "U: "; um.display(std::cout, U); std::cout << "\n";
464 std::cout << "V: "; um.display(std::cout, V); std::cout << "\n";
465 std::cout << "D: "; um.display(std::cout, D); std::cout << "\n";
466 }
467
tst_sturm()468 static void tst_sturm() {
469 std::cout << "\nSturm Seq\n";
470 reslimit rl;
471 polynomial::numeral_manager nm;
472 polynomial::manager m(rl, nm);
473 polynomial_ref x(m);
474 x = m.mk_polynomial(m.mk_var());
475 // create univariate polynomial using multivariate polynomial package
476 polynomial_ref p(m);
477 p = 7*(x^10) + 3*(x^9) + (x^8) + (x^6) + 10*(x^4) + 10*(x^3) + 8*(x^2) + 2*x + 8;
478 // p = ((x^17) + 5*(x^16) + 3*(x^15) + 10*(x^13) + 13*(x^10) + (x^9) + 8*(x^5) + 3*(x^2) + 7)*(((x^5) - x - 1)^2)*(((x^3) - 2)^2);
479 // p = ((x^17) + 5*(x^16) + 3*(x^15) + 10*(x^13) + 13*(x^10) + (x^9) + 8*(x^5) + 3*(x^2) + 7)*(((x^5) - x - 1))*(((x^3) - 2));
480
481 upolynomial::manager um(rl, nm);
482 upolynomial::scoped_numeral_vector _p(um);
483 upolynomial::scoped_upolynomial_sequence seq2(um);
484 um.to_numeral_vector(p, _p);
485 um.sturm_seq(_p.size(), _p.data(), seq2);
486 std::cout << "upolynomial sturm seq...\n";
487 um.display(std::cout, seq2);
488 }
489
490
tst_refinable(polynomial_ref const & p,mpbq_manager & bqm,mpbq & a,mpbq & b)491 static void tst_refinable(polynomial_ref const & p, mpbq_manager & bqm, mpbq & a, mpbq & b) {
492 reslimit rl;
493 upolynomial::manager um(rl, p.m().m());
494 upolynomial::scoped_numeral_vector _p(um);
495 um.to_numeral_vector(p, _p);
496 std::cout << "before (" << bqm.to_string(a) << ", " << bqm.to_string(b) << ")\n";
497 bool r = um.isolating2refinable(_p.size(), _p.data(), bqm, a, b);
498 if (r) {
499 std::cout << "new (" << bqm.to_string(a) << ", " << bqm.to_string(b) << ")\n";
500 int sign_a = um.eval_sign_at(_p.size(), _p.data(), a);
501 int sign_b = um.eval_sign_at(_p.size(), _p.data(), b);
502 VERIFY(sign_a != 0 && sign_b != 0 && sign_a == -sign_b);
503 }
504 else {
505 std::cout << "new root: " << bqm.to_string(a) << "\n";
506 ENSURE(um.eval_sign_at(_p.size(), _p.data(), a) == 0);
507 }
508 }
509
tst_refinable()510 static void tst_refinable() {
511 std::cout << "\nRefinable intervals\n";
512 reslimit rl;
513 polynomial::numeral_manager nm;
514 polynomial::manager m(rl, nm);
515 polynomial_ref x(m);
516 x = m.mk_polynomial(m.mk_var());
517 // create univariate polynomial using multivariate polynomial package
518 polynomial_ref p(m);
519 p = (x - 1)*(4*x - 11)*(x - 3);
520 std::cout << "p: " << p << "\n";
521 mpbq_manager bqm(nm);
522 mpbq a(1);
523 mpbq b(3);
524 tst_refinable(p, bqm, a, b);
525 bqm.set(a, 2);
526 bqm.set(b, 3);
527 tst_refinable(p, bqm, a, b);
528 bqm.set(a, 5, 1);
529 bqm.set(b, 3);
530 tst_refinable(p, bqm, a, b);
531
532 p = (x - 1)*(5*x - 11)*(x - 3);
533 std::cout << "p: " << p << "\n";
534 bqm.set(a, 1);
535 bqm.set(b, 3);
536 tst_refinable(p, bqm, a, b);
537 bqm.set(a, 2);
538 bqm.set(b, 3);
539 tst_refinable(p, bqm, a, b);
540 bqm.set(a, 3, 1);
541 bqm.set(b, 3);
542 tst_refinable(p, bqm, a, b);
543 bqm.set(a, 1);
544 bqm.set(b, 5, 1);
545 tst_refinable(p, bqm, a, b);
546 bqm.set(a, 3, 1);
547 bqm.set(b, 5, 1);
548 tst_refinable(p, bqm, a, b);
549
550 p = (x - 1)*(x - 2)*(x - 3);
551 std::cout << "p: " << p << "\n";
552 bqm.set(a, 1);
553 bqm.set(b, 3);
554 tst_refinable(p, bqm, a, b);
555
556 bqm.del(a); bqm.del(b);
557 }
558
tst_refine(polynomial_ref const & p,mpbq_manager & bqm,mpbq & a,mpbq & b,unsigned prec_k=100)559 static void tst_refine(polynomial_ref const & p, mpbq_manager & bqm, mpbq & a, mpbq & b, unsigned prec_k=100) {
560 reslimit rl; upolynomial::manager um(rl, p.m().m());
561 upolynomial::scoped_numeral_vector _p(um);
562 um.to_numeral_vector(p, _p);
563 std::cout << "before (" << bqm.to_string(a) << ", " << bqm.to_string(b) << ")\n";
564 bool r = um.refine(_p.size(), _p.data(), bqm, a, b, prec_k);
565 if (r) {
566 std::cout << "new (" << bqm.to_string(a) << ", " << bqm.to_string(b) << ")\n";
567 std::cout << "as decimal: "; bqm.display_decimal(std::cout, a, prec_k); std::cout << "\n";
568 }
569 else {
570 std::cout << "new root: " << bqm.to_string(a) << "\n";
571 std::cout << "as decimal: "; bqm.display_decimal(std::cout, a, prec_k); std::cout << "\n";
572 }
573 }
574
tst_refine()575 static void tst_refine() {
576 std::cout << "\nRefining intervals\n";
577 reslimit rl;
578 polynomial::numeral_manager nm;
579 polynomial::manager m(rl, nm);
580 polynomial_ref x(m);
581 x = m.mk_polynomial(m.mk_var());
582 // create univariate polynomial using multivariate polynomial package
583 polynomial_ref p(m);
584 p = (x^5) - x - 1;
585 std::cout << "p: " << p << "\n";
586 mpbq_manager bqm(nm);
587 scoped_mpbq a(bqm), b(bqm);
588 a = 1;
589 b = 2;
590 tst_refine(p, bqm, a, b, 20);
591
592 p = (x^2) - 2;
593 std::cout << "p: " << p << "\n";
594 a = 1;
595 b = 2;
596 tst_refine(p, bqm, a, b, 200);
597 }
598
tst_translate_q()599 static void tst_translate_q() {
600 reslimit rl;
601 unsynch_mpq_manager nm;
602 polynomial::manager m(rl, nm);
603 polynomial_ref x(m);
604 x = m.mk_polynomial(m.mk_var());
605 // create univariate polynomial using multivariate polynomial package
606 polynomial_ref p(m);
607 p = (x-1)*(x-2)*(x-3)*(x-4);
608 upolynomial::manager um(rl, nm);
609 upolynomial::scoped_numeral_vector _p(um), _q(um);
610 um.to_numeral_vector(p, _p);
611 ENSURE(um.eval_sign_at(_p.size(), _p.data(), mpq(1)) == 0);
612 ENSURE(um.eval_sign_at(_p.size(), _p.data(), mpq(2)) == 0);
613 ENSURE(um.eval_sign_at(_p.size(), _p.data(), mpq(3)) == 0);
614 ENSURE(um.eval_sign_at(_p.size(), _p.data(), mpq(4)) == 0);
615 ENSURE(um.eval_sign_at(_p.size(), _p.data(), mpq(-1)) != 0);
616 ENSURE(um.eval_sign_at(_p.size(), _p.data(), mpq(5)) != 0);
617 ENSURE(um.eval_sign_at(_p.size(), _p.data(), mpq(-2)) != 0);
618 scoped_mpq c(nm);
619 nm.set(c, 1, 3);
620 scoped_mpq r1(nm);
621 r1 = 1;
622 r1 -= c;
623 scoped_mpq r2(nm);
624 r2 = 3;
625 r2 -= c;
626 ENSURE(um.eval_sign_at(_p.size(), _p.data(), r1) != 0);
627 ENSURE(um.eval_sign_at(_p.size(), _p.data(), r2) != 0);
628 std::cout << "p: "; um.display(std::cout, _p); std::cout << "\n";
629 um.translate_q(_p.size(), _p.data(), c, _q);
630 std::cout << "q: "; um.display(std::cout, _q); std::cout << "\n";
631 ENSURE(um.eval_sign_at(_q.size(), _q.data(), mpq(1)) != 0);
632 ENSURE(um.eval_sign_at(_q.size(), _q.data(), mpq(2)) != 0);
633 ENSURE(um.eval_sign_at(_q.size(), _q.data(), mpq(3)) != 0);
634 ENSURE(um.eval_sign_at(_q.size(), _q.data(), mpq(4)) != 0);
635 ENSURE(um.eval_sign_at(_q.size(), _q.data(), mpq(-1)) != 0);
636 ENSURE(um.eval_sign_at(_q.size(), _q.data(), mpq(5)) != 0);
637 ENSURE(um.eval_sign_at(_q.size(), _q.data(), mpq(-2)) != 0);
638 ENSURE(um.eval_sign_at(_q.size(), _q.data(), r1) == 0);
639 ENSURE(um.eval_sign_at(_q.size(), _q.data(), r2) == 0);
640 um.p_1_div_x(_p.size(), _p.data());
641 std::cout << "p: "; um.display(std::cout, _p); std::cout << "\n";
642 ENSURE(um.eval_sign_at(_p.size(), _p.data(), mpq(1)) == 0);
643 nm.set(c, 1, 2);
644 ENSURE(um.eval_sign_at(_p.size(), _p.data(), c) == 0);
645 nm.set(c, 1, 3);
646 ENSURE(um.eval_sign_at(_p.size(), _p.data(), c) == 0);
647 nm.set(c, 1, 4);
648 ENSURE(um.eval_sign_at(_p.size(), _p.data(), c) == 0);
649 ENSURE(um.eval_sign_at(_p.size(), _p.data(), mpq(2)) != 0);
650 ENSURE(um.eval_sign_at(_p.size(), _p.data(), mpq(3)) != 0);
651 ENSURE(um.eval_sign_at(_p.size(), _p.data(), mpq(4)) != 0);
652 }
653
tst_convert_q2bq(unsynch_mpq_manager & m,polynomial_ref const & p,mpq const & a,mpq const & b)654 static void tst_convert_q2bq(unsynch_mpq_manager & m, polynomial_ref const & p, mpq const & a, mpq const & b) {
655 reslimit rl;
656 upolynomial::manager um(rl, m);
657 upolynomial::scoped_numeral_vector _p(um);
658 um.to_numeral_vector(p, _p);
659 std::cout << "\np: ";
660 um.display(std::cout, _p); std::cout << "\n";
661 std::cout << "before (" << m.to_string(a) << ", " << m.to_string(b) << ") (";
662 m.display_decimal(std::cout, a, 10); std::cout << ", "; m.display_decimal(std::cout, b, 10); std::cout << ")\n";
663 mpbq_manager bqm(m);
664 scoped_mpbq c(bqm);
665 scoped_mpbq d(bqm);
666 if (!um.convert_q2bq_interval(_p.size(), _p.data(), a, b, bqm, c, d)) {
667 std::cout << "found root: " << c << "\n";
668 }
669 else {
670 std::cout << "after (" << c << ", " << d << ")" << " (";
671 bqm.display_decimal(std::cout, c, 10); std::cout << ", "; bqm.display_decimal(std::cout, d, 10); std::cout << ")\n";
672 }
673 }
674
tst_convert_q2bq()675 static void tst_convert_q2bq() {
676 reslimit rl;
677 unsynch_mpq_manager nm;
678 polynomial::manager m(rl, nm);
679 polynomial_ref x(m);
680 x = m.mk_polynomial(m.mk_var());
681 // create univariate polynomial using multivariate polynomial package
682 polynomial_ref p(m);
683 p = (x-1)*(x-2)*(x-3)*(x-4);
684 scoped_mpq a(nm), b(nm);
685
686 nm.set(a, 1, 3);
687 nm.set(b, 7, 5);
688 tst_convert_q2bq(nm, p, a, b);
689
690 nm.set(a, 1, 2);
691 nm.set(b, 7, 5);
692 tst_convert_q2bq(nm, p, a, b);
693
694 nm.set(a, 3, 7);
695 nm.set(b, 3, 2);
696 tst_convert_q2bq(nm, p, a, b);
697
698 nm.set(a, 0);
699 nm.set(b, 3, 2);
700 tst_convert_q2bq(nm, p, a, b);
701
702 nm.set(a, 0);
703 nm.set(b, 23, 21);
704 tst_convert_q2bq(nm, p, a, b);
705
706 nm.set(a, 7, 2);
707 nm.set(b, 5);
708 tst_convert_q2bq(nm, p, a, b);
709
710 nm.set(a, 999, 1000);
711 nm.set(b, 1001, 1000);
712 tst_convert_q2bq(nm, p, a, b);
713
714 nm.set(a, 9999, 10000);
715 nm.set(b, 10001, 10000);
716 tst_convert_q2bq(nm, p, a, b);
717
718 nm.set(a, 39999, 10000);
719 nm.set(b, 40001, 10000);
720 tst_convert_q2bq(nm, p, a, b);
721 }
722
tst_sturm2()723 static void tst_sturm2() {
724 reslimit rl;
725 polynomial::numeral_manager nm;
726 polynomial::manager m(rl, nm);
727 polynomial_ref x(m);
728 x = m.mk_polynomial(m.mk_var());
729 // create univariate polynomial using multivariate polynomial package
730 polynomial_ref p(m);
731 polynomial_ref q(m);
732
733 p = (x^16) - 136*(x^14) + 6476*(x^12) - 141912*(x^10) + 1513334*(x^8) - 7453176*(x^6) + 13950764*(x^4) - 5596840*(x^2) + 46225;
734 q = ((x^8) - 40*(x^6) + 352*(x^4) - 960*(x^2) + 576)^2;
735
736 upolynomial::manager um(rl, nm);
737 upolynomial::scoped_numeral_vector _p(um), _q(um);
738 upolynomial::scoped_upolynomial_sequence seq2(um);
739 um.to_numeral_vector(p, _p);
740 um.to_numeral_vector(q, _q);
741 um.sturm_tarski_seq(_p.size(), _p.data(), _q.size(), _q.data(), seq2);
742
743 std::cout << "upolynomial sturm seq...\n";
744 um.display(std::cout, seq2);
745 }
746
747 #if 0
748 static void tst_isolate_roots2() {
749 polynomial::numeral_manager nm;
750 polynomial::manager m(nm);
751 polynomial_ref x(m);
752 x = m.mk_polynomial(m.mk_var());
753 // create univariate polynomial using multivariate polynomial package
754 polynomial_ref p(m);
755 p = (2*x - 1)*(x - 21)*(x + 12)*(x - 19)*(x + 11)*(x + 34)*(x - 9)*(x - 72)*(10000*x - 4999)*((x^5) - x - 1)*((x^2) - 2)*((x^2) - 3)*((x^7) - 3)*((x^101) - 3);
756 {
757 tst_isolate_roots(p, 10);
758 }
759 }
760
761 static void tst_isolate_roots3() {
762 polynomial::numeral_manager nm;
763 polynomial::manager m(nm);
764 polynomial_ref x1(m), x2(m), x3(m), x4(m), x5(m), x6(m), x(m);
765 x = m.mk_polynomial(m.mk_var());
766 x1 = m.mk_polynomial(m.mk_var());
767 x2 = m.mk_polynomial(m.mk_var());
768 x3 = m.mk_polynomial(m.mk_var());
769 x4 = m.mk_polynomial(m.mk_var());
770 x5 = m.mk_polynomial(m.mk_var());
771 x6 = m.mk_polynomial(m.mk_var());
772 // create univariate polynomial using multivariate polynomial package
773 polynomial_ref p1(m);
774 polynomial_ref p2(m);
775 polynomial_ref p3(m);
776 polynomial_ref p4(m);
777 polynomial_ref p5(m);
778 polynomial_ref p6(m);
779 polynomial_ref q(m);
780 polynomial_ref r(m);
781 p1 = ((x1^2) - 2);
782 p2 = ((x2^2) - 3);
783 p3 = ((x3^2) - 5);
784 p4 = ((x4^2) - 7);
785 p5 = ((x5^2) - 11);
786 p6 = ((x6^2) - 13);
787 q = (x - x1 - x2 - x3 - x4 - x5 - x6);
788 r = resultant(resultant(resultant(resultant(resultant(resultant(q, p1, 1), p2, 2), p3, 3), p4, 4), p5, 5), p6, 6);
789 std::cout << "r: " << r << "\n";
790 {
791 timeit timer(true, "isolate");
792 tst_isolate_roots(r, 10);
793 }
794 }
795
796 static void tst_gcd2() {
797 polynomial::numeral_manager nm;
798 polynomial::manager m(nm);
799 polynomial_ref x(m);
800 x = m.mk_polynomial(m.mk_var());
801 // create univariate polynomial using multivariate polynomial package
802 polynomial_ref p(m);
803 p = ((x^1000) - x + 1)^5;
804
805 reslimit rl; upolynomial::manager um(rl, nm);
806 upolynomial::scoped_numeral_vector _p(um);
807 upolynomial::scoped_numeral_vector _p_sqf(um);
808 um.to_numeral_vector(p, _p);
809 {
810 timeit timer(true, "gcd");
811 um.square_free(_p.size(), _p.c_ptr(), _p_sqf);
812 }
813 um.display(std::cout, _p_sqf.size(), _p_sqf.c_ptr()); std::cout << "\n";
814 }
815 #endif
816
tst_isolate_roots5()817 static void tst_isolate_roots5() {
818 reslimit rl;
819 polynomial::numeral_manager nm;
820 polynomial::manager m(rl, nm);
821 polynomial_ref x(m);
822 x = m.mk_polynomial(m.mk_var());
823 // create univariate polynomial using multivariate polynomial package
824 polynomial_ref p(m);
825 p = (x^70) - 6*(x^65) - (x^60) + 60*(x^55) - 54*(x^50) - 230*(x^45) + 274*(x^40) + 542*(x^35) - 615*(x^30)
826 - 1120*(x^25) + 1500*(x^20) - 160*(x^15) - 395*(x^10) + 76*(x^5) + 34;
827 {
828 tst_isolate_roots(p, 10);
829 }
830 }
831
tst_exact_div(polynomial_ref const & p1,polynomial_ref const & p2,bool expected,polynomial_ref const & expected_q)832 static void tst_exact_div(polynomial_ref const & p1, polynomial_ref const & p2, bool expected, polynomial_ref const & expected_q) {
833 reslimit rl;
834 upolynomial::manager um(rl, p1.m().m());
835 upolynomial::scoped_numeral_vector _p1(um), _p2(um), _q(um), _r(um);
836 um.to_numeral_vector(p1, _p1);
837 um.to_numeral_vector(p2, _p2);
838 if (expected)
839 um.to_numeral_vector(expected_q, _q);
840 std::cout << "------\n";
841 std::cout << "p1: "; um.display(std::cout, _p1); std::cout << "\n";
842 std::cout << "p2: "; um.display(std::cout, _p2); std::cout << std::endl;
843 bool res = um.exact_div(_p1.size(), _p1.data(), _p2.size(), _p2.data(), _r);
844 if (res) {
845 std::cout << "r: "; um.display(std::cout, _r); std::cout << "\n";
846 }
847 if (expected) {
848 std::cout << "expected: "; um.display(std::cout, _q); std::cout << "\n";
849 }
850 std::cout.flush();
851 ENSURE(res == expected);
852 ENSURE(expected == um.divides(_p1.size(), _p1.data(), _p2.size(), _p2.data()));
853 ENSURE(!expected || um.eq(_r, _q));
854 }
855
tst_exact_div()856 static void tst_exact_div() {
857 reslimit rl;
858 polynomial::numeral_manager nm;
859 polynomial::manager m(rl, nm);
860 polynomial_ref x(m);
861 x = m.mk_polynomial(m.mk_var());
862 // create univariate polynomial using multivariate polynomial package
863 polynomial_ref p(m);
864 tst_exact_div((x - 1)*(x - 2)*(x - 3), (x-2)*(x-1), true, (x-3));
865 tst_exact_div((x - 1)*(2*x - 4)*(x - 3), (x-2)*(x-1), true, (2*x-6));
866 tst_exact_div((x - 1)*(2*x - 4)*(x - 3), (x-2)*(x-1)*(x-4), false, x);
867 tst_exact_div((x - 3), (x-1), false, x);
868 polynomial_ref z(m);
869 z = m.mk_const(rational(0));
870 tst_exact_div(z, (x-2)*(x-1)*(x-4), true, z);
871 tst_exact_div((x-2)*(x-1)*(x-4), z, false, z);
872 tst_exact_div(z, z, false, z);
873 polynomial_ref two(m);
874 two = m.mk_const(rational(2));
875 tst_exact_div((2*x - 2), (x-1), true, two);
876 tst_exact_div((2*x - 2), (4*x-4), false, two);
877 tst_exact_div((6*x - 4), two, true, (3*x - 2));
878 }
879
tst_fact(polynomial_ref const & p,unsigned num_distinct_factors,upolynomial::factor_params const & params=upolynomial::factor_params ())880 static void tst_fact(polynomial_ref const & p, unsigned num_distinct_factors, upolynomial::factor_params const & params = upolynomial::factor_params()) {
881 ENSURE(is_univariate(p));
882 std::cout << "---------------\n";
883 std::cout << "p: " << p << std::endl;
884 reslimit rl; upolynomial::manager um(rl, p.m().m());
885 upolynomial::scoped_numeral_vector _p(um);
886 upolynomial::factors fs(um);
887 um.to_numeral_vector(p, _p);
888 um.factor(_p, fs, params);
889 std::cout << "factors:\n";
890 std::cout << um.m().to_string(fs.get_constant()) << "\n";
891 for (unsigned i = 0; i < fs.distinct_factors(); i++) {
892 std::cout << "*("; um.display(std::cout, fs[i]); std::cout << ")^" << fs.get_degree(i) << std::endl;
893 }
894 std::cout << fs.distinct_factors() << " " << num_distinct_factors << "\n";
895 ENSURE(fs.distinct_factors() == num_distinct_factors);
896 upolynomial::scoped_numeral_vector _r(um);
897 fs.multiply(_r);
898 TRACE("upolynomial", tout << "_r: "; um.display(tout, _r); tout << "\n_p: "; um.display(tout, _p); tout << "\n";);
899 ENSURE(um.eq(_p, _r));
900 }
901
tst_fact()902 static void tst_fact() {
903 reslimit rl;
904 polynomial::numeral_manager nm;
905 polynomial::manager m(rl, nm);
906 polynomial_ref x0(m);
907 x0 = m.mk_polynomial(m.mk_var());
908 tst_fact((x0^4) + (x0^2) - 20, 3);
909 tst_fact((x0^4) + (x0^2) - 20, 1, upolynomial::factor_params(5, 1, 1000));
910 tst_fact((x0^4) + (x0^2) - 20, 1, upolynomial::factor_params(7, 1, 1000));
911 tst_fact((x0^70) - 6*(x0^65) - (x0^60) + 60*(x0^55) - 54*(x0^50) - 230*(x0^45) + 274*(x0^40) + 542*(x0^35) - 615*(x0^30) - 1120*(x0^25) + 1500*(x0^20) - 160*(x0^15) - 395*(x0^10) + 76*(x0^5) + 34, 1, upolynomial::factor_params(3, 1, 20));
912 tst_fact((x0^70) - 6*(x0^65) - (x0^60) + 60*(x0^55) - 54*(x0^50) - 230*(x0^45) + 274*(x0^40) + 542*(x0^35) - 615*(x0^30) - 1120*(x0^25) + 1500*(x0^20) - 160*(x0^15) - 395*(x0^10) + 76*(x0^5) + 34, 1, upolynomial::factor_params(3, 1, 72));
913 tst_fact((x0^70) - 6*(x0^65) - (x0^60) + 60*(x0^55) - 54*(x0^50) - 230*(x0^45) + 274*(x0^40) + 542*(x0^35) - 615*(x0^30) - 1120*(x0^25) + 1500*(x0^20) - 160*(x0^15) - 395*(x0^10) + 76*(x0^5) + 34, 1, upolynomial::factor_params(3, 1, 80));
914 tst_fact( (x0^10) - 10*(x0^8) + 38*(x0^6) - 2*(x0^5) - 100*(x0^4) - 40*(x0^3) + 121*(x0^2) - 38*x0 - 17, 1);
915 tst_fact( (x0^4) - 404*(x0^2) + 39204, 2);
916 tst_fact(((x0^5) - (x0^2) + 1)*((-1)*x0 + 1)*((x0^2) - 2*x0 + 3), 3);
917 tst_fact((x0^4) + (x0^2) - 20, 3);
918 tst_fact((-11)*((x0^5) - (x0^2) + 1)*((-1)*x0 + 1)*((x0^2) - 2*x0 + 3), 3);
919 tst_fact(x0 - 2*(x0^2) + 1, 2);
920 tst_fact(13*((x0 - 3)^6)*((x0 - 5)^5)*((x0 - 11)^7), 3);
921 tst_fact((x0+1)^30, 1);
922 tst_fact((x0^70) - 6*(x0^65) - (x0^60) + 60*(x0^55) - 54*(x0^50) - 230*(x0^45) + 274*(x0^40) + 542*(x0^35) - 615*(x0^30) - 1120*(x0^25) + 1500*(x0^20) - 160*(x0^15) - 395*(x0^10) + 76*(x0^5) + 34, 3);
923 tst_fact(((x0^4) - 8*(x0^2)), 2);
924 tst_fact((x0^5) - 2*(x0^3) + x0 - 1, 1);
925 tst_fact( (x0^25) - 4*(x0^21) - 5*(x0^20) + 6*(x0^17) + 11*(x0^16) + 10*(x0^15) - 4*(x0^13) - 7*(x0^12) - 9*(x0^11) - 10*(x0^10) +
926 (x0^9) + (x0^8) + (x0^7) + (x0^6) + 3*(x0^5) + x0 - 1, 2);
927 tst_fact( (x0^25) - 10*(x0^21) - 10*(x0^20) - 95*(x0^17) - 470*(x0^16) - 585*(x0^15) - 40*(x0^13) - 1280*(x0^12) - 4190*(x0^11) - 3830*(x0^10) + 400*(x0^9)+ 1760*(x0^8) + 760*(x0^7) - 2280*(x0^6) + 449*(x0^5) + 640*(x0^3) - 640*(x0^2) + 240*x0 - 32, 2);
928 tst_fact( x0^10, 1);
929 tst_fact( (x0^2) - 1, 2);
930 tst_fact( (-2)*(x0^2) + 2, 2);
931 polynomial_ref zero(m);
932 polynomial_ref three(m);
933 zero = m.mk_zero();
934 three = m.mk_const(rational(3));
935 tst_fact(zero, 0);
936 tst_fact(three, 0);
937 tst_fact(x0 + 1, 1);
938 tst_fact(x0 - 1, 1);
939 tst_fact((-1)*x0 - 1, 1);
940 tst_fact((-1)*x0 + 1, 1);
941 tst_fact( (x0^10) - 10*(x0^8) + 38*(x0^6) - 2*(x0^5) - 100*(x0^4) - 40*(x0^3) + 121*(x0^2) - 38*x0 - 17, 1);
942 tst_fact( (x0^50) - 10*(x0^40) + 38*(x0^30) - 2*(x0^25) - 100*(x0^20) - 40*(x0^15) + 121*(x0^10) - 38*(x0^5) - 17, 1);
943
944 tst_fact( (((x0^5) + 5*(x0^4) + 10*(x0^3) + 10*(x0^2) + 5*x0)^10)
945 + 10*(((x0^5) + 5*(x0^4) + 10*(x0^3) + 10*(x0^2) + 5*x0)^9)
946 + 35*(((x0^5) + 5*(x0^4) + 10*(x0^3) + 10*(x0^2) + 5*x0)^8)
947 + 40*(((x0^5) + 5*(x0^4) + 10*(x0^3) + 10*(x0^2) + 5*x0)^7)
948 - 32*(((x0^5) + 5*(x0^4) + 10*(x0^3) + 10*(x0^2) + 5*x0)^6)
949 - 82*(((x0^5) + 5*(x0^4) + 10*(x0^3) + 10*(x0^2) + 5*x0)^5)
950 - 30*(((x0^5) + 5*(x0^4) + 10*(x0^3) + 10*(x0^2) + 5*x0)^4)
951 - 140*(((x0^5) + 5*(x0^4) + 10*(x0^3) + 10*(x0^2) + 5*x0)^3)
952 - 284*(((x0^5) + 5*(x0^4) + 10*(x0^3) + 10*(x0^2) + 5*x0)^2)
953 - 168*((x0^5) + 5*(x0^4) + 10*(x0^3) + 10*(x0^2) + 5*x0)
954 - 47, 1);
955
956 tst_fact( (x0^4) - 404*(x0^2) + 39204, 2);
957 tst_fact( ((x0^5) - 15552)*
958 ((x0^20)- 15708*(x0^15) + rational("138771724")*(x0^10)- rational("432104148432")*(x0^5) + rational("614198284585616")),
959 2);
960 tst_fact( (x0^25) -
961 rational("3125")*(x0^21) -
962 rational("15630")*(x0^20) +
963 rational("3888750")*(x0^17) +
964 rational("38684375")*(x0^16) +
965 rational("95765635")*(x0^15) -
966 rational("2489846500")*(x0^13) -
967 rational("37650481875")*(x0^12) -
968 rational("190548065625")*(x0^11) -
969 rational("323785250010")*(x0^10) +
970 rational("750249453025")*(x0^9) +
971 rational("14962295699875")*(x0^8) +
972 rational("111775113235000")*(x0^7) +
973 rational("370399286731250")*(x0^6) +
974 rational("362903064503129")*(x0^5) -
975 rational("2387239013984400")*(x0^4) -
976 rational("23872390139844000")*(x0^3) -
977 rational("119361950699220000")*(x0^2) -
978 rational("298404876748050000")*x0 -
979 rational("298500366308609376"), 2);
980
981 tst_fact( rational("54")*(x0^24) - (x0^27) - 324*(x0^21) + rational("17496")*(x0^18) - 34992*(x0^15)+ rational("1889568")*(x0^12)- 1259712*(x0^9) + rational("68024448")*(x0^6), 3);
982
983 tst_fact( ((x0^3)- 432)*(((x0^3)+54)^2)*((x0^6)+108)*((x0^6)+6912)*((x0^6)- 324*(x0^3)+37044),
984 5);
985
986 tst_fact( ((x0^6)- 6*(x0^4) - 864*(x0^3) + 12*(x0^2) - 5184*x0 + 186616)*
987 (((x0^6) - 6*(x0^4) + 108*(x0^3) + 12*(x0^2) + 648*x0 + 2908)^2)*
988 ((x0^12) - 12*(x0^10) + 60*(x0^8) + 56*(x0^6) + 6720*(x0^4) + 12768*(x0^2) + 13456)*
989 ((x0^12) - 12*(x0^10) + 60*(x0^8) + 13664*(x0^6) + 414960*(x0^4) + 829248*(x0^2) + 47886400)*
990 ((x0^12) - 12*(x0^10) - 648*(x0^9)+ 60*(x0^8) + 178904*(x0^6) + 15552*(x0^5) + 1593024*(x0^4) - 24045984*(x0^3) +
991 5704800*(x0^2) - 143995968*x0 + 1372010896),
992 5);
993 }
994
tst_rem(polynomial_ref const & p,polynomial_ref const & q,polynomial_ref const & expected)995 static void tst_rem(polynomial_ref const & p, polynomial_ref const & q, polynomial_ref const & expected) {
996 ENSURE(is_univariate(p));
997 ENSURE(is_univariate(q));
998 std::cout << "---------------\n";
999 std::cout << "p: " << p << std::endl;
1000 std::cout << "q: " << q << std::endl;
1001 reslimit rl; upolynomial::manager um(rl, p.m().m());
1002 upolynomial::scoped_numeral_vector _p(um), _q(um), _r(um);
1003 um.to_numeral_vector(p, _p);
1004 um.to_numeral_vector(q, _q);
1005 um.rem(_p.size(), _p.data(), _q.size(), _q.data(), _r);
1006 polynomial_ref r(p.m());
1007 r = p.m().to_polynomial(_r.size(), _r.data(), 0);
1008 std::cout << "r: " << r << std::endl;
1009 ENSURE(eq(expected, r));
1010 }
1011
tst_rem()1012 static void tst_rem() {
1013 reslimit rl;
1014 polynomial::numeral_manager nm;
1015 polynomial::manager m(rl, nm);
1016 polynomial_ref x0(m), zero(m), one(m);
1017 x0 = m.mk_polynomial(m.mk_var());
1018 zero = m.mk_zero();
1019 one = m.mk_const(rational(1));
1020 tst_rem((x0^2) + x0, x0, zero);
1021 tst_rem((x0^2) + x0 + 1, x0, one);
1022 tst_rem((x0^2) + 2*x0 + 1, 2*x0 + 2, zero);
1023 }
1024
tst_lower_bound(polynomial_ref const & p)1025 static void tst_lower_bound(polynomial_ref const & p) {
1026 ENSURE(is_univariate(p));
1027 std::cout << "---------------\n";
1028 std::cout << "p: " << p << std::endl;
1029 reslimit rl; upolynomial::manager um(rl, p.m().m());
1030 upolynomial::scoped_numeral_vector _p(um);
1031 um.to_numeral_vector(p, _p);
1032 std::cout << "_p: "; um.display(std::cout, _p); std::cout << "\n";
1033 unsigned k = um.nonzero_root_lower_bound(_p.size(), _p.data());
1034 std::cout << "_p: "; um.display(std::cout, _p); std::cout << "\n";
1035 std::cout << "k: " << k << "\n";
1036 }
1037
tst_lower_bound()1038 static void tst_lower_bound() {
1039 reslimit rl;
1040 polynomial::numeral_manager nm;
1041 polynomial::manager m(rl, nm);
1042 polynomial_ref x(m), zero(m), one(m);
1043 x = m.mk_polynomial(m.mk_var());
1044 zero = m.mk_zero();
1045 one = m.mk_const(rational(1));
1046 tst_lower_bound((x^2) - 2);
1047 tst_lower_bound((x^5));
1048 tst_lower_bound((x - 1)*(2*x - 1)*(4*x - 1)*(8*x - 1));
1049 tst_lower_bound((x - 1)*(2*x - 1)*(4*x - 1)*(8*x - 1)*(16*x - 1));
1050 tst_lower_bound((x - 1)*(2*x - 1)*(4*x - 1)*(8*x - 1)*(16*x - 1)*(x^3));
1051 tst_lower_bound((x^5) - x - 1);
1052 tst_lower_bound((1000*x - 1)*(x - 1));
1053 tst_lower_bound((x + 1)*(2*x - 1)*(4*x + 1)*(8*x - 1)*(16*x + 1));
1054 tst_lower_bound((x + 1)*(2*x + 1)*(4*x + 1)*(8*x + 1)*(16*x + 1));
1055 tst_lower_bound((x^10) - 10*(x^8) + 38*(x^6) - 2*(x^5) - 100*(x^4) - 40*(x^3) + 121*(x^2) - 38*x - 17);
1056 tst_lower_bound(((x^17) + 5*(x^16) + 3*(x^15) + 10*(x^13) + 13*(x^10) + (x^9) + 8*(x^5) + 3*(x^2) + 7)*(((x^5) - x - 1)^2)*(((x^3) - 2)^2));
1057 tst_lower_bound((((x^5) - 1000000000)^3)*((3*x - 10000000)^2)*((10*x - 632)^2));
1058 }
1059
tst_upolynomial()1060 void tst_upolynomial() {
1061 set_verbosity_level(1000);
1062 enable_trace("mpz_gcd");
1063 enable_trace("normalize_bug");
1064 enable_trace("factor_bug");
1065 enable_trace("factor");
1066 // enable_trace("mpzp_inv_bug");
1067 // enable_trace("mpz");
1068 tst_gcd();
1069 tst_lower_bound();
1070 tst_fact();
1071 tst_rem();
1072 tst_exact_div();
1073 tst_isolate_roots5();
1074 // tst_gcd2();
1075 // tst_isolate_roots4();
1076 // tst_isolate_roots3();
1077 // tst_isolate_roots2();
1078 // return;
1079 tst_isolate_roots();
1080 tst_sturm2();
1081 tst_convert_q2bq();
1082 enable_trace("div_bug");
1083 enable_trace("mpbq_bug");
1084 tst_translate_q();
1085 tst_refine();
1086 tst_refinable();
1087 tst_sturm();
1088 tst_remove_one_half();
1089 tst_isolate_roots();
1090 tst1();
1091 tst_zp();
1092 tst_zp2();
1093 tst_ext_gcd();
1094 tst_ext_gcd_z7();
1095 }
1096