Gordon Royle on Thu, 11 Apr 2019 09:38:38 +0200 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
Re: Fast test for integer-rooted polynomial |
Dear All
Thank you all for your valuable suggestions.
I have done some more experimenting and timing based on your ideas and have come up with some that, experimentally, seems to be the best-so-far.
First: my matrices will almost never have integral eigenvalues and so the number of hits is very small and the number of misses very large; the largest case for which I have complete information is 11 x 11 matrices with 8400 hits out of a total
of just over 1 billion matrices, which is just less than 0.001 %.
So I created a test set of 10^6 matrices of order 12 x 12, seeded it with a couple of winners (to check that the functions recognise hits).
Then I tried the following four tests
test0(a) = my(p,f); p=charpoly(a);f=factor(p);vecmax(apply(poldegree,f[,1]))==1;
test1(a) = my(p = charpoly(a)); sum(i = 0, #a, valuation(p, x-i)) == #a;
testp(a) = my(p,f); p=charpoly(a);f1=factormod(p,31,1);if(vecsum(f1[,2])<#a,0,f=factor(p);vecmax(apply(poldegree,f[,1]))==1);
test2(a) = my(p=charpoly(a)); for (i=0,#a,while(subst(p,x,i)==0,p\=(x-i))); p==1;
Test0 is Denis Simon’s version of my original program
Test1 is Karim Belabas’s version using valuation
Testp is Denis Simon’s “check first modulo prime”
Test2 is my own version that just repeatedly factors out linear factors of the right type until there is nothing left
Outcome:
- the naive method using charpoly and factor took about 3m 30s
- the valuation method took MUCH LESS time, only 1m 20s
- the “check first modulo prime” took about 1m 30s
- my “repeatedly divide” method also took 1m 20s
The time taken in computing JUST the characteristic polynomials is 1m 12, and so the overhead after the characteristic polynomials is pretty
So somehow we need to avoid computing the char poly if possible.
I have one idea on this… suppose A is a winning matrix. Then
- it has integer roots in [0..#A]
- it has 0 as a simple eigenvalue (all of them do), and so
- A+I has integer roots in [1..#A+1]
Therefore the DETERMINANT of A+I must factorise into integers in the range [1..#A+1], so I can replace a characteristic polynomial calculation with a determinant calculation.
heuristictest3(a) = my(f=factor(matdet(a+matid(#a))));vecmax(f[,1])<=#a+1
This now takes only 55seconds to process my test set, but of course it produces some “false positives” which are matrices that pass the test based on the determinant, but actually don’t have integer eigenvalues at all. For my sample of 1000000 matrices,
it found 21 false positives, which take negligible time to remove at the end.
So good progress so far…
Thanks to all
Gordon
|