Karim Belabas on Fri, 08 Jun 2018 08:30:13 +0200 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
Re: Counting real roots of integer polynomials |
* Gordon Royle [2018-06-08 07:48]: > However, I could not find a way to use polsturm effectively - the > polsturm in Pari 2.9.5 needs a squarefree polynomial, and while the > one in Pari 2.10.0 version will accept a non-square-free polynomial, > it only returns distinct roots. > > So to get the actual multiplicities, I could see no better way than > using “factor” to first factorise the polynomial, and then deal with > each factor separately. > > This proved to be a bad idea, because for polynomials of the size that > I am dealing with, “factor” takes about 5 times as long as just > running “polrootsreal”. Yes, in pure GP you can't easily do better. Here's another way using libpari's "squarefree factorization", which writes P in Z[X] as \prod F[i]^E[i] with F[i] squarefree and pairwise coprime. install(ZX_squff,"G&"); val(P) = { my (x = variable(P), v = 0, v2); P /= x-1; v2 = valuation(P, x-2); if (v2, P /= (x-2)^v2); F = ZX_squff(P, E); for (i = 1, #F, v += E[i] * polsturm(F[i], [1,2])); [v, v2]; } ? P = (x-1) * (2*x - 3)^3 * (x^2 - 2)^2 * (x-3)^3 * (x-2)^2; ? ZX_squff(P,E) %2 = [x - 1, x^3 - 2*x^2 - 2*x + 4, 2*x^2 - 9*x + 9]~ ? E %3 = Vecsmall([1, 2, 3]) ? val(P) %4 = [5, 2] It should be faster than polrootsreal (and much faster than factor): ? for(i=1,10^4,polrootsreal(P)) time = 2,903 ms. ? for(i=1,10^4,val(P)) time = 1,071 ms. Cheers, K.B. -- Karim Belabas, IMB (UMR 5251) Tel: (+33) (0)5 40 00 26 17 Universite de Bordeaux Fax: (+33) (0)5 40 00 21 23 351, cours de la Liberation http://www.math.u-bordeaux.fr/~kbelabas/ F-33405 Talence (France) http://pari.math.u-bordeaux.fr/ [PARI/GP] `